master
  1// -*- C++ -*-
  2//===----------------------------------------------------------------------===//
  3//
  4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  5// See https://llvm.org/LICENSE.txt for license information.
  6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  7//
  8//===----------------------------------------------------------------------===//
  9
 10#ifndef _LIBCPP___ALGORITHM_FOR_EACH_N_H
 11#define _LIBCPP___ALGORITHM_FOR_EACH_N_H
 12
 13#include <__algorithm/for_each.h>
 14#include <__algorithm/for_each_n_segment.h>
 15#include <__config>
 16#include <__functional/identity.h>
 17#include <__iterator/iterator_traits.h>
 18#include <__iterator/segmented_iterator.h>
 19#include <__type_traits/disjunction.h>
 20#include <__type_traits/enable_if.h>
 21#include <__type_traits/invoke.h>
 22#include <__type_traits/negation.h>
 23#include <__utility/convert_to_integral.h>
 24#include <__utility/move.h>
 25
 26#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 27#  pragma GCC system_header
 28#endif
 29
 30_LIBCPP_PUSH_MACROS
 31#include <__undef_macros>
 32
 33_LIBCPP_BEGIN_NAMESPACE_STD
 34
 35template <class _InputIterator,
 36          class _Size,
 37          class _Func,
 38          class _Proj,
 39          __enable_if_t<!__has_random_access_iterator_category<_InputIterator>::value &&
 40                            _Or< _Not<__is_segmented_iterator<_InputIterator> >,
 41                                 _Not<__has_random_access_local_iterator<_InputIterator> > >::value,
 42                        int> = 0>
 43_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator
 44__for_each_n(_InputIterator __first, _Size __orig_n, _Func& __f, _Proj& __proj) {
 45  typedef decltype(std::__convert_to_integral(__orig_n)) _IntegralSize;
 46  _IntegralSize __n = __orig_n;
 47  while (__n > 0) {
 48    std::__invoke(__f, std::__invoke(__proj, *__first));
 49    ++__first;
 50    --__n;
 51  }
 52  return std::move(__first);
 53}
 54
 55template <class _RandIter,
 56          class _Size,
 57          class _Func,
 58          class _Proj,
 59          __enable_if_t<__has_random_access_iterator_category<_RandIter>::value, int> = 0>
 60_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandIter
 61__for_each_n(_RandIter __first, _Size __orig_n, _Func& __f, _Proj& __proj) {
 62  typename std::iterator_traits<_RandIter>::difference_type __n = __orig_n;
 63  auto __last                                                   = __first + __n;
 64  std::__for_each(__first, __last, __f, __proj);
 65  return __last;
 66}
 67
 68#ifndef _LIBCPP_CXX03_LANG
 69template <class _SegmentedIterator,
 70          class _Size,
 71          class _Func,
 72          class _Proj,
 73          __enable_if_t<!__has_random_access_iterator_category<_SegmentedIterator>::value &&
 74                            __is_segmented_iterator<_SegmentedIterator>::value &&
 75                            __has_random_access_iterator_category<
 76                                typename __segmented_iterator_traits<_SegmentedIterator>::__local_iterator>::value,
 77                        int> = 0>
 78_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _SegmentedIterator
 79__for_each_n(_SegmentedIterator __first, _Size __orig_n, _Func& __f, _Proj& __proj) {
 80  using __local_iterator_t = typename __segmented_iterator_traits<_SegmentedIterator>::__local_iterator;
 81  return std::__for_each_n_segment(__first, __orig_n, [&](__local_iterator_t __lfirst, __local_iterator_t __llast) {
 82    std::__for_each(__lfirst, __llast, __f, __proj);
 83  });
 84}
 85#endif // !_LIBCPP_CXX03_LANG
 86
 87#if _LIBCPP_STD_VER >= 17
 88
 89template <class _InputIterator, class _Size, class _Func>
 90inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator
 91for_each_n(_InputIterator __first, _Size __orig_n, _Func __f) {
 92  __identity __proj;
 93  return std::__for_each_n(__first, __orig_n, __f, __proj);
 94}
 95
 96#endif // _LIBCPP_STD_VER >= 17
 97
 98_LIBCPP_END_NAMESPACE_STD
 99
100_LIBCPP_POP_MACROS
101
102#endif // _LIBCPP___ALGORITHM_FOR_EACH_N_H