move_backward.h 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  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. #ifndef _LIBCPP___ALGORITHM_MOVE_BACKWARD_H
  9. #define _LIBCPP___ALGORITHM_MOVE_BACKWARD_H
  10. #include <__algorithm/unwrap_iter.h>
  11. #include <__config>
  12. #include <__utility/move.h>
  13. #include <cstring>
  14. #include <type_traits>
  15. #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
  16. # pragma GCC system_header
  17. #endif
  18. _LIBCPP_BEGIN_NAMESPACE_STD
  19. template <class _InputIterator, class _OutputIterator>
  20. inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
  21. _OutputIterator
  22. __move_backward_constexpr(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
  23. {
  24. while (__first != __last)
  25. *--__result = _VSTD::move(*--__last);
  26. return __result;
  27. }
  28. template <class _InputIterator, class _OutputIterator>
  29. inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
  30. _OutputIterator
  31. __move_backward(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
  32. {
  33. return _VSTD::__move_backward_constexpr(__first, __last, __result);
  34. }
  35. template <class _Tp, class _Up>
  36. inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
  37. typename enable_if
  38. <
  39. is_same<typename remove_const<_Tp>::type, _Up>::value &&
  40. is_trivially_move_assignable<_Up>::value,
  41. _Up*
  42. >::type
  43. __move_backward(_Tp* __first, _Tp* __last, _Up* __result)
  44. {
  45. const size_t __n = static_cast<size_t>(__last - __first);
  46. if (__n > 0)
  47. {
  48. __result -= __n;
  49. _VSTD::memmove(__result, __first, __n * sizeof(_Up));
  50. }
  51. return __result;
  52. }
  53. template <class _BidirectionalIterator1, class _BidirectionalIterator2>
  54. inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
  55. _BidirectionalIterator2
  56. move_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last,
  57. _BidirectionalIterator2 __result)
  58. {
  59. if (__libcpp_is_constant_evaluated()) {
  60. return _VSTD::__move_backward_constexpr(__first, __last, __result);
  61. } else {
  62. return _VSTD::__rewrap_iter(__result,
  63. _VSTD::__move_backward(_VSTD::__unwrap_iter(__first),
  64. _VSTD::__unwrap_iter(__last),
  65. _VSTD::__unwrap_iter(__result)));
  66. }
  67. }
  68. _LIBCPP_END_NAMESPACE_STD
  69. #endif // _LIBCPP___ALGORITHM_MOVE_BACKWARD_H