xref: /freebsd/contrib/llvm-project/libcxx/include/__algorithm/copy_backward.h (revision d56accc7c3dcc897489b6a07834763a03b9f3d68)
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_BACKWARD_H
10 #define _LIBCPP___ALGORITHM_COPY_BACKWARD_H
11 
12 #include <__algorithm/unwrap_iter.h>
13 #include <__config>
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_BEGIN_NAMESPACE_STD
23 
24 template <class _BidirectionalIterator, class _OutputIterator>
25 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
26 _OutputIterator
27 __copy_backward_constexpr(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result)
28 {
29     while (__first != __last)
30         *--__result = *--__last;
31     return __result;
32 }
33 
34 template <class _BidirectionalIterator, class _OutputIterator>
35 inline _LIBCPP_INLINE_VISIBILITY
36 _OutputIterator
37 __copy_backward(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result)
38 {
39     return _VSTD::__copy_backward_constexpr(__first, __last, __result);
40 }
41 
42 template <class _Tp, class _Up>
43 inline _LIBCPP_INLINE_VISIBILITY
44 typename enable_if
45 <
46     is_same<typename remove_const<_Tp>::type, _Up>::value &&
47     is_trivially_copy_assignable<_Up>::value,
48     _Up*
49 >::type
50 __copy_backward(_Tp* __first, _Tp* __last, _Up* __result)
51 {
52     const size_t __n = static_cast<size_t>(__last - __first);
53     if (__n > 0)
54     {
55         __result -= __n;
56         _VSTD::memmove(__result, __first, __n * sizeof(_Up));
57     }
58     return __result;
59 }
60 
61 template <class _BidirectionalIterator1, class _BidirectionalIterator2>
62 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
63 _BidirectionalIterator2
64 copy_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last,
65               _BidirectionalIterator2 __result)
66 {
67     if (__libcpp_is_constant_evaluated()) {
68         return _VSTD::__copy_backward_constexpr(__first, __last, __result);
69     } else {
70         return _VSTD::__rewrap_iter(__result,
71             _VSTD::__copy_backward(_VSTD::__unwrap_iter(__first),
72                                    _VSTD::__unwrap_iter(__last),
73                                    _VSTD::__unwrap_iter(__result)));
74     }
75 }
76 
77 _LIBCPP_END_NAMESPACE_STD
78 
79 #endif // _LIBCPP___ALGORITHM_COPY_BACKWARD_H
80