xref: /openbsd-src/gnu/llvm/libcxx/include/__iterator/iter_swap.h (revision 4bdff4bed0e3d54e55670334c7d0077db4170f86)
176d0caaeSpatrick // -*- C++ -*-
276d0caaeSpatrick //===----------------------------------------------------------------------===//
376d0caaeSpatrick //
476d0caaeSpatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
576d0caaeSpatrick // See https://llvm.org/LICENSE.txt for license information.
676d0caaeSpatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
776d0caaeSpatrick //
876d0caaeSpatrick //===----------------------------------------------------------------------===//
9*4bdff4beSrobert 
1076d0caaeSpatrick #ifndef _LIBCPP___ITERATOR_ITER_SWAP_H
1176d0caaeSpatrick #define _LIBCPP___ITERATOR_ITER_SWAP_H
1276d0caaeSpatrick 
13*4bdff4beSrobert #include <__concepts/class_or_enum.h>
14*4bdff4beSrobert #include <__concepts/swappable.h>
1576d0caaeSpatrick #include <__config>
1676d0caaeSpatrick #include <__iterator/concepts.h>
1776d0caaeSpatrick #include <__iterator/iter_move.h>
1876d0caaeSpatrick #include <__iterator/iterator_traits.h>
1976d0caaeSpatrick #include <__iterator/readable_traits.h>
20*4bdff4beSrobert #include <__type_traits/remove_cvref.h>
21*4bdff4beSrobert #include <__utility/declval.h>
22*4bdff4beSrobert #include <__utility/forward.h>
23*4bdff4beSrobert #include <__utility/move.h>
2476d0caaeSpatrick 
2576d0caaeSpatrick #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2676d0caaeSpatrick #  pragma GCC system_header
2776d0caaeSpatrick #endif
2876d0caaeSpatrick 
2976d0caaeSpatrick _LIBCPP_BEGIN_NAMESPACE_STD
3076d0caaeSpatrick 
31*4bdff4beSrobert #if _LIBCPP_STD_VER > 17
32*4bdff4beSrobert 
33*4bdff4beSrobert // [iter.cust.swap]
3476d0caaeSpatrick 
3576d0caaeSpatrick namespace ranges {
3676d0caaeSpatrick namespace __iter_swap {
3776d0caaeSpatrick   template<class _I1, class _I2>
3876d0caaeSpatrick   void iter_swap(_I1, _I2) = delete;
3976d0caaeSpatrick 
4076d0caaeSpatrick   template<class _T1, class _T2>
41*4bdff4beSrobert   concept __unqualified_iter_swap =
42*4bdff4beSrobert     (__class_or_enum<remove_cvref_t<_T1>> || __class_or_enum<remove_cvref_t<_T2>>) &&
requires(_T1 && __x,_T2 && __y)43*4bdff4beSrobert     requires (_T1&& __x, _T2&& __y) {
44*4bdff4beSrobert       // NOLINTNEXTLINE(libcpp-robust-against-adl) iter_swap ADL calls should only be made through ranges::iter_swap
4576d0caaeSpatrick       iter_swap(_VSTD::forward<_T1>(__x), _VSTD::forward<_T2>(__y));
4676d0caaeSpatrick     };
4776d0caaeSpatrick 
4876d0caaeSpatrick   template<class _T1, class _T2>
4976d0caaeSpatrick   concept __readable_swappable =
5076d0caaeSpatrick     indirectly_readable<_T1> && indirectly_readable<_T2> &&
5176d0caaeSpatrick     swappable_with<iter_reference_t<_T1>, iter_reference_t<_T2>>;
5276d0caaeSpatrick 
53*4bdff4beSrobert 
5476d0caaeSpatrick   struct __fn {
55*4bdff4beSrobert     // NOLINTBEGIN(libcpp-robust-against-adl) iter_swap ADL calls should only be made through ranges::iter_swap
5676d0caaeSpatrick     template <class _T1, class _T2>
5776d0caaeSpatrick       requires __unqualified_iter_swap<_T1, _T2>
5876d0caaeSpatrick     _LIBCPP_HIDE_FROM_ABI
operator__fn5976d0caaeSpatrick     constexpr void operator()(_T1&& __x, _T2&& __y) const
6076d0caaeSpatrick       noexcept(noexcept(iter_swap(_VSTD::forward<_T1>(__x), _VSTD::forward<_T2>(__y))))
6176d0caaeSpatrick     {
6276d0caaeSpatrick       (void)iter_swap(_VSTD::forward<_T1>(__x), _VSTD::forward<_T2>(__y));
6376d0caaeSpatrick     }
64*4bdff4beSrobert     // NOLINTEND(libcpp-robust-against-adl)
6576d0caaeSpatrick 
6676d0caaeSpatrick     template <class _T1, class _T2>
6776d0caaeSpatrick       requires (!__unqualified_iter_swap<_T1, _T2>) &&
6876d0caaeSpatrick                __readable_swappable<_T1, _T2>
6976d0caaeSpatrick     _LIBCPP_HIDE_FROM_ABI
operator__fn7076d0caaeSpatrick     constexpr void operator()(_T1&& __x, _T2&& __y) const
7176d0caaeSpatrick       noexcept(noexcept(ranges::swap(*_VSTD::forward<_T1>(__x), *_VSTD::forward<_T2>(__y))))
7276d0caaeSpatrick     {
7376d0caaeSpatrick       ranges::swap(*_VSTD::forward<_T1>(__x), *_VSTD::forward<_T2>(__y));
7476d0caaeSpatrick     }
7576d0caaeSpatrick 
7676d0caaeSpatrick     template <class _T1, class _T2>
7776d0caaeSpatrick       requires (!__unqualified_iter_swap<_T1, _T2> &&
7876d0caaeSpatrick                 !__readable_swappable<_T1, _T2>) &&
7976d0caaeSpatrick                indirectly_movable_storable<_T1, _T2> &&
8076d0caaeSpatrick                indirectly_movable_storable<_T2, _T1>
8176d0caaeSpatrick     _LIBCPP_HIDE_FROM_ABI
operator__fn8276d0caaeSpatrick     constexpr void operator()(_T1&& __x, _T2&& __y) const
8376d0caaeSpatrick       noexcept(noexcept(iter_value_t<_T2>(ranges::iter_move(__y))) &&
8476d0caaeSpatrick                noexcept(*__y = ranges::iter_move(__x)) &&
85*4bdff4beSrobert                noexcept(*_VSTD::forward<_T1>(__x) = std::declval<iter_value_t<_T2>>()))
8676d0caaeSpatrick     {
8776d0caaeSpatrick       iter_value_t<_T2> __old(ranges::iter_move(__y));
8876d0caaeSpatrick       *__y = ranges::iter_move(__x);
8976d0caaeSpatrick       *_VSTD::forward<_T1>(__x) = _VSTD::move(__old);
9076d0caaeSpatrick     }
9176d0caaeSpatrick   };
92*4bdff4beSrobert } // namespace __iter_swap
9376d0caaeSpatrick 
9476d0caaeSpatrick inline namespace __cpo {
9576d0caaeSpatrick   inline constexpr auto iter_swap = __iter_swap::__fn{};
9676d0caaeSpatrick } // namespace __cpo
9776d0caaeSpatrick } // namespace ranges
9876d0caaeSpatrick 
9976d0caaeSpatrick template<class _I1, class _I2 = _I1>
10076d0caaeSpatrick concept indirectly_swappable =
10176d0caaeSpatrick   indirectly_readable<_I1> && indirectly_readable<_I2> &&
requires(const _I1 __i1,const _I2 __i2)10276d0caaeSpatrick   requires(const _I1 __i1, const _I2 __i2) {
10376d0caaeSpatrick     ranges::iter_swap(__i1, __i1);
10476d0caaeSpatrick     ranges::iter_swap(__i2, __i2);
10576d0caaeSpatrick     ranges::iter_swap(__i1, __i2);
10676d0caaeSpatrick     ranges::iter_swap(__i2, __i1);
10776d0caaeSpatrick   };
10876d0caaeSpatrick 
109*4bdff4beSrobert #endif // _LIBCPP_STD_VER > 17
11076d0caaeSpatrick 
11176d0caaeSpatrick _LIBCPP_END_NAMESPACE_STD
11276d0caaeSpatrick 
11376d0caaeSpatrick #endif // _LIBCPP___ITERATOR_ITER_SWAP_H
114