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