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 TEST_STD_RANGES_RANGE_FACTORIES_RANGE_IOTA_VIEW_TYPES_H
10 #define TEST_STD_RANGES_RANGE_FACTORIES_RANGE_IOTA_VIEW_TYPES_H
11 
12 #include "test_macros.h"
13 
14 struct SomeInt {
15   using difference_type = int;
16 
17   int value_;
value_SomeInt18   constexpr explicit SomeInt(int value = 0) : value_(value) {}
19 
20   auto operator<=>(const SomeInt&) const = default;
21 
22   friend constexpr SomeInt& operator+=(SomeInt &lhs, const SomeInt& rhs) {
23     lhs.value_ += rhs.value_; return lhs;
24   }
25   friend constexpr SomeInt& operator-=(SomeInt &lhs, const SomeInt& rhs) {
26     lhs.value_ -= rhs.value_; return lhs;
27   }
28 
29   friend constexpr SomeInt& operator+=(SomeInt &lhs, difference_type rhs) {
30     lhs.value_ += rhs; return lhs;
31   }
32   friend constexpr SomeInt& operator-=(SomeInt &lhs, difference_type rhs) {
33     lhs.value_ -= rhs; return lhs;
34   }
35 
36   friend constexpr SomeInt operator+(SomeInt lhs, SomeInt rhs) {
37     return SomeInt{lhs.value_ + rhs.value_};
38   }
39   friend constexpr int operator-(SomeInt lhs, SomeInt rhs) {
40     return lhs.value_ - rhs.value_;
41   }
42 
43   friend constexpr SomeInt operator+(SomeInt lhs, difference_type rhs) {
44     return SomeInt{lhs.value_ + rhs};
45   }
46   friend constexpr int operator-(SomeInt lhs, difference_type rhs) {
47     return lhs.value_ - rhs;
48   }
49 
50   friend constexpr SomeInt operator+(difference_type lhs, SomeInt rhs) {
51     return SomeInt{lhs + rhs.value_};
52   }
53   friend constexpr int operator-(difference_type lhs, SomeInt rhs) {
54     return lhs - rhs.value_;
55   }
56 
57   constexpr SomeInt& operator++() { ++value_; return *this; }
58   constexpr SomeInt  operator++(int) { auto tmp = *this; ++value_; return tmp; }
59   constexpr SomeInt& operator--() { --value_; return *this; }
60   constexpr SomeInt  operator--(int) { auto tmp = *this; --value_; return tmp; }
61 };
62 
63 template<class T>
64 struct IntComparableWith {
65   using difference_type = std::iter_difference_t<T>;
66 
67   T value_;
value_IntComparableWith68   constexpr explicit IntComparableWith(T value = T()) : value_(value) {}
69 
70   friend constexpr bool operator==(IntComparableWith lhs, IntComparableWith rhs) {
71     return lhs.value_ == rhs.value_;
72   }
73   friend constexpr bool operator==(IntComparableWith lhs, T rhs) {
74     return lhs.value_ == rhs;
75   }
76   friend constexpr bool operator==(T lhs, IntComparableWith rhs) {
77     return lhs == rhs.value_;
78   }
79 
80   friend constexpr IntComparableWith operator+(IntComparableWith lhs, IntComparableWith rhs) {
81     return IntComparableWith{lhs.value_ + rhs.value_};
82   }
83   friend constexpr difference_type operator-(IntComparableWith lhs, IntComparableWith rhs) {
84     return lhs.value_ - rhs.value_;
85   }
86 
87   constexpr IntComparableWith& operator++() { ++value_; return *this; }
88   constexpr IntComparableWith  operator++(int) { auto tmp = *this; ++value_; return tmp; }
89   constexpr IntComparableWith  operator--() { --value_; return *this; }
90 };
91 
92 template<class T>
93 struct IntSentinelWith {
94   using difference_type = std::iter_difference_t<T>;
95 
96   T value_;
value_IntSentinelWith97   constexpr explicit IntSentinelWith(T value = T()) : value_(value) {}
98 
99   friend constexpr bool operator==(IntSentinelWith lhs, IntSentinelWith rhs) {
100     return lhs.value_ == rhs.value_;
101   }
102   friend constexpr bool operator==(IntSentinelWith lhs, T rhs) {
103     return lhs.value_ == rhs;
104   }
105   friend constexpr bool operator==(T lhs, IntSentinelWith rhs) {
106     return lhs == rhs.value_;
107   }
108 
109   friend constexpr IntSentinelWith operator+(IntSentinelWith lhs, IntSentinelWith rhs) {
110     return IntSentinelWith{lhs.value_ + rhs.value_};
111   }
112   friend constexpr difference_type operator-(IntSentinelWith lhs, IntSentinelWith rhs) {
113     return lhs.value_ - rhs.value_;
114   }
115   friend constexpr difference_type operator-(IntSentinelWith lhs, T rhs) {
116     return lhs.value_ - rhs;
117   }
118   friend constexpr difference_type operator-(T lhs, IntSentinelWith rhs) {
119     return lhs - rhs.value_;
120   }
121 
122   constexpr IntSentinelWith& operator++() { ++value_; return *this; }
123   constexpr IntSentinelWith  operator++(int) { auto tmp = *this; ++value_; return tmp; }
124   constexpr IntSentinelWith  operator--() { --value_; return *this; }
125 };
126 
127 struct NotIncrementable {
128   using difference_type = int;
129 
130   int value_;
value_NotIncrementable131   constexpr explicit NotIncrementable(int value = 0) : value_(value) {}
132 
133   bool operator==(const NotIncrementable&) const = default;
134 
135   friend constexpr NotIncrementable& operator+=(NotIncrementable &lhs, const NotIncrementable& rhs) {
136     lhs.value_ += rhs.value_; return lhs;
137   }
138   friend constexpr NotIncrementable& operator-=(NotIncrementable &lhs, const NotIncrementable& rhs) {
139     lhs.value_ -= rhs.value_; return lhs;
140   }
141 
142   friend constexpr NotIncrementable operator+(NotIncrementable lhs, NotIncrementable rhs) {
143     return NotIncrementable{lhs.value_ + rhs.value_};
144   }
145   friend constexpr int operator-(NotIncrementable lhs, NotIncrementable rhs) {
146     return lhs.value_ - rhs.value_;
147   }
148 
149   constexpr NotIncrementable& operator++()    { ++value_; return *this; }
150   constexpr void              operator++(int) { ++value_;               }
151   constexpr NotIncrementable& operator--()    { --value_; return *this; }
152 };
153 static_assert(!std::incrementable<NotIncrementable>);
154 
155 struct NotDecrementable {
156   using difference_type = int;
157 
158   int value_;
value_NotDecrementable159   constexpr explicit NotDecrementable(int value = 0) : value_(value) {}
160 
161   bool operator==(const NotDecrementable&) const = default;
162 
163   friend constexpr NotDecrementable& operator+=(NotDecrementable &lhs, const NotDecrementable& rhs) {
164     lhs.value_ += rhs.value_; return lhs;
165   }
166   friend constexpr NotDecrementable& operator-=(NotDecrementable &lhs, const NotDecrementable& rhs) {
167     lhs.value_ -= rhs.value_; return lhs;
168   }
169 
170   friend constexpr NotDecrementable operator+(NotDecrementable lhs, NotDecrementable rhs) {
171     return NotDecrementable{lhs.value_ + rhs.value_};
172   }
173   friend constexpr int operator-(NotDecrementable lhs, NotDecrementable rhs) {
174     return lhs.value_ - rhs.value_;
175   }
176 
177   constexpr NotDecrementable& operator++()    { ++value_; return *this; }
178   constexpr void              operator++(int) { ++value_;               }
179 };
180 
181 enum CtorKind { DefaultTo42, ValueCtor };
182 
183 template<CtorKind CK>
184 struct Int42 {
185   using difference_type = int;
186 
187   int value_;
Int42Int42188   constexpr explicit Int42(int value) : value_(value) {}
Int42Int42189   constexpr explicit Int42() requires (CK == DefaultTo42)
190     : value_(42) {}
191 
192   bool operator==(const Int42&) const = default;
193 
194   friend constexpr Int42& operator+=(Int42 &lhs, const Int42& rhs) {
195     lhs.value_ += rhs.value_; return lhs;
196   }
197   friend constexpr Int42& operator-=(Int42 &lhs, const Int42& rhs) {
198     lhs.value_ -= rhs.value_; return lhs;
199   }
200 
201   friend constexpr Int42 operator+(Int42 lhs, Int42 rhs) {
202     return Int42{lhs.value_ + rhs.value_};
203   }
204   friend constexpr int operator-(Int42 lhs, Int42 rhs) {
205     return lhs.value_ - rhs.value_;
206   }
207 
208   constexpr Int42& operator++()    { ++value_; return *this; }
209   constexpr void   operator++(int) { ++value_;               }
210 };
211 
212 #endif // TEST_STD_RANGES_RANGE_FACTORIES_RANGE_IOTA_VIEW_TYPES_H
213