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