xref: /aosp_15_r20/external/cronet/third_party/libc++/src/test/support/almost_satisfies_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 ALMOST_SATISFIES_TYPES_H
10 #define ALMOST_SATISFIES_TYPES_H
11 
12 #include <functional>
13 #include <iterator>
14 #include <ranges>
15 
16 #include "test_iterators.h"
17 
18 template <class T, class U = sentinel_wrapper<T>>
19 class UncheckedRange {
20 public:
21   T begin();
22   U end();
23 };
24 
25 static_assert(std::ranges::contiguous_range<UncheckedRange<int*, int*>>);
26 
27 // almost an input_iterator
28 template <class T>
29 class InputIteratorNotDerivedFromGeneric {
30 public:
31   using difference_type = long;
32   using value_type = T;
33   using iterator_category = void;
34 
35   InputIteratorNotDerivedFromGeneric& operator++();
36   void operator++(int);
37   const T& operator*() const;
38 };
39 
40 using InputIteratorNotDerivedFrom = InputIteratorNotDerivedFromGeneric<int>;
41 
42 template <class T>
43 using InputRangeNotDerivedFromGeneric = UncheckedRange<InputIteratorNotDerivedFromGeneric<T>>;
44 using InputRangeNotDerivedFrom = UncheckedRange<InputIteratorNotDerivedFrom>;
45 
46 static_assert(std::input_or_output_iterator<InputIteratorNotDerivedFrom>);
47 static_assert(std::indirectly_readable<InputIteratorNotDerivedFrom>);
48 static_assert(!std::input_iterator<InputIteratorNotDerivedFrom>);
49 static_assert(!std::ranges::input_range<InputRangeNotDerivedFrom>);
50 
51 class InputIteratorNotIndirectlyReadable {
52 public:
53   using difference_type = long;
54   using iterator_category = std::input_iterator_tag;
55 
56   InputIteratorNotIndirectlyReadable& operator++();
57   void operator++(int);
58   const int& operator*() const;
59 };
60 
61 using InputRangeNotIndirectlyReadable = UncheckedRange<InputIteratorNotIndirectlyReadable>;
62 
63 static_assert(std::input_or_output_iterator<InputIteratorNotIndirectlyReadable>);
64 static_assert(!std::indirectly_readable<InputIteratorNotIndirectlyReadable>);
65 static_assert(!std::input_iterator<InputIteratorNotIndirectlyReadable>);
66 static_assert(!std::ranges::input_range<InputRangeNotIndirectlyReadable>);
67 
68 class InputIteratorNotInputOrOutputIterator {
69 public:
70   using difference_type = long;
71   using value_type = int;
72   using iterator_category = std::input_iterator_tag;
73 
74   int& operator++();
75   void operator++(int);
76   const int& operator*() const;
77 };
78 
79 using InputRangeNotInputOrOutputIterator = UncheckedRange<InputIteratorNotInputOrOutputIterator>;
80 
81 static_assert(!std::input_or_output_iterator<InputIteratorNotInputOrOutputIterator>);
82 static_assert(std::indirectly_readable<InputIteratorNotInputOrOutputIterator>);
83 static_assert(!std::input_iterator<InputIteratorNotInputOrOutputIterator>);
84 static_assert(!std::ranges::input_range<InputRangeNotInputOrOutputIterator>);
85 
86 // almost an indirect_unary_predicate
87 class IndirectUnaryPredicateNotCopyConstructible {
88 public:
89   IndirectUnaryPredicateNotCopyConstructible(const IndirectUnaryPredicateNotCopyConstructible&) = delete;
90   bool operator()(int) const;
91 };
92 
93 static_assert(std::predicate<IndirectUnaryPredicateNotCopyConstructible, int&>);
94 static_assert(!std::indirect_unary_predicate<IndirectUnaryPredicateNotCopyConstructible, int*>);
95 
96 class IndirectUnaryPredicateNotPredicate {
97 public:
98   bool operator()(int&&) const;
99 };
100 
101 static_assert(!std::predicate<IndirectUnaryPredicateNotPredicate, int&>);
102 static_assert(!std::indirect_unary_predicate<IndirectUnaryPredicateNotPredicate, int*>);
103 
104 // almost a sentinel_for cpp20_input_iterator
105 class SentinelForNotSemiregular {
106 public:
107   SentinelForNotSemiregular() = delete;
108   using difference_type = long;
109   SentinelForNotSemiregular& operator++();
110   void operator++(int);
111   const int& operator*() const;
112   friend bool operator==(const SentinelForNotSemiregular&, const cpp20_input_iterator<int*>&);
113 };
114 
115 using InputRangeNotSentinelSemiregular = UncheckedRange<cpp20_input_iterator<int*>, SentinelForNotSemiregular>;
116 using OutputRangeNotSentinelSemiregular = UncheckedRange<cpp20_output_iterator<int*>, SentinelForNotSemiregular>;
117 
118 static_assert(std::input_or_output_iterator<SentinelForNotSemiregular>);
119 static_assert(!std::semiregular<SentinelForNotSemiregular>);
120 static_assert(!std::sentinel_for<SentinelForNotSemiregular, cpp20_input_iterator<int*>>);
121 
122 // almost a sentinel_for cpp20_input_iterator
123 class SentinelForNotWeaklyEqualityComparableWith {
124 public:
125   using difference_type = long;
126   SentinelForNotWeaklyEqualityComparableWith& operator++();
127   void operator++(int);
128   const int& operator*() const;
129 };
130 
131 using InputRangeNotSentinelEqualityComparableWith =
132   UncheckedRange<cpp20_input_iterator<int*>, SentinelForNotWeaklyEqualityComparableWith>;
133 using OutputRangeNotSentinelEqualityComparableWith =
134   UncheckedRange<cpp20_output_iterator<int*>, SentinelForNotWeaklyEqualityComparableWith>;
135 
136 static_assert(std::input_or_output_iterator<SentinelForNotWeaklyEqualityComparableWith>);
137 static_assert(std::semiregular<SentinelForNotWeaklyEqualityComparableWith>);
138 static_assert(!std::sentinel_for<SentinelForNotWeaklyEqualityComparableWith, cpp20_input_iterator<int*>>);
139 
140 class WeaklyIncrementableNotMovable {
141 public:
142   using difference_type = long;
143   WeaklyIncrementableNotMovable& operator++();
144   void operator++(int);
145   WeaklyIncrementableNotMovable(const WeaklyIncrementableNotMovable&) = delete;
146 };
147 
148 static_assert(!std::movable<WeaklyIncrementableNotMovable>);
149 static_assert(!std::weakly_incrementable<WeaklyIncrementableNotMovable>);
150 
151 // almost a forward_iterator
152 class ForwardIteratorNotDerivedFrom {
153 public:
154   using difference_type = long;
155   using value_type = int;
156   using iterator_category = std::input_iterator_tag;
157 
158   ForwardIteratorNotDerivedFrom& operator++();
159   ForwardIteratorNotDerivedFrom operator++(int);
160   const int& operator*() const;
161   bool operator==(const ForwardIteratorNotDerivedFrom&) const = default;
162 };
163 
164 using ForwardRangeNotDerivedFrom = UncheckedRange<ForwardIteratorNotDerivedFrom>;
165 
166 static_assert(std::input_iterator<ForwardIteratorNotDerivedFrom>);
167 static_assert(std::incrementable<ForwardIteratorNotDerivedFrom>);
168 static_assert(std::sentinel_for<ForwardIteratorNotDerivedFrom, ForwardIteratorNotDerivedFrom>);
169 static_assert(!std::forward_iterator<ForwardIteratorNotDerivedFrom>);
170 
171 class ForwardIteratorNotIncrementable {
172 public:
173   using difference_type = long;
174   using value_type = int;
175   using iterator_category = std::forward_iterator_tag;
176 
177   ForwardIteratorNotIncrementable& operator++();
178   int operator++(int);
179   const int& operator*() const;
180   bool operator==(const ForwardIteratorNotIncrementable&) const = default;
181 };
182 
183 using ForwardRangeNotIncrementable = UncheckedRange<ForwardIteratorNotIncrementable>;
184 
185 static_assert(std::input_iterator<ForwardIteratorNotIncrementable>);
186 static_assert(!std::incrementable<ForwardIteratorNotIncrementable>);
187 static_assert(std::sentinel_for<ForwardIteratorNotIncrementable, ForwardIteratorNotIncrementable>);
188 static_assert(!std::forward_iterator<ForwardIteratorNotIncrementable>);
189 
190 using ForwardRangeNotSentinelSemiregular = UncheckedRange<forward_iterator<int*>, SentinelForNotSemiregular>;
191 using ForwardRangeNotSentinelEqualityComparableWith =
192     UncheckedRange<forward_iterator<int*>, SentinelForNotWeaklyEqualityComparableWith>;
193 
194 class BidirectionalIteratorNotDerivedFrom {
195 public:
196   using difference_type = long;
197   using value_type = int;
198   using iterator_category = std::forward_iterator_tag;
199 
200   BidirectionalIteratorNotDerivedFrom& operator++();
201   BidirectionalIteratorNotDerivedFrom operator++(int);
202   BidirectionalIteratorNotDerivedFrom& operator--();
203   BidirectionalIteratorNotDerivedFrom operator--(int);
204   int& operator*() const;
205 
206   bool operator==(const BidirectionalIteratorNotDerivedFrom&) const = default;
207 };
208 
209 using BidirectionalRangeNotDerivedFrom = UncheckedRange<BidirectionalIteratorNotDerivedFrom>;
210 using BidirectionalRangeNotSentinelSemiregular =
211     UncheckedRange<bidirectional_iterator<int*>, SentinelForNotSemiregular>;
212 using BidirectionalRangeNotSentinelWeaklyEqualityComparableWith =
213     UncheckedRange<bidirectional_iterator<int*>, SentinelForNotWeaklyEqualityComparableWith>;
214 
215 static_assert(std::forward_iterator<BidirectionalIteratorNotDerivedFrom>);
216 static_assert(!std::bidirectional_iterator<BidirectionalIteratorNotDerivedFrom>);
217 static_assert(!std::ranges::bidirectional_range<BidirectionalRangeNotDerivedFrom>);
218 
219 class BidirectionalIteratorNotDecrementable {
220 public:
221   using difference_type = long;
222   using value_type = int;
223   using iterator_category = std::bidirectional_iterator_tag;
224 
225   BidirectionalIteratorNotDecrementable& operator++();
226   BidirectionalIteratorNotDecrementable operator++(int);
227   int& operator*() const;
228 
229   bool operator==(const BidirectionalIteratorNotDecrementable&) const = default;
230 };
231 
232 using BidirectionalRangeNotDecrementable = UncheckedRange<BidirectionalIteratorNotDecrementable>;
233 
234 static_assert(std::forward_iterator<BidirectionalIteratorNotDecrementable>);
235 static_assert(!std::bidirectional_iterator<BidirectionalIteratorNotDecrementable>);
236 static_assert(!std::ranges::bidirectional_range<BidirectionalRangeNotDecrementable>);
237 
238 class PermutableNotForwardIterator {
239 public:
240   using difference_type = long;
241   using value_type = int;
242   using iterator_category = std::input_iterator_tag;
243 
244   PermutableNotForwardIterator& operator++();
245   void operator++(int);
246   int& operator*() const;
247 };
248 
249 using PermutableRangeNotForwardIterator = UncheckedRange<PermutableNotForwardIterator>;
250 
251 static_assert(std::input_iterator<PermutableNotForwardIterator>);
252 static_assert(!std::forward_iterator<PermutableNotForwardIterator>);
253 static_assert(!std::permutable<PermutableNotForwardIterator>);
254 
255 class PermutableNotSwappable {
256 public:
257   class NotSwappable {
258     NotSwappable(NotSwappable&&) = delete;
259   };
260 
261   using difference_type = long;
262   using value_type = NotSwappable;
263   using iterator_category = std::contiguous_iterator_tag;
264 
265   PermutableNotSwappable& operator++();
266   PermutableNotSwappable operator++(int);
267   NotSwappable& operator*() const;
268 
269   bool operator==(const PermutableNotSwappable&) const = default;
270 };
271 
272 using PermutableRangeNotSwappable = UncheckedRange<PermutableNotSwappable>;
273 
274 static_assert(std::input_iterator<PermutableNotSwappable>);
275 static_assert(std::forward_iterator<PermutableNotSwappable>);
276 static_assert(!std::permutable<PermutableNotSwappable>);
277 static_assert(!std::indirectly_swappable<PermutableNotSwappable>);
278 
279 class OutputIteratorNotInputOrOutputIterator {
280 public:
281   using difference_type = long;
282   using value_type = int;
283   using iterator_category = std::input_iterator_tag;
284 
285   int& operator++();
286   void operator++(int);
287   int& operator*();
288 };
289 
290 using OutputRangeNotInputOrOutputIterator = UncheckedRange<InputIteratorNotInputOrOutputIterator>;
291 
292 static_assert(!std::input_or_output_iterator<OutputIteratorNotInputOrOutputIterator>);
293 static_assert(std::indirectly_writable<OutputIteratorNotInputOrOutputIterator, int>);
294 static_assert(!std::output_iterator<OutputIteratorNotInputOrOutputIterator, int>);
295 static_assert(!std::ranges::output_range<OutputRangeNotInputOrOutputIterator, int>);
296 
297 class OutputIteratorNotIndirectlyWritable {
298 public:
299   using difference_type = long;
300   using iterator_category = std::input_iterator_tag;
301 
302   OutputIteratorNotIndirectlyWritable& operator++();
303   void operator++(int);
304   const int& operator*() const;
305 };
306 
307 using OutputRangeNotIndirectlyWritable = UncheckedRange<OutputIteratorNotIndirectlyWritable>;
308 
309 static_assert(std::input_or_output_iterator<OutputIteratorNotIndirectlyWritable>);
310 static_assert(!std::indirectly_writable<OutputIteratorNotIndirectlyWritable, int>);
311 static_assert(!std::output_iterator<OutputIteratorNotIndirectlyWritable, int>);
312 static_assert(!std::ranges::output_range<OutputIteratorNotIndirectlyWritable, int>);
313 
314 class IndirectBinaryPredicateNotIndirectlyReadable {
315 public:
316   using difference_type = long;
317   using iterator_category = std::input_iterator_tag;
318 
319   int& operator++();
320   void operator++(int);
321   const int& operator*() const;
322 };
323 
324 using InputRangeIndirectBinaryPredicateNotIndirectlyReadable
325      = UncheckedRange<cpp20_input_iterator<int*>, IndirectBinaryPredicateNotIndirectlyReadable>;
326 
327 static_assert(!std::indirect_binary_predicate<std::ranges::equal_to, IndirectBinaryPredicateNotIndirectlyReadable, int*>);
328 
329 class RandomAccessIteratorNotDerivedFrom {
330   using Self = RandomAccessIteratorNotDerivedFrom;
331 
332 public:
333   using value_type = int;
334   using difference_type = long;
335   using pointer = int*;
336   using reference = int&;
337   // Deliberately not using the `std::random_access_iterator_tag` category.
338   using iterator_category = std::bidirectional_iterator_tag;
339 
340   reference operator*() const;
341   reference operator[](difference_type) const;
342 
343   Self& operator++();
344   Self& operator--();
345   Self operator++(int);
346   Self operator--(int);
347 
348   Self& operator+=(difference_type);
349   Self& operator-=(difference_type);
350   friend Self operator+(Self, difference_type);
351   friend Self operator+(difference_type, Self);
352   friend Self operator-(Self, difference_type);
353   friend difference_type operator-(Self, Self);
354 
355   auto operator<=>(const Self&) const = default;
356 };
357 
358 static_assert(std::bidirectional_iterator<RandomAccessIteratorNotDerivedFrom>);
359 static_assert(!std::random_access_iterator<RandomAccessIteratorNotDerivedFrom>);
360 
361 using RandomAccessRangeNotDerivedFrom = UncheckedRange<RandomAccessIteratorNotDerivedFrom>;
362 
363 class RandomAccessIteratorBadIndex {
364   using Self = RandomAccessIteratorBadIndex;
365 
366 public:
367   using value_type = int;
368   using difference_type = long;
369   using pointer = int*;
370   using reference = int&;
371   using iterator_category = std::random_access_iterator_tag;
372 
373   reference operator*() const;
374   // Deliberately returning a type different from `reference`.
375   const int& operator[](difference_type) const;
376 
377   Self& operator++();
378   Self& operator--();
379   Self operator++(int);
380   Self operator--(int);
381 
382   Self& operator+=(difference_type);
383   Self& operator-=(difference_type);
384   friend Self operator+(Self, difference_type);
385   friend Self operator+(difference_type, Self);
386   friend Self operator-(Self, difference_type);
387   friend difference_type operator-(Self, Self);
388 
389   auto operator<=>(const Self&) const = default;
390 };
391 
392 static_assert(std::bidirectional_iterator<RandomAccessIteratorBadIndex>);
393 static_assert(!std::random_access_iterator<RandomAccessIteratorBadIndex>);
394 
395 using RandomAccessRangeBadIndex = UncheckedRange<RandomAccessIteratorBadIndex>;
396 
397 class RandomAccessIteratorBadDifferenceType {
398   using Self = RandomAccessIteratorBadDifferenceType;
399 
400 public:
401   using value_type = int;
402   // Deliberately use a non-integer `difference_type`
403   using difference_type   = double;
404   using pointer           = double*;
405   using reference         = double&;
406   using iterator_category = std::random_access_iterator_tag;
407 
408   reference operator*() const;
409   reference operator[](difference_type) const;
410 
411   Self& operator++();
412   Self& operator--();
413   Self operator++(int);
414   Self operator--(int);
415 
416   Self& operator+=(difference_type);
417   Self& operator-=(difference_type);
418   friend Self operator+(Self, difference_type);
419   friend Self operator+(difference_type, Self);
420   friend Self operator-(Self, difference_type);
421   friend difference_type operator-(Self, Self);
422 
423   auto operator<=>(const Self&) const = default;
424 };
425 
426 static_assert(std::regular<RandomAccessIteratorBadDifferenceType>);
427 static_assert(!std::weakly_incrementable<RandomAccessIteratorBadDifferenceType>);
428 static_assert(!std::random_access_iterator<RandomAccessIteratorBadDifferenceType>);
429 
430 template <class Iter>
431 class ComparatorNotCopyable {
432 public:
433   ComparatorNotCopyable(ComparatorNotCopyable&&) = default;
434   ComparatorNotCopyable& operator=(ComparatorNotCopyable&&) = default;
435   ComparatorNotCopyable(const ComparatorNotCopyable&) = delete;
436   ComparatorNotCopyable& operator=(const ComparatorNotCopyable&) = delete;
437 
438   bool operator()(Iter&, Iter&) const;
439 };
440 
441 #endif // ALMOST_SATISFIES_TYPES_H
442