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