xref: /llvm-project/libcxx/include/__algorithm/copy_n.h (revision 9783f28cbb155e4a8d49c12e1c60ce14dcfaf0c7)
1134723edSLouis Dionne //===----------------------------------------------------------------------===//
2134723edSLouis Dionne //
3134723edSLouis Dionne // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4134723edSLouis Dionne // See https://llvm.org/LICENSE.txt for license information.
5134723edSLouis Dionne // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6134723edSLouis Dionne //
7134723edSLouis Dionne //===----------------------------------------------------------------------===//
8134723edSLouis Dionne 
9134723edSLouis Dionne #ifndef _LIBCPP___ALGORITHM_COPY_N_H
10134723edSLouis Dionne #define _LIBCPP___ALGORITHM_COPY_N_H
11134723edSLouis Dionne 
12134723edSLouis Dionne #include <__algorithm/copy.h>
134d81a46fSArthur O'Dwyer #include <__config>
14134723edSLouis Dionne #include <__iterator/iterator_traits.h>
15e698c595SNikolas Klauser #include <__type_traits/enable_if.h>
167ae66e5eSNikolas Klauser #include <__utility/convert_to_integral.h>
17134723edSLouis Dionne 
18134723edSLouis Dionne #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19134723edSLouis Dionne #  pragma GCC system_header
20134723edSLouis Dionne #endif
21134723edSLouis Dionne 
22134723edSLouis Dionne _LIBCPP_BEGIN_NAMESPACE_STD
23134723edSLouis Dionne 
24*9783f28cSLouis Dionne template <class _InputIterator,
25*9783f28cSLouis Dionne           class _Size,
26*9783f28cSLouis Dionne           class _OutputIterator,
27475bd19eSNikolas Klauser           __enable_if_t<__has_input_iterator_category<_InputIterator>::value &&
28*9783f28cSLouis Dionne                             !__has_random_access_iterator_category<_InputIterator>::value,
29*9783f28cSLouis Dionne                         int> = 0>
30*9783f28cSLouis Dionne inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
copy_n(_InputIterator __first,_Size __orig_n,_OutputIterator __result)31*9783f28cSLouis Dionne copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) {
3277a00c0dSLouis Dionne   typedef decltype(std::__convert_to_integral(__orig_n)) _IntegralSize;
33134723edSLouis Dionne   _IntegralSize __n = __orig_n;
34*9783f28cSLouis Dionne   if (__n > 0) {
35134723edSLouis Dionne     *__result = *__first;
36134723edSLouis Dionne     ++__result;
37*9783f28cSLouis Dionne     for (--__n; __n > 0; --__n) {
38134723edSLouis Dionne       ++__first;
39134723edSLouis Dionne       *__result = *__first;
40134723edSLouis Dionne       ++__result;
41134723edSLouis Dionne     }
42134723edSLouis Dionne   }
43134723edSLouis Dionne   return __result;
44134723edSLouis Dionne }
45134723edSLouis Dionne 
46*9783f28cSLouis Dionne template <class _InputIterator,
47*9783f28cSLouis Dionne           class _Size,
48*9783f28cSLouis Dionne           class _OutputIterator,
49475bd19eSNikolas Klauser           __enable_if_t<__has_random_access_iterator_category<_InputIterator>::value, int> = 0>
50*9783f28cSLouis Dionne inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
copy_n(_InputIterator __first,_Size __orig_n,_OutputIterator __result)51*9783f28cSLouis Dionne copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) {
52dc1c2714SFabian Wolff   typedef typename iterator_traits<_InputIterator>::difference_type difference_type;
5377a00c0dSLouis Dionne   typedef decltype(std::__convert_to_integral(__orig_n)) _IntegralSize;
54134723edSLouis Dionne   _IntegralSize __n = __orig_n;
5577a00c0dSLouis Dionne   return std::copy(__first, __first + difference_type(__n), __result);
56134723edSLouis Dionne }
57134723edSLouis Dionne 
58134723edSLouis Dionne _LIBCPP_END_NAMESPACE_STD
59134723edSLouis Dionne 
60134723edSLouis Dionne #endif // _LIBCPP___ALGORITHM_COPY_N_H
61