xref: /freebsd/contrib/llvm-project/libcxx/include/__algorithm/copy_n.h (revision d54a7d337331d991e039e4f42f6b4dc64aedce08)
1  //===----------------------------------------------------------------------===//
2  //
3  // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4  // See https://llvm.org/LICENSE.txt for license information.
5  // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6  //
7  //===----------------------------------------------------------------------===//
8  
9  #ifndef _LIBCPP___ALGORITHM_COPY_N_H
10  #define _LIBCPP___ALGORITHM_COPY_N_H
11  
12  #include <__algorithm/copy.h>
13  #include <__config>
14  #include <__iterator/iterator_traits.h>
15  #include <__utility/convert_to_integral.h>
16  #include <type_traits>
17  
18  #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19  #  pragma GCC system_header
20  #endif
21  
22  _LIBCPP_BEGIN_NAMESPACE_STD
23  
24  template<class _InputIterator, class _Size, class _OutputIterator>
25  inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
26  typename enable_if
27  <
28      __is_cpp17_input_iterator<_InputIterator>::value &&
29     !__is_cpp17_random_access_iterator<_InputIterator>::value,
30      _OutputIterator
31  >::type
32  copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result)
33  {
34      typedef decltype(_VSTD::__convert_to_integral(__orig_n)) _IntegralSize;
35      _IntegralSize __n = __orig_n;
36      if (__n > 0)
37      {
38          *__result = *__first;
39          ++__result;
40          for (--__n; __n > 0; --__n)
41          {
42              ++__first;
43              *__result = *__first;
44              ++__result;
45          }
46      }
47      return __result;
48  }
49  
50  template<class _InputIterator, class _Size, class _OutputIterator>
51  inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
52  typename enable_if
53  <
54      __is_cpp17_random_access_iterator<_InputIterator>::value,
55      _OutputIterator
56  >::type
57  copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result)
58  {
59      typedef typename iterator_traits<_InputIterator>::difference_type difference_type;
60      typedef decltype(_VSTD::__convert_to_integral(__orig_n)) _IntegralSize;
61      _IntegralSize __n = __orig_n;
62      return _VSTD::copy(__first, __first + difference_type(__n), __result);
63  }
64  
65  _LIBCPP_END_NAMESPACE_STD
66  
67  #endif // _LIBCPP___ALGORITHM_COPY_N_H
68