1 // Copyright 2016 The Android Open Source Project
2 //
3 // This software is licensed under the terms of the GNU General Public
4 // License version 2, as published by the Free Software Foundation, and
5 // may be copied, distributed, and modified under those terms.
6 //
7 // This program is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 // GNU General Public License for more details.
11
12 #include "base/Optional.h"
13
14
15 #include <gtest/gtest.h>
16
17 #include <memory>
18 #include <vector>
19
20 namespace android {
21 namespace base {
22
TEST(Optional,TypeProperties)23 TEST(Optional, TypeProperties) {
24 // Making sure optional has the correct alignment and doesn't waste too much
25 // space
26
27 static_assert(sizeof(Optional<bool>) == 2, "bad Optional<bool> size");
28 static_assert(std::alignment_of<Optional<bool>>::value ==
29 std::alignment_of<bool>::value,
30 "bad Optional<bool> alignment");
31
32 static_assert(sizeof(Optional<char>) == 2, "bad Optional<char> size");
33 static_assert(std::alignment_of<Optional<char>>::value ==
34 std::alignment_of<char>::value,
35 "bad Optional<char> alignment");
36
37 static_assert(sizeof(Optional<int16_t>) == 4, "bad Optional<int16_t> size");
38 static_assert(std::alignment_of<Optional<int16_t>>::value ==
39 std::alignment_of<int16_t>::value,
40 "bad Optional<int16_t> alignment");
41
42 static_assert(sizeof(Optional<int32_t>) == 8, "bad Optional<int32_t> size");
43 static_assert(std::alignment_of<Optional<int32_t>>::value ==
44 std::alignment_of<int32_t>::value,
45 "bad Optional<int32_t> alignment");
46
47 static_assert(sizeof(Optional<int64_t>) == 16,
48 "bad Optional<int64_t> size");
49 static_assert(std::alignment_of<Optional<int64_t>>::value ==
50 std::alignment_of<int64_t>::value,
51 "bad Optional<int64_t> alignment");
52
53 struct S128 {
54 int64_t data[2];
55 };
56
57 static_assert(sizeof(Optional<S128>) == 3*sizeof(int64_t),
58 "bad Optional<S128> size");
59 static_assert(std::alignment_of<Optional<S128>>::value ==
60 std::alignment_of<S128>::value,
61 "bad Optional<S128> alignment");
62 }
63
TEST(Optional,ConstructFromValue)64 TEST(Optional, ConstructFromValue) {
65 {
66 Optional<int> o;
67 EXPECT_FALSE(o);
68 }
69 {
70 Optional<int> o = {};
71 EXPECT_FALSE(o);
72 }
73 {
74 Optional<int> o = kNullopt;
75 EXPECT_FALSE(o);
76 }
77 {
78 Optional<int> o(1);
79 EXPECT_TRUE(o);
80 EXPECT_EQ(1, *o);
81 }
82 {
83 // check the std::decay<> constructor
84 Optional<int> o = static_cast<const short&>(1);
85 EXPECT_TRUE(o);
86 EXPECT_EQ(1, *o);
87 }
88 {
89 Optional<int> o = 1;
90 EXPECT_TRUE(o);
91 EXPECT_EQ(1, *o);
92 }
93 {
94 Optional<int> o { 1 };
95 EXPECT_TRUE(o);
96 EXPECT_EQ(1, *o);
97 }
98 {
99 short val = 10;
100 Optional<int> o = val;
101 EXPECT_TRUE(o);
102 EXPECT_EQ(10, *o);
103 }
104 {
105 Optional<std::vector<int>> o(kInplace, 10);
106 EXPECT_TRUE(o);
107 EXPECT_EQ((std::vector<int>(10)), *o);
108 }
109 {
110 Optional<std::vector<int>> o(kInplace, {1,2,3,4});
111 EXPECT_TRUE(o);
112 EXPECT_EQ((std::vector<int>{1,2,3,4}), *o);
113 }
114 }
115
TEST(Optional,ConstructFromOptional)116 TEST(Optional, ConstructFromOptional) {
117 {
118 Optional<int> o = Optional<int>();
119 EXPECT_FALSE(o);
120 }
121 {
122 Optional<short> o2;
123 Optional<int> o(o2);
124 EXPECT_FALSE(o);
125 }
126 {
127 Optional<short> o2 = 42;
128 Optional<int> o(o2);
129 EXPECT_TRUE(o);
130 EXPECT_EQ(42, *o);
131 }
132 {
133 Optional<int> o(Optional<int>(1));
134 EXPECT_TRUE(o);
135 EXPECT_EQ(1, *o);
136 }
137 {
138 Optional<int> o2 = 2;
139 Optional<int> o = o2;
140 EXPECT_TRUE(o);
141 EXPECT_EQ(2, *o);
142 }
143 {
144 Optional<std::vector<int>> o2 = std::vector<int>{20, 30, 40};
145 Optional<std::vector<int>> o = o2;
146 EXPECT_TRUE(o);
147 EXPECT_EQ((std::vector<int>{20, 30, 40}), *o);
148 }
149 }
150
TEST(Optional,Assign)151 TEST(Optional, Assign) {
152 {
153 Optional<int> o;
154 o = 1;
155 EXPECT_TRUE(o);
156 EXPECT_EQ(1, *o);
157
158 o = 2;
159 EXPECT_TRUE(o);
160 EXPECT_EQ(2, *o);
161
162 o = kNullopt;
163 EXPECT_FALSE(o);
164
165 o = Optional<int>(10);
166 EXPECT_TRUE(o);
167 EXPECT_EQ(10, *o);
168
169 Optional<int> o2;
170 o = o2;
171 EXPECT_FALSE(o);
172
173 o = 2u;
174 EXPECT_TRUE(o);
175 EXPECT_EQ(2, *o);
176
177 o = Optional<short>();
178 EXPECT_FALSE(o);
179
180 o = Optional<short>(20);
181 EXPECT_TRUE(o);
182 EXPECT_EQ(20, *o);
183
184 Optional<short> o3(200);
185 o = o3;
186 EXPECT_TRUE(o);
187 EXPECT_EQ(200, *o);
188
189 o = {};
190 EXPECT_FALSE(o);
191
192 // check the std::decay<> assignment
193 o = static_cast<const short&>(1);
194 EXPECT_TRUE(o);
195 EXPECT_EQ(1, *o);
196 }
197 }
198
TEST(Optional,MakeOptional)199 TEST(Optional, MakeOptional) {
200 {
201 auto o = makeOptional(1);
202 static_assert(std::is_same<decltype(o), Optional<int>>::value,
203 "Bad type deduction in makeOptional()");
204 EXPECT_TRUE(o);
205 EXPECT_EQ(1, *o);
206 }
207 {
208 auto o = makeOptional(std::vector<char>{'1', '2'});
209 static_assert(std::is_same<decltype(o), Optional<std::vector<char>>>::value,
210 "Bad type deduction in makeOptional()");
211 EXPECT_TRUE(o);
212 EXPECT_EQ((std::vector<char>{'1', '2'}), *o);
213 }
214 {
215 // check std::decay<> in the factory function
216 auto o = makeOptional("String");
217 static_assert(std::is_same<decltype(o), Optional<const char*>>::value,
218 "Bad type deduction in makeOptional()");
219 EXPECT_TRUE(o);
220 EXPECT_STREQ("String", *o);
221 }
222 {
223 auto o = makeOptional<std::string>("String");
224 static_assert(std::is_same<decltype(o), Optional<std::string>>::value,
225 "Bad type deduction in makeOptional()");
226 EXPECT_TRUE(o);
227 EXPECT_STREQ("String", o->c_str());
228 }
229 {
230 auto o = makeOptional<std::string>(5, 'b');
231 static_assert(std::is_same<decltype(o), Optional<std::string>>::value,
232 "Bad type deduction in makeOptional()");
233 EXPECT_TRUE(o);
234 EXPECT_STREQ("bbbbb", o->c_str());
235 }
236 {
237 auto o = makeOptional<std::string>();
238 static_assert(std::is_same<decltype(o), Optional<std::string>>::value,
239 "Bad type deduction in makeOptional()");
240 EXPECT_TRUE(o);
241 EXPECT_STREQ("", o->c_str());
242 }
243 }
244
TEST(Optional,Move)245 TEST(Optional, Move) {
246 auto o = makeOptional(std::unique_ptr<int>(new int(10)));
247 {
248 decltype(o) o2 = std::move(o);
249 EXPECT_TRUE(o);
250 EXPECT_TRUE(o2);
251 EXPECT_FALSE(bool(*o));
252 EXPECT_TRUE(bool(*o2));
253 EXPECT_EQ(10, **o2);
254
255 decltype(o) o3;
256 o3 = std::move(o2);
257 EXPECT_TRUE(o2);
258 EXPECT_TRUE(o3);
259 EXPECT_FALSE(bool(*o2));
260 EXPECT_TRUE(bool(*o3));
261 EXPECT_EQ(10, **o3);
262
263 o3 = std::move(o2);
264 EXPECT_TRUE(o2);
265 EXPECT_TRUE(o3);
266 EXPECT_FALSE(bool(*o2));
267 EXPECT_FALSE(bool(*o3));
268 }
269
270 {
271 decltype(o) o1;
272 decltype(o) o2 = std::move(o1);
273 EXPECT_FALSE(o1);
274 EXPECT_FALSE(o2);
275
276 o2 = std::move(o1);
277 EXPECT_FALSE(o1);
278 EXPECT_FALSE(o2);
279
280 decltype(o) o3 {kInplace, new int(20)};
281 o3 = std::move(o1);
282 EXPECT_FALSE(o1);
283 EXPECT_FALSE(o3);
284 }
285 }
286
TEST(Optional,Value)287 TEST(Optional, Value) {
288 auto o = makeOptional(1);
289 EXPECT_EQ(1, o.value());
290 EXPECT_EQ(1, o.valueOr(2));
291
292 o = kNullopt;
293 EXPECT_EQ(2, o.valueOr(2));
294 }
295
TEST(Optional,Clear)296 TEST(Optional, Clear) {
297 auto o = makeOptional(1);
298 o.clear();
299 EXPECT_FALSE(o);
300
301 o.clear();
302 EXPECT_FALSE(o);
303 }
304
TEST(Optional,Emplace)305 TEST(Optional, Emplace) {
306 auto o = makeOptional(std::vector<int>{1,2,3,4});
307 o.emplace(3, 1);
308 EXPECT_TRUE(o);
309 EXPECT_EQ((std::vector<int>{1,1,1}), *o);
310 EXPECT_EQ(3U, o->capacity());
311
312 o.clear();
313 o.emplace({1,2});
314 EXPECT_TRUE(o);
315 EXPECT_EQ((std::vector<int>{1,2}), *o);
316 EXPECT_EQ(2U, o->capacity());
317 }
318
TEST(Optional,Reset)319 TEST(Optional, Reset) {
320 auto o = makeOptional(std::vector<int>{1,2,3,4});
321 o.reset(std::vector<int>{4,3});
322 EXPECT_TRUE(o);
323 EXPECT_EQ((std::vector<int>{4,3}), *o);
324 EXPECT_EQ(2U, o->capacity());
325
326 o.clear();
327 o.reset(std::vector<int>{1});
328 EXPECT_EQ((std::vector<int>{1}), *o);
329 EXPECT_EQ(1U, o->capacity());
330 }
331
TEST(Optional,CompareEqual)332 TEST(Optional, CompareEqual) {
333 EXPECT_TRUE(makeOptional(1) == makeOptional(1));
334 EXPECT_TRUE(makeOptional(1) == 1);
335 EXPECT_TRUE(1 == makeOptional(1));
336 EXPECT_FALSE(makeOptional(1) == makeOptional(2));
337 EXPECT_FALSE(makeOptional(2) == 1);
338 EXPECT_FALSE(2 == makeOptional(1));
339 EXPECT_TRUE(makeOptional(1) != makeOptional(2));
340 EXPECT_TRUE(makeOptional(1) != 2);
341 EXPECT_TRUE(1 != makeOptional(2));
342
343 EXPECT_FALSE(makeOptional(1) == kNullopt);
344 EXPECT_FALSE(makeOptional(1) == Optional<int>());
345 EXPECT_FALSE(kNullopt == makeOptional(1));
346 EXPECT_FALSE(Optional<int>() == makeOptional(1));
347 EXPECT_TRUE(makeOptional(1) != kNullopt);
348 EXPECT_TRUE(makeOptional(1) != Optional<int>());
349 EXPECT_TRUE(kNullopt != makeOptional(1));
350 EXPECT_TRUE(Optional<int>() != makeOptional(1));
351
352 EXPECT_TRUE(kNullopt == Optional<int>());
353 EXPECT_TRUE(kNullopt == Optional<char*>());
354 EXPECT_FALSE(kNullopt != Optional<int>());
355 EXPECT_FALSE(kNullopt != Optional<char*>());
356 EXPECT_TRUE(Optional<int>() == Optional<int>());
357 EXPECT_FALSE(Optional<int>() != Optional<int>());
358 }
359
TEST(Optional,CompareLess)360 TEST(Optional, CompareLess) {
361 EXPECT_TRUE(makeOptional(1) < makeOptional(2));
362 EXPECT_TRUE(1 < makeOptional(2));
363 EXPECT_TRUE(makeOptional(1) < 2);
364
365 EXPECT_FALSE(makeOptional(1) < makeOptional(1));
366 EXPECT_FALSE(1 < makeOptional(1));
367 EXPECT_FALSE(makeOptional(1) < 1);
368 EXPECT_FALSE(makeOptional(2) < makeOptional(1));
369 EXPECT_FALSE(2 < makeOptional(1));
370 EXPECT_FALSE(makeOptional(2) < 1);
371
372 EXPECT_TRUE(kNullopt < makeOptional(2));
373 EXPECT_TRUE(Optional<int>() < makeOptional(2));
374 EXPECT_TRUE(Optional<int>() < 2);
375 EXPECT_FALSE(makeOptional(2) < kNullopt);
376 EXPECT_FALSE(makeOptional(2) < Optional<int>());
377 EXPECT_FALSE(2 < Optional<int>());
378
379 EXPECT_FALSE(kNullopt < Optional<int>());
380 EXPECT_FALSE(Optional<int>() < kNullopt);
381 }
382
TEST(Optional,Destruction)383 TEST(Optional, Destruction) {
384 // create a reference counting class to check if we delete everything
385 // we've created
386 struct Track {
387 Track(int& val) : mVal(val) {
388 ++mVal.get();
389 }
390 Track(std::initializer_list<int*> vals) : mVal(**vals.begin()) {
391 ++mVal.get();
392 }
393 Track(const Track& other) : mVal(other.mVal) {
394 ++mVal.get();
395 }
396 Track(Track&& other) : mVal(other.mVal) {
397 ++mVal.get();
398 }
399 Track& operator=(const Track& other) {
400 --mVal.get();
401 mVal = other.mVal;
402 ++mVal.get();
403 return *this;
404 }
405 Track& operator=(Track&& other) {
406 --mVal.get();
407 mVal = other.mVal;
408 ++mVal.get();
409 return *this;
410 }
411
412 ~Track() {
413 --mVal.get();
414 }
415
416 std::reference_wrapper<int> mVal;
417 };
418
419 int counter = 0;
420 {
421 auto o = makeOptional(Track(counter));
422 EXPECT_EQ(1, counter);
423 }
424 EXPECT_EQ(0, counter);
425
426 {
427 auto o = makeOptional(Track(counter));
428 EXPECT_EQ(1, counter);
429 o.clear();
430 EXPECT_EQ(0, counter);
431 }
432 EXPECT_EQ(0, counter);
433
434 {
435 auto o = makeOptional(Track(counter));
436 EXPECT_EQ(1, counter);
437 int counter2 = 0;
438 o.emplace(counter2);
439 EXPECT_EQ(0, counter);
440 EXPECT_EQ(1, counter2);
441 o = Track(counter);
442 EXPECT_EQ(1, counter);
443 EXPECT_EQ(0, counter2);
444
445 auto o2 = o;
446 EXPECT_EQ(2, counter);
447 EXPECT_EQ(0, counter2);
448 }
449 EXPECT_EQ(0, counter);
450
451 {
452 auto o = makeOptional(Track(counter));
453 auto o2 = std::move(o);
454 EXPECT_EQ(2, counter);
455 o = o2;
456 EXPECT_EQ(2, counter);
457 }
458 EXPECT_EQ(0, counter);
459
460 int counter2 = 0;
461 {
462 Optional<Track> o;
463 o.emplace(counter);
464 EXPECT_EQ(1, counter);
465
466 o.emplace(counter2);
467 EXPECT_EQ(0, counter);
468 EXPECT_EQ(1, counter2);
469 }
470 EXPECT_EQ(0, counter);
471 EXPECT_EQ(0, counter2);
472
473 {
474 Optional<Track> o;
475 o.emplace({&counter});
476 EXPECT_EQ(1, counter);
477
478 counter2 = 0;
479 o.emplace({&counter2});
480 EXPECT_EQ(0, counter);
481 EXPECT_EQ(1, counter2);
482 }
483 EXPECT_EQ(0, counter);
484 EXPECT_EQ(0, counter2);
485 }
486
487 } // namespace base
488 } // namespace android
489