"Fossies" - the Fresh Open Source Software Archive 
Member "abseil-cpp-20230802.1/absl/types/any_test.cc" (18 Sep 2023, 24082 Bytes) of package /linux/misc/abseil-cpp-20230802.1.tar.gz:
1 // Copyright 2017 The Abseil Authors.
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 "absl/types/any.h"
16
17 // This test is a no-op when absl::any is an alias for std::any.
18 #if !defined(ABSL_USES_STD_ANY)
19
20 #include <initializer_list>
21 #include <type_traits>
22 #include <utility>
23 #include <vector>
24
25 #include "gtest/gtest.h"
26 #include "absl/base/config.h"
27 #include "absl/base/internal/exception_testing.h"
28 #include "absl/container/internal/test_instance_tracker.h"
29 #include "absl/log/log.h"
30
31 namespace {
32 using absl::test_internal::CopyableOnlyInstance;
33 using absl::test_internal::InstanceTracker;
34
35 template <typename T>
36 const T& AsConst(const T& t) {
37 return t;
38 }
39
40 struct MoveOnly {
41 MoveOnly() = default;
42 explicit MoveOnly(int value) : value(value) {}
43 MoveOnly(MoveOnly&&) = default;
44 MoveOnly& operator=(MoveOnly&&) = default;
45
46 int value = 0;
47 };
48
49 struct CopyOnly {
50 CopyOnly() = default;
51 explicit CopyOnly(int value) : value(value) {}
52 CopyOnly(CopyOnly&&) = delete;
53 CopyOnly& operator=(CopyOnly&&) = delete;
54 CopyOnly(const CopyOnly&) = default;
55 CopyOnly& operator=(const CopyOnly&) = default;
56
57 int value = 0;
58 };
59
60 struct MoveOnlyWithListConstructor {
61 MoveOnlyWithListConstructor() = default;
62 explicit MoveOnlyWithListConstructor(std::initializer_list<int> /*ilist*/,
63 int value)
64 : value(value) {}
65 MoveOnlyWithListConstructor(MoveOnlyWithListConstructor&&) = default;
66 MoveOnlyWithListConstructor& operator=(MoveOnlyWithListConstructor&&) =
67 default;
68
69 int value = 0;
70 };
71
72 struct IntMoveOnlyCopyOnly {
73 IntMoveOnlyCopyOnly(int value, MoveOnly /*move_only*/, CopyOnly /*copy_only*/)
74 : value(value) {}
75
76 int value;
77 };
78
79 struct ListMoveOnlyCopyOnly {
80 ListMoveOnlyCopyOnly(std::initializer_list<int> ilist, MoveOnly /*move_only*/,
81 CopyOnly /*copy_only*/)
82 : values(ilist) {}
83
84 std::vector<int> values;
85 };
86
87 using FunctionType = void();
88 void FunctionToEmplace() {}
89
90 using ArrayType = int[2];
91 using DecayedArray = absl::decay_t<ArrayType>;
92
93 TEST(AnyTest, Noexcept) {
94 static_assert(std::is_nothrow_default_constructible<absl::any>(), "");
95 static_assert(std::is_nothrow_move_constructible<absl::any>(), "");
96 static_assert(std::is_nothrow_move_assignable<absl::any>(), "");
97 static_assert(noexcept(std::declval<absl::any&>().has_value()), "");
98 static_assert(noexcept(std::declval<absl::any&>().type()), "");
99 static_assert(noexcept(absl::any_cast<int>(std::declval<absl::any*>())), "");
100 static_assert(
101 noexcept(std::declval<absl::any&>().swap(std::declval<absl::any&>())),
102 "");
103
104 using std::swap;
105 static_assert(
106 noexcept(swap(std::declval<absl::any&>(), std::declval<absl::any&>())),
107 "");
108 }
109
110 TEST(AnyTest, HasValue) {
111 absl::any o;
112 EXPECT_FALSE(o.has_value());
113 o.emplace<int>();
114 EXPECT_TRUE(o.has_value());
115 o.reset();
116 EXPECT_FALSE(o.has_value());
117 }
118
119 TEST(AnyTest, Type) {
120 absl::any o;
121 EXPECT_EQ(typeid(void), o.type());
122 o.emplace<int>(5);
123 EXPECT_EQ(typeid(int), o.type());
124 o.emplace<float>(5.f);
125 EXPECT_EQ(typeid(float), o.type());
126 o.reset();
127 EXPECT_EQ(typeid(void), o.type());
128 }
129
130 TEST(AnyTest, EmptyPointerCast) {
131 // pointer-to-unqualified overload
132 {
133 absl::any o;
134 EXPECT_EQ(nullptr, absl::any_cast<int>(&o));
135 o.emplace<int>();
136 EXPECT_NE(nullptr, absl::any_cast<int>(&o));
137 o.reset();
138 EXPECT_EQ(nullptr, absl::any_cast<int>(&o));
139 }
140
141 // pointer-to-const overload
142 {
143 absl::any o;
144 EXPECT_EQ(nullptr, absl::any_cast<int>(&AsConst(o)));
145 o.emplace<int>();
146 EXPECT_NE(nullptr, absl::any_cast<int>(&AsConst(o)));
147 o.reset();
148 EXPECT_EQ(nullptr, absl::any_cast<int>(&AsConst(o)));
149 }
150 }
151
152 TEST(AnyTest, InPlaceConstruction) {
153 const CopyOnly copy_only{};
154 absl::any o(absl::in_place_type_t<IntMoveOnlyCopyOnly>(), 5, MoveOnly(),
155 copy_only);
156 IntMoveOnlyCopyOnly& v = absl::any_cast<IntMoveOnlyCopyOnly&>(o);
157 EXPECT_EQ(5, v.value);
158 }
159
160 TEST(AnyTest, InPlaceConstructionVariableTemplate) {
161 const CopyOnly copy_only{};
162 absl::any o(absl::in_place_type<IntMoveOnlyCopyOnly>, 5, MoveOnly(),
163 copy_only);
164 auto& v = absl::any_cast<IntMoveOnlyCopyOnly&>(o);
165 EXPECT_EQ(5, v.value);
166 }
167
168 TEST(AnyTest, InPlaceConstructionWithCV) {
169 const CopyOnly copy_only{};
170 absl::any o(absl::in_place_type_t<const volatile IntMoveOnlyCopyOnly>(), 5,
171 MoveOnly(), copy_only);
172 IntMoveOnlyCopyOnly& v = absl::any_cast<IntMoveOnlyCopyOnly&>(o);
173 EXPECT_EQ(5, v.value);
174 }
175
176 TEST(AnyTest, InPlaceConstructionWithCVVariableTemplate) {
177 const CopyOnly copy_only{};
178 absl::any o(absl::in_place_type<const volatile IntMoveOnlyCopyOnly>, 5,
179 MoveOnly(), copy_only);
180 auto& v = absl::any_cast<IntMoveOnlyCopyOnly&>(o);
181 EXPECT_EQ(5, v.value);
182 }
183
184 TEST(AnyTest, InPlaceConstructionWithFunction) {
185 absl::any o(absl::in_place_type_t<FunctionType>(), FunctionToEmplace);
186 FunctionType*& construction_result = absl::any_cast<FunctionType*&>(o);
187 EXPECT_EQ(&FunctionToEmplace, construction_result);
188 }
189
190 TEST(AnyTest, InPlaceConstructionWithFunctionVariableTemplate) {
191 absl::any o(absl::in_place_type<FunctionType>, FunctionToEmplace);
192 auto& construction_result = absl::any_cast<FunctionType*&>(o);
193 EXPECT_EQ(&FunctionToEmplace, construction_result);
194 }
195
196 TEST(AnyTest, InPlaceConstructionWithArray) {
197 ArrayType ar = {5, 42};
198 absl::any o(absl::in_place_type_t<ArrayType>(), ar);
199 DecayedArray& construction_result = absl::any_cast<DecayedArray&>(o);
200 EXPECT_EQ(&ar[0], construction_result);
201 }
202
203 TEST(AnyTest, InPlaceConstructionWithArrayVariableTemplate) {
204 ArrayType ar = {5, 42};
205 absl::any o(absl::in_place_type<ArrayType>, ar);
206 auto& construction_result = absl::any_cast<DecayedArray&>(o);
207 EXPECT_EQ(&ar[0], construction_result);
208 }
209
210 TEST(AnyTest, InPlaceConstructionIlist) {
211 const CopyOnly copy_only{};
212 absl::any o(absl::in_place_type_t<ListMoveOnlyCopyOnly>(), {1, 2, 3, 4},
213 MoveOnly(), copy_only);
214 ListMoveOnlyCopyOnly& v = absl::any_cast<ListMoveOnlyCopyOnly&>(o);
215 std::vector<int> expected_values = {1, 2, 3, 4};
216 EXPECT_EQ(expected_values, v.values);
217 }
218
219 TEST(AnyTest, InPlaceConstructionIlistVariableTemplate) {
220 const CopyOnly copy_only{};
221 absl::any o(absl::in_place_type<ListMoveOnlyCopyOnly>, {1, 2, 3, 4},
222 MoveOnly(), copy_only);
223 auto& v = absl::any_cast<ListMoveOnlyCopyOnly&>(o);
224 std::vector<int> expected_values = {1, 2, 3, 4};
225 EXPECT_EQ(expected_values, v.values);
226 }
227
228 TEST(AnyTest, InPlaceConstructionIlistWithCV) {
229 const CopyOnly copy_only{};
230 absl::any o(absl::in_place_type_t<const volatile ListMoveOnlyCopyOnly>(),
231 {1, 2, 3, 4}, MoveOnly(), copy_only);
232 ListMoveOnlyCopyOnly& v = absl::any_cast<ListMoveOnlyCopyOnly&>(o);
233 std::vector<int> expected_values = {1, 2, 3, 4};
234 EXPECT_EQ(expected_values, v.values);
235 }
236
237 TEST(AnyTest, InPlaceConstructionIlistWithCVVariableTemplate) {
238 const CopyOnly copy_only{};
239 absl::any o(absl::in_place_type<const volatile ListMoveOnlyCopyOnly>,
240 {1, 2, 3, 4}, MoveOnly(), copy_only);
241 auto& v = absl::any_cast<ListMoveOnlyCopyOnly&>(o);
242 std::vector<int> expected_values = {1, 2, 3, 4};
243 EXPECT_EQ(expected_values, v.values);
244 }
245
246 TEST(AnyTest, InPlaceNoArgs) {
247 absl::any o(absl::in_place_type_t<int>{});
248 EXPECT_EQ(0, absl::any_cast<int&>(o));
249 }
250
251 TEST(AnyTest, InPlaceNoArgsVariableTemplate) {
252 absl::any o(absl::in_place_type<int>);
253 EXPECT_EQ(0, absl::any_cast<int&>(o));
254 }
255
256 template <typename Enabler, typename T, typename... Args>
257 struct CanEmplaceAnyImpl : std::false_type {};
258
259 template <typename T, typename... Args>
260 struct CanEmplaceAnyImpl<
261 absl::void_t<decltype(
262 std::declval<absl::any&>().emplace<T>(std::declval<Args>()...))>,
263 T, Args...> : std::true_type {};
264
265 template <typename T, typename... Args>
266 using CanEmplaceAny = CanEmplaceAnyImpl<void, T, Args...>;
267
268 TEST(AnyTest, Emplace) {
269 const CopyOnly copy_only{};
270 absl::any o;
271 EXPECT_TRUE((std::is_same<decltype(o.emplace<IntMoveOnlyCopyOnly>(
272 5, MoveOnly(), copy_only)),
273 IntMoveOnlyCopyOnly&>::value));
274 IntMoveOnlyCopyOnly& emplace_result =
275 o.emplace<IntMoveOnlyCopyOnly>(5, MoveOnly(), copy_only);
276 EXPECT_EQ(5, emplace_result.value);
277 IntMoveOnlyCopyOnly& v = absl::any_cast<IntMoveOnlyCopyOnly&>(o);
278 EXPECT_EQ(5, v.value);
279 EXPECT_EQ(&emplace_result, &v);
280
281 static_assert(!CanEmplaceAny<int, int, int>::value, "");
282 static_assert(!CanEmplaceAny<MoveOnly, MoveOnly>::value, "");
283 }
284
285 TEST(AnyTest, EmplaceWithCV) {
286 const CopyOnly copy_only{};
287 absl::any o;
288 EXPECT_TRUE(
289 (std::is_same<decltype(o.emplace<const volatile IntMoveOnlyCopyOnly>(
290 5, MoveOnly(), copy_only)),
291 IntMoveOnlyCopyOnly&>::value));
292 IntMoveOnlyCopyOnly& emplace_result =
293 o.emplace<const volatile IntMoveOnlyCopyOnly>(5, MoveOnly(), copy_only);
294 EXPECT_EQ(5, emplace_result.value);
295 IntMoveOnlyCopyOnly& v = absl::any_cast<IntMoveOnlyCopyOnly&>(o);
296 EXPECT_EQ(5, v.value);
297 EXPECT_EQ(&emplace_result, &v);
298 }
299
300 TEST(AnyTest, EmplaceWithFunction) {
301 absl::any o;
302 EXPECT_TRUE(
303 (std::is_same<decltype(o.emplace<FunctionType>(FunctionToEmplace)),
304 FunctionType*&>::value));
305 FunctionType*& emplace_result = o.emplace<FunctionType>(FunctionToEmplace);
306 EXPECT_EQ(&FunctionToEmplace, emplace_result);
307 }
308
309 TEST(AnyTest, EmplaceWithArray) {
310 absl::any o;
311 ArrayType ar = {5, 42};
312 EXPECT_TRUE(
313 (std::is_same<decltype(o.emplace<ArrayType>(ar)), DecayedArray&>::value));
314 DecayedArray& emplace_result = o.emplace<ArrayType>(ar);
315 EXPECT_EQ(&ar[0], emplace_result);
316 }
317
318 TEST(AnyTest, EmplaceIlist) {
319 const CopyOnly copy_only{};
320 absl::any o;
321 EXPECT_TRUE((std::is_same<decltype(o.emplace<ListMoveOnlyCopyOnly>(
322 {1, 2, 3, 4}, MoveOnly(), copy_only)),
323 ListMoveOnlyCopyOnly&>::value));
324 ListMoveOnlyCopyOnly& emplace_result =
325 o.emplace<ListMoveOnlyCopyOnly>({1, 2, 3, 4}, MoveOnly(), copy_only);
326 ListMoveOnlyCopyOnly& v = absl::any_cast<ListMoveOnlyCopyOnly&>(o);
327 EXPECT_EQ(&v, &emplace_result);
328 std::vector<int> expected_values = {1, 2, 3, 4};
329 EXPECT_EQ(expected_values, v.values);
330
331 static_assert(!CanEmplaceAny<int, std::initializer_list<int>>::value, "");
332 static_assert(!CanEmplaceAny<MoveOnlyWithListConstructor,
333 std::initializer_list<int>, int>::value,
334 "");
335 }
336
337 TEST(AnyTest, EmplaceIlistWithCV) {
338 const CopyOnly copy_only{};
339 absl::any o;
340 EXPECT_TRUE(
341 (std::is_same<decltype(o.emplace<const volatile ListMoveOnlyCopyOnly>(
342 {1, 2, 3, 4}, MoveOnly(), copy_only)),
343 ListMoveOnlyCopyOnly&>::value));
344 ListMoveOnlyCopyOnly& emplace_result =
345 o.emplace<const volatile ListMoveOnlyCopyOnly>({1, 2, 3, 4}, MoveOnly(),
346 copy_only);
347 ListMoveOnlyCopyOnly& v = absl::any_cast<ListMoveOnlyCopyOnly&>(o);
348 EXPECT_EQ(&v, &emplace_result);
349 std::vector<int> expected_values = {1, 2, 3, 4};
350 EXPECT_EQ(expected_values, v.values);
351 }
352
353 TEST(AnyTest, EmplaceNoArgs) {
354 absl::any o;
355 o.emplace<int>();
356 EXPECT_EQ(0, absl::any_cast<int>(o));
357 }
358
359 TEST(AnyTest, ConversionConstruction) {
360 {
361 absl::any o = 5;
362 EXPECT_EQ(5, absl::any_cast<int>(o));
363 }
364
365 {
366 const CopyOnly copy_only(5);
367 absl::any o = copy_only;
368 EXPECT_EQ(5, absl::any_cast<CopyOnly&>(o).value);
369 }
370
371 static_assert(!std::is_convertible<MoveOnly, absl::any>::value, "");
372 }
373
374 TEST(AnyTest, ConversionAssignment) {
375 {
376 absl::any o;
377 o = 5;
378 EXPECT_EQ(5, absl::any_cast<int>(o));
379 }
380
381 {
382 const CopyOnly copy_only(5);
383 absl::any o;
384 o = copy_only;
385 EXPECT_EQ(5, absl::any_cast<CopyOnly&>(o).value);
386 }
387
388 static_assert(!std::is_assignable<MoveOnly, absl::any>::value, "");
389 }
390
391 // Suppress MSVC warnings.
392 // 4521: multiple copy constructors specified
393 // We wrote multiple of them to test that the correct overloads are selected.
394 #ifdef _MSC_VER
395 #pragma warning( push )
396 #pragma warning( disable : 4521)
397 #endif
398
399 // Weird type for testing, only used to make sure we "properly" perfect-forward
400 // when being placed into an absl::any (use the l-value constructor if given an
401 // l-value rather than use the copy constructor).
402 struct WeirdConstructor42 {
403 explicit WeirdConstructor42(int value) : value(value) {}
404
405 // Copy-constructor
406 WeirdConstructor42(const WeirdConstructor42& other) : value(other.value) {}
407
408 // L-value "weird" constructor (used when given an l-value)
409 WeirdConstructor42(
410 WeirdConstructor42& /*other*/) // NOLINT(runtime/references)
411 : value(42) {}
412
413 int value;
414 };
415 #ifdef _MSC_VER
416 #pragma warning( pop )
417 #endif
418
419 TEST(AnyTest, WeirdConversionConstruction) {
420 {
421 const WeirdConstructor42 source(5);
422 absl::any o = source; // Actual copy
423 EXPECT_EQ(5, absl::any_cast<WeirdConstructor42&>(o).value);
424 }
425
426 {
427 WeirdConstructor42 source(5);
428 absl::any o = source; // Weird "conversion"
429 EXPECT_EQ(42, absl::any_cast<WeirdConstructor42&>(o).value);
430 }
431 }
432
433 TEST(AnyTest, WeirdConversionAssignment) {
434 {
435 const WeirdConstructor42 source(5);
436 absl::any o;
437 o = source; // Actual copy
438 EXPECT_EQ(5, absl::any_cast<WeirdConstructor42&>(o).value);
439 }
440
441 {
442 WeirdConstructor42 source(5);
443 absl::any o;
444 o = source; // Weird "conversion"
445 EXPECT_EQ(42, absl::any_cast<WeirdConstructor42&>(o).value);
446 }
447 }
448
449 struct Value {};
450
451 TEST(AnyTest, AnyCastValue) {
452 {
453 absl::any o;
454 o.emplace<int>(5);
455 EXPECT_EQ(5, absl::any_cast<int>(o));
456 EXPECT_EQ(5, absl::any_cast<int>(AsConst(o)));
457 static_assert(
458 std::is_same<decltype(absl::any_cast<Value>(o)), Value>::value, "");
459 }
460
461 {
462 absl::any o;
463 o.emplace<int>(5);
464 EXPECT_EQ(5, absl::any_cast<const int>(o));
465 EXPECT_EQ(5, absl::any_cast<const int>(AsConst(o)));
466 static_assert(std::is_same<decltype(absl::any_cast<const Value>(o)),
467 const Value>::value,
468 "");
469 }
470 }
471
472 TEST(AnyTest, AnyCastReference) {
473 {
474 absl::any o;
475 o.emplace<int>(5);
476 EXPECT_EQ(5, absl::any_cast<int&>(o));
477 EXPECT_EQ(5, absl::any_cast<const int&>(AsConst(o)));
478 static_assert(
479 std::is_same<decltype(absl::any_cast<Value&>(o)), Value&>::value, "");
480 }
481
482 {
483 absl::any o;
484 o.emplace<int>(5);
485 EXPECT_EQ(5, absl::any_cast<const int>(o));
486 EXPECT_EQ(5, absl::any_cast<const int>(AsConst(o)));
487 static_assert(std::is_same<decltype(absl::any_cast<const Value&>(o)),
488 const Value&>::value,
489 "");
490 }
491
492 {
493 absl::any o;
494 o.emplace<int>(5);
495 EXPECT_EQ(5, absl::any_cast<int&&>(std::move(o)));
496 static_assert(std::is_same<decltype(absl::any_cast<Value&&>(std::move(o))),
497 Value&&>::value,
498 "");
499 }
500
501 {
502 absl::any o;
503 o.emplace<int>(5);
504 EXPECT_EQ(5, absl::any_cast<const int>(std::move(o)));
505 static_assert(
506 std::is_same<decltype(absl::any_cast<const Value&&>(std::move(o))),
507 const Value&&>::value,
508 "");
509 }
510 }
511
512 TEST(AnyTest, AnyCastPointer) {
513 {
514 absl::any o;
515 EXPECT_EQ(nullptr, absl::any_cast<char>(&o));
516 o.emplace<int>(5);
517 EXPECT_EQ(nullptr, absl::any_cast<char>(&o));
518 o.emplace<char>('a');
519 EXPECT_EQ('a', *absl::any_cast<char>(&o));
520 static_assert(
521 std::is_same<decltype(absl::any_cast<Value>(&o)), Value*>::value, "");
522 }
523
524 {
525 absl::any o;
526 EXPECT_EQ(nullptr, absl::any_cast<const char>(&o));
527 o.emplace<int>(5);
528 EXPECT_EQ(nullptr, absl::any_cast<const char>(&o));
529 o.emplace<char>('a');
530 EXPECT_EQ('a', *absl::any_cast<const char>(&o));
531 static_assert(std::is_same<decltype(absl::any_cast<const Value>(&o)),
532 const Value*>::value,
533 "");
534 }
535 }
536
537 TEST(AnyTest, MakeAny) {
538 const CopyOnly copy_only{};
539 auto o = absl::make_any<IntMoveOnlyCopyOnly>(5, MoveOnly(), copy_only);
540 static_assert(std::is_same<decltype(o), absl::any>::value, "");
541 EXPECT_EQ(5, absl::any_cast<IntMoveOnlyCopyOnly&>(o).value);
542 }
543
544 TEST(AnyTest, MakeAnyIList) {
545 const CopyOnly copy_only{};
546 auto o =
547 absl::make_any<ListMoveOnlyCopyOnly>({1, 2, 3}, MoveOnly(), copy_only);
548 static_assert(std::is_same<decltype(o), absl::any>::value, "");
549 ListMoveOnlyCopyOnly& v = absl::any_cast<ListMoveOnlyCopyOnly&>(o);
550 std::vector<int> expected_values = {1, 2, 3};
551 EXPECT_EQ(expected_values, v.values);
552 }
553
554 // Test the use of copy constructor and operator=
555 TEST(AnyTest, Copy) {
556 InstanceTracker tracker_raii;
557
558 {
559 absl::any o(absl::in_place_type<CopyableOnlyInstance>, 123);
560 CopyableOnlyInstance* f1 = absl::any_cast<CopyableOnlyInstance>(&o);
561
562 absl::any o2(o);
563 const CopyableOnlyInstance* f2 = absl::any_cast<CopyableOnlyInstance>(&o2);
564 EXPECT_EQ(123, f2->value());
565 EXPECT_NE(f1, f2);
566
567 absl::any o3;
568 o3 = o2;
569 const CopyableOnlyInstance* f3 = absl::any_cast<CopyableOnlyInstance>(&o3);
570 EXPECT_EQ(123, f3->value());
571 EXPECT_NE(f2, f3);
572
573 const absl::any o4(4);
574 // copy construct from const lvalue ref.
575 absl::any o5 = o4;
576 EXPECT_EQ(4, absl::any_cast<int>(o4));
577 EXPECT_EQ(4, absl::any_cast<int>(o5));
578
579 // Copy construct from const rvalue ref.
580 absl::any o6 = std::move(o4); // NOLINT
581 EXPECT_EQ(4, absl::any_cast<int>(o4));
582 EXPECT_EQ(4, absl::any_cast<int>(o6));
583 }
584 }
585
586 TEST(AnyTest, Move) {
587 InstanceTracker tracker_raii;
588
589 absl::any any1;
590 any1.emplace<CopyableOnlyInstance>(5);
591
592 // This is a copy, so copy count increases to 1.
593 absl::any any2 = any1;
594 EXPECT_EQ(5, absl::any_cast<CopyableOnlyInstance&>(any1).value());
595 EXPECT_EQ(5, absl::any_cast<CopyableOnlyInstance&>(any2).value());
596 EXPECT_EQ(1, tracker_raii.copies());
597
598 // This isn't a copy, so copy count doesn't increase.
599 absl::any any3 = std::move(any2);
600 EXPECT_EQ(5, absl::any_cast<CopyableOnlyInstance&>(any3).value());
601 EXPECT_EQ(1, tracker_raii.copies());
602
603 absl::any any4;
604 any4 = std::move(any3);
605 EXPECT_EQ(5, absl::any_cast<CopyableOnlyInstance&>(any4).value());
606 EXPECT_EQ(1, tracker_raii.copies());
607
608 absl::any tmp4(4);
609 absl::any o4(std::move(tmp4)); // move construct
610 EXPECT_EQ(4, absl::any_cast<int>(o4));
611 o4 = *&o4; // self assign
612 EXPECT_EQ(4, absl::any_cast<int>(o4));
613 EXPECT_TRUE(o4.has_value());
614
615 absl::any o5;
616 absl::any tmp5(5);
617 o5 = std::move(tmp5); // move assign
618 EXPECT_EQ(5, absl::any_cast<int>(o5));
619 }
620
621 // Reset the ObjectOwner with an object of a different type
622 TEST(AnyTest, Reset) {
623 absl::any o;
624 o.emplace<int>();
625
626 o.reset();
627 EXPECT_FALSE(o.has_value());
628
629 o.emplace<char>();
630 EXPECT_TRUE(o.has_value());
631 }
632
633 TEST(AnyTest, ConversionConstructionCausesOneCopy) {
634 InstanceTracker tracker_raii;
635 CopyableOnlyInstance counter(5);
636 absl::any o(counter);
637 EXPECT_EQ(5, absl::any_cast<CopyableOnlyInstance&>(o).value());
638 EXPECT_EQ(1, tracker_raii.copies());
639 }
640
641 //////////////////////////////////
642 // Tests for Exception Behavior //
643 //////////////////////////////////
644
645 #if defined(ABSL_USES_STD_ANY)
646
647 // If using a std `any` implementation, we can't check for a specific message.
648 #define ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(...) \
649 ABSL_BASE_INTERNAL_EXPECT_FAIL((__VA_ARGS__), absl::bad_any_cast, \
650 "")
651
652 #else
653
654 // If using the absl `any` implementation, we can rely on a specific message.
655 #define ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(...) \
656 ABSL_BASE_INTERNAL_EXPECT_FAIL((__VA_ARGS__), absl::bad_any_cast, \
657 "Bad any cast")
658
659 #endif // defined(ABSL_USES_STD_ANY)
660
661 TEST(AnyTest, ThrowBadAlloc) {
662 {
663 absl::any a;
664 ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(absl::any_cast<int&>(a));
665 ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(absl::any_cast<const int&>(a));
666 ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(absl::any_cast<int&&>(absl::any{}));
667 ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(absl::any_cast<const int&&>(absl::any{}));
668 ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(absl::any_cast<int>(a));
669 ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(absl::any_cast<const int>(a));
670 ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(absl::any_cast<int>(absl::any{}));
671 ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(absl::any_cast<const int>(absl::any{}));
672
673 // const absl::any operand
674 ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(absl::any_cast<const int&>(AsConst(a)));
675 ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(absl::any_cast<int>(AsConst(a)));
676 ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(absl::any_cast<const int>(AsConst(a)));
677 }
678
679 {
680 absl::any a(absl::in_place_type<int>);
681 ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(absl::any_cast<float&>(a));
682 ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(absl::any_cast<const float&>(a));
683 ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(absl::any_cast<float&&>(absl::any{}));
684 ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(
685 absl::any_cast<const float&&>(absl::any{}));
686 ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(absl::any_cast<float>(a));
687 ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(absl::any_cast<const float>(a));
688 ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(absl::any_cast<float>(absl::any{}));
689 ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(absl::any_cast<const float>(absl::any{}));
690
691 // const absl::any operand
692 ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(absl::any_cast<const float&>(AsConst(a)));
693 ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(absl::any_cast<float>(AsConst(a)));
694 ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(absl::any_cast<const float>(AsConst(a)));
695 }
696 }
697
698 class BadCopy {};
699
700 struct BadCopyable {
701 BadCopyable() = default;
702 BadCopyable(BadCopyable&&) = default;
703 BadCopyable(const BadCopyable&) {
704 #ifdef ABSL_HAVE_EXCEPTIONS
705 throw BadCopy();
706 #else
707 LOG(FATAL) << "Bad copy";
708 #endif
709 }
710 };
711
712 #define ABSL_ANY_TEST_EXPECT_BAD_COPY(...) \
713 ABSL_BASE_INTERNAL_EXPECT_FAIL((__VA_ARGS__), BadCopy, "Bad copy")
714
715 // Test the guarantees regarding exceptions in copy/assign.
716 TEST(AnyTest, FailedCopy) {
717 {
718 const BadCopyable bad{};
719 ABSL_ANY_TEST_EXPECT_BAD_COPY(absl::any{bad});
720 }
721
722 {
723 absl::any src(absl::in_place_type<BadCopyable>);
724 ABSL_ANY_TEST_EXPECT_BAD_COPY(absl::any{src});
725 }
726
727 {
728 BadCopyable bad;
729 absl::any target;
730 ABSL_ANY_TEST_EXPECT_BAD_COPY(target = bad);
731 }
732
733 {
734 BadCopyable bad;
735 absl::any target(absl::in_place_type<BadCopyable>);
736 ABSL_ANY_TEST_EXPECT_BAD_COPY(target = bad);
737 EXPECT_TRUE(target.has_value());
738 }
739
740 {
741 absl::any src(absl::in_place_type<BadCopyable>);
742 absl::any target;
743 ABSL_ANY_TEST_EXPECT_BAD_COPY(target = src);
744 EXPECT_FALSE(target.has_value());
745 }
746
747 {
748 absl::any src(absl::in_place_type<BadCopyable>);
749 absl::any target(absl::in_place_type<BadCopyable>);
750 ABSL_ANY_TEST_EXPECT_BAD_COPY(target = src);
751 EXPECT_TRUE(target.has_value());
752 }
753 }
754
755 // Test the guarantees regarding exceptions in emplace.
756 TEST(AnyTest, FailedEmplace) {
757 BadCopyable bad;
758 absl::any target;
759 ABSL_ANY_TEST_EXPECT_BAD_COPY(target.emplace<BadCopyable>(bad));
760 }
761
762 // GCC and Clang have a bug here.
763 // Ine some cases, the exception seems to be thrown at the wrong time, and
764 // target may contain a value.
765 #ifdef __GNUC__
766 TEST(AnyTest, DISABLED_FailedEmplaceInPlace) {
767 #else
768 TEST(AnyTest, FailedEmplaceInPlace) {
769 #endif
770 BadCopyable bad;
771 absl::any target(absl::in_place_type<int>);
772 ABSL_ANY_TEST_EXPECT_BAD_COPY(target.emplace<BadCopyable>(bad));
773 EXPECT_FALSE(target.has_value());
774 }
775
776 } // namespace
777
778 #endif // #if !defined(ABSL_USES_STD_ANY)