1fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 2fe6060f1SDimitry Andric // 3fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6fe6060f1SDimitry Andric // 7fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 8fe6060f1SDimitry Andric 9fe6060f1SDimitry Andric #ifndef _LIBCPP___ALGORITHM_COPY_N_H 10fe6060f1SDimitry Andric #define _LIBCPP___ALGORITHM_COPY_N_H 11fe6060f1SDimitry Andric 12fe6060f1SDimitry Andric #include <__algorithm/copy.h> 1304eeddc0SDimitry Andric #include <__config> 14fe6060f1SDimitry Andric #include <__iterator/iterator_traits.h> 1506c3fb27SDimitry Andric #include <__type_traits/enable_if.h> 16bdd1243dSDimitry Andric #include <__utility/convert_to_integral.h> 17fe6060f1SDimitry Andric 18fe6060f1SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 19fe6060f1SDimitry Andric # pragma GCC system_header 20fe6060f1SDimitry Andric #endif 21fe6060f1SDimitry Andric 22fe6060f1SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD 23fe6060f1SDimitry Andric 24*cb14a3feSDimitry Andric template <class _InputIterator, 25*cb14a3feSDimitry Andric class _Size, 26*cb14a3feSDimitry Andric class _OutputIterator, 275f757f3fSDimitry Andric __enable_if_t<__has_input_iterator_category<_InputIterator>::value && 28*cb14a3feSDimitry Andric !__has_random_access_iterator_category<_InputIterator>::value, 29*cb14a3feSDimitry Andric int> = 0> 30*cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator 31*cb14a3feSDimitry Andric copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) { 325f757f3fSDimitry Andric typedef decltype(std::__convert_to_integral(__orig_n)) _IntegralSize; 33fe6060f1SDimitry Andric _IntegralSize __n = __orig_n; 34*cb14a3feSDimitry Andric if (__n > 0) { 35fe6060f1SDimitry Andric *__result = *__first; 36fe6060f1SDimitry Andric ++__result; 37*cb14a3feSDimitry Andric for (--__n; __n > 0; --__n) { 38fe6060f1SDimitry Andric ++__first; 39fe6060f1SDimitry Andric *__result = *__first; 40fe6060f1SDimitry Andric ++__result; 41fe6060f1SDimitry Andric } 42fe6060f1SDimitry Andric } 43fe6060f1SDimitry Andric return __result; 44fe6060f1SDimitry Andric } 45fe6060f1SDimitry Andric 46*cb14a3feSDimitry Andric template <class _InputIterator, 47*cb14a3feSDimitry Andric class _Size, 48*cb14a3feSDimitry Andric class _OutputIterator, 495f757f3fSDimitry Andric __enable_if_t<__has_random_access_iterator_category<_InputIterator>::value, int> = 0> 50*cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator 51*cb14a3feSDimitry Andric copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) { 52349cc55cSDimitry Andric typedef typename iterator_traits<_InputIterator>::difference_type difference_type; 535f757f3fSDimitry Andric typedef decltype(std::__convert_to_integral(__orig_n)) _IntegralSize; 54fe6060f1SDimitry Andric _IntegralSize __n = __orig_n; 555f757f3fSDimitry Andric return std::copy(__first, __first + difference_type(__n), __result); 56fe6060f1SDimitry Andric } 57fe6060f1SDimitry Andric 58fe6060f1SDimitry Andric _LIBCPP_END_NAMESPACE_STD 59fe6060f1SDimitry Andric 60fe6060f1SDimitry Andric #endif // _LIBCPP___ALGORITHM_COPY_N_H 61