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