Skip to content

Commit 677b8f0

Browse files
committed
[libc++] Merge the implementations of ranges::copy_n and std::copy_n
1 parent 0a9b54b commit 677b8f0

File tree

3 files changed

+29
-71
lines changed

3 files changed

+29
-71
lines changed

libcxx/include/__algorithm/copy_n.h

Lines changed: 24 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -13,46 +13,42 @@
1313
#include <__config>
1414
#include <__iterator/iterator_traits.h>
1515
#include <__type_traits/enable_if.h>
16-
#include <__utility/convert_to_integral.h>
1716

1817
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1918
# pragma GCC system_header
2019
#endif
2120

2221
_LIBCPP_BEGIN_NAMESPACE_STD
2322

24-
template <class _InputIterator,
25-
class _Size,
26-
class _OutputIterator,
27-
__enable_if_t<__has_input_iterator_category<_InputIterator>::value &&
28-
!__has_random_access_iterator_category<_InputIterator>::value,
29-
int> = 0>
30-
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
31-
copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) {
32-
typedef decltype(std::__convert_to_integral(__orig_n)) _IntegralSize;
33-
_IntegralSize __n = __orig_n;
34-
if (__n > 0) {
23+
template <class _InIter,
24+
class _DiffType,
25+
class _OutIter,
26+
__enable_if_t<__has_random_access_iterator_category<_InIter>::value, int> = 0>
27+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InIter, _OutIter>
28+
__copy_n(_InIter __first, _DiffType __n, _OutIter __result) {
29+
return std::__copy(__first, __first + __n, std::move(__result));
30+
}
31+
32+
template <class _InIter,
33+
class _DiffType,
34+
class _OutIter,
35+
__enable_if_t<!__has_random_access_iterator_category<_InIter>::value, int> = 0>
36+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InIter, _OutIter>
37+
__copy_n(_InIter __first, _DiffType __n, _OutIter __result) {
38+
while (__n != 0) {
3539
*__result = *__first;
40+
++__first;
3641
++__result;
37-
for (--__n; __n > 0; --__n) {
38-
++__first;
39-
*__result = *__first;
40-
++__result;
41-
}
42+
--__n;
4243
}
43-
return __result;
44+
return std::make_pair(std::move(__first), std::move(__result));
4445
}
4546

46-
template <class _InputIterator,
47-
class _Size,
48-
class _OutputIterator,
49-
__enable_if_t<__has_random_access_iterator_category<_InputIterator>::value, int> = 0>
50-
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
51-
copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) {
52-
typedef typename iterator_traits<_InputIterator>::difference_type difference_type;
53-
typedef decltype(std::__convert_to_integral(__orig_n)) _IntegralSize;
54-
_IntegralSize __n = __orig_n;
55-
return std::copy(__first, __first + difference_type(__n), __result);
47+
template <class _InputIterator, class _Size, class _OutputIterator>
48+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
49+
copy_n(_InputIterator __first, _Size __n, _OutputIterator __result) {
50+
using __diff_t = __iter_diff_t<_InputIterator>;
51+
return std::__copy_n(__first, __diff_t(__n), __result).second;
5652
}
5753

5854
_LIBCPP_END_NAMESPACE_STD

libcxx/include/__algorithm/ranges_copy_n.h

Lines changed: 3 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,11 @@
99
#ifndef _LIBCPP___ALGORITHM_RANGES_COPY_N_H
1010
#define _LIBCPP___ALGORITHM_RANGES_COPY_N_H
1111

12-
#include <__algorithm/copy.h>
12+
#include <__algorithm/copy_n.h>
1313
#include <__algorithm/in_out_result.h>
14-
#include <__algorithm/iterator_operations.h>
15-
#include <__algorithm/ranges_copy.h>
1614
#include <__config>
17-
#include <__functional/identity.h>
1815
#include <__iterator/concepts.h>
1916
#include <__iterator/incrementable_traits.h>
20-
#include <__iterator/unreachable_sentinel.h>
21-
#include <__iterator/wrap_iter.h>
2217
#include <__utility/move.h>
2318

2419
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -37,32 +32,13 @@ namespace ranges {
3732
template <class _Ip, class _Op>
3833
using copy_n_result = in_out_result<_Ip, _Op>;
3934

40-
// TODO: Merge this with copy_n
4135
struct __copy_n {
42-
template <class _InIter, class _DiffType, class _OutIter>
43-
_LIBCPP_HIDE_FROM_ABI constexpr static copy_n_result<_InIter, _OutIter>
44-
__go(_InIter __first, _DiffType __n, _OutIter __result) {
45-
while (__n != 0) {
46-
*__result = *__first;
47-
++__first;
48-
++__result;
49-
--__n;
50-
}
51-
return {std::move(__first), std::move(__result)};
52-
}
53-
54-
template <random_access_iterator _InIter, class _DiffType, random_access_iterator _OutIter>
55-
_LIBCPP_HIDE_FROM_ABI constexpr static copy_n_result<_InIter, _OutIter>
56-
__go(_InIter __first, _DiffType __n, _OutIter __result) {
57-
auto __ret = std::__copy(__first, __first + __n, __result);
58-
return {__ret.first, __ret.second};
59-
}
60-
6136
template <input_iterator _Ip, weakly_incrementable _Op>
6237
requires indirectly_copyable<_Ip, _Op>
6338
_LIBCPP_HIDE_FROM_ABI constexpr copy_n_result<_Ip, _Op>
6439
operator()(_Ip __first, iter_difference_t<_Ip> __n, _Op __result) const {
65-
return __go(std::move(__first), __n, std::move(__result));
40+
auto __res = std::__copy_n(std::move(__first), __n, std::move(__result));
41+
return {std::move(__res.first), std::move(__res.second)};
6642
}
6743
};
6844

libcxx/include/__vector/vector.h

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
#include <__algorithm/min.h>
1717
#include <__algorithm/move.h>
1818
#include <__algorithm/move_backward.h>
19-
#include <__algorithm/ranges_copy_n.h>
2019
#include <__algorithm/rotate.h>
2120
#include <__assert>
2221
#include <__config>
@@ -640,14 +639,7 @@ class vector {
640639
__enable_if_t<is_same<decltype(*std::declval<_Iterator&>())&&, value_type&&>::value, int> = 0>
641640
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
642641
__insert_assign_n_unchecked(_Iterator __first, difference_type __n, pointer __position) {
643-
#if _LIBCPP_STD_VER >= 23
644-
if constexpr (!forward_iterator<_Iterator>) { // Handles input-only sized ranges for insert_range
645-
ranges::copy_n(std::move(__first), __n, __position);
646-
} else
647-
#endif
648-
{
649-
std::copy_n(__first, __n, __position);
650-
}
642+
std::__copy_n(__first, __n, __position);
651643
}
652644

653645
template <class _InputIterator, class _Sentinel>
@@ -1066,14 +1058,8 @@ vector<_Tp, _Allocator>::__assign_with_size(_Iterator __first, _Sentinel __last,
10661058
size_type __new_size = static_cast<size_type>(__n);
10671059
if (__new_size <= capacity()) {
10681060
if (__new_size > size()) {
1069-
#if _LIBCPP_STD_VER >= 23
1070-
auto __mid = ranges::copy_n(std::move(__first), size(), this->__begin_).in;
1061+
auto __mid = std::__copy_n(std::move(__first), size(), this->__begin_).first;
10711062
__construct_at_end(std::move(__mid), std::move(__last), __new_size - size());
1072-
#else
1073-
_Iterator __mid = std::next(__first, size());
1074-
std::copy(__first, __mid, this->__begin_);
1075-
__construct_at_end(__mid, __last, __new_size - size());
1076-
#endif
10771063
} else {
10781064
pointer __m = std::__copy(std::move(__first), __last, this->__begin_).second;
10791065
this->__destruct_at_end(__m);

0 commit comments

Comments
 (0)