xref: /freebsd/contrib/llvm-project/libcxx/include/__algorithm/copy_n.h (revision cb14a3fe5122c879eae1fb480ed7ce82a699ddb6)
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