1 //===----------------------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef _LIBCPP___ALGORITHM_ITERATOR_OPERATIONS_H 10 #define _LIBCPP___ALGORITHM_ITERATOR_OPERATIONS_H 11 12 #include <__algorithm/iter_swap.h> 13 #include <__config> 14 #include <__iterator/advance.h> 15 #include <__iterator/distance.h> 16 #include <__iterator/iter_move.h> 17 #include <__iterator/iter_swap.h> 18 #include <__iterator/iterator_traits.h> 19 #include <__iterator/next.h> 20 #include <__utility/forward.h> 21 #include <__utility/move.h> 22 #include <type_traits> 23 24 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 25 # pragma GCC system_header 26 #endif 27 28 _LIBCPP_BEGIN_NAMESPACE_STD 29 30 template <class _AlgPolicy> struct _IterOps; 31 32 #if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) 33 struct _RangeAlgPolicy {}; 34 35 template <> 36 struct _IterOps<_RangeAlgPolicy> { 37 static constexpr auto advance = ranges::advance; 38 static constexpr auto distance = ranges::distance; 39 static constexpr auto __iter_move = ranges::iter_move; 40 static constexpr auto iter_swap = ranges::iter_swap; 41 static constexpr auto next = ranges::next; 42 static constexpr auto __advance_to = ranges::advance; 43 }; 44 45 #endif 46 47 struct _ClassicAlgPolicy {}; 48 49 template <> 50 struct _IterOps<_ClassicAlgPolicy> { 51 52 // advance 53 template <class _Iter, class _Distance> 54 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 55 static void advance(_Iter& __iter, _Distance __count) { 56 std::advance(__iter, __count); 57 } 58 59 // distance 60 template <class _Iter> 61 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 62 static typename iterator_traits<_Iter>::difference_type distance(_Iter __first, _Iter __last) { 63 return std::distance(__first, __last); 64 } 65 66 // iter_move 67 template <class _Iter> 68 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 69 // Declaring the return type is necessary for C++03, so we basically mirror what `decltype(auto)` would deduce. 70 static __enable_if_t< 71 is_reference<typename iterator_traits<__uncvref_t<_Iter> >::reference>::value, 72 typename remove_reference< typename iterator_traits<__uncvref_t<_Iter> >::reference >::type&&> 73 __iter_move(_Iter&& __i) { 74 return std::move(*std::forward<_Iter>(__i)); 75 } 76 77 template <class _Iter> 78 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 79 // Declaring the return type is necessary for C++03, so we basically mirror what `decltype(auto)` would deduce. 80 static __enable_if_t< 81 !is_reference<typename iterator_traits<__uncvref_t<_Iter> >::reference>::value, 82 typename iterator_traits<__uncvref_t<_Iter> >::reference> 83 __iter_move(_Iter&& __i) { 84 return *std::forward<_Iter>(__i); 85 } 86 87 // iter_swap 88 template <class _Iter1, class _Iter2> 89 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 90 static void iter_swap(_Iter1&& __a, _Iter2&& __b) { 91 std::iter_swap(std::forward<_Iter1>(__a), std::forward<_Iter2>(__b)); 92 } 93 94 // next 95 template <class _Iterator> 96 _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_AFTER_CXX11 97 _Iterator next(_Iterator, _Iterator __last) { 98 return __last; 99 } 100 101 template <class _Iter> 102 _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_AFTER_CXX11 103 __uncvref_t<_Iter> next(_Iter&& __it, 104 typename iterator_traits<__uncvref_t<_Iter> >::difference_type __n = 1){ 105 return std::next(std::forward<_Iter>(__it), __n); 106 } 107 108 template <class _Iter> 109 _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_AFTER_CXX11 110 void __advance_to(_Iter& __first, _Iter __last) { 111 __first = __last; 112 } 113 }; 114 115 _LIBCPP_END_NAMESPACE_STD 116 117 #endif // _LIBCPP___ALGORITHM_ITERATOR_OPERATIONS_H 118