xref: /aosp_15_r20/external/cronet/base/ranges/ranges.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2020 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #ifndef BASE_RANGES_RANGES_H_
6*6777b538SAndroid Build Coastguard Worker #define BASE_RANGES_RANGES_H_
7*6777b538SAndroid Build Coastguard Worker 
8*6777b538SAndroid Build Coastguard Worker #include <array>
9*6777b538SAndroid Build Coastguard Worker #include <iterator>
10*6777b538SAndroid Build Coastguard Worker #include <type_traits>
11*6777b538SAndroid Build Coastguard Worker #include <utility>
12*6777b538SAndroid Build Coastguard Worker 
13*6777b538SAndroid Build Coastguard Worker #include "base/template_util.h"
14*6777b538SAndroid Build Coastguard Worker 
15*6777b538SAndroid Build Coastguard Worker namespace base {
16*6777b538SAndroid Build Coastguard Worker 
17*6777b538SAndroid Build Coastguard Worker namespace internal {
18*6777b538SAndroid Build Coastguard Worker 
19*6777b538SAndroid Build Coastguard Worker // Overload for C array.
20*6777b538SAndroid Build Coastguard Worker template <typename T, size_t N>
begin(T (& array)[N],priority_tag<2>)21*6777b538SAndroid Build Coastguard Worker constexpr T* begin(T (&array)[N], priority_tag<2>) {
22*6777b538SAndroid Build Coastguard Worker   return array;
23*6777b538SAndroid Build Coastguard Worker }
24*6777b538SAndroid Build Coastguard Worker 
25*6777b538SAndroid Build Coastguard Worker // Generic container overload.
26*6777b538SAndroid Build Coastguard Worker template <typename Range>
27*6777b538SAndroid Build Coastguard Worker constexpr auto begin(Range&& range, priority_tag<1>)
28*6777b538SAndroid Build Coastguard Worker     -> decltype(std::forward<Range>(range).begin()) {
29*6777b538SAndroid Build Coastguard Worker   return std::forward<Range>(range).begin();
30*6777b538SAndroid Build Coastguard Worker }
31*6777b538SAndroid Build Coastguard Worker 
32*6777b538SAndroid Build Coastguard Worker // Overload for free begin() function.
33*6777b538SAndroid Build Coastguard Worker template <typename Range>
34*6777b538SAndroid Build Coastguard Worker constexpr auto begin(Range&& range, priority_tag<0>)
35*6777b538SAndroid Build Coastguard Worker     -> decltype(begin(std::forward<Range>(range))) {
36*6777b538SAndroid Build Coastguard Worker   return begin(std::forward<Range>(range));
37*6777b538SAndroid Build Coastguard Worker }
38*6777b538SAndroid Build Coastguard Worker 
39*6777b538SAndroid Build Coastguard Worker // Overload for C array.
40*6777b538SAndroid Build Coastguard Worker template <typename T, size_t N>
end(T (& array)[N],priority_tag<2>)41*6777b538SAndroid Build Coastguard Worker constexpr T* end(T (&array)[N], priority_tag<2>) {
42*6777b538SAndroid Build Coastguard Worker   return array + N;
43*6777b538SAndroid Build Coastguard Worker }
44*6777b538SAndroid Build Coastguard Worker 
45*6777b538SAndroid Build Coastguard Worker // Generic container overload.
46*6777b538SAndroid Build Coastguard Worker template <typename Range>
47*6777b538SAndroid Build Coastguard Worker constexpr auto end(Range&& range, priority_tag<1>)
48*6777b538SAndroid Build Coastguard Worker     -> decltype(std::forward<Range>(range).end()) {
49*6777b538SAndroid Build Coastguard Worker   return std::forward<Range>(range).end();
50*6777b538SAndroid Build Coastguard Worker }
51*6777b538SAndroid Build Coastguard Worker 
52*6777b538SAndroid Build Coastguard Worker // Overload for free end() function.
53*6777b538SAndroid Build Coastguard Worker template <typename Range>
54*6777b538SAndroid Build Coastguard Worker constexpr auto end(Range&& range, priority_tag<0>)
55*6777b538SAndroid Build Coastguard Worker     -> decltype(end(std::forward<Range>(range))) {
56*6777b538SAndroid Build Coastguard Worker   return end(std::forward<Range>(range));
57*6777b538SAndroid Build Coastguard Worker }
58*6777b538SAndroid Build Coastguard Worker 
59*6777b538SAndroid Build Coastguard Worker }  // namespace internal
60*6777b538SAndroid Build Coastguard Worker 
61*6777b538SAndroid Build Coastguard Worker namespace ranges {
62*6777b538SAndroid Build Coastguard Worker 
63*6777b538SAndroid Build Coastguard Worker // Simplified implementation of C++20's std::ranges::begin.
64*6777b538SAndroid Build Coastguard Worker // As opposed to std::ranges::begin, this implementation does does not check
65*6777b538SAndroid Build Coastguard Worker // whether begin() returns an iterator and does not inhibit ADL.
66*6777b538SAndroid Build Coastguard Worker //
67*6777b538SAndroid Build Coastguard Worker // The trailing return type and dispatch to the internal implementation is
68*6777b538SAndroid Build Coastguard Worker // necessary to be SFINAE friendly.
69*6777b538SAndroid Build Coastguard Worker //
70*6777b538SAndroid Build Coastguard Worker // Reference: https://wg21.link/range.access.begin
71*6777b538SAndroid Build Coastguard Worker template <typename Range>
72*6777b538SAndroid Build Coastguard Worker constexpr auto begin(Range&& range) noexcept
73*6777b538SAndroid Build Coastguard Worker     -> decltype(internal::begin(std::forward<Range>(range),
74*6777b538SAndroid Build Coastguard Worker                                 internal::priority_tag<2>())) {
75*6777b538SAndroid Build Coastguard Worker   return internal::begin(std::forward<Range>(range),
76*6777b538SAndroid Build Coastguard Worker                          internal::priority_tag<2>());
77*6777b538SAndroid Build Coastguard Worker }
78*6777b538SAndroid Build Coastguard Worker 
79*6777b538SAndroid Build Coastguard Worker // Simplified implementation of C++20's std::ranges::end.
80*6777b538SAndroid Build Coastguard Worker // As opposed to std::ranges::end, this implementation does does not check
81*6777b538SAndroid Build Coastguard Worker // whether end() returns an iterator and does not inhibit ADL.
82*6777b538SAndroid Build Coastguard Worker //
83*6777b538SAndroid Build Coastguard Worker // The trailing return type and dispatch to the internal implementation is
84*6777b538SAndroid Build Coastguard Worker // necessary to be SFINAE friendly.
85*6777b538SAndroid Build Coastguard Worker //
86*6777b538SAndroid Build Coastguard Worker // Reference: - https://wg21.link/range.access.end
87*6777b538SAndroid Build Coastguard Worker template <typename Range>
88*6777b538SAndroid Build Coastguard Worker constexpr auto end(Range&& range) noexcept
89*6777b538SAndroid Build Coastguard Worker     -> decltype(internal::end(std::forward<Range>(range),
90*6777b538SAndroid Build Coastguard Worker                               internal::priority_tag<2>())) {
91*6777b538SAndroid Build Coastguard Worker   return internal::end(std::forward<Range>(range), internal::priority_tag<2>());
92*6777b538SAndroid Build Coastguard Worker }
93*6777b538SAndroid Build Coastguard Worker 
94*6777b538SAndroid Build Coastguard Worker // Implementation of C++20's std::ranges::iterator_t.
95*6777b538SAndroid Build Coastguard Worker //
96*6777b538SAndroid Build Coastguard Worker // Reference: https://wg21.link/ranges.syn#:~:text=iterator_t
97*6777b538SAndroid Build Coastguard Worker template <typename Range>
98*6777b538SAndroid Build Coastguard Worker using iterator_t = decltype(ranges::begin(std::declval<Range&>()));
99*6777b538SAndroid Build Coastguard Worker 
100*6777b538SAndroid Build Coastguard Worker // Implementation of C++20's std::ranges::range_value_t.
101*6777b538SAndroid Build Coastguard Worker //
102*6777b538SAndroid Build Coastguard Worker // Reference: https://wg21.link/ranges.syn#:~:text=range_value_t
103*6777b538SAndroid Build Coastguard Worker template <typename Range>
104*6777b538SAndroid Build Coastguard Worker using range_value_t = std::iter_value_t<iterator_t<Range>>;
105*6777b538SAndroid Build Coastguard Worker 
106*6777b538SAndroid Build Coastguard Worker }  // namespace ranges
107*6777b538SAndroid Build Coastguard Worker 
108*6777b538SAndroid Build Coastguard Worker }  // namespace base
109*6777b538SAndroid Build Coastguard Worker 
110*6777b538SAndroid Build Coastguard Worker #endif  // BASE_RANGES_RANGES_H_
111