xref: /aosp_15_r20/external/cronet/base/types/optional_ref_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2022 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "base/types/optional_ref.h"
6 
7 #include <cstddef>
8 #include <optional>
9 #include <type_traits>
10 #include <utility>
11 
12 #include "base/test/gtest_util.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 
15 namespace base {
16 
17 namespace {
18 
19 // Construction from `std::nullptr_t` is disallowed; `std::nullopt` must be
20 // used to construct an empty `optional_ref`.
21 static_assert(!std::is_constructible_v<optional_ref<int>, std::nullptr_t>);
22 
23 // No-compile asserts for various const -> mutable conversions.
24 static_assert(
25     !std::is_constructible_v<optional_ref<int>, const std::optional<int>&>);
26 static_assert(!std::is_constructible_v<optional_ref<int>, const int*>);
27 static_assert(!std::is_constructible_v<optional_ref<int>, const int&>);
28 static_assert(!std::is_constructible_v<optional_ref<int>, int&&>);
29 static_assert(!std::is_constructible_v<optional_ref<int>, const int>);
30 static_assert(
31     !std::is_constructible_v<optional_ref<int>, optional_ref<const int>>);
32 
33 // No-compile asserts for implicit conversions.
34 static_assert(!std::is_constructible_v<optional_ref<bool>, int>);
35 static_assert(!std::is_constructible_v<optional_ref<bool>, const int&>);
36 static_assert(!std::is_constructible_v<optional_ref<bool>, int&>);
37 static_assert(!std::is_constructible_v<optional_ref<bool>, const int*>);
38 static_assert(!std::is_constructible_v<optional_ref<bool>, int*>);
39 
40 class ImplicitInt {
41  public:
42   // NOLINTNEXTLINE(google-explicit-constructor)
ImplicitInt(int)43   ImplicitInt(int) {}
44 };
45 
46 static_assert(!std::is_constructible_v<optional_ref<ImplicitInt>, int>);
47 static_assert(!std::is_constructible_v<optional_ref<ImplicitInt>, const int&>);
48 static_assert(!std::is_constructible_v<optional_ref<ImplicitInt>, int&>);
49 static_assert(!std::is_constructible_v<optional_ref<ImplicitInt>, const int*>);
50 static_assert(!std::is_constructible_v<optional_ref<ImplicitInt>, int*>);
51 
52 class TestClass {
53  public:
ConstMethod() const54   void ConstMethod() const {}
MutableMethod()55   void MutableMethod() {}
56 };
57 
TEST(OptionalRefTest,FromNullopt)58 TEST(OptionalRefTest, FromNullopt) {
59   [](optional_ref<const int> r) { EXPECT_FALSE(r.has_value()); }(std::nullopt);
60 
61   [](optional_ref<int> r) { EXPECT_FALSE(r.has_value()); }(std::nullopt);
62 }
63 
TEST(OptionalRefTest,FromConstEmptyOptional)64 TEST(OptionalRefTest, FromConstEmptyOptional) {
65   const std::optional<int> optional_int;
66 
67   [](optional_ref<const int> r) { EXPECT_FALSE(r.has_value()); }(optional_int);
68 
69   // Mutable case covered by static_assert test above.
70 }
71 
TEST(OptionalRefTest,FromMutableEmptyOptional)72 TEST(OptionalRefTest, FromMutableEmptyOptional) {
73   std::optional<int> optional_int;
74 
75   [](optional_ref<const int> r) { EXPECT_FALSE(r.has_value()); }(optional_int);
76 
77   [](optional_ref<int> r) { EXPECT_FALSE(r.has_value()); }(optional_int);
78 }
79 
TEST(OptionalRefTest,FromConstOptional)80 TEST(OptionalRefTest, FromConstOptional) {
81   const std::optional<int> optional_int(6);
82 
83   [](optional_ref<const int> r) {
84     EXPECT_TRUE(r.has_value());
85     EXPECT_EQ(6, r.value());
86   }(optional_int);
87 
88   // Mutable case covered by static_assert test above.
89 }
90 
TEST(OptionalRefTest,FromMutableOptional)91 TEST(OptionalRefTest, FromMutableOptional) {
92   std::optional<int> optional_int(6);
93 
94   [](optional_ref<const int> r) {
95     EXPECT_TRUE(r.has_value());
96     EXPECT_EQ(6, r.value());
97   }(optional_int);
98 
99   [](optional_ref<int> r) {
100     EXPECT_TRUE(r.has_value());
101     EXPECT_EQ(6, r.value());
102   }(optional_int);
103 }
104 
105 // The From*NullPointer tests intentionally avoid passing nullptr directly,
106 // which is explicitly disallowed to reduce ambiguity when constructing an empty
107 // `optional_ref`.
TEST(OptionalRefTest,FromConstNullPointer)108 TEST(OptionalRefTest, FromConstNullPointer) {
109   const int* ptr = nullptr;
110 
111   [](optional_ref<const int> r) { EXPECT_FALSE(r.has_value()); }(ptr);
112 
113   // Mutable case covered by static_assert test above.
114 }
115 
TEST(OptionalRefTest,FromMutableNullPointer)116 TEST(OptionalRefTest, FromMutableNullPointer) {
117   int* ptr = nullptr;
118 
119   [](optional_ref<const int> r) { EXPECT_FALSE(r.has_value()); }(ptr);
120 
121   [](optional_ref<int> r) { EXPECT_FALSE(r.has_value()); }(ptr);
122 }
123 
TEST(OptionalRefTest,FromConstPointer)124 TEST(OptionalRefTest, FromConstPointer) {
125   int value = 6;
126   const int* ptr = &value;
127 
128   [](optional_ref<const int> r) {
129     EXPECT_TRUE(r.has_value());
130     EXPECT_EQ(6, r.value());
131   }(ptr);
132 
133   // Mutable case covered by static_assert test above.
134 }
135 
TEST(OptionalRefTest,FromPointer)136 TEST(OptionalRefTest, FromPointer) {
137   int value = 6;
138   int* ptr = &value;
139 
140   [](optional_ref<const int> r) {
141     EXPECT_TRUE(r.has_value());
142     EXPECT_EQ(6, r.value());
143   }(ptr);
144 
145   [](optional_ref<int> r) {
146     EXPECT_TRUE(r.has_value());
147     EXPECT_EQ(6, r.value());
148   }(ptr);
149 }
150 
TEST(OptionalRefTest,FromConstRef)151 TEST(OptionalRefTest, FromConstRef) {
152   int value = 6;
153   const int& ref = value;
154 
155   [](optional_ref<const int> r) {
156     EXPECT_TRUE(r.has_value());
157     EXPECT_EQ(6, r.value());
158   }(ref);
159 
160   // Mutable case covered by static_assert test above.
161 }
162 
TEST(OptionalRefTest,FromMutableRef)163 TEST(OptionalRefTest, FromMutableRef) {
164   int value = 6;
165   int& ref = value;
166 
167   [](optional_ref<const int> r) {
168     EXPECT_TRUE(r.has_value());
169     EXPECT_EQ(6, r.value());
170   }(ref);
171 
172   [](optional_ref<int> r) {
173     EXPECT_TRUE(r.has_value());
174     EXPECT_EQ(6, r.value());
175   }(ref);
176 }
177 
TEST(OptionalRefTest,FromConstValue)178 TEST(OptionalRefTest, FromConstValue) {
179   const int value = 6;
180 
181   [](optional_ref<const int> r) {
182     EXPECT_TRUE(r.has_value());
183     EXPECT_EQ(6, r.value());
184   }(value);
185 
186   [](optional_ref<const int> r) {
187     EXPECT_TRUE(r.has_value());
188     EXPECT_EQ(6, r.value());
189   }(6);
190 
191   // Mutable case covered by static_assert test above.
192 }
193 
TEST(OptionalRefTest,FromMutableValue)194 TEST(OptionalRefTest, FromMutableValue) {
195   int value = 6;
196 
197   [](optional_ref<const int> r) {
198     EXPECT_TRUE(r.has_value());
199     EXPECT_EQ(6, r.value());
200   }(value);
201 
202   [](optional_ref<int> r) {
203     EXPECT_TRUE(r.has_value());
204     EXPECT_EQ(6, r.value());
205   }(value);
206 }
207 
TEST(OptionalRefTest,FromMutableEmptyOptionalRefTest)208 TEST(OptionalRefTest, FromMutableEmptyOptionalRefTest) {
209   {
210     optional_ref<int> r1;
211     [](optional_ref<const int> r2) { EXPECT_FALSE(r2.has_value()); }(r1);
212   }
213 
214   {
215     optional_ref<int> r1(std::nullopt);
216     [](optional_ref<int> r2) { EXPECT_FALSE(r2.has_value()); }(r1);
217   }
218 }
219 
TEST(OptionalRefTest,FromMutableOptionalRefTest)220 TEST(OptionalRefTest, FromMutableOptionalRefTest) {
221   int value = 6;
222   optional_ref<int> r1(value);
223 
224   [](optional_ref<const int> r2) {
225     EXPECT_TRUE(r2.has_value());
226     EXPECT_EQ(6, r2.value());
227   }(r1);
228 
229   [](optional_ref<int> r2) {
230     EXPECT_TRUE(r2.has_value());
231     EXPECT_EQ(6, r2.value());
232   }(r1);
233 }
234 
TEST(OptionalRefTest,FromCopyConstructorConst)235 TEST(OptionalRefTest, FromCopyConstructorConst) {
236   [](optional_ref<const int> r) {
237     EXPECT_FALSE(r.has_value());
238   }(optional_ref<const int>());
239 
240   int value = 6;
241   optional_ref<const int> r1(value);
242   [](optional_ref<const int> r2) {
243     EXPECT_TRUE(r2.has_value());
244     EXPECT_EQ(6, r2.value());
245   }(r1);
246 
247   // Mutable case covered by static_assert test above.
248 }
249 
TEST(OptionalRefTest,FromCopyConstructorMutable)250 TEST(OptionalRefTest, FromCopyConstructorMutable) {
251   [](optional_ref<int> r) { EXPECT_FALSE(r.has_value()); }(optional_ref<int>());
252 
253   int value = 6;
254   optional_ref<int> r1(value);
255   [](optional_ref<int> r2) {
256     EXPECT_TRUE(r2.has_value());
257     EXPECT_EQ(6, r2.value());
258   }(r1);
259 }
260 
TEST(OptionalRefTest,Arrow)261 TEST(OptionalRefTest, Arrow) {
262   int uninitialized_value;
263 
264   {
265     const optional_ref<const int> r(uninitialized_value);
266     static_assert(std::is_same_v<decltype(r.operator->()), const int*>);
267     EXPECT_EQ(&uninitialized_value, r.operator->());
268   }
269 
270   {
271     optional_ref<const int> r(uninitialized_value);
272     static_assert(std::is_same_v<decltype(r.operator->()), const int*>);
273     EXPECT_EQ(&uninitialized_value, r.operator->());
274   }
275 
276   {
277     const optional_ref<int> r(uninitialized_value);
278     static_assert(std::is_same_v<decltype(r.operator->()), int*>);
279     EXPECT_EQ(&uninitialized_value, r.operator->());
280   }
281 
282   {
283     optional_ref<int> r(uninitialized_value);
284     static_assert(std::is_same_v<decltype(r.operator->()), int*>);
285     EXPECT_EQ(&uninitialized_value, r.operator->());
286   }
287 }
288 
TEST(OptionalRefTest,Star)289 TEST(OptionalRefTest, Star) {
290   int uninitialized_value;
291 
292   {
293     const optional_ref<const int> r(uninitialized_value);
294     static_assert(std::is_same_v<decltype(r.operator*()), const int&>);
295     EXPECT_EQ(&uninitialized_value, &r.operator*());
296   }
297 
298   {
299     optional_ref<const int> r(uninitialized_value);
300     static_assert(std::is_same_v<decltype(r.operator*()), const int&>);
301     EXPECT_EQ(&uninitialized_value, &r.operator*());
302   }
303 
304   {
305     const optional_ref<int> r(uninitialized_value);
306     static_assert(std::is_same_v<decltype(r.operator*()), int&>);
307     EXPECT_EQ(&uninitialized_value, &r.operator*());
308   }
309 
310   {
311     optional_ref<int> r(uninitialized_value);
312     static_assert(std::is_same_v<decltype(r.operator*()), int&>);
313     EXPECT_EQ(&uninitialized_value, &r.operator*());
314   }
315 }
316 
TEST(OptionalRefTest,Value)317 TEST(OptionalRefTest, Value) {
318   // has_value() and value() are generally covered by the construction tests.
319   // Make sure value() doesn't somehow break const-ness here.
320   {
321     const optional_ref<const int> r;
322     static_assert(std::is_same_v<decltype(r.value()), const int&>);
323   }
324 
325   {
326     optional_ref<const int> r;
327     static_assert(std::is_same_v<decltype(r.value()), const int&>);
328   }
329 
330   {
331     const optional_ref<int> r;
332     static_assert(std::is_same_v<decltype(r.value()), int&>);
333   }
334 
335   {
336     optional_ref<int> r;
337     static_assert(std::is_same_v<decltype(r.value()), int&>);
338   }
339 }
340 
TEST(OptionalRefTest,AsPtr)341 TEST(OptionalRefTest, AsPtr) {
342   optional_ref<int> r1;
343   EXPECT_EQ(nullptr, r1.as_ptr());
344 
345   int uninitialized_value;
346   {
347     const optional_ref<const int> r(uninitialized_value);
348     static_assert(std::is_same_v<decltype(r.as_ptr()), const int*>);
349     EXPECT_EQ(&uninitialized_value, r.as_ptr());
350   }
351 
352   {
353     optional_ref<const int> r(uninitialized_value);
354     static_assert(std::is_same_v<decltype(r.as_ptr()), const int*>);
355     EXPECT_EQ(&uninitialized_value, r.as_ptr());
356   }
357 
358   {
359     const optional_ref<int> r(uninitialized_value);
360     static_assert(std::is_same_v<decltype(r.as_ptr()), int*>);
361     EXPECT_EQ(&uninitialized_value, r.as_ptr());
362   }
363 
364   {
365     optional_ref<int> r(uninitialized_value);
366     static_assert(std::is_same_v<decltype(r.as_ptr()), int*>);
367     EXPECT_EQ(&uninitialized_value, r.as_ptr());
368   }
369 }
370 
TEST(OptionalRefTest,CopyAsOptional)371 TEST(OptionalRefTest, CopyAsOptional) {
372   optional_ref<int> r1;
373   std::optional<int> o1 = r1.CopyAsOptional();
374   EXPECT_EQ(std::nullopt, o1);
375 
376   int value = 6;
377   optional_ref<int> r2(value);
378   std::optional<int> o2 = r2.CopyAsOptional();
379   EXPECT_EQ(6, o2);
380 }
381 
TEST(OptionalRefTest,EqualityComparisonWithNullOpt)382 TEST(OptionalRefTest, EqualityComparisonWithNullOpt) {
383   {
384     optional_ref<int> r;
385     EXPECT_EQ(r, std::nullopt);
386     EXPECT_EQ(std::nullopt, r);
387   }
388 
389   {
390     int value = 5;
391     optional_ref<int> r(value);
392     EXPECT_NE(r, std::nullopt);
393     EXPECT_NE(std::nullopt, r);
394   }
395 }
396 
TEST(OptionalRefDeathTest,ArrowOnEmpty)397 TEST(OptionalRefDeathTest, ArrowOnEmpty) {
398   [](optional_ref<const TestClass> r) {
399     EXPECT_CHECK_DEATH(r->ConstMethod());
400   }(std::nullopt);
401 
402   [](optional_ref<TestClass> r) {
403     EXPECT_CHECK_DEATH(r->ConstMethod());
404     EXPECT_CHECK_DEATH(r->MutableMethod());
405   }(std::nullopt);
406 }
407 
TEST(OptionalRefDeathTest,StarOnEmpty)408 TEST(OptionalRefDeathTest, StarOnEmpty) {
409   [](optional_ref<const TestClass> r) {
410     EXPECT_CHECK_DEATH((*r).ConstMethod());
411   }(std::nullopt);
412 
413   [](optional_ref<TestClass> r) {
414     EXPECT_CHECK_DEATH((*r).ConstMethod());
415     EXPECT_CHECK_DEATH((*r).MutableMethod());
416   }(std::nullopt);
417 }
418 
TEST(OptionalRefDeathTest,ValueOnEmpty)419 TEST(OptionalRefDeathTest, ValueOnEmpty) {
420   [](optional_ref<const TestClass> r) {
421     EXPECT_CHECK_DEATH(r.value());
422   }(std::nullopt);
423 
424   [](optional_ref<TestClass> r) {
425     EXPECT_CHECK_DEATH(r.value());
426   }(std::nullopt);
427 }
428 
TEST(OptionalRefTest,ClassTemplateArgumentDeduction)429 TEST(OptionalRefTest, ClassTemplateArgumentDeduction) {
430   static_assert(
431       std::is_same_v<decltype(optional_ref{int()}), optional_ref<const int>>);
432 
433   {
434     const int i = 0;
435     static_assert(
436         std::is_same_v<decltype(optional_ref(i)), optional_ref<const int>>);
437   }
438 
439   {
440     int i = 0;
441     static_assert(std::is_same_v<decltype(optional_ref(i)), optional_ref<int>>);
442   }
443 
444   static_assert(std::is_same_v<decltype(optional_ref(std::optional<int>())),
445                                optional_ref<const int>>);
446 
447   {
448     const std::optional<int> o;
449     static_assert(
450         std::is_same_v<decltype(optional_ref(o)), optional_ref<const int>>);
451   }
452 
453   {
454     std::optional<int> o;
455     static_assert(std::is_same_v<decltype(optional_ref(o)), optional_ref<int>>);
456   }
457 
458   {
459     const int* p = nullptr;
460     static_assert(
461         std::is_same_v<decltype(optional_ref(p)), optional_ref<const int>>);
462   }
463 
464   {
465     int* p = nullptr;
466     static_assert(std::is_same_v<decltype(optional_ref(p)), optional_ref<int>>);
467   }
468 }
469 
470 }  // namespace
471 
472 }  // namespace base
473