Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 49 additions & 16 deletions libcxx/include/__algorithm/copy_n.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,31 +10,63 @@
#define _LIBCPP___ALGORITHM_COPY_N_H

#include <__algorithm/copy.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
#endif

_LIBCPP_PUSH_MACROS
#include <__undef_macros>

_LIBCPP_BEGIN_NAMESPACE_STD

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>
__copy_n(_InIter __first, typename _IterOps<_AlgPolicy>::template __difference_type<_InIter> __n, _OutIter __result) {
return std::__copy(__first, __first + __n, std::move(__result));
}

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>
__copy_n(_InIter __first, typename _IterOps<_AlgPolicy>::template __difference_type<_InIter> __n, _OutIter __result) {
while (__n != 0) {
*__result = *__first;
++__first;
++__result;
--__n;
}
return std::make_pair(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
// if not absolutely required. This was done to allow its use with istream_iterator and we want to avoid breaking
// people, at least currently.
// See https://github.com/llvm/llvm-project/commit/99847d2bf132854fffa019bab19818768102ccad
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) {
__enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
copy_n(_InputIterator __first, _Size __n, _OutputIterator __result) {
using _IntegralSize = decltype(std::__convert_to_integral(__n));
_IntegralSize __converted = __n;
if (__converted > 0) {
*__result = *__first;
++__result;
for (--__n; __n > 0; --__n) {
for (--__converted; __converted > 0; --__converted) {
++__first;
*__result = *__first;
++__result;
Expand All @@ -46,15 +78,16 @@ copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __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);
__enable_if_t<!__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
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, __iter_difference_t<_InputIterator>(__converted), __result).second;
}

_LIBCPP_END_NAMESPACE_STD

_LIBCPP_POP_MACROS

#endif // _LIBCPP___ALGORITHM_COPY_N_H
29 changes: 3 additions & 26 deletions libcxx/include/__algorithm/ranges_copy_n.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,12 @@
#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)
Expand All @@ -37,32 +33,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<_RangeAlgPolicy>(std::move(__first), __n, std::move(__result));
return {std::move(__res.first), std::move(__res.second)};
}
};

Expand Down
24 changes: 4 additions & 20 deletions libcxx/include/__vector/vector.h
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -628,8 +627,7 @@ class vector {
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
__assign_with_size(_Iterator __first, _Sentinel __last, difference_type __n);

template <class _Iterator,
__enable_if_t<!is_same<decltype(*std::declval<_Iterator&>())&&, value_type&&>::value, int> = 0>
template <class _Iterator, __enable_if_t<!is_same<__iter_value_t<_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) {
for (pointer __end_position = __position + __n; __position != __end_position; ++__position, (void)++__first) {
Expand All @@ -638,18 +636,10 @@ class vector {
}
}

template <class _Iterator,
__enable_if_t<is_same<decltype(*std::declval<_Iterator&>())&&, value_type&&>::value, int> = 0>
template <class _Iterator, __enable_if_t<is_same<__iter_value_t<_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(std::move(__first), __n, __position);
}

template <class _InputIterator, class _Sentinel>
Expand Down Expand Up @@ -1083,14 +1073,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);
Expand Down
Loading