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_COPY_H 10 #define _LIBCPP___ALGORITHM_COPY_H 11 12 #include <__config> 13 #include <__algorithm/unwrap_iter.h> 14 #include <__iterator/iterator_traits.h> 15 #include <cstring> 16 #include <type_traits> 17 18 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 19 #pragma GCC system_header 20 #endif 21 22 _LIBCPP_PUSH_MACROS 23 #include <__undef_macros> 24 25 _LIBCPP_BEGIN_NAMESPACE_STD 26 27 // copy 28 29 template <class _InputIterator, class _OutputIterator> 30 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 31 _OutputIterator 32 __copy_constexpr(_InputIterator __first, _InputIterator __last, _OutputIterator __result) 33 { 34 for (; __first != __last; ++__first, (void) ++__result) 35 *__result = *__first; 36 return __result; 37 } 38 39 template <class _InputIterator, class _OutputIterator> 40 inline _LIBCPP_INLINE_VISIBILITY 41 _OutputIterator 42 __copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result) 43 { 44 return _VSTD::__copy_constexpr(__first, __last, __result); 45 } 46 47 template <class _Tp, class _Up> 48 inline _LIBCPP_INLINE_VISIBILITY 49 typename enable_if 50 < 51 is_same<typename remove_const<_Tp>::type, _Up>::value && 52 is_trivially_copy_assignable<_Up>::value, 53 _Up* 54 >::type 55 __copy(_Tp* __first, _Tp* __last, _Up* __result) 56 { 57 const size_t __n = static_cast<size_t>(__last - __first); 58 if (__n > 0) 59 _VSTD::memmove(__result, __first, __n * sizeof(_Up)); 60 return __result + __n; 61 } 62 63 template <class _InputIterator, class _OutputIterator> 64 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 65 _OutputIterator 66 copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result) 67 { 68 if (__libcpp_is_constant_evaluated()) { 69 return _VSTD::__copy_constexpr(__first, __last, __result); 70 } else { 71 return _VSTD::__rewrap_iter(__result, 72 _VSTD::__copy(_VSTD::__unwrap_iter(__first), 73 _VSTD::__unwrap_iter(__last), 74 _VSTD::__unwrap_iter(__result))); 75 } 76 } 77 78 // copy_backward 79 80 template <class _BidirectionalIterator, class _OutputIterator> 81 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 82 _OutputIterator 83 __copy_backward_constexpr(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result) 84 { 85 while (__first != __last) 86 *--__result = *--__last; 87 return __result; 88 } 89 90 template <class _BidirectionalIterator, class _OutputIterator> 91 inline _LIBCPP_INLINE_VISIBILITY 92 _OutputIterator 93 __copy_backward(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result) 94 { 95 return _VSTD::__copy_backward_constexpr(__first, __last, __result); 96 } 97 98 template <class _Tp, class _Up> 99 inline _LIBCPP_INLINE_VISIBILITY 100 typename enable_if 101 < 102 is_same<typename remove_const<_Tp>::type, _Up>::value && 103 is_trivially_copy_assignable<_Up>::value, 104 _Up* 105 >::type 106 __copy_backward(_Tp* __first, _Tp* __last, _Up* __result) 107 { 108 const size_t __n = static_cast<size_t>(__last - __first); 109 if (__n > 0) 110 { 111 __result -= __n; 112 _VSTD::memmove(__result, __first, __n * sizeof(_Up)); 113 } 114 return __result; 115 } 116 117 template <class _BidirectionalIterator1, class _BidirectionalIterator2> 118 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 119 _BidirectionalIterator2 120 copy_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last, 121 _BidirectionalIterator2 __result) 122 { 123 if (__libcpp_is_constant_evaluated()) { 124 return _VSTD::__copy_backward_constexpr(__first, __last, __result); 125 } else { 126 return _VSTD::__rewrap_iter(__result, 127 _VSTD::__copy_backward(_VSTD::__unwrap_iter(__first), 128 _VSTD::__unwrap_iter(__last), 129 _VSTD::__unwrap_iter(__result))); 130 } 131 } 132 133 // copy_if 134 135 template<class _InputIterator, class _OutputIterator, class _Predicate> 136 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 137 _OutputIterator 138 copy_if(_InputIterator __first, _InputIterator __last, 139 _OutputIterator __result, _Predicate __pred) 140 { 141 for (; __first != __last; ++__first) 142 { 143 if (__pred(*__first)) 144 { 145 *__result = *__first; 146 ++__result; 147 } 148 } 149 return __result; 150 } 151 152 // copy_n 153 154 template<class _InputIterator, class _Size, class _OutputIterator> 155 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 156 typename enable_if 157 < 158 __is_cpp17_input_iterator<_InputIterator>::value && 159 !__is_cpp17_random_access_iterator<_InputIterator>::value, 160 _OutputIterator 161 >::type 162 copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) 163 { 164 typedef decltype(_VSTD::__convert_to_integral(__orig_n)) _IntegralSize; 165 _IntegralSize __n = __orig_n; 166 if (__n > 0) 167 { 168 *__result = *__first; 169 ++__result; 170 for (--__n; __n > 0; --__n) 171 { 172 ++__first; 173 *__result = *__first; 174 ++__result; 175 } 176 } 177 return __result; 178 } 179 180 template<class _InputIterator, class _Size, class _OutputIterator> 181 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 182 typename enable_if 183 < 184 __is_cpp17_random_access_iterator<_InputIterator>::value, 185 _OutputIterator 186 >::type 187 copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) 188 { 189 typedef decltype(_VSTD::__convert_to_integral(__orig_n)) _IntegralSize; 190 _IntegralSize __n = __orig_n; 191 return _VSTD::copy(__first, __first + __n, __result); 192 } 193 194 _LIBCPP_END_NAMESPACE_STD 195 196 _LIBCPP_POP_MACROS 197 198 #endif // _LIBCPP___ALGORITHM_COPY_H 199