File indexing completed on 2026-05-03 08:13:07
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef _LIBCPP___ALGORITHM_COPY_MOVE_COMMON_H
0010 #define _LIBCPP___ALGORITHM_COPY_MOVE_COMMON_H
0011
0012 #include <__algorithm/unwrap_iter.h>
0013 #include <__algorithm/unwrap_range.h>
0014 #include <__config>
0015 #include <__cstddef/size_t.h>
0016 #include <__iterator/iterator_traits.h>
0017 #include <__memory/pointer_traits.h>
0018 #include <__string/constexpr_c_functions.h>
0019 #include <__type_traits/enable_if.h>
0020 #include <__type_traits/is_always_bitcastable.h>
0021 #include <__type_traits/is_constant_evaluated.h>
0022 #include <__type_traits/is_constructible.h>
0023 #include <__type_traits/is_trivially_assignable.h>
0024 #include <__type_traits/is_volatile.h>
0025 #include <__utility/move.h>
0026 #include <__utility/pair.h>
0027
0028 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0029 # pragma GCC system_header
0030 #endif
0031
0032 _LIBCPP_PUSH_MACROS
0033 #include <__undef_macros>
0034
0035 _LIBCPP_BEGIN_NAMESPACE_STD
0036
0037
0038
0039 template <class _From, class _To>
0040 struct __can_lower_copy_assignment_to_memmove {
0041 static const bool value =
0042
0043 __is_always_bitcastable<_From, _To>::value &&
0044
0045 is_trivially_assignable<_To&, const _From&>::value &&
0046
0047 !is_volatile<_From>::value && !is_volatile<_To>::value;
0048 };
0049
0050 template <class _From, class _To>
0051 struct __can_lower_move_assignment_to_memmove {
0052 static const bool value =
0053 __is_always_bitcastable<_From, _To>::value && is_trivially_assignable<_To&, _From&&>::value &&
0054 !is_volatile<_From>::value && !is_volatile<_To>::value;
0055 };
0056
0057
0058
0059 template <class _In, class _Out>
0060 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*>
0061 __copy_trivial_impl(_In* __first, _In* __last, _Out* __result) {
0062 const size_t __n = static_cast<size_t>(__last - __first);
0063
0064 std::__constexpr_memmove(__result, __first, __element_count(__n));
0065
0066 return std::make_pair(__last, __result + __n);
0067 }
0068
0069 template <class _In, class _Out>
0070 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*>
0071 __copy_backward_trivial_impl(_In* __first, _In* __last, _Out* __result) {
0072 const size_t __n = static_cast<size_t>(__last - __first);
0073 __result -= __n;
0074
0075 std::__constexpr_memmove(__result, __first, __element_count(__n));
0076
0077 return std::make_pair(__last, __result);
0078 }
0079
0080
0081
0082 template <class _InIter, class _OutIter>
0083 struct __can_rewrap
0084 : integral_constant<bool, is_copy_constructible<_InIter>::value && is_copy_constructible<_OutIter>::value> {};
0085
0086 template <class _Algorithm,
0087 class _InIter,
0088 class _Sent,
0089 class _OutIter,
0090 __enable_if_t<__can_rewrap<_InIter, _OutIter>::value, int> = 0>
0091 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 pair<_InIter, _OutIter>
0092 __copy_move_unwrap_iters(_InIter __first, _Sent __last, _OutIter __out_first) {
0093 auto __range = std::__unwrap_range(__first, std::move(__last));
0094 auto __result = _Algorithm()(std::move(__range.first), std::move(__range.second), std::__unwrap_iter(__out_first));
0095 return std::make_pair(std::__rewrap_range<_Sent>(std::move(__first), std::move(__result.first)),
0096 std::__rewrap_iter(std::move(__out_first), std::move(__result.second)));
0097 }
0098
0099 template <class _Algorithm,
0100 class _InIter,
0101 class _Sent,
0102 class _OutIter,
0103 __enable_if_t<!__can_rewrap<_InIter, _OutIter>::value, int> = 0>
0104 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 pair<_InIter, _OutIter>
0105 __copy_move_unwrap_iters(_InIter __first, _Sent __last, _OutIter __out_first) {
0106 return _Algorithm()(std::move(__first), std::move(__last), std::move(__out_first));
0107 }
0108
0109 _LIBCPP_END_NAMESPACE_STD
0110
0111 _LIBCPP_POP_MACROS
0112
0113 #endif