brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.5 KiB · a433df5 Raw
64 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef _LIBCPP___ALGORITHM_FOR_EACH_N_SEGMENT_H10#define _LIBCPP___ALGORITHM_FOR_EACH_N_SEGMENT_H11 12#include <__config>13#include <__iterator/iterator_traits.h>14#include <__iterator/segmented_iterator.h>15 16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)17#  pragma GCC system_header18#endif19 20_LIBCPP_BEGIN_NAMESPACE_STD21 22// __for_each_n_segment optimizes linear iteration over segmented iterators. It processes a segmented23// input range [__first, __first + __n) by applying the functor __func to each element within the segment.24// The return value of __func is ignored, and the function returns an iterator pointing to one past the25// last processed element in the input range.26 27template <class _SegmentedIterator, class _Size, class _Functor>28_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _SegmentedIterator29__for_each_n_segment(_SegmentedIterator __first, _Size __orig_n, _Functor __func) {30  static_assert(__is_segmented_iterator_v<_SegmentedIterator> &&31                    __has_random_access_iterator_category<32                        typename __segmented_iterator_traits<_SegmentedIterator>::__local_iterator>::value,33                "__for_each_n_segment only works with segmented iterators with random-access local iterators");34  if (__orig_n <= 0)35    return __first;36 37  using _Traits        = __segmented_iterator_traits<_SegmentedIterator>;38  using __local_iter_t = typename _Traits::__local_iterator;39  using __difference_t = typename std::iterator_traits<__local_iter_t>::difference_type;40  __difference_t __n   = __orig_n;41  auto __seg           = _Traits::__segment(__first);42  auto __local_first   = _Traits::__local(__first);43  __local_iter_t __local_last;44 45  while (__n > 0) {46    __local_last    = _Traits::__end(__seg);47    auto __seg_size = __local_last - __local_first;48    if (__n <= __seg_size) {49      __local_last = __local_first + __n;50      __func(__local_first, __local_last);51      break;52    }53    __func(__local_first, __local_last);54    __n -= __seg_size;55    __local_first = _Traits::__begin(++__seg);56  }57 58  return _Traits::__compose(__seg, __local_last);59}60 61_LIBCPP_END_NAMESPACE_STD62 63#endif // _LIBCPP___ALGORITHM_FOR_EACH_N_SEGMENT_H64