xref: /llvm-project/libcxx/include/__algorithm/ranges_copy_n.h (revision a2042521a0387d7d7b80b2987f4b21f5a50bc7bb)
11d83750fSNikolas Klauser //===----------------------------------------------------------------------===//
21d83750fSNikolas Klauser //
31d83750fSNikolas Klauser // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
41d83750fSNikolas Klauser // See https://llvm.org/LICENSE.txt for license information.
51d83750fSNikolas Klauser // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
61d83750fSNikolas Klauser //
71d83750fSNikolas Klauser //===----------------------------------------------------------------------===//
81d83750fSNikolas Klauser 
91d83750fSNikolas Klauser #ifndef _LIBCPP___ALGORITHM_RANGES_COPY_N_H
101d83750fSNikolas Klauser #define _LIBCPP___ALGORITHM_RANGES_COPY_N_H
111d83750fSNikolas Klauser 
121d83750fSNikolas Klauser #include <__algorithm/copy.h>
131d83750fSNikolas Klauser #include <__algorithm/in_out_result.h>
145629d492Svarconst #include <__algorithm/iterator_operations.h>
151d83750fSNikolas Klauser #include <__algorithm/ranges_copy.h>
161d83750fSNikolas Klauser #include <__config>
171d83750fSNikolas Klauser #include <__functional/identity.h>
181d83750fSNikolas Klauser #include <__iterator/concepts.h>
191d83750fSNikolas Klauser #include <__iterator/incrementable_traits.h>
201d83750fSNikolas Klauser #include <__iterator/unreachable_sentinel.h>
211d83750fSNikolas Klauser #include <__iterator/wrap_iter.h>
221d83750fSNikolas Klauser #include <__utility/move.h>
231d83750fSNikolas Klauser 
241d83750fSNikolas Klauser #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
251d83750fSNikolas Klauser #  pragma GCC system_header
261d83750fSNikolas Klauser #endif
271d83750fSNikolas Klauser 
287b462251SLouis Dionne _LIBCPP_PUSH_MACROS
297b462251SLouis Dionne #include <__undef_macros>
307b462251SLouis Dionne 
311d83750fSNikolas Klauser _LIBCPP_BEGIN_NAMESPACE_STD
321d83750fSNikolas Klauser 
334f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 20
341d83750fSNikolas Klauser 
351d83750fSNikolas Klauser namespace ranges {
361d83750fSNikolas Klauser 
371d83750fSNikolas Klauser template <class _Ip, class _Op>
381d83750fSNikolas Klauser using copy_n_result = in_out_result<_Ip, _Op>;
391d83750fSNikolas Klauser 
40eab7be5dSNikolas Klauser // TODO: Merge this with copy_n
41d10dc5a0SChristopher Di Bella struct __copy_n {
421d83750fSNikolas Klauser   template <class _InIter, class _DiffType, class _OutIter>
435aa03b64SLouis Dionne   _LIBCPP_HIDE_FROM_ABI constexpr static copy_n_result<_InIter, _OutIter>
445aa03b64SLouis Dionne   __go(_InIter __first, _DiffType __n, _OutIter __result) {
451d83750fSNikolas Klauser     while (__n != 0) {
461d83750fSNikolas Klauser       *__result = *__first;
471d83750fSNikolas Klauser       ++__first;
481d83750fSNikolas Klauser       ++__result;
491d83750fSNikolas Klauser       --__n;
501d83750fSNikolas Klauser     }
511d83750fSNikolas Klauser     return {std::move(__first), std::move(__result)};
521d83750fSNikolas Klauser   }
531d83750fSNikolas Klauser 
541d83750fSNikolas Klauser   template <random_access_iterator _InIter, class _DiffType, random_access_iterator _OutIter>
555aa03b64SLouis Dionne   _LIBCPP_HIDE_FROM_ABI constexpr static copy_n_result<_InIter, _OutIter>
565aa03b64SLouis Dionne   __go(_InIter __first, _DiffType __n, _OutIter __result) {
57*a2042521SNikolas Klauser     auto __ret = std::__copy(__first, __first + __n, __result);
581d83750fSNikolas Klauser     return {__ret.first, __ret.second};
591d83750fSNikolas Klauser   }
601d83750fSNikolas Klauser 
611d83750fSNikolas Klauser   template <input_iterator _Ip, weakly_incrementable _Op>
621d83750fSNikolas Klauser     requires indirectly_copyable<_Ip, _Op>
635aa03b64SLouis Dionne   _LIBCPP_HIDE_FROM_ABI constexpr copy_n_result<_Ip, _Op>
645aa03b64SLouis Dionne   operator()(_Ip __first, iter_difference_t<_Ip> __n, _Op __result) const {
651d83750fSNikolas Klauser     return __go(std::move(__first), __n, std::move(__result));
661d83750fSNikolas Klauser   }
671d83750fSNikolas Klauser };
681d83750fSNikolas Klauser 
691d83750fSNikolas Klauser inline namespace __cpo {
70d10dc5a0SChristopher Di Bella inline constexpr auto copy_n = __copy_n{};
711d83750fSNikolas Klauser } // namespace __cpo
721d83750fSNikolas Klauser } // namespace ranges
731d83750fSNikolas Klauser 
744f15267dSNikolas Klauser #endif // _LIBCPP_STD_VER >= 20
751d83750fSNikolas Klauser 
761d83750fSNikolas Klauser _LIBCPP_END_NAMESPACE_STD
771d83750fSNikolas Klauser 
787b462251SLouis Dionne _LIBCPP_POP_MACROS
797b462251SLouis Dionne 
801d83750fSNikolas Klauser #endif // _LIBCPP___ALGORITHM_RANGES_COPY_N_H
81