xref: /llvm-project/libcxx/include/__algorithm/for_each_segment.h (revision dc124cda7c7808e4cadc8cf6d24c73680878a3d2)
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