1 // Copyright 2019 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "runtime/cpp/emboss_arithmetic.h"
16
17 #include "gtest/gtest.h"
18
19 namespace emboss {
20 namespace support {
21
22 // EXPECT_EQ uses operator==. For un-Known() Maybes, this follows the semantics
23 // for operator==(std::optional<T>, std::optional<T>), which returns true if
24 // neither argument has_value(). (It also matches Rust's Option and Haskell's
25 // Maybe.)
26 //
27 // Given the name "Known", it arguably should follow NaN != NaN semantics
28 // instead, but this is more useful for tests.
29 template <typename T>
operator ==(const Maybe<T> & l,const Maybe<T> & r)30 constexpr inline bool operator==(const Maybe<T> &l, const Maybe<T> &r) {
31 return l.Known() == r.Known() && l.ValueOrDefault() == r.ValueOrDefault();
32 }
33
34 namespace test {
35
36 using ::std::int32_t;
37 using ::std::int64_t;
38 using ::std::uint32_t;
39 using ::std::uint64_t;
40
TEST(Sum,Sum)41 TEST(Sum, Sum) {
42 EXPECT_EQ(
43 Maybe</**/ ::std::int32_t>(0),
44 (Sum</**/ ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(
45 Maybe</**/ ::std::int32_t>(0), Maybe</**/ ::std::int32_t>(0))));
46 EXPECT_EQ(
47 Maybe</**/ ::std::int32_t>(2147483647),
48 (Sum</**/ ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(
49 Maybe</**/ ::std::int32_t>(2147483646),
50 Maybe</**/ ::std::int32_t>(1))));
51 EXPECT_EQ(
52 Maybe</**/ ::std::int32_t>(-2147483647 - 1),
53 (Sum</**/ ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(
54 Maybe</**/ ::std::int32_t>(-2147483647),
55 Maybe</**/ ::std::int32_t>(-1))));
56 EXPECT_EQ(Maybe</**/ ::std::uint32_t>(2147483648U),
57 (Sum</**/ ::std::uint32_t, ::std::uint32_t, ::std::int32_t,
58 ::std::int32_t>(Maybe</**/ ::std::int32_t>(2147483647),
59 Maybe</**/ ::std::int32_t>(1))));
60 EXPECT_EQ(Maybe</**/ ::std::int32_t>(2147483647),
61 (Sum</**/ ::std::int64_t, ::std::int32_t, ::std::uint32_t,
62 ::std::int32_t>(Maybe</**/ ::std::uint32_t>(2147483648U),
63 Maybe</**/ ::std::int32_t>(-1))));
64 EXPECT_EQ(Maybe</**/ ::std::int32_t>(),
65 (Sum</**/ ::std::int64_t, ::std::int32_t, ::std::uint32_t,
66 ::std::int32_t>(Maybe</**/ ::std::uint32_t>(),
67 Maybe</**/ ::std::int32_t>(-1))));
68 }
69
TEST(Difference,Difference)70 TEST(Difference, Difference) {
71 EXPECT_EQ(Maybe</**/ ::std::int32_t>(0),
72 (Difference</**/ ::std::int32_t, ::std::int32_t, ::std::int32_t,
73 ::std::int32_t>(Maybe</**/ ::std::int32_t>(0),
74 Maybe</**/ ::std::int32_t>(0))));
75 EXPECT_EQ(Maybe</**/ ::std::int32_t>(2147483647),
76 (Difference</**/ ::std::int32_t, ::std::int32_t, ::std::int32_t,
77 ::std::int32_t>(Maybe</**/ ::std::int32_t>(2147483646),
78 Maybe</**/ ::std::int32_t>(-1))));
79 EXPECT_EQ(Maybe</**/ ::std::int32_t>(-2147483647 - 1),
80 (Difference</**/ ::std::int32_t, ::std::int32_t, ::std::int32_t,
81 ::std::int32_t>(Maybe</**/ ::std::int32_t>(-2147483647),
82 Maybe</**/ ::std::int32_t>(1))));
83 EXPECT_EQ(Maybe</**/ ::std::uint32_t>(2147483648U),
84 (Difference</**/ ::std::uint32_t, ::std::uint32_t, ::std::int32_t,
85 ::std::int32_t>(Maybe</**/ ::std::int32_t>(2147483647),
86 Maybe</**/ ::std::int32_t>(-1))));
87 EXPECT_EQ(
88 Maybe</**/ ::std::int32_t>(2147483647),
89 (Difference</**/ ::std::uint32_t, ::std::int32_t, ::std::uint32_t,
90 ::std::int32_t>(Maybe</**/ ::std::uint32_t>(2147483648U),
91 Maybe</**/ ::std::int32_t>(1))));
92 EXPECT_EQ(
93 Maybe</**/ ::std::int32_t>(-2147483647 - 1),
94 (Difference</**/ ::std::int64_t, ::std::int32_t, ::std::int32_t,
95 ::std::uint32_t>(Maybe</**/ ::std::int32_t>(1),
96 Maybe</**/ ::std::uint32_t>(2147483649U))));
97 EXPECT_EQ(Maybe</**/ ::std::int32_t>(),
98 (Difference</**/ ::std::int64_t, ::std::int32_t, ::std::int32_t,
99 ::std::uint32_t>(Maybe</**/ ::std::int32_t>(1),
100 Maybe</**/ ::std::uint32_t>())));
101 }
102
TEST(Product,Product)103 TEST(Product, Product) {
104 EXPECT_EQ(Maybe</**/ ::std::int32_t>(0),
105 (Product</**/ ::std::int32_t, ::std::int32_t, ::std::int32_t,
106 ::std::int32_t>(Maybe</**/ ::std::int32_t>(0),
107 Maybe</**/ ::std::int32_t>(0))));
108 EXPECT_EQ(Maybe</**/ ::std::int32_t>(-2147483646),
109 (Product</**/ ::std::int32_t, ::std::int32_t, ::std::int32_t,
110 ::std::int32_t>(Maybe</**/ ::std::int32_t>(2147483646),
111 Maybe</**/ ::std::int32_t>(-1))));
112 EXPECT_EQ(
113 Maybe</**/ ::std::int32_t>(-2147483647 - 1),
114 (Product</**/ ::std::int32_t, ::std::int32_t, ::std::int32_t,
115 ::std::int32_t>(Maybe</**/ ::std::int32_t>(-2147483647 - 1),
116 Maybe</**/ ::std::int32_t>(1))));
117 EXPECT_EQ(Maybe</**/ ::std::uint32_t>(2147483648U),
118 (Product</**/ ::std::uint32_t, ::std::uint32_t, ::std::int32_t,
119 ::std::int32_t>(Maybe</**/ ::std::int32_t>(1073741824),
120 Maybe</**/ ::std::int32_t>(2))));
121 EXPECT_EQ(Maybe</**/ ::std::uint32_t>(),
122 (Product</**/ ::std::uint32_t, ::std::uint32_t, ::std::int32_t,
123 ::std::int32_t>(Maybe</**/ ::std::int32_t>(),
124 Maybe</**/ ::std::int32_t>(2))));
125 }
126
TEST(Equal,Equal)127 TEST(Equal, Equal) {
128 EXPECT_EQ(Maybe<bool>(true),
129 (Equal</**/ ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(
130 Maybe</**/ ::std::int32_t>(0), Maybe</**/ ::std::int32_t>(0))));
131 EXPECT_EQ(Maybe<bool>(false),
132 (Equal</**/ ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(
133 Maybe</**/ ::std::int32_t>(2147483646),
134 Maybe</**/ ::std::int32_t>(-1))));
135 EXPECT_EQ(Maybe<bool>(true),
136 (Equal</**/ ::std::int32_t, bool, ::std::int32_t, ::std::uint32_t>(
137 Maybe</**/ ::std::int32_t>(2147483647),
138 Maybe</**/ ::std::uint32_t>(2147483647))));
139 EXPECT_EQ(Maybe<bool>(false),
140 (Equal</**/ ::std::int64_t, bool, ::std::int32_t, ::std::uint32_t>(
141 Maybe</**/ ::std::int32_t>(-2147483648LL),
142 Maybe</**/ ::std::uint32_t>(2147483648U))));
143 EXPECT_EQ(Maybe<bool>(),
144 (Equal</**/ ::std::int64_t, bool, ::std::int32_t, ::std::uint32_t>(
145 Maybe</**/ ::std::int32_t>(),
146 Maybe</**/ ::std::uint32_t>(2147483648U))));
147 }
148
TEST(NotEqual,NotEqual)149 TEST(NotEqual, NotEqual) {
150 EXPECT_EQ(
151 Maybe<bool>(false),
152 (NotEqual</**/ ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(
153 Maybe</**/ ::std::int32_t>(0), Maybe</**/ ::std::int32_t>(0))));
154 EXPECT_EQ(
155 Maybe<bool>(true),
156 (NotEqual</**/ ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(
157 Maybe</**/ ::std::int32_t>(2147483646),
158 Maybe</**/ ::std::int32_t>(-1))));
159 EXPECT_EQ(
160 Maybe<bool>(false),
161 (NotEqual</**/ ::std::int32_t, bool, ::std::int32_t, ::std::uint32_t>(
162 Maybe</**/ ::std::int32_t>(2147483647),
163 Maybe</**/ ::std::uint32_t>(2147483647))));
164 EXPECT_EQ(
165 Maybe<bool>(true),
166 (NotEqual</**/ ::std::int64_t, bool, ::std::int32_t, ::std::uint32_t>(
167 Maybe</**/ ::std::int32_t>(-2147483648LL),
168 Maybe</**/ ::std::uint32_t>(2147483648U))));
169 EXPECT_EQ(
170 Maybe<bool>(),
171 (NotEqual</**/ ::std::int64_t, bool, ::std::int32_t, ::std::uint32_t>(
172 Maybe</**/ ::std::int32_t>(-2147483648LL),
173 Maybe</**/ ::std::uint32_t>())));
174 }
175
TEST(LessThan,LessThan)176 TEST(LessThan, LessThan) {
177 EXPECT_EQ(
178 Maybe<bool>(false),
179 (LessThan</**/ ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(
180 Maybe</**/ ::std::int32_t>(0), Maybe</**/ ::std::int32_t>(0))));
181 EXPECT_EQ(
182 Maybe<bool>(false),
183 (LessThan</**/ ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(
184 Maybe</**/ ::std::int32_t>(2147483646),
185 Maybe</**/ ::std::int32_t>(-1))));
186 EXPECT_EQ(
187 Maybe<bool>(false),
188 (LessThan</**/ ::std::int32_t, bool, ::std::int32_t, ::std::uint32_t>(
189 Maybe</**/ ::std::int32_t>(2147483647),
190 Maybe</**/ ::std::uint32_t>(2147483647))));
191 EXPECT_EQ(
192 Maybe<bool>(true),
193 (LessThan</**/ ::std::int64_t, bool, ::std::int32_t, ::std::uint32_t>(
194 Maybe</**/ ::std::int32_t>(-2147483648LL),
195 Maybe</**/ ::std::uint32_t>(2147483648U))));
196 EXPECT_EQ(
197 Maybe<bool>(),
198 (LessThan</**/ ::std::int64_t, bool, ::std::int32_t, ::std::uint32_t>(
199 Maybe</**/ ::std::int32_t>(),
200 Maybe</**/ ::std::uint32_t>(2147483648U))));
201 }
202
TEST(LessThanOrEqual,LessThanOrEqual)203 TEST(LessThanOrEqual, LessThanOrEqual) {
204 EXPECT_EQ(Maybe<bool>(true),
205 (LessThanOrEqual</**/ ::std::int32_t, bool, ::std::int32_t,
206 ::std::int32_t>(Maybe</**/ ::std::int32_t>(0),
207 Maybe</**/ ::std::int32_t>(0))));
208 EXPECT_EQ(
209 Maybe<bool>(false),
210 (LessThanOrEqual</**/ ::std::int32_t, bool, ::std::int32_t,
211 ::std::int32_t>(Maybe</**/ ::std::int32_t>(2147483646),
212 Maybe</**/ ::std::int32_t>(-1))));
213 EXPECT_EQ(Maybe<bool>(true),
214 (LessThanOrEqual</**/ ::std::int32_t, bool, ::std::int32_t,
215 ::std::uint32_t>(
216 Maybe</**/ ::std::int32_t>(2147483647),
217 Maybe</**/ ::std::uint32_t>(2147483647))));
218 EXPECT_EQ(Maybe<bool>(true),
219 (LessThanOrEqual</**/ ::std::int64_t, bool, ::std::int32_t,
220 ::std::uint32_t>(
221 Maybe</**/ ::std::int32_t>(-2147483648LL),
222 Maybe</**/ ::std::uint32_t>(2147483648U))));
223 EXPECT_EQ(Maybe<bool>(), (LessThanOrEqual</**/ ::std::int64_t, bool,
224 ::std::int32_t, ::std::uint32_t>(
225 Maybe</**/ ::std::int32_t>(),
226 Maybe</**/ ::std::uint32_t>(2147483648U))));
227 }
228
TEST(GreaterThan,GreaterThan)229 TEST(GreaterThan, GreaterThan) {
230 EXPECT_EQ(
231 Maybe<bool>(false),
232 (GreaterThan</**/ ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(
233 Maybe</**/ ::std::int32_t>(0), Maybe</**/ ::std::int32_t>(0))));
234 EXPECT_EQ(
235 Maybe<bool>(true),
236 (GreaterThan</**/ ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(
237 Maybe</**/ ::std::int32_t>(2147483646),
238 Maybe</**/ ::std::int32_t>(-1))));
239 EXPECT_EQ(
240 Maybe<bool>(false),
241 (GreaterThan</**/ ::std::int32_t, bool, ::std::int32_t, ::std::uint32_t>(
242 Maybe</**/ ::std::int32_t>(2147483647),
243 Maybe</**/ ::std::uint32_t>(2147483647))));
244 EXPECT_EQ(
245 Maybe<bool>(false),
246 (GreaterThan</**/ ::std::int64_t, bool, ::std::int32_t, ::std::uint32_t>(
247 Maybe</**/ ::std::int32_t>(-2147483648LL),
248 Maybe</**/ ::std::uint32_t>(2147483648U))));
249 EXPECT_EQ(
250 Maybe<bool>(),
251 (GreaterThan</**/ ::std::int64_t, bool, ::std::int32_t, ::std::uint32_t>(
252 Maybe</**/ ::std::int32_t>(),
253 Maybe</**/ ::std::uint32_t>(2147483648U))));
254 }
255
TEST(GreaterThanOrEqual,GreaterThanOrEqual)256 TEST(GreaterThanOrEqual, GreaterThanOrEqual) {
257 EXPECT_EQ(Maybe<bool>(true),
258 (GreaterThanOrEqual</**/ ::std::int32_t, bool, ::std::int32_t,
259 ::std::int32_t>(
260 Maybe</**/ ::std::int32_t>(0), Maybe</**/ ::std::int32_t>(0))));
261 EXPECT_EQ(Maybe<bool>(true),
262 (GreaterThanOrEqual</**/ ::std::int32_t, bool, ::std::int32_t,
263 ::std::int32_t>(
264 Maybe</**/ ::std::int32_t>(2147483646),
265 Maybe</**/ ::std::int32_t>(-1))));
266 EXPECT_EQ(Maybe<bool>(true),
267 (GreaterThanOrEqual</**/ ::std::int32_t, bool, ::std::int32_t,
268 ::std::uint32_t>(
269 Maybe</**/ ::std::int32_t>(2147483647),
270 Maybe</**/ ::std::uint32_t>(2147483647))));
271 EXPECT_EQ(Maybe<bool>(false),
272 (GreaterThanOrEqual</**/ ::std::int64_t, bool, ::std::int32_t,
273 ::std::uint32_t>(
274 Maybe</**/ ::std::int32_t>(-2147483648LL),
275 Maybe</**/ ::std::uint32_t>(2147483648U))));
276 EXPECT_EQ(Maybe<bool>(), (GreaterThanOrEqual</**/ ::std::int64_t, bool,
277 ::std::int32_t, ::std::uint32_t>(
278 Maybe</**/ ::std::int32_t>(),
279 Maybe</**/ ::std::uint32_t>(2147483648U))));
280 }
281
TEST(And,And)282 TEST(And, And) {
283 EXPECT_EQ(Maybe<bool>(true), (And<bool, bool, bool, bool>(
284 Maybe<bool>(true), Maybe<bool>(true))));
285 EXPECT_EQ(Maybe<bool>(),
286 (And<bool, bool, bool, bool>(Maybe<bool>(), Maybe<bool>(true))));
287 EXPECT_EQ(Maybe<bool>(),
288 (And<bool, bool, bool, bool>(Maybe<bool>(), Maybe<bool>())));
289 EXPECT_EQ(Maybe<bool>(),
290 (And<bool, bool, bool, bool>(Maybe<bool>(true), Maybe<bool>())));
291 EXPECT_EQ(Maybe<bool>(false), (And<bool, bool, bool, bool>(
292 Maybe<bool>(false), Maybe<bool>(true))));
293 EXPECT_EQ(Maybe<bool>(false),
294 (And<bool, bool, bool, bool>(Maybe<bool>(false), Maybe<bool>())));
295 EXPECT_EQ(Maybe<bool>(false), (And<bool, bool, bool, bool>(
296 Maybe<bool>(false), Maybe<bool>(false))));
297 EXPECT_EQ(Maybe<bool>(false), (And<bool, bool, bool, bool>(
298 Maybe<bool>(true), Maybe<bool>(false))));
299 EXPECT_EQ(Maybe<bool>(false),
300 (And<bool, bool, bool, bool>(Maybe<bool>(), Maybe<bool>(false))));
301 }
302
TEST(Or,Or)303 TEST(Or, Or) {
304 EXPECT_EQ(Maybe<bool>(false), (Or<bool, bool, bool, bool>(
305 Maybe<bool>(false), Maybe<bool>(false))));
306 EXPECT_EQ(Maybe<bool>(),
307 (Or<bool, bool, bool, bool>(Maybe<bool>(), Maybe<bool>(false))));
308 EXPECT_EQ(Maybe<bool>(),
309 (Or<bool, bool, bool, bool>(Maybe<bool>(), Maybe<bool>())));
310 EXPECT_EQ(Maybe<bool>(),
311 (Or<bool, bool, bool, bool>(Maybe<bool>(false), Maybe<bool>())));
312 EXPECT_EQ(Maybe<bool>(true), (Or<bool, bool, bool, bool>(Maybe<bool>(false),
313 Maybe<bool>(true))));
314 EXPECT_EQ(Maybe<bool>(true),
315 (Or<bool, bool, bool, bool>(Maybe<bool>(true), Maybe<bool>())));
316 EXPECT_EQ(Maybe<bool>(true),
317 (Or<bool, bool, bool, bool>(Maybe<bool>(true), Maybe<bool>(true))));
318 EXPECT_EQ(Maybe<bool>(true), (Or<bool, bool, bool, bool>(
319 Maybe<bool>(true), Maybe<bool>(false))));
320 EXPECT_EQ(Maybe<bool>(true),
321 (Or<bool, bool, bool, bool>(Maybe<bool>(), Maybe<bool>(true))));
322 }
323
TEST(Choice,Choice)324 TEST(Choice, Choice) {
325 EXPECT_EQ(Maybe<int>(), (Choice<int, int, bool, int, int>(
326 Maybe<bool>(), Maybe<int>(1), Maybe<int>(2))));
327 EXPECT_EQ(Maybe<int>(1),
328 (Choice<int, int, bool, int, int>(Maybe<bool>(true), Maybe<int>(1),
329 Maybe<int>(2))));
330 EXPECT_EQ(Maybe<int>(2),
331 (Choice<int, int, bool, int, int>(Maybe<bool>(false), Maybe<int>(1),
332 Maybe<int>(2))));
333 EXPECT_EQ(Maybe<int>(), (Choice<int, int, bool, int, int>(
334 Maybe<bool>(true), Maybe<int>(), Maybe<int>(2))));
335 EXPECT_EQ(Maybe<int>(),
336 (Choice<int, int, bool, int, int>(Maybe<bool>(false), Maybe<int>(1),
337 Maybe<int>())));
338 EXPECT_EQ(
339 Maybe</**/ ::std::int64_t>(2),
340 (Choice</**/ ::std::int64_t, ::std::int64_t, bool, ::std::int32_t,
341 ::std::int32_t>(Maybe<bool>(false), Maybe</**/ ::std::int32_t>(1),
342 Maybe</**/ ::std::int32_t>(2))));
343 EXPECT_EQ(Maybe</**/ ::std::int64_t>(2),
344 (Choice</**/ ::std::int64_t, ::std::int64_t, bool, ::std::int32_t,
345 ::std::uint32_t>(Maybe<bool>(false),
346 Maybe</**/ ::std::int32_t>(-1),
347 Maybe</**/ ::std::uint32_t>(2))));
348 EXPECT_EQ(Maybe</**/ ::std::int64_t>(-1),
349 (Choice</**/ ::std::int64_t, ::std::int64_t, bool, ::std::int32_t,
350 ::std::uint32_t>(Maybe<bool>(true),
351 Maybe</**/ ::std::int32_t>(-1),
352 Maybe</**/ ::std::uint32_t>(2))));
353 EXPECT_EQ(Maybe<bool>(true),
354 (Choice<bool, bool, bool, bool, bool>(
355 Maybe<bool>(false), Maybe<bool>(false), Maybe<bool>(true))));
356 }
357
TEST(Maximum,Maximum)358 TEST(Maximum, Maximum) {
359 EXPECT_EQ(Maybe<int>(100), (Maximum<int, int, int>(Maybe<int>(100))));
360 EXPECT_EQ(Maybe<int>(99),
361 (Maximum<int, int, int, int>(Maybe<int>(99), Maybe<int>(50))));
362 EXPECT_EQ(Maybe<int>(98),
363 (Maximum<int, int, int, int>(Maybe<int>(50), Maybe<int>(98))));
364 EXPECT_EQ(Maybe<int>(97),
365 (Maximum<int, int, int, int, int>(Maybe<int>(50), Maybe<int>(70),
366 Maybe<int>(97))));
367 EXPECT_EQ(Maybe<int>(), (Maximum<int, int, int, int, int>(
368 Maybe<int>(50), Maybe<int>(), Maybe<int>(97))));
369 EXPECT_EQ(Maybe<int>(-100),
370 (Maximum<int, int, int, int, int>(
371 Maybe<int>(-120), Maybe<int>(-150), Maybe<int>(-100))));
372 EXPECT_EQ(Maybe<int>(), (Maximum<int, int, int>(Maybe<int>())));
373 }
374
375 } // namespace test
376 } // namespace support
377 } // namespace emboss
378