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 <__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 template <class _BidirectionalIterator, class _OutputIterator> 28 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 29 _OutputIterator 30 __copy_backward_constexpr(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result) 31 { 32 while (__first != __last) 33 *--__result = *--__last; 34 return __result; 35 } 36 37 template <class _BidirectionalIterator, class _OutputIterator> 38 inline _LIBCPP_INLINE_VISIBILITY 39 _OutputIterator 40 __copy_backward(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result) 41 { 42 return _VSTD::__copy_backward_constexpr(__first, __last, __result); 43 } 44 45 template <class _Tp, class _Up> 46 inline _LIBCPP_INLINE_VISIBILITY 47 typename enable_if 48 < 49 is_same<typename remove_const<_Tp>::type, _Up>::value && 50 is_trivially_copy_assignable<_Up>::value, 51 _Up* 52 >::type 53 __copy_backward(_Tp* __first, _Tp* __last, _Up* __result) 54 { 55 const size_t __n = static_cast<size_t>(__last - __first); 56 if (__n > 0) 57 { 58 __result -= __n; 59 _VSTD::memmove(__result, __first, __n * sizeof(_Up)); 60 } 61 return __result; 62 } 63 64 template <class _BidirectionalIterator1, class _BidirectionalIterator2> 65 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 66 _BidirectionalIterator2 67 copy_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last, 68 _BidirectionalIterator2 __result) 69 { 70 if (__libcpp_is_constant_evaluated()) { 71 return _VSTD::__copy_backward_constexpr(__first, __last, __result); 72 } else { 73 return _VSTD::__rewrap_iter(__result, 74 _VSTD::__copy_backward(_VSTD::__unwrap_iter(__first), 75 _VSTD::__unwrap_iter(__last), 76 _VSTD::__unwrap_iter(__result))); 77 } 78 } 79 80 _LIBCPP_END_NAMESPACE_STD 81 82 _LIBCPP_POP_MACROS 83 84 #endif // _LIBCPP___ALGORITHM_COPY_BACKWARD_H 85