1*dc124cdaSNikolas Klauser //===----------------------------------------------------------------------===//
2*dc124cdaSNikolas Klauser //
3*dc124cdaSNikolas Klauser // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*dc124cdaSNikolas Klauser // See https://llvm.org/LICENSE.txt for license information.
5*dc124cdaSNikolas Klauser // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*dc124cdaSNikolas Klauser //
7*dc124cdaSNikolas Klauser //===----------------------------------------------------------------------===//
8*dc124cdaSNikolas Klauser
9*dc124cdaSNikolas Klauser #ifndef _LIBCPP___ALGORITHM_FOR_EACH_SEGMENT_H
10*dc124cdaSNikolas Klauser #define _LIBCPP___ALGORITHM_FOR_EACH_SEGMENT_H
11*dc124cdaSNikolas Klauser
12*dc124cdaSNikolas Klauser #include <__config>
13*dc124cdaSNikolas Klauser #include <__iterator/segmented_iterator.h>
14*dc124cdaSNikolas Klauser
15*dc124cdaSNikolas Klauser #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
16*dc124cdaSNikolas Klauser # pragma GCC system_header
17*dc124cdaSNikolas Klauser #endif
18*dc124cdaSNikolas Klauser
19*dc124cdaSNikolas Klauser _LIBCPP_BEGIN_NAMESPACE_STD
20*dc124cdaSNikolas Klauser
21*dc124cdaSNikolas Klauser // __for_each_segment is a utility function for optimizing iterating over segmented iterators linearly.
22*dc124cdaSNikolas Klauser // __first and __last are expected to be a segmented range. __func is expected to take a range of local iterators.
23*dc124cdaSNikolas Klauser // Anything that is returned from __func is ignored.
24*dc124cdaSNikolas Klauser
25*dc124cdaSNikolas Klauser template <class _SegmentedIterator, class _Functor>
26*dc124cdaSNikolas Klauser _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void
__for_each_segment(_SegmentedIterator __first,_SegmentedIterator __last,_Functor __func)27*dc124cdaSNikolas Klauser __for_each_segment(_SegmentedIterator __first, _SegmentedIterator __last, _Functor __func) {
28*dc124cdaSNikolas Klauser using _Traits = __segmented_iterator_traits<_SegmentedIterator>;
29*dc124cdaSNikolas Klauser
30*dc124cdaSNikolas Klauser auto __sfirst = _Traits::__segment(__first);
31*dc124cdaSNikolas Klauser auto __slast = _Traits::__segment(__last);
32*dc124cdaSNikolas Klauser
33*dc124cdaSNikolas Klauser // We are in a single segment, so we might not be at the beginning or end
34*dc124cdaSNikolas Klauser if (__sfirst == __slast) {
35*dc124cdaSNikolas Klauser __func(_Traits::__local(__first), _Traits::__local(__last));
36*dc124cdaSNikolas Klauser return;
37*dc124cdaSNikolas Klauser }
38*dc124cdaSNikolas Klauser
39*dc124cdaSNikolas Klauser // We have more than one segment. Iterate over the first segment, since we might not start at the beginning
40*dc124cdaSNikolas Klauser __func(_Traits::__local(__first), _Traits::__end(__sfirst));
41*dc124cdaSNikolas Klauser ++__sfirst;
42*dc124cdaSNikolas Klauser // iterate over the segments which are guaranteed to be completely in the range
43*dc124cdaSNikolas Klauser while (__sfirst != __slast) {
44*dc124cdaSNikolas Klauser __func(_Traits::__begin(__sfirst), _Traits::__end(__sfirst));
45*dc124cdaSNikolas Klauser ++__sfirst;
46*dc124cdaSNikolas Klauser }
47*dc124cdaSNikolas Klauser // iterate over the last segment
48*dc124cdaSNikolas Klauser __func(_Traits::__begin(__sfirst), _Traits::__local(__last));
49*dc124cdaSNikolas Klauser }
50*dc124cdaSNikolas Klauser
51*dc124cdaSNikolas Klauser _LIBCPP_END_NAMESPACE_STD
52*dc124cdaSNikolas Klauser
53*dc124cdaSNikolas Klauser #endif // _LIBCPP___ALGORITHM_FOR_EACH_SEGMENT_H
54