xref: /aosp_15_r20/external/cronet/third_party/libc++/src/test/std/ranges/range.utility/range.subrange/types.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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 LIBCXX_TEST_STD_RANGES_RANGE_UTILITY_RANGE_SUBRANGE_TYPES_H
10 #define LIBCXX_TEST_STD_RANGES_RANGE_UTILITY_RANGE_SUBRANGE_TYPES_H
11 
12 #include <cstddef>
13 #include <iterator>
14 #include <ranges>
15 #include <type_traits>
16 
17 #include "test_macros.h"
18 #include "test_iterators.h"
19 
20 int globalBuff[8];
21 
22 struct Empty {};
23 
24 using InputIter = cpp17_input_iterator<int*>;
25 using ForwardIter = forward_iterator<int*>;
26 using BidirIter = bidirectional_iterator<int*>;
27 
28 using ForwardSubrange = std::ranges::subrange<ForwardIter, ForwardIter, std::ranges::subrange_kind::unsized>;
29 using SizedIntPtrSubrange = std::ranges::subrange<int*, int*, std::ranges::subrange_kind::sized>;
30 
31 struct MoveOnlyForwardIter {
32     typedef std::forward_iterator_tag       iterator_category;
33     typedef int                             value_type;
34     typedef std::ptrdiff_t                  difference_type;
35     typedef int*                            pointer;
36     typedef int&                            reference;
37     typedef MoveOnlyForwardIter             self;
38 
39     int *base = nullptr;
40 
41     MoveOnlyForwardIter() = default;
42     MoveOnlyForwardIter(MoveOnlyForwardIter &&) = default;
43     MoveOnlyForwardIter &operator=(MoveOnlyForwardIter&&) = default;
44     MoveOnlyForwardIter(MoveOnlyForwardIter const&) = delete;
MoveOnlyForwardIterMoveOnlyForwardIter45     constexpr MoveOnlyForwardIter(int *ptr) : base(ptr) { }
46 
47     friend bool operator==(const self&, const self&);
48     friend constexpr bool operator==(const self& lhs, int* rhs) { return lhs.base == rhs; }
49 
50     reference operator*() const;
51     pointer operator->() const;
52     self& operator++();
53     self operator++(int);
54     self& operator--();
55     self operator--(int);
56 
pointerMoveOnlyForwardIter57     constexpr operator pointer() const { return base; }
58 };
59 
60 struct SizedSentinelForwardIter {
61     typedef std::forward_iterator_tag            iterator_category;
62     typedef int                                  value_type;
63     typedef std::ptrdiff_t                       difference_type;
64     typedef int*                                 pointer;
65     typedef int&                                 reference;
66     typedef std::make_unsigned_t<std::ptrdiff_t> udifference_type;
67     typedef SizedSentinelForwardIter             self;
68 
69     SizedSentinelForwardIter() = default;
SizedSentinelForwardIterSizedSentinelForwardIter70     constexpr explicit SizedSentinelForwardIter(int *ptr, bool *minusWasCalled)
71       : base_(ptr), minusWasCalled_(minusWasCalled)
72     { }
73 
74     friend constexpr bool operator==(const self& lhs, const self& rhs) { return lhs.base_ == rhs.base_; }
75 
76     reference operator*() const;
77     pointer operator->() const;
78     self& operator++();
79     self operator++(int);
80     self& operator--();
81     self operator--(int);
82 
83     friend constexpr difference_type operator-(SizedSentinelForwardIter const& a,
84                                                SizedSentinelForwardIter const& b) {
85       if (a.minusWasCalled_)
86         *a.minusWasCalled_ = true;
87       if (b.minusWasCalled_)
88         *b.minusWasCalled_ = true;
89       return a.base_ - b.base_;
90     }
91 
92 private:
93     int *base_ = nullptr;
94     bool *minusWasCalled_ = nullptr;
95 };
96 static_assert(std::sized_sentinel_for<SizedSentinelForwardIter, SizedSentinelForwardIter>);
97 
98 struct ConvertibleForwardIter {
99     typedef std::forward_iterator_tag       iterator_category;
100     typedef int                             value_type;
101     typedef std::ptrdiff_t                  difference_type;
102     typedef int*                            pointer;
103     typedef int&                            reference;
104     typedef ConvertibleForwardIter          self;
105 
106     int *base_ = nullptr;
107 
108     constexpr ConvertibleForwardIter() = default;
ConvertibleForwardIterConvertibleForwardIter109     constexpr explicit ConvertibleForwardIter(int *ptr) : base_(ptr) { }
110 
111     friend bool operator==(const self&, const self&);
112 
113     reference operator*() const;
114     pointer operator->() const;
115     self& operator++();
116     self operator++(int);
117     self& operator--();
118     self operator--(int);
119 
pointerConvertibleForwardIter120     constexpr operator pointer() const { return base_; }
121 
122     // Explicitly deleted so this doesn't model sized_sentinel_for.
123     friend constexpr difference_type operator-(int *, self const&) = delete;
124     friend constexpr difference_type operator-(self const&, int*) = delete;
125 };
126 using ConvertibleForwardSubrange = std::ranges::subrange<ConvertibleForwardIter, int*,
127                                                          std::ranges::subrange_kind::unsized>;
128 static_assert(std::is_convertible_v<ConvertibleForwardIter, int*>);
129 
130 template<bool EnableConvertible>
131 struct ConditionallyConvertibleBase {
132     typedef std::forward_iterator_tag            iterator_category;
133     typedef int                                  value_type;
134     typedef std::ptrdiff_t                       difference_type;
135     typedef int*                                 pointer;
136     typedef int&                                 reference;
137     typedef std::make_unsigned_t<std::ptrdiff_t> udifference_type;
138     typedef ConditionallyConvertibleBase         self;
139 
140     int *base_ = nullptr;
141 
142     constexpr ConditionallyConvertibleBase() = default;
ConditionallyConvertibleBaseConditionallyConvertibleBase143     constexpr explicit ConditionallyConvertibleBase(int *ptr) : base_(ptr) {}
144 
baseConditionallyConvertibleBase145     constexpr int *base() const { return base_; }
146 
147     friend bool operator==(const self&, const self&) = default;
148 
149     reference operator*() const;
150     pointer operator->() const;
151     self& operator++();
152     self operator++(int);
153     self& operator--();
154     self operator--(int);
155 
156     template<bool E = EnableConvertible>
157       requires E
pointerConditionallyConvertibleBase158     constexpr operator pointer() const { return base_; }
159 };
160 using ConditionallyConvertibleIter = ConditionallyConvertibleBase<false>;
161 using SizedSentinelForwardSubrange = std::ranges::subrange<ConditionallyConvertibleIter,
162                                                            ConditionallyConvertibleIter,
163                                                            std::ranges::subrange_kind::sized>;
164 using ConvertibleSizedSentinelForwardIter = ConditionallyConvertibleBase<true>;
165 using ConvertibleSizedSentinelForwardSubrange = std::ranges::subrange<ConvertibleSizedSentinelForwardIter, int*,
166                                                                       std::ranges::subrange_kind::sized>;
167 
168 struct ForwardBorrowedRange {
beginForwardBorrowedRange169   constexpr ForwardIter begin() const { return ForwardIter(globalBuff); }
endForwardBorrowedRange170   constexpr ForwardIter end() const { return ForwardIter(globalBuff + 8); }
171 };
172 
173 template<>
174 inline constexpr bool std::ranges::enable_borrowed_range<ForwardBorrowedRange> = true;
175 
176 struct ForwardRange {
177   ForwardIter begin() const;
178   ForwardIter end() const;
179 };
180 
181 struct ConvertibleForwardBorrowedRange {
beginConvertibleForwardBorrowedRange182   constexpr ConvertibleForwardIter begin() const { return ConvertibleForwardIter(globalBuff); }
endConvertibleForwardBorrowedRange183   constexpr int *end() const { return globalBuff + 8; }
184 };
185 
186 template<>
187 inline constexpr bool std::ranges::enable_borrowed_range<ConvertibleForwardBorrowedRange> = true;
188 
189 struct ForwardBorrowedRangeDifferentSentinel {
190   struct sentinel {
191     int *value;
192     friend bool operator==(sentinel s, ForwardIter i) { return s.value == base(i); }
193   };
194 
beginForwardBorrowedRangeDifferentSentinel195   constexpr ForwardIter begin() const { return ForwardIter(globalBuff); }
endForwardBorrowedRangeDifferentSentinel196   constexpr sentinel end() const { return sentinel{globalBuff + 8}; }
197 };
198 
199 template<>
200 inline constexpr bool std::ranges::enable_borrowed_range<ForwardBorrowedRangeDifferentSentinel> = true;
201 
202 using DifferentSentinelSubrange = std::ranges::subrange<ForwardIter,
203                                                         ForwardBorrowedRangeDifferentSentinel::sentinel,
204                                                         std::ranges::subrange_kind::unsized>;
205 
206 struct DifferentSentinelWithSizeMember {
207   struct sentinel {
208     int *value;
209     friend bool operator==(sentinel s, ForwardIter i) { return s.value == base(i); }
210   };
211 
beginDifferentSentinelWithSizeMember212   constexpr ForwardIter begin() const { return ForwardIter(globalBuff); }
endDifferentSentinelWithSizeMember213   constexpr sentinel end() const { return sentinel{globalBuff + 8}; }
sizeDifferentSentinelWithSizeMember214   constexpr std::size_t size() const { return 8; }
215 };
216 
217 template<>
218 inline constexpr bool std::ranges::enable_borrowed_range<DifferentSentinelWithSizeMember> = true;
219 
220 using DifferentSentinelWithSizeMemberSubrange = std::ranges::subrange<ForwardIter,
221                                                                       DifferentSentinelWithSizeMember::sentinel,
222                                                                       std::ranges::subrange_kind::unsized>;
223 
224 #endif // LIBCXX_TEST_STD_RANGES_RANGE_UTILITY_RANGE_SUBRANGE_TYPES_H
225