-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[libc++] Merge the implementations of ranges::copy_n and std::copy_n and fix vector::insert to assign #157444
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
677b8f0
to
0960353
Compare
@llvm/pr-subscribers-libcxx Author: Nikolas Klauser (philnik777) ChangesThis reduces the amount of code we have to maintain a bit. This also simplifies Full diff: https://github.com/llvm/llvm-project/pull/157444.diff 3 Files Affected:
diff --git a/libcxx/include/__algorithm/copy_n.h b/libcxx/include/__algorithm/copy_n.h
index f93f39203a7e3..c868852cf3afe 100644
--- a/libcxx/include/__algorithm/copy_n.h
+++ b/libcxx/include/__algorithm/copy_n.h
@@ -13,48 +13,51 @@
#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
#endif
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
_LIBCPP_BEGIN_NAMESPACE_STD
-template <class _InputIterator,
- class _Size,
- class _OutputIterator,
- __enable_if_t<__has_input_iterator_category<_InputIterator>::value &&
- !__has_random_access_iterator_category<_InputIterator>::value,
- int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
-copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) {
- typedef decltype(std::__convert_to_integral(__orig_n)) _IntegralSize;
- _IntegralSize __n = __orig_n;
- if (__n > 0) {
+template <class _InIter,
+ class _DiffType,
+ 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>
+__copy_n(_InIter __first, _DiffType __n, _OutIter __result) {
+ return std::__copy(__first, __first + __n, std::move(__result));
+}
+
+template <class _InIter,
+ class _DiffType,
+ 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>
+__copy_n(_InIter __first, _DiffType __n, _OutIter __result) {
+ while (__n != 0) {
*__result = *__first;
+ ++__first;
++__result;
- for (--__n; __n > 0; --__n) {
- ++__first;
- *__result = *__first;
- ++__result;
- }
+ --__n;
}
- return __result;
+ return std::make_pair(std::move(__first), std::move(__result));
}
-template <class _InputIterator,
- class _Size,
- class _OutputIterator,
- __enable_if_t<__has_random_access_iterator_category<_InputIterator>::value, int> = 0>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
-copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) {
- typedef typename iterator_traits<_InputIterator>::difference_type difference_type;
- typedef decltype(std::__convert_to_integral(__orig_n)) _IntegralSize;
- _IntegralSize __n = __orig_n;
- return std::copy(__first, __first + difference_type(__n), __result);
+template <class _InputIterator, class _Size, class _OutputIterator>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
+copy_n(_InputIterator __first, _Size __n, _OutputIterator __result) {
+ using __diff_t = __iter_diff_t<_InputIterator>;
+ return std::__copy_n(__first, __diff_t(__n), __result).second;
}
_LIBCPP_END_NAMESPACE_STD
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP___ALGORITHM_COPY_N_H
diff --git a/libcxx/include/__algorithm/ranges_copy_n.h b/libcxx/include/__algorithm/ranges_copy_n.h
index 1fbc61674e2dd..3819779701076 100644
--- a/libcxx/include/__algorithm/ranges_copy_n.h
+++ b/libcxx/include/__algorithm/ranges_copy_n.h
@@ -9,16 +9,11 @@
#ifndef _LIBCPP___ALGORITHM_RANGES_COPY_N_H
#define _LIBCPP___ALGORITHM_RANGES_COPY_N_H
-#include <__algorithm/copy.h>
+#include <__algorithm/copy_n.h>
#include <__algorithm/in_out_result.h>
-#include <__algorithm/iterator_operations.h>
-#include <__algorithm/ranges_copy.h>
#include <__config>
-#include <__functional/identity.h>
#include <__iterator/concepts.h>
#include <__iterator/incrementable_traits.h>
-#include <__iterator/unreachable_sentinel.h>
-#include <__iterator/wrap_iter.h>
#include <__utility/move.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -37,32 +32,13 @@ namespace ranges {
template <class _Ip, class _Op>
using copy_n_result = in_out_result<_Ip, _Op>;
-// TODO: Merge this with copy_n
struct __copy_n {
- template <class _InIter, class _DiffType, class _OutIter>
- _LIBCPP_HIDE_FROM_ABI constexpr static copy_n_result<_InIter, _OutIter>
- __go(_InIter __first, _DiffType __n, _OutIter __result) {
- while (__n != 0) {
- *__result = *__first;
- ++__first;
- ++__result;
- --__n;
- }
- return {std::move(__first), std::move(__result)};
- }
-
- template <random_access_iterator _InIter, class _DiffType, random_access_iterator _OutIter>
- _LIBCPP_HIDE_FROM_ABI constexpr static copy_n_result<_InIter, _OutIter>
- __go(_InIter __first, _DiffType __n, _OutIter __result) {
- auto __ret = std::__copy(__first, __first + __n, __result);
- return {__ret.first, __ret.second};
- }
-
template <input_iterator _Ip, weakly_incrementable _Op>
requires indirectly_copyable<_Ip, _Op>
_LIBCPP_HIDE_FROM_ABI constexpr copy_n_result<_Ip, _Op>
operator()(_Ip __first, iter_difference_t<_Ip> __n, _Op __result) const {
- return __go(std::move(__first), __n, std::move(__result));
+ auto __res = std::__copy_n(std::move(__first), __n, std::move(__result));
+ return {std::move(__res.first), std::move(__res.second)};
}
};
diff --git a/libcxx/include/__vector/vector.h b/libcxx/include/__vector/vector.h
index 4307e78f6ddbc..b9b5beddd5a99 100644
--- a/libcxx/include/__vector/vector.h
+++ b/libcxx/include/__vector/vector.h
@@ -16,7 +16,6 @@
#include <__algorithm/min.h>
#include <__algorithm/move.h>
#include <__algorithm/move_backward.h>
-#include <__algorithm/ranges_copy_n.h>
#include <__algorithm/rotate.h>
#include <__assert>
#include <__config>
@@ -640,14 +639,7 @@ class vector {
__enable_if_t<is_same<decltype(*std::declval<_Iterator&>())&&, value_type&&>::value, int> = 0>
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
__insert_assign_n_unchecked(_Iterator __first, difference_type __n, pointer __position) {
-#if _LIBCPP_STD_VER >= 23
- if constexpr (!forward_iterator<_Iterator>) { // Handles input-only sized ranges for insert_range
- ranges::copy_n(std::move(__first), __n, __position);
- } else
-#endif
- {
- std::copy_n(__first, __n, __position);
- }
+ std::__copy_n(__first, __n, __position);
}
template <class _InputIterator, class _Sentinel>
@@ -1066,14 +1058,8 @@ vector<_Tp, _Allocator>::__assign_with_size(_Iterator __first, _Sentinel __last,
size_type __new_size = static_cast<size_type>(__n);
if (__new_size <= capacity()) {
if (__new_size > size()) {
-#if _LIBCPP_STD_VER >= 23
- auto __mid = ranges::copy_n(std::move(__first), size(), this->__begin_).in;
+ auto __mid = std::__copy_n(std::move(__first), size(), this->__begin_).first;
__construct_at_end(std::move(__mid), std::move(__last), __new_size - size());
-#else
- _Iterator __mid = std::next(__first, size());
- std::copy(__first, __mid, this->__begin_);
- __construct_at_end(__mid, __last, __new_size - size());
-#endif
} else {
pointer __m = std::__copy(std::move(__first), __last, this->__begin_).second;
this->__destruct_at_end(__m);
|
0960353
to
cb4802e
Compare
e6e6f2f
to
df67f59
Compare
#else | ||
|
||
template <class _Iter> | ||
using __iter_value_t _LIBCPP_NODEBUG = __iter_value_type<_Iter>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The naming in this file is starting to be pretty confusing. I'd like us to rename __iter_reference
, __iter_diff_t
and friends to something else. Maybe __classic_iter_diff_t
or __iterator_traits_diff_t
?
df67f59
to
1c004a3
Compare
This reduces the amount of code we have to maintain a bit.
This also simplifies
vector
by using the internal API instead of#if
s to switch based on language dialect.