1 /*
2  * Copyright (c) Facebook, Inc. and its affiliates.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <thrift/conformance/cpp2/AnyRef.h>
18 
19 #include <folly/portability/GTest.h>
20 
21 namespace apache::thrift::conformance {
22 namespace {
23 
TEST(AnyRefTest,DocExample1)24 TEST(AnyRefTest, DocExample1) {
25   std::any a;
26   any_ref ra = a;
27   // ra can now be assigned any value
28   ra.assign_value(1); // a is now an int.
29   ra.assign_value(1.5); // a is now a double.
30 
31   int i;
32   any_ref ri = i;
33   ri.assign_value(1); // i is now 1;
34   EXPECT_THROW(
35       ri.assign_value(1.5f),
36       std::bad_any_cast); // Thows a bad_any_cast exception
37                           // because i is not a double.
38 }
39 
TEST(AnyRefTest,DocExample2)40 TEST(AnyRefTest, DocExample2) {
41   auto foo = [](any_ref in) {
42     if (const auto* i = any_cast<const int>(&in)) {
43       return 1;
44     } else if (const auto* f = any_cast<const float>(&in)) {
45       return 2;
46     }
47     return 3;
48   };
49 
50   EXPECT_EQ(foo(1), 1); // Captured as int&&.
51   const float f = 0.5f;
52   EXPECT_EQ(foo(f), 2); // Captured as const float&.
53   EXPECT_EQ(foo(1.5), 3);
54 }
55 
TEST(AnyRefTest,DocExample3)56 TEST(AnyRefTest, DocExample3) {
57   auto foo2 = [](any_ref out) { // Previously was void foo(int& out).
58     out.assign_value(1);
59   };
60   int i;
61   std::any a;
62   double d;
63   foo2(i); // i is now 1.
64   EXPECT_EQ(i, 1);
65   foo2(a); // a now stores the integer 1.
66   EXPECT_EQ(std::any_cast<int>(a), 1);
67   EXPECT_THROW(foo2(d), std::bad_any_cast); // throws std::bad_any_cast.
68 }
69 
TEST(AnyRefTest,DocExample4)70 TEST(AnyRefTest, DocExample4) {
71   std::any foo;
72   any_ref fooRef = foo;
73   EXPECT_TRUE(fooRef.has_reference()); // Is set to an empty std::any.
74   // The empty std::any advertises the any type.
75   EXPECT_EQ(fooRef.type(), typeid(std::any));
76 
77   // The std::any value can be set through the any_ref.
78   fooRef.assign_value(1);
79   // Now it advertises the int type.
80   EXPECT_EQ(fooRef.type(), typeid(int));
81   // Which can be accessed directly through the any_ref.
82   fooRef.assign_value(2);
83   // The original value shows the change.
84   EXPECT_EQ(std::any_cast<int>(foo), 2);
85 
86   // The std::any is still accessible.
87   fooRef.assign_value(2.0);
88   EXPECT_EQ(fooRef.type(), typeid(double));
89 }
90 
TEST(AnyRefTest,DocExample5)91 TEST(AnyRefTest, DocExample5) {
92   any_ref ref;
93   int i = 0;
94   ref = {i};
95   ref.assign_value(1); // i now equals 1
96   EXPECT_EQ(i, 1);
97   double d = 0;
98   ref = {d};
99   ref.assign_value(1.0); // d now equals 1.0.
100   EXPECT_EQ(d, 1.0);
101   ref = {}; // ref doesn't refer to anything.
102   EXPECT_FALSE(ref.has_reference());
103 }
104 
TEST(AnyRefTest,Empty)105 TEST(AnyRefTest, Empty) {
106   any_ref empty;
107   EXPECT_FALSE(empty.has_reference());
108   EXPECT_FALSE(empty.has_value());
109   EXPECT_FALSE(empty);
110   EXPECT_EQ(empty.type(), typeid(void));
111   EXPECT_FALSE(empty.is_const());
112   EXPECT_FALSE(empty.is_rvalue_reference());
113 
114   EXPECT_THROW(any_cast<const int&>(empty), std::bad_any_cast);
115   EXPECT_THROW(any_cast_exact<const int&>(empty), std::bad_any_cast);
116   EXPECT_THROW(any_cast<void*>(empty), std::bad_any_cast);
117 
118   // Uncomment to get epxected compiler error.
119   // EXPECT_EQ(ref, std::nullopt);
120 }
121 
TEST(AnyRefTest,Const)122 TEST(AnyRefTest, Const) {
123   constexpr int i = 1;
124   any_ref ref = i;
125   EXPECT_TRUE(ref.has_reference());
126   EXPECT_TRUE(ref.has_value());
127   EXPECT_TRUE(ref);
128   EXPECT_EQ(ref.type(), typeid(int));
129   EXPECT_TRUE(ref.is_const());
130   EXPECT_FALSE(ref.is_rvalue_reference());
131 
132   EXPECT_EQ(any_cast<const int>(ref), i);
133   EXPECT_EQ(any_cast<int>(ref), i);
134   EXPECT_THROW(any_cast<double>(ref), std::bad_any_cast);
135 
136   EXPECT_EQ(&any_cast<const int&>(ref), &i);
137   EXPECT_EQ(&any_cast_exact<const int&>(ref), &i);
138 
139   EXPECT_THROW(any_cast<const int&&>(ref), std::bad_any_cast);
140   EXPECT_THROW(any_cast_exact<const int&&>(ref), std::bad_any_cast);
141 
142   EXPECT_THROW(any_cast<int&>(ref), std::bad_any_cast);
143   EXPECT_THROW(any_cast_exact<int&>(ref), std::bad_any_cast);
144 
145   EXPECT_THROW(any_cast<const double&>(ref), std::bad_any_cast);
146   EXPECT_THROW(any_cast_exact<const double&>(ref), std::bad_any_cast);
147 
148   ref = {std::move(i)};
149   EXPECT_TRUE(ref.has_reference());
150   EXPECT_TRUE(ref.has_value());
151   EXPECT_TRUE(ref);
152   EXPECT_EQ(ref.type(), typeid(int));
153   EXPECT_TRUE(ref.is_const());
154   EXPECT_TRUE(ref.is_rvalue_reference());
155 
156   EXPECT_EQ(any_cast<const int>(ref), i);
157   EXPECT_EQ(any_cast<int>(ref), i);
158   EXPECT_THROW(any_cast<double>(ref), std::bad_any_cast);
159 
160   EXPECT_EQ(&any_cast<const int&>(ref), &i);
161   EXPECT_THROW(&any_cast_exact<const int&>(ref), std::bad_any_cast);
162 
163   EXPECT_EQ(any_cast<const int&&>(ref), i);
164   EXPECT_EQ(any_cast_exact<const int&&>(ref), i);
165 
166   EXPECT_THROW(any_cast<int&>(ref), std::bad_any_cast);
167   EXPECT_THROW(any_cast_exact<int&>(ref), std::bad_any_cast);
168 
169   EXPECT_THROW(any_cast<const double&>(ref), std::bad_any_cast);
170   EXPECT_THROW(any_cast_exact<const double&>(ref), std::bad_any_cast);
171 }
172 
TEST(AnyRefTest,NonConst)173 TEST(AnyRefTest, NonConst) {
174   any_ref ref;
175   int i = 2;
176   ref = {i};
177   EXPECT_TRUE(ref.has_reference());
178   EXPECT_TRUE(ref.has_value());
179   EXPECT_TRUE(ref);
180   EXPECT_FALSE(ref.is_const());
181   EXPECT_FALSE(ref.is_rvalue_reference());
182 
183   EXPECT_EQ(&any_cast<const int&>(ref), &i);
184   EXPECT_THROW(any_cast_exact<const int&>(ref), std::bad_any_cast);
185 
186   EXPECT_EQ(&any_cast<int&>(ref), &i);
187   EXPECT_EQ(&any_cast_exact<int&>(ref), &i);
188 
189   any_cast<int&>(ref) = 3;
190   EXPECT_EQ(i, 3);
191   any_cast_exact<int&>(ref) = 4;
192   EXPECT_EQ(i, 4);
193 
194   ref = {std::move(i)};
195   EXPECT_TRUE(ref.has_reference());
196   EXPECT_TRUE(ref.has_value());
197   EXPECT_TRUE(ref);
198   EXPECT_FALSE(ref.is_const());
199   EXPECT_TRUE(ref.is_rvalue_reference());
200 
201   EXPECT_EQ(any_cast<const int>(ref), i);
202   EXPECT_EQ(any_cast<int>(ref), i);
203   EXPECT_THROW(any_cast<double>(ref), std::bad_any_cast);
204 
205   EXPECT_EQ(&any_cast<int&>(ref), &i);
206   EXPECT_THROW(any_cast_exact<int&>(ref), std::bad_any_cast);
207 
208   EXPECT_EQ(any_cast<int&&>(ref), i);
209   EXPECT_EQ(any_cast_exact<int&&>(ref), i);
210 
211   EXPECT_EQ(&any_cast<const int&>(ref), &i);
212   EXPECT_THROW(any_cast_exact<const int&>(ref), std::bad_any_cast);
213 
214   EXPECT_EQ(any_cast<const int&&>(ref), i);
215   EXPECT_THROW(any_cast_exact<const int&&>(ref), std::bad_any_cast);
216 
217   EXPECT_THROW(any_cast<double&&>(ref), std::bad_any_cast);
218   EXPECT_THROW(any_cast_exact<double&&>(ref), std::bad_any_cast);
219 
220   EXPECT_THROW(any_cast<double&>(ref), std::bad_any_cast);
221   EXPECT_THROW(any_cast_exact<double&>(ref), std::bad_any_cast);
222 
223   const float f = 1.5f;
224   ref = {f};
225   EXPECT_TRUE(ref.is_const());
226   EXPECT_THROW(any_cast<double>(ref), std::bad_any_cast);
227   EXPECT_EQ(any_cast<float>(ref), 1.5f);
228   EXPECT_EQ(any_cast_exact<const float&>(ref), 1.5f);
229 }
230 
TEST(AnyRefTest,NullOpt)231 TEST(AnyRefTest, NullOpt) {
232   // Should not beable to create an any reference to nullopt.
233   // Uncomment to produce expected compiler error.
234   // any_ref empty(std::nullopt);
235 }
236 
TEST(AnyRefTest,Volatile)237 TEST(AnyRefTest, Volatile) {
238   // Uncomment to get expected compile-time error.
239   // volatile int i;
240   // any_ref ref = i;
241 }
242 
TEST(AnyRefTest,MoveOnly)243 TEST(AnyRefTest, MoveOnly) {
244   auto i = std::make_unique<int>(2);
245   any_ref ref = i;
246   EXPECT_TRUE(ref.has_reference());
247   EXPECT_TRUE(ref.has_value());
248   EXPECT_TRUE(ref);
249   EXPECT_FALSE(ref.is_const());
250   EXPECT_FALSE(ref.is_rvalue_reference());
251 
252   EXPECT_EQ(&any_cast<std::unique_ptr<int>&>(ref), &i);
253   EXPECT_EQ(&any_cast_exact<std::unique_ptr<int>&>(ref), &i);
254 
255   EXPECT_THROW(any_cast<std::unique_ptr<int>&&>(ref), std::bad_any_cast);
256   EXPECT_THROW(any_cast_exact<std::unique_ptr<int>&&>(ref), std::bad_any_cast);
257 
258   // Uncomment to get expected compile-time error.
259   // any_cast<std::unique_ptr<int>>(ref);
260 
261   ref = {std::move(i)};
262   EXPECT_NE(i, nullptr);
263   EXPECT_FALSE(ref.is_const());
264   EXPECT_TRUE(ref.is_rvalue_reference());
265 
266   EXPECT_EQ(&any_cast<std::unique_ptr<int>&>(ref), &i);
267   EXPECT_THROW(any_cast_exact<std::unique_ptr<int>&>(ref), std::bad_any_cast);
268 
269   EXPECT_EQ(any_cast<std::unique_ptr<int>&&>(ref).get(), i.get());
270   EXPECT_EQ(any_cast_exact<std::unique_ptr<int>&&>(ref).get(), i.get());
271 }
272 
TEST(AnyRefTest,ImplicitCapture)273 TEST(AnyRefTest, ImplicitCapture) {
274   auto func = [](any_ref ref) -> int& { return any_cast<int&>(ref); };
275 
276   EXPECT_THROW(func({}), std::bad_any_cast);
277   EXPECT_THROW(func({1.0}), std::bad_any_cast);
278   EXPECT_EQ(func(1), 1);
279   int i = 1;
280   EXPECT_EQ(&func(i), &i);
281   func(i) = 2;
282   EXPECT_EQ(i, 2);
283   func(std::move(i)) = 3;
284   EXPECT_EQ(i, 3);
285   any_ref ref = i;
286   EXPECT_EQ(&func(ref), &i);
287 }
288 
TEST(AnyRefTest,Pointer)289 TEST(AnyRefTest, Pointer) {
290   int i = 2;
291   int* pi = &i;
292   any_ref ref = pi;
293 
294   EXPECT_TRUE(ref.has_reference());
295   EXPECT_TRUE(ref.has_value());
296   EXPECT_TRUE(ref);
297   EXPECT_EQ(ref.type(), typeid(int*));
298   EXPECT_NE(ref.type(), typeid(int));
299   EXPECT_THROW(any_cast<const int&>(ref), std::bad_any_cast);
300   EXPECT_THROW(any_cast_exact<const int&>(ref), std::bad_any_cast);
301   EXPECT_THROW(any_cast<int>(ref), std::bad_any_cast);
302   EXPECT_EQ(any_cast<int*>(ref), &i);
303   EXPECT_EQ(&any_cast<int*&>(ref), &pi);
304   EXPECT_EQ(&any_cast_exact<int*&>(ref), &pi);
305 
306   // Uncomment to get epxected compiler error.
307   // EXPECT_NE(ref, nullptr);
308 }
309 
TEST(AnyRefTest,AnyTransparency_Empty)310 TEST(AnyRefTest, AnyTransparency_Empty) {
311   std::any a;
312   any_ref ref = a;
313   EXPECT_TRUE(ref.has_reference());
314   EXPECT_FALSE(ref.has_value());
315   EXPECT_FALSE(ref);
316   EXPECT_EQ(ref.type(), typeid(std::any));
317   EXPECT_FALSE(ref.is_const());
318   EXPECT_FALSE(ref.is_rvalue_reference());
319 
320   EXPECT_EQ(&any_cast<std::any&>(ref), &a);
321   EXPECT_THROW(any_cast<int>(ref), std::bad_any_cast);
322   EXPECT_THROW(any_cast<double>(ref), std::bad_any_cast);
323 
324   EXPECT_THROW(any_cast<int&>(ref), std::bad_any_cast);
325   EXPECT_THROW(any_cast_exact<int&>(ref), std::bad_any_cast);
326 
327   EXPECT_FALSE(any_cast<std::any>(ref).has_value());
328 
329   EXPECT_FALSE(any_cast<std::any&>(ref).has_value());
330   EXPECT_FALSE(any_cast_exact<std::any&>(ref).has_value());
331 
332   EXPECT_FALSE(any_cast<const std::any&>(ref).has_value());
333   EXPECT_THROW(any_cast_exact<const std::any&>(ref), std::bad_any_cast);
334 
335   // Can be assigned via the any_ref
336   any_cast<std::any&>(ref) = 1;
337   EXPECT_EQ(ref.type(), typeid(int));
338   EXPECT_FALSE(ref.is_const());
339   EXPECT_FALSE(ref.is_rvalue_reference());
340   EXPECT_EQ(std::any_cast<int&>(a), 1);
341 }
342 
TEST(AnyRefTest,AnyTransparency_NonConst)343 TEST(AnyRefTest, AnyTransparency_NonConst) {
344   int i = 2;
345   std::any a = i;
346   any_ref ref = a;
347   EXPECT_TRUE(ref.has_reference());
348   EXPECT_TRUE(ref.has_value());
349   EXPECT_TRUE(ref);
350   EXPECT_EQ(ref.type(), typeid(int));
351   EXPECT_FALSE(ref.is_const());
352   EXPECT_FALSE(ref.is_rvalue_reference());
353 
354   EXPECT_EQ(any_cast<int>(ref), 2);
355 
356   EXPECT_EQ(&any_cast<std::any&>(ref), &a);
357   EXPECT_EQ(&any_cast_exact<std::any&>(ref), &a);
358 
359   EXPECT_EQ(&any_cast<const std::any&>(ref), &a);
360   EXPECT_THROW(any_cast_exact<const std::any&>(ref), std::bad_any_cast);
361 
362   EXPECT_THROW(any_cast<std::any&&>(ref), std::bad_any_cast);
363   EXPECT_THROW(any_cast_exact<std::any&&>(ref), std::bad_any_cast);
364 
365   EXPECT_EQ(&any_cast<int&>(ref), &std::any_cast<int&>(a));
366   EXPECT_EQ(&any_cast_exact<int&>(ref), &std::any_cast<int&>(a));
367 
368   EXPECT_EQ(&any_cast<const int&>(ref), &std::any_cast<const int&>(a));
369   EXPECT_THROW(any_cast_exact<const int&>(ref), std::bad_any_cast);
370 
371   EXPECT_THROW(any_cast<int&&>(ref), std::bad_any_cast);
372   EXPECT_THROW(any_cast_exact<int&&>(ref), std::bad_any_cast);
373 
374   EXPECT_NE(&any_cast<int&>(ref), &i);
375   EXPECT_NE(&any_cast_exact<int&>(ref), &i);
376 
377   EXPECT_THROW(any_cast<double>(ref), std::bad_any_cast);
378   EXPECT_THROW(any_cast_exact<double&>(ref), std::bad_any_cast);
379 
380   any_cast<int&>(ref) = 3;
381   EXPECT_EQ(i, 2);
382   EXPECT_EQ(any_cast<int&>(a), 3);
383 }
384 
TEST(AnyRefTest,AnyTransparency_Const)385 TEST(AnyRefTest, AnyTransparency_Const) {
386   int i = 2;
387   std::any a = i;
388   const std::any& ca = a;
389   any_ref ref = ca;
390   EXPECT_TRUE(ref.has_reference());
391   EXPECT_TRUE(ref.has_value());
392   EXPECT_TRUE(ref);
393   EXPECT_EQ(ref.type(), typeid(int));
394   EXPECT_TRUE(ref.is_const());
395   EXPECT_FALSE(ref.is_rvalue_reference());
396 
397   EXPECT_EQ(any_cast<int>(ref), 2);
398 
399   EXPECT_THROW(any_cast<std::any&>(ref), std::bad_any_cast);
400   EXPECT_THROW(any_cast_exact<std::any&>(ref), std::bad_any_cast);
401 
402   EXPECT_EQ(&any_cast<const std::any&>(ref), &a);
403   EXPECT_EQ(&any_cast_exact<const std::any&>(ref), &a);
404 
405   EXPECT_THROW(any_cast<std::any&&>(ref), std::bad_any_cast);
406   EXPECT_THROW(any_cast_exact<std::any&&>(ref), std::bad_any_cast);
407 
408   EXPECT_THROW(any_cast<int&>(ref), std::bad_any_cast);
409   EXPECT_THROW(any_cast_exact<int&>(ref), std::bad_any_cast);
410 
411   EXPECT_EQ(&any_cast<const int&>(ref), &std::any_cast<const int&>(a));
412   EXPECT_EQ(&any_cast_exact<const int&>(ref), &std::any_cast<const int&>(a));
413 
414   EXPECT_THROW(any_cast<const int&&>(ref), std::bad_any_cast);
415   EXPECT_THROW(any_cast_exact<const int&&>(ref), std::bad_any_cast);
416 
417   EXPECT_NE(&any_cast<const int&>(ref), &i);
418   EXPECT_NE(&any_cast_exact<const int&>(ref), &i);
419 
420   EXPECT_THROW(any_cast<double>(ref), std::bad_any_cast);
421   EXPECT_THROW(any_cast_exact<const double&>(ref), std::bad_any_cast);
422 }
423 
424 } // namespace
425 } // namespace apache::thrift::conformance
426 
427 namespace {
428 
TEST(AnyRefTest,ADL)429 TEST(AnyRefTest, ADL) {
430 // Requires c++20 to work.
431 #if __cplusplus >= 202002L
432   std::any a = 1;
433   apache::thrift::conformance::any_ref ra = a;
434   EXPECT_EQ(any_cast<int>(a), 1);
435   EXPECT_EQ(any_cast<int>(ra), 1);
436 #endif
437 }
438 
TEST(AnyRefTest,ADL_using)439 TEST(AnyRefTest, ADL_using) {
440   std::any a = 1;
441   apache::thrift::conformance::any_ref ra = a;
442   using apache::thrift::conformance::any_cast;
443   using std::any_cast;
444   EXPECT_EQ(any_cast<int>(a), 1);
445   EXPECT_EQ(any_cast<int>(ra), 1);
446 }
447 
TEST(AnyRefTest,ADL_using_std)448 TEST(AnyRefTest, ADL_using_std) {
449   std::any a = 1;
450   apache::thrift::conformance::any_ref ra = a;
451   using std::any_cast;
452   EXPECT_EQ(any_cast<int>(a), 1);
453   EXPECT_EQ(any_cast<int>(ra), 1);
454 }
455 
TEST(AnyRefTest,ADL_using_thrift)456 TEST(AnyRefTest, ADL_using_thrift) {
457   std::any a = 1;
458   apache::thrift::conformance::any_ref ra = a;
459   using apache::thrift::conformance::any_cast;
460   EXPECT_EQ(any_cast<int>(a), 1);
461   EXPECT_EQ(any_cast<int>(ra), 1);
462 }
463 
464 } // namespace
465