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_MOVE_H 10 #define _LIBCPP___ALGORITHM_MOVE_H 11 12 #include <__config> 13 #include <__algorithm/unwrap_iter.h> 14 #include <cstring> 15 #include <type_traits> 16 17 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 18 #pragma GCC system_header 19 #endif 20 21 _LIBCPP_PUSH_MACROS 22 #include <__undef_macros> 23 24 _LIBCPP_BEGIN_NAMESPACE_STD 25 26 // move 27 28 template <class _InputIterator, class _OutputIterator> 29 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 30 _OutputIterator 31 __move_constexpr(_InputIterator __first, _InputIterator __last, _OutputIterator __result) 32 { 33 for (; __first != __last; ++__first, (void) ++__result) 34 *__result = _VSTD::move(*__first); 35 return __result; 36 } 37 38 template <class _InputIterator, class _OutputIterator> 39 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 40 _OutputIterator 41 __move(_InputIterator __first, _InputIterator __last, _OutputIterator __result) 42 { 43 return _VSTD::__move_constexpr(__first, __last, __result); 44 } 45 46 template <class _Tp, class _Up> 47 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 48 typename enable_if 49 < 50 is_same<typename remove_const<_Tp>::type, _Up>::value && 51 is_trivially_move_assignable<_Up>::value, 52 _Up* 53 >::type 54 __move(_Tp* __first, _Tp* __last, _Up* __result) 55 { 56 const size_t __n = static_cast<size_t>(__last - __first); 57 if (__n > 0) 58 _VSTD::memmove(__result, __first, __n * sizeof(_Up)); 59 return __result + __n; 60 } 61 62 template <class _InputIterator, class _OutputIterator> 63 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 64 _OutputIterator 65 move(_InputIterator __first, _InputIterator __last, _OutputIterator __result) 66 { 67 if (__libcpp_is_constant_evaluated()) { 68 return _VSTD::__move_constexpr(__first, __last, __result); 69 } else { 70 return _VSTD::__rewrap_iter(__result, 71 _VSTD::__move(_VSTD::__unwrap_iter(__first), 72 _VSTD::__unwrap_iter(__last), 73 _VSTD::__unwrap_iter(__result))); 74 } 75 } 76 77 // move_backward 78 79 template <class _InputIterator, class _OutputIterator> 80 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 81 _OutputIterator 82 __move_backward_constexpr(_InputIterator __first, _InputIterator __last, _OutputIterator __result) 83 { 84 while (__first != __last) 85 *--__result = _VSTD::move(*--__last); 86 return __result; 87 } 88 89 template <class _InputIterator, class _OutputIterator> 90 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 91 _OutputIterator 92 __move_backward(_InputIterator __first, _InputIterator __last, _OutputIterator __result) 93 { 94 return _VSTD::__move_backward_constexpr(__first, __last, __result); 95 } 96 97 template <class _Tp, class _Up> 98 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 99 typename enable_if 100 < 101 is_same<typename remove_const<_Tp>::type, _Up>::value && 102 is_trivially_move_assignable<_Up>::value, 103 _Up* 104 >::type 105 __move_backward(_Tp* __first, _Tp* __last, _Up* __result) 106 { 107 const size_t __n = static_cast<size_t>(__last - __first); 108 if (__n > 0) 109 { 110 __result -= __n; 111 _VSTD::memmove(__result, __first, __n * sizeof(_Up)); 112 } 113 return __result; 114 } 115 116 template <class _BidirectionalIterator1, class _BidirectionalIterator2> 117 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 118 _BidirectionalIterator2 119 move_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last, 120 _BidirectionalIterator2 __result) 121 { 122 if (__libcpp_is_constant_evaluated()) { 123 return _VSTD::__move_backward_constexpr(__first, __last, __result); 124 } else { 125 return _VSTD::__rewrap_iter(__result, 126 _VSTD::__move_backward(_VSTD::__unwrap_iter(__first), 127 _VSTD::__unwrap_iter(__last), 128 _VSTD::__unwrap_iter(__result))); 129 } 130 } 131 132 _LIBCPP_END_NAMESPACE_STD 133 134 _LIBCPP_POP_MACROS 135 136 #endif // _LIBCPP___ALGORITHM_MOVE_H 137