[libcxx-commits] [libcxx] [libc++] Introduce a private version of in_out_result and use it for copy/move algorithms (PR #198086)

via libcxx-commits libcxx-commits at lists.llvm.org
Sat May 16 10:20:26 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libcxx

Author: Nikolas Klauser (philnik777)

<details>
<summary>Changes</summary>

This patch introduces a new `__in_out_result`, which is an internal back-ported version of `in_out_result`, and is convertible to that when it exists. This improves the readability of the code, since it replaces uses of `first` and `last` with `__in_` and `__out_`, making it clear which iterator is accessed.

Other algorithms will be updated in separate patches.

---

Patch is 55.25 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/198086.diff


23 Files Affected:

- (modified) libcxx/include/__algorithm/copy.h (+16-15) 
- (modified) libcxx/include/__algorithm/copy_backward.h (+18-17) 
- (modified) libcxx/include/__algorithm/copy_move_common.h (+9-12) 
- (modified) libcxx/include/__algorithm/copy_n.h (+5-5) 
- (modified) libcxx/include/__algorithm/in_out_result.h (+14) 
- (modified) libcxx/include/__algorithm/move.h (+16-15) 
- (modified) libcxx/include/__algorithm/move_backward.h (+16-14) 
- (modified) libcxx/include/__algorithm/ranges_copy.h (+2-4) 
- (modified) libcxx/include/__algorithm/ranges_copy_backward.h (+2-4) 
- (modified) libcxx/include/__algorithm/ranges_copy_n.h (+1-2) 
- (modified) libcxx/include/__algorithm/ranges_move.h (+2-9) 
- (modified) libcxx/include/__algorithm/ranges_move_backward.h (+2-9) 
- (modified) libcxx/include/__algorithm/ranges_set_difference.h (+2-7) 
- (modified) libcxx/include/__algorithm/rotate.h (+2-2) 
- (modified) libcxx/include/__algorithm/set_difference.h (+5-6) 
- (modified) libcxx/include/__algorithm/set_symmetric_difference.h (+2-2) 
- (modified) libcxx/include/__algorithm/set_union.h (+2-2) 
- (modified) libcxx/include/__algorithm/shift_left.h (+1-1) 
- (modified) libcxx/include/__algorithm/shift_right.h (+3-3) 
- (modified) libcxx/include/__bit_reference (+4-4) 
- (modified) libcxx/include/__iterator/ostreambuf_iterator.h (+3-3) 
- (modified) libcxx/include/__vector/vector.h (+2-2) 
- (modified) libcxx/include/module.modulemap.in (+8-2) 


``````````diff
diff --git a/libcxx/include/__algorithm/copy.h b/libcxx/include/__algorithm/copy.h
index 344a53e516e3e..711cb644462cb 100644
--- a/libcxx/include/__algorithm/copy.h
+++ b/libcxx/include/__algorithm/copy.h
@@ -11,6 +11,7 @@
 
 #include <__algorithm/copy_move_common.h>
 #include <__algorithm/for_each_segment.h>
+#include <__algorithm/in_out_result.h>
 #include <__algorithm/min.h>
 #include <__algorithm/specialized_algorithms.h>
 #include <__config>
@@ -19,7 +20,6 @@
 #include <__type_traits/common_type.h>
 #include <__type_traits/enable_if.h>
 #include <__utility/move.h>
-#include <__utility/pair.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -35,7 +35,8 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
 copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result);
 
 template <class _InIter, class _Sent, class _OutIter>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> __copy(_InIter, _Sent, _OutIter);
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __in_out_result<_InIter, _OutIter>
+    __copy(_InIter, _Sent, _OutIter);
 
 struct __copy_impl {
   template <class _InIter,
@@ -45,7 +46,7 @@ struct __copy_impl {
                                                    __iterator_pair<_InIter, _Sent>,
                                                    __single_iterator<_OutIter> >::__has_algorithm,
                           int> = 0>
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __in_out_result<_InIter, _OutIter>
   operator()(_InIter __first, _Sent __last, _OutIter __result) const {
     while (__first != __last) {
       *__result = *__first;
@@ -53,7 +54,7 @@ struct __copy_impl {
       ++__result;
     }
 
-    return std::make_pair(std::move(__first), std::move(__result));
+    return {std::move(__first), std::move(__result)};
   }
 
   template <class _InIter,
@@ -63,20 +64,20 @@ struct __copy_impl {
                                                   __iterator_pair<_InIter, _Sent>,
                                                   __single_iterator<_OutIter> >::__has_algorithm,
                           int> = 0>
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static pair<_InIter, _OutIter>
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static __in_out_result<_InIter, _OutIter>
   operator()(_InIter __first, _Sent __last, _OutIter __result) {
     return __specialized_algorithm<_Algorithm::__copy, __iterator_pair<_InIter, _Sent>, __single_iterator<_OutIter> >()(
         std::move(__first), std::move(__last), std::move(__result));
   }
 
   template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator_v<_InIter>, int> = 0>
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __in_out_result<_InIter, _OutIter>
   operator()(_InIter __first, _InIter __last, _OutIter __result) const {
     using __local_iterator = typename __segmented_iterator_traits<_InIter>::__local_iterator;
     std::__for_each_segment(__first, __last, [&__result](__local_iterator __lfirst, __local_iterator __llast) {
-      __result = std::__copy(std::move(__lfirst), std::move(__llast), std::move(__result)).second;
+      __result = std::__copy(std::move(__lfirst), std::move(__llast), std::move(__result)).__out_;
     });
-    return std::make_pair(__last, std::move(__result));
+    return {__last, std::move(__result)};
   }
 
   template <class _InIter,
@@ -84,14 +85,14 @@ struct __copy_impl {
             __enable_if_t<__has_random_access_iterator_category<_InIter>::value &&
                               !__is_segmented_iterator_v<_InIter> && __is_segmented_iterator_v<_OutIter>,
                           int> = 0>
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __in_out_result<_InIter, _OutIter>
   operator()(_InIter __first, _InIter __last, _OutIter __result) const {
     using _Traits = __segmented_iterator_traits<_OutIter>;
     using _DiffT =
         typename common_type<__iterator_difference_type<_InIter>, __iterator_difference_type<_OutIter> >::type;
 
     if (__first == __last)
-      return std::make_pair(std::move(__first), std::move(__result));
+      return {std::move(__first), std::move(__result)};
 
     auto __local_first      = _Traits::__local(__result);
     auto __segment_iterator = _Traits::__segment(__result);
@@ -99,10 +100,10 @@ struct __copy_impl {
       auto __local_last = _Traits::__end(__segment_iterator);
       auto __size       = std::min<_DiffT>(__local_last - __local_first, __last - __first);
       auto __iters      = std::__copy(__first, __first + __size, __local_first);
-      __first           = std::move(__iters.first);
+      __first           = std::move(__iters.__in_);
 
       if (__first == __last)
-        return std::make_pair(std::move(__first), _Traits::__compose(__segment_iterator, std::move(__iters.second)));
+        return {std::move(__first), _Traits::__compose(__segment_iterator, std::move(__iters.__out_))};
 
       __local_first = _Traits::__begin(++__segment_iterator);
     }
@@ -110,14 +111,14 @@ struct __copy_impl {
 
   // At this point, the iterators have been unwrapped so any `contiguous_iterator` has been unwrapped to a pointer.
   template <class _In, class _Out, __enable_if_t<__can_lower_copy_assignment_to_memmove<_In, _Out>::value, int> = 0>
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*>
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __in_out_result<_In*, _Out*>
   operator()(_In* __first, _In* __last, _Out* __result) const {
     return std::__copy_trivial_impl(__first, __last, __result);
   }
 };
 
 template <class _InIter, class _Sent, class _OutIter>
-pair<_InIter, _OutIter> inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
+__in_out_result<_InIter, _OutIter> inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
 __copy(_InIter __first, _Sent __last, _OutIter __result) {
   return std::__copy_move_unwrap_iters<__copy_impl>(std::move(__first), std::move(__last), std::move(__result));
 }
@@ -125,7 +126,7 @@ __copy(_InIter __first, _Sent __last, _OutIter __result) {
 template <class _InputIterator, class _OutputIterator>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
 copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result) {
-  return std::__copy(__first, __last, __result).second;
+  return std::__copy(__first, __last, __result).__out_;
 }
 
 _LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/copy_backward.h b/libcxx/include/__algorithm/copy_backward.h
index 8758d2c9e7b5d..15c213a4c5dec 100644
--- a/libcxx/include/__algorithm/copy_backward.h
+++ b/libcxx/include/__algorithm/copy_backward.h
@@ -12,6 +12,7 @@
 #include <__algorithm/copy_move_common.h>
 #include <__algorithm/copy_n.h>
 #include <__algorithm/for_each_segment.h>
+#include <__algorithm/in_out_result.h>
 #include <__algorithm/iterator_operations.h>
 #include <__algorithm/min.h>
 #include <__config>
@@ -23,7 +24,6 @@
 #include <__type_traits/enable_if.h>
 #include <__type_traits/is_constructible.h>
 #include <__utility/move.h>
-#include <__utility/pair.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -35,7 +35,7 @@ _LIBCPP_PUSH_MACROS
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _AlgPolicy, class _InIter, class _Sent, class _OutIter>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InIter, _OutIter>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __in_out_result<_InIter, _OutIter>
 __copy_backward(_InIter __first, _Sent __last, _OutIter __result);
 
 template <class _Cp, bool _IsConst>
@@ -159,7 +159,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> _
 template <class _AlgPolicy>
 struct __copy_backward_impl {
   template <class _InIter, class _Sent, class _OutIter>
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __in_out_result<_InIter, _OutIter>
   operator()(_InIter __first, _Sent __last, _OutIter __result) const {
     auto __last_iter          = _IterOps<_AlgPolicy>::next(__first, __last);
     auto __original_last_iter = __last_iter;
@@ -168,17 +168,17 @@ struct __copy_backward_impl {
       *--__result = *--__last_iter;
     }
 
-    return std::make_pair(std::move(__original_last_iter), std::move(__result));
+    return {std::move(__original_last_iter), std::move(__result)};
   }
 
   template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator_v<_InIter>, int> = 0>
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __in_out_result<_InIter, _OutIter>
   operator()(_InIter __first, _InIter __last, _OutIter __result) const {
     using __local_iterator = typename __segmented_iterator_traits<_InIter>::__local_iterator;
     std::__for_each_segment_backward(__first, __last, [&__result](__local_iterator __lfirst, __local_iterator __llast) {
-      __result = std::__copy_backward<_AlgPolicy>(std::move(__lfirst), std::move(__llast), std::move(__result)).second;
+      __result = std::__copy_backward<_AlgPolicy>(std::move(__lfirst), std::move(__llast), std::move(__result)).__out_;
     });
-    return std::make_pair(__last, std::move(__result));
+    return {__last, std::move(__result)};
   }
 
   template <class _InIter,
@@ -186,7 +186,7 @@ struct __copy_backward_impl {
             __enable_if_t<__has_random_access_iterator_category<_InIter>::value &&
                               !__is_segmented_iterator_v<_InIter> && __is_segmented_iterator_v<_OutIter>,
                           int> = 0>
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __in_out_result<_InIter, _OutIter>
   operator()(_InIter __first, _InIter __last, _OutIter __result) const {
     using _Traits           = __segmented_iterator_traits<_OutIter>;
     auto __orig_last        = __last;
@@ -194,7 +194,7 @@ struct __copy_backward_impl {
 
     // When the range contains no elements, __result might not be a valid iterator
     if (__first == __last)
-      return std::make_pair(__first, __result);
+      return {__first, __result};
 
     auto __local_last = _Traits::__local(__result);
     while (true) {
@@ -203,36 +203,37 @@ struct __copy_backward_impl {
 
       auto __local_first = _Traits::__begin(__segment_iterator);
       auto __size        = std::min<_DiffT>(__local_last - __local_first, __last - __first);
-      auto __iter        = std::__copy_backward<_AlgPolicy>(__last - __size, __last, __local_last).second;
+      auto __iter        = std::__copy_backward<_AlgPolicy>(__last - __size, __last, __local_last).__out_;
       __last -= __size;
 
       if (__first == __last)
-        return std::make_pair(std::move(__orig_last), _Traits::__compose(__segment_iterator, std::move(__iter)));
+        return {std::move(__orig_last), _Traits::__compose(__segment_iterator, std::move(__iter))};
       --__segment_iterator;
       __local_last = _Traits::__end(__segment_iterator);
     }
   }
 
   template <class _Cp, bool _IsConst>
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<__bit_iterator<_Cp, _IsConst>, __bit_iterator<_Cp, false> >
+  _LIBCPP_HIDE_FROM_ABI
+  _LIBCPP_CONSTEXPR_SINCE_CXX20 __in_out_result<__bit_iterator<_Cp, _IsConst>, __bit_iterator<_Cp, false> >
   operator()(__bit_iterator<_Cp, _IsConst> __first,
              __bit_iterator<_Cp, _IsConst> __last,
              __bit_iterator<_Cp, false> __result) {
     if (__last.__ctz_ == __result.__ctz_)
-      return std::make_pair(__last, std::__copy_backward_aligned(__first, __last, __result));
-    return std::make_pair(__last, std::__copy_backward_unaligned(__first, __last, __result));
+      return {__last, std::__copy_backward_aligned(__first, __last, __result)};
+    return {__last, std::__copy_backward_unaligned(__first, __last, __result)};
   }
 
   // At this point, the iterators have been unwrapped so any `contiguous_iterator` has been unwrapped to a pointer.
   template <class _In, class _Out, __enable_if_t<__can_lower_copy_assignment_to_memmove<_In, _Out>::value, int> = 0>
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*>
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __in_out_result<_In*, _Out*>
   operator()(_In* __first, _In* __last, _Out* __result) const {
     return std::__copy_backward_trivial_impl(__first, __last, __result);
   }
 };
 
 template <class _AlgPolicy, class _BidirectionalIterator1, class _Sentinel, class _BidirectionalIterator2>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_BidirectionalIterator1, _BidirectionalIterator2>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __in_out_result<_BidirectionalIterator1, _BidirectionalIterator2>
 __copy_backward(_BidirectionalIterator1 __first, _Sentinel __last, _BidirectionalIterator2 __result) {
   return std::__copy_move_unwrap_iters<__copy_backward_impl<_AlgPolicy> >(
       std::move(__first), std::move(__last), std::move(__result));
@@ -245,7 +246,7 @@ copy_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last, _
                     std::is_copy_constructible<_BidirectionalIterator1>::value,
                 "Iterators must be copy constructible.");
 
-  return std::__copy_backward<_ClassicAlgPolicy>(std::move(__first), std::move(__last), std::move(__result)).second;
+  return std::__copy_backward<_ClassicAlgPolicy>(std::move(__first), std::move(__last), std::move(__result)).__out_;
 }
 
 _LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/copy_move_common.h b/libcxx/include/__algorithm/copy_move_common.h
index 7471012c01d96..85723a7ebe587 100644
--- a/libcxx/include/__algorithm/copy_move_common.h
+++ b/libcxx/include/__algorithm/copy_move_common.h
@@ -9,21 +9,18 @@
 #ifndef _LIBCPP___ALGORITHM_COPY_MOVE_COMMON_H
 #define _LIBCPP___ALGORITHM_COPY_MOVE_COMMON_H
 
+#include <__algorithm/in_out_result.h>
 #include <__algorithm/unwrap_iter.h>
 #include <__algorithm/unwrap_range.h>
 #include <__config>
 #include <__cstddef/size_t.h>
-#include <__iterator/iterator_traits.h>
-#include <__memory/pointer_traits.h>
 #include <__string/constexpr_c_functions.h>
 #include <__type_traits/enable_if.h>
 #include <__type_traits/is_always_bitcastable.h>
-#include <__type_traits/is_constant_evaluated.h>
 #include <__type_traits/is_constructible.h>
 #include <__type_traits/is_trivially_assignable.h>
 #include <__type_traits/is_volatile.h>
 #include <__utility/move.h>
-#include <__utility/pair.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -57,24 +54,24 @@ struct __can_lower_move_assignment_to_memmove {
 // `memmove` algorithms implementation.
 
 template <class _In, class _Out>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __in_out_result<_In*, _Out*>
 __copy_trivial_impl(_In* __first, _In* __last, _Out* __result) {
   const size_t __n = static_cast<size_t>(__last - __first);
 
   std::__constexpr_memmove(__result, __first, __element_count(__n));
 
-  return std::make_pair(__last, __result + __n);
+  return {__last, __result + __n};
 }
 
 template <class _In, class _Out>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __in_out_result<_In*, _Out*>
 __copy_backward_trivial_impl(_In* __first, _In* __last, _Out* __result) {
   const size_t __n = static_cast<size_t>(__last - __first);
   __result -= __n;
 
   std::__constexpr_memmove(__result, __first, __element_count(__n));
 
-  return std::make_pair(__last, __result);
+  return {__last, __result};
 }
 
 // Iterator unwrapping and dispatching to the correct overload.
@@ -88,12 +85,12 @@ template <class _Algorithm,
           class _Sent,
           class _OutIter,
           __enable_if_t<__can_rewrap<_InIter, _OutIter>::value, int> = 0>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 pair<_InIter, _OutIter>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 __in_out_result<_InIter, _OutIter>
 __copy_move_unwrap_iters(_InIter __first, _Sent __last, _OutIter __out_first) {
   auto __range  = std::__unwrap_range(__first, std::move(__last));
   auto __result = _Algorithm()(std::move(__range.first), std::move(__range.second), std::__unwrap_iter(__out_first));
-  return std::make_pair(std::__rewrap_range<_Sent>(std::move(__first), std::move(__result.first)),
-                        std::__rewrap_iter(std::move(__out_first), std::move(__result.second)));
+  return {std::__rewrap_range<_Sent>(std::move(__first), std::move(__result.__in_)),
+          std::__rewrap_iter(std::move(__out_first), std::move(__result.__out_))};
 }
 
 template <class _Algorithm,
@@ -101,7 +98,7 @@ template <class _Algorithm,
           class _Sent,
           class _OutIter,
           __enable_if_t<!__can_rewrap<_InIter, _OutIter>::value, int> = 0>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 pair<_InIter, _OutIter>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 __in_out_result<_InIter, _OutIter>
 __copy_move_unwrap_iters(_InIter __first, _Sent __last, _OutIter __out_first) {
   return _Algorithm()(std::move(__first), std::move(__last), std::move(__out_first));
 }
diff --git a/libcxx/include/__algorithm/copy_n.h b/libcxx/include/__algorithm/copy_n.h
index 56fb44811fc4a..ac52b2b686c28 100644
--- a/libcxx/include/__algorithm/copy_n.h
+++ b/libcxx/include/__algorithm/copy_n.h
@@ -10,13 +10,13 @@
 #define _LIBCPP___ALGORITHM_COPY_N_H
 
 #include <__algorithm/copy.h>
+#include <__algorithm/in_out_result.h>
 #include <__algorithm/iterator_operations.h>
 #include <__config>
 #include <__iterator/iterator_traits.h>
 #include <__type_traits/enable_if.h>
 #include <__utility/convert_to_integral.h>
 #include <__utility/move.h>
-#include <__utility/pair.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -31,7 +31,7 @@ template <class _AlgPolicy,
           class _InIter,
           class _OutIter,
           __enable_if_t<__has_random_access_iterator_category<_InIter>::value, int> = 0>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InIter, _OutIter>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __in_out_result<_InIter, _OutIter>
 __copy_n(_InIter __first, typename _IterOps<_AlgPolicy>::template __difference_type<_InIter> __n, _OutIter __result) {
   return std::__copy(__first, __first + __n, std::move(__result));
 }
@@ -40,7 +40,7 @@ template <class _AlgPolicy,
           class _InIter,
           class _OutIter,
           __enable_if_t<!__has_random_access_iterator_category<_InIter>::value, int> = 0>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InIter, _OutIter>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __in_out_result<_InIter, _OutIter>
 __copy_n(_InIter __first, typename _IterOps<_AlgPolicy>::template __difference_type<_InIter> __n, _OutIter __result) {
   while (__n != 0) {
     *__result = *__first;
@@ -48,7 +48,7 @@ __copy_n(_InIter __first, typename _IterOps<_AlgPolicy>::template __difference_t
     ++__result;
     --__n;
   }
-  return std::make_pair(std::move(__first), std::move(__result));
+  return {std::move(__first), std::move(__result)};
 }
 
 // The InputIterator case is handled specially here because it's been written in a way to avoid incrementing __first
@@ -84,7 +84,7 @@ copy_n(_InputIterator __first, _Size __n, _OutputIterator __result) {
   using _IntegralSize       = decltype(std::__convert_to_integral(__n));
   _IntegralSize __converted = __n;
   return std::__copy_n<_ClassicAlgPolicy>(__first, __iterator_difference_type<_InputIterator>(__converted), __result)
-      .second;
+      .__out_;
 }
 
 _LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__algorithm/in_out_result.h b/libcxx/include/__algorithm/in_out_result.h
index a7a986cf8e6c0..2616bb89d1e21 100644
--- a/libcxx/include/__algorithm/in_out_result.h
+++ b/libcxx/include/__algorithm/in_out_result.h
@@ -49,6 +49,20 @@ struct in_out_result {
 
 #endi...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/198086


More information about the libcxx-commits mailing list