Warning: This file is not a C or C++ file. It does not have highlighting.
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-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #ifndef _LIBCPP___ALGORITHM_FOR_EACH_N_SEGMENT_H |
10 | #define _LIBCPP___ALGORITHM_FOR_EACH_N_SEGMENT_H |
11 | |
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_header |
18 | #endif |
19 | |
20 | _LIBCPP_BEGIN_NAMESPACE_STD |
21 | |
22 | // __for_each_n_segment optimizes linear iteration over segmented iterators. It processes a segmented |
23 | // 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 the |
25 | // last processed element in the input range. |
26 | |
27 | template <class _SegmentedIterator, class _Size, class _Functor> |
28 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _SegmentedIterator |
29 | __for_each_n_segment(_SegmentedIterator __first, _Size __orig_n, _Functor __func) { |
30 | static_assert(__is_segmented_iterator<_SegmentedIterator>::value && |
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_STD |
62 | |
63 | #endif // _LIBCPP___ALGORITHM_FOR_EACH_N_SEGMENT_H |
64 |
Warning: This file is not a C or C++ file. It does not have highlighting.