1 #include <algorithm>
2 #include <string.h>
3 #include <unordered_map>
4 #include <vector>
5 #include <gtest/gtest.h>
6 #include <entt/core/any.hpp>
7
8 struct empty {
~emptyempty9 ~empty() { ++counter; }
10 inline static int counter = 0;
11 };
12
13 struct fat {
fatfat14 fat(double v1, double v2, double v3, double v4)
15 : value{v1, v2, v3, v4}
16 {}
17
~fatfat18 ~fat() { ++counter; }
19
operator ==fat20 bool operator==(const fat &other) const {
21 return std::equal(std::begin(value), std::end(value), std::begin(other.value), std::end(other.value));
22 }
23
24 inline static int counter{0};
25 double value[4];
26 };
27
28 struct not_comparable {
29 bool operator==(const not_comparable &) const = delete;
30 };
31
32 template<auto Sz>
33 struct not_copyable {
not_copyablenot_copyable34 not_copyable(): payload{} {}
35 not_copyable(const not_copyable &) = delete;
36 not_copyable(not_copyable &&) = default;
37 not_copyable & operator=(const not_copyable &) = delete;
38 not_copyable & operator=(not_copyable &&) = default;
39 double payload[Sz];
40 };
41
42 struct alignas(64u) over_aligned {};
43
44 struct Any: ::testing::Test {
SetUpAny45 void SetUp() override {
46 fat::counter = 0;
47 empty::counter = 0;
48 }
49 };
50
TEST_F(Any,SBO)51 TEST_F(Any, SBO) {
52 entt::any any{'c'};
53
54 ASSERT_TRUE(any);
55 ASSERT_TRUE(any.owner());
56 ASSERT_EQ(any.type(), entt::type_id<char>());
57 ASSERT_EQ(entt::any_cast<double>(&any), nullptr);
58 ASSERT_EQ(entt::any_cast<char>(any), 'c');
59 }
60
TEST_F(Any,NoSBO)61 TEST_F(Any, NoSBO) {
62 fat instance{.1, .2, .3, .4};
63 entt::any any{instance};
64
65 ASSERT_TRUE(any);
66 ASSERT_TRUE(any.owner());
67 ASSERT_EQ(any.type(), entt::type_id<fat>());
68 ASSERT_EQ(entt::any_cast<double>(&any), nullptr);
69 ASSERT_EQ(entt::any_cast<fat>(any), instance);
70 }
71
TEST_F(Any,Empty)72 TEST_F(Any, Empty) {
73 entt::any any{};
74
75 ASSERT_FALSE(any);
76 ASSERT_TRUE(any.owner());
77 ASSERT_FALSE(any.type());
78 ASSERT_EQ(entt::any_cast<double>(&any), nullptr);
79 ASSERT_EQ(any.data(), nullptr);
80 }
81
TEST_F(Any,SBOInPlaceTypeConstruction)82 TEST_F(Any, SBOInPlaceTypeConstruction) {
83 entt::any any{std::in_place_type<int>, 42};
84
85 ASSERT_TRUE(any);
86 ASSERT_TRUE(any.owner());
87 ASSERT_EQ(any.type(), entt::type_id<int>());
88 ASSERT_EQ(entt::any_cast<double>(&any), nullptr);
89 ASSERT_EQ(entt::any_cast<int>(any), 42);
90
91 auto other = any.as_ref();
92
93 ASSERT_TRUE(other);
94 ASSERT_FALSE(other.owner());
95 ASSERT_EQ(other.type(), entt::type_id<int>());
96 ASSERT_EQ(entt::any_cast<int>(other), 42);
97 ASSERT_EQ(other.data(), any.data());
98 }
99
TEST_F(Any,SBOAsRefConstruction)100 TEST_F(Any, SBOAsRefConstruction) {
101 int value = 42;
102 entt::any any{entt::forward_as_any(value)};
103
104 ASSERT_TRUE(any);
105 ASSERT_FALSE(any.owner());
106 ASSERT_EQ(any.type(), entt::type_id<int>());
107
108 ASSERT_EQ(entt::any_cast<double>(&any), nullptr);
109 ASSERT_EQ(entt::any_cast<const int>(&any), &value);
110 ASSERT_EQ(entt::any_cast<int>(&any), &value);
111 ASSERT_EQ(entt::any_cast<const int>(&std::as_const(any)), &value);
112 ASSERT_EQ(entt::any_cast<int>(&std::as_const(any)), &value);
113
114 ASSERT_EQ(entt::any_cast<const int &>(any), 42);
115 ASSERT_EQ(entt::any_cast<int>(any), 42);
116
117 ASSERT_EQ(any.data(), &value);
118 ASSERT_EQ(std::as_const(any).data(), &value);
119
120 any.emplace<int &>(value);
121
122 ASSERT_TRUE(any);
123 ASSERT_FALSE(any.owner());
124 ASSERT_EQ(any.type(), entt::type_id<int>());
125 ASSERT_EQ(entt::any_cast<int>(&any), &value);
126
127 auto other = any.as_ref();
128
129 ASSERT_TRUE(other);
130 ASSERT_FALSE(other.owner());
131 ASSERT_EQ(other.type(), entt::type_id<int>());
132 ASSERT_EQ(entt::any_cast<int>(other), 42);
133 ASSERT_EQ(other.data(), any.data());
134 }
135
TEST_F(Any,SBOAsConstRefConstruction)136 TEST_F(Any, SBOAsConstRefConstruction) {
137 const int value = 42;
138 entt::any any{entt::forward_as_any(value)};
139
140 ASSERT_TRUE(any);
141 ASSERT_FALSE(any.owner());
142 ASSERT_EQ(any.type(), entt::type_id<int>());
143
144 ASSERT_EQ(entt::any_cast<double>(&any), nullptr);
145 ASSERT_EQ(entt::any_cast<const int>(&any), &value);
146 ASSERT_EQ(entt::any_cast<int>(&any), nullptr);
147 ASSERT_EQ(entt::any_cast<const int>(&std::as_const(any)), &value);
148 ASSERT_EQ(entt::any_cast<int>(&std::as_const(any)), &value);
149
150 ASSERT_EQ(entt::any_cast<const int &>(any), 42);
151 ASSERT_EQ(entt::any_cast<int>(any), 42);
152
153 ASSERT_EQ(any.data(), nullptr);
154 ASSERT_EQ(std::as_const(any).data(), &value);
155
156 any.emplace<const int &>(value);
157
158 ASSERT_TRUE(any);
159 ASSERT_FALSE(any.owner());
160 ASSERT_EQ(any.type(), entt::type_id<int>());
161 ASSERT_EQ(entt::any_cast<const int>(&any), &value);
162
163 auto other = any.as_ref();
164
165 ASSERT_TRUE(other);
166 ASSERT_FALSE(other.owner());
167 ASSERT_EQ(other.type(), entt::type_id<int>());
168 ASSERT_EQ(entt::any_cast<int>(other), 42);
169 ASSERT_EQ(other.data(), any.data());
170 }
171
TEST_F(Any,SBOCopyConstruction)172 TEST_F(Any, SBOCopyConstruction) {
173 entt::any any{42};
174 entt::any other{any};
175
176 ASSERT_TRUE(any);
177 ASSERT_TRUE(other);
178 ASSERT_TRUE(any.owner());
179 ASSERT_TRUE(other.owner());
180 ASSERT_EQ(any.type(), entt::type_id<int>());
181 ASSERT_EQ(other.type(), entt::type_id<int>());
182 ASSERT_EQ(entt::any_cast<double>(&other), nullptr);
183 ASSERT_EQ(entt::any_cast<int>(other), 42);
184 }
185
TEST_F(Any,SBOCopyAssignment)186 TEST_F(Any, SBOCopyAssignment) {
187 entt::any any{42};
188 entt::any other{3};
189
190 other = any;
191
192 ASSERT_TRUE(any);
193 ASSERT_TRUE(other);
194 ASSERT_TRUE(any.owner());
195 ASSERT_TRUE(other.owner());
196 ASSERT_EQ(any.type(), entt::type_id<int>());
197 ASSERT_EQ(other.type(), entt::type_id<int>());
198 ASSERT_EQ(entt::any_cast<double>(&other), nullptr);
199 ASSERT_EQ(entt::any_cast<int>(other), 42);
200 }
201
TEST_F(Any,SBOMoveConstruction)202 TEST_F(Any, SBOMoveConstruction) {
203 entt::any any{42};
204 entt::any other{std::move(any)};
205
206 ASSERT_TRUE(any);
207 ASSERT_TRUE(other);
208 ASSERT_TRUE(any.owner());
209 ASSERT_TRUE(other.owner());
210 ASSERT_NE(any.data(), nullptr);
211 ASSERT_EQ(any.type(), entt::type_id<int>());
212 ASSERT_EQ(other.type(), entt::type_id<int>());
213 ASSERT_EQ(entt::any_cast<double>(&other), nullptr);
214 ASSERT_EQ(entt::any_cast<int>(other), 42);
215 }
216
TEST_F(Any,SBOMoveAssignment)217 TEST_F(Any, SBOMoveAssignment) {
218 entt::any any{42};
219 entt::any other{3};
220
221 other = std::move(any);
222
223 ASSERT_TRUE(any);
224 ASSERT_TRUE(other);
225 ASSERT_TRUE(any.owner());
226 ASSERT_TRUE(other.owner());
227 ASSERT_NE(any.data(), nullptr);
228 ASSERT_EQ(any.type(), entt::type_id<int>());
229 ASSERT_EQ(other.type(), entt::type_id<int>());
230 ASSERT_EQ(entt::any_cast<double>(&other), nullptr);
231 ASSERT_EQ(entt::any_cast<int>(other), 42);
232 }
233
TEST_F(Any,SBODirectAssignment)234 TEST_F(Any, SBODirectAssignment) {
235 entt::any any{};
236 any = 42;
237
238 ASSERT_TRUE(any);
239 ASSERT_TRUE(any.owner());
240 ASSERT_EQ(any.type(), entt::type_id<int>());
241 ASSERT_EQ(entt::any_cast<double>(&any), nullptr);
242 ASSERT_EQ(entt::any_cast<int>(any), 42);
243 }
244
TEST_F(Any,NoSBOInPlaceTypeConstruction)245 TEST_F(Any, NoSBOInPlaceTypeConstruction) {
246 fat instance{.1, .2, .3, .4};
247 entt::any any{std::in_place_type<fat>, instance};
248
249 ASSERT_TRUE(any);
250 ASSERT_TRUE(any.owner());
251 ASSERT_EQ(any.type(), entt::type_id<fat>());
252 ASSERT_EQ(entt::any_cast<double>(&any), nullptr);
253 ASSERT_EQ(entt::any_cast<fat>(any), instance);
254
255 auto other = any.as_ref();
256
257 ASSERT_TRUE(other);
258 ASSERT_FALSE(other.owner());
259 ASSERT_EQ(other.type(), entt::type_id<fat>());
260 ASSERT_EQ(entt::any_cast<fat>(other), (fat{.1, .2, .3, .4}));
261 ASSERT_EQ(other.data(), any.data());
262 }
263
TEST_F(Any,NoSBOAsRefConstruction)264 TEST_F(Any, NoSBOAsRefConstruction) {
265 fat instance{.1, .2, .3, .4};
266 entt::any any{entt::forward_as_any(instance)};
267
268 ASSERT_TRUE(any);
269 ASSERT_FALSE(any.owner());
270 ASSERT_EQ(any.type(), entt::type_id<fat>());
271
272 ASSERT_EQ(entt::any_cast<double>(&any), nullptr);
273 ASSERT_EQ(entt::any_cast<const fat>(&any), &instance);
274 ASSERT_EQ(entt::any_cast<fat>(&any), &instance);
275 ASSERT_EQ(entt::any_cast<const fat>(&std::as_const(any)), &instance);
276 ASSERT_EQ(entt::any_cast<fat>(&std::as_const(any)), &instance);
277
278 ASSERT_EQ(entt::any_cast<const fat &>(any), instance);
279 ASSERT_EQ(entt::any_cast<fat>(any), instance);
280
281 ASSERT_EQ(any.data(), &instance);
282 ASSERT_EQ(std::as_const(any).data(), &instance);
283
284 any.emplace<fat &>(instance);
285
286 ASSERT_TRUE(any);
287 ASSERT_FALSE(any.owner());
288 ASSERT_EQ(any.type(), entt::type_id<fat>());
289 ASSERT_EQ(entt::any_cast<fat>(&any), &instance);
290
291 auto other = any.as_ref();
292
293 ASSERT_TRUE(other);
294 ASSERT_FALSE(other.owner());
295 ASSERT_EQ(other.type(), entt::type_id<fat>());
296 ASSERT_EQ(entt::any_cast<fat>(other), (fat{.1, .2, .3, .4}));
297 ASSERT_EQ(other.data(), any.data());
298 }
299
TEST_F(Any,NoSBOAsConstRefConstruction)300 TEST_F(Any, NoSBOAsConstRefConstruction) {
301 const fat instance{.1, .2, .3, .4};
302 entt::any any{entt::forward_as_any(instance)};
303
304 ASSERT_TRUE(any);
305 ASSERT_FALSE(any.owner());
306 ASSERT_EQ(any.type(), entt::type_id<fat>());
307
308 ASSERT_EQ(entt::any_cast<double>(&any), nullptr);
309 ASSERT_EQ(entt::any_cast<const fat>(&any), &instance);
310 ASSERT_EQ(entt::any_cast<fat>(&any), nullptr);
311 ASSERT_EQ(entt::any_cast<const fat>(&std::as_const(any)), &instance);
312 ASSERT_EQ(entt::any_cast<fat>(&std::as_const(any)), &instance);
313
314 ASSERT_EQ(entt::any_cast<const fat &>(any), instance);
315 ASSERT_EQ(entt::any_cast<fat>(any), instance);
316
317 ASSERT_EQ(any.data(), nullptr);
318 ASSERT_EQ(std::as_const(any).data(), &instance);
319
320 any.emplace<const fat &>(instance);
321
322 ASSERT_TRUE(any);
323 ASSERT_FALSE(any.owner());
324 ASSERT_EQ(any.type(), entt::type_id<fat>());
325 ASSERT_EQ(entt::any_cast<const fat>(&any), &instance);
326
327 auto other = any.as_ref();
328
329 ASSERT_TRUE(other);
330 ASSERT_FALSE(other.owner());
331 ASSERT_EQ(other.type(), entt::type_id<fat>());
332 ASSERT_EQ(entt::any_cast<fat>(other), (fat{.1, .2, .3, .4}));
333 ASSERT_EQ(other.data(), any.data());
334 }
335
TEST_F(Any,NoSBOCopyConstruction)336 TEST_F(Any, NoSBOCopyConstruction) {
337 fat instance{.1, .2, .3, .4};
338 entt::any any{instance};
339 entt::any other{any};
340
341 ASSERT_TRUE(any);
342 ASSERT_TRUE(other);
343 ASSERT_TRUE(any.owner());
344 ASSERT_TRUE(other.owner());
345 ASSERT_EQ(any.type(), entt::type_id<fat>());
346 ASSERT_EQ(other.type(), entt::type_id<fat>());
347 ASSERT_EQ(entt::any_cast<double>(&other), nullptr);
348 ASSERT_EQ(entt::any_cast<fat>(other), instance);
349 }
350
TEST_F(Any,NoSBOCopyAssignment)351 TEST_F(Any, NoSBOCopyAssignment) {
352 fat instance{.1, .2, .3, .4};
353 entt::any any{instance};
354 entt::any other{3};
355
356 other = any;
357
358 ASSERT_TRUE(any);
359 ASSERT_TRUE(other);
360 ASSERT_TRUE(any.owner());
361 ASSERT_TRUE(other.owner());
362 ASSERT_EQ(any.type(), entt::type_id<fat>());
363 ASSERT_EQ(other.type(), entt::type_id<fat>());
364 ASSERT_EQ(entt::any_cast<double>(&other), nullptr);
365 ASSERT_EQ(entt::any_cast<fat>(other), instance);
366 }
367
TEST_F(Any,NoSBOMoveConstruction)368 TEST_F(Any, NoSBOMoveConstruction) {
369 fat instance{.1, .2, .3, .4};
370 entt::any any{instance};
371 entt::any other{std::move(any)};
372
373 ASSERT_FALSE(any);
374 ASSERT_TRUE(other);
375 ASSERT_TRUE(any.owner());
376 ASSERT_TRUE(other.owner());
377 ASSERT_EQ(any.data(), nullptr);
378 ASSERT_EQ(any.type(), entt::type_id<fat>());
379 ASSERT_EQ(other.type(), entt::type_id<fat>());
380 ASSERT_EQ(entt::any_cast<double>(&other), nullptr);
381 ASSERT_EQ(entt::any_cast<fat>(other), instance);
382 }
383
TEST_F(Any,NoSBOMoveAssignment)384 TEST_F(Any, NoSBOMoveAssignment) {
385 fat instance{.1, .2, .3, .4};
386 entt::any any{instance};
387 entt::any other{3};
388
389 other = std::move(any);
390
391 ASSERT_FALSE(any);
392 ASSERT_TRUE(other);
393 ASSERT_TRUE(any.owner());
394 ASSERT_TRUE(other.owner());
395 ASSERT_EQ(any.data(), nullptr);
396 ASSERT_EQ(any.type(), entt::type_id<fat>());
397 ASSERT_EQ(other.type(), entt::type_id<fat>());
398 ASSERT_EQ(entt::any_cast<double>(&other), nullptr);
399 ASSERT_EQ(entt::any_cast<fat>(other), instance);
400 }
401
TEST_F(Any,NoSBODirectAssignment)402 TEST_F(Any, NoSBODirectAssignment) {
403 fat instance{.1, .2, .3, .4};
404 entt::any any{};
405 any = instance;
406
407 ASSERT_TRUE(any);
408 ASSERT_TRUE(any.owner());
409 ASSERT_EQ(any.type(), entt::type_id<fat>());
410 ASSERT_EQ(entt::any_cast<double>(&any), nullptr);
411 ASSERT_EQ(entt::any_cast<fat>(any), instance);
412 }
413
TEST_F(Any,VoidInPlaceTypeConstruction)414 TEST_F(Any, VoidInPlaceTypeConstruction) {
415 entt::any any{std::in_place_type<void>};
416
417 ASSERT_FALSE(any);
418 ASSERT_TRUE(any.owner());
419 ASSERT_FALSE(any.type());
420 ASSERT_EQ(entt::any_cast<int>(&any), nullptr);
421 }
422
TEST_F(Any,VoidCopyConstruction)423 TEST_F(Any, VoidCopyConstruction) {
424 entt::any any{std::in_place_type<void>};
425 entt::any other{any};
426
427 ASSERT_FALSE(any);
428 ASSERT_FALSE(other);
429 ASSERT_TRUE(any.owner());
430 ASSERT_TRUE(other.owner());
431 ASSERT_FALSE(any.type());
432 ASSERT_FALSE(other.type());
433 ASSERT_EQ(entt::any_cast<int>(&any), nullptr);
434 ASSERT_EQ(entt::any_cast<double>(&other), nullptr);
435 }
436
TEST_F(Any,VoidCopyAssignment)437 TEST_F(Any, VoidCopyAssignment) {
438 entt::any any{std::in_place_type<void>};
439 entt::any other{42};
440
441 other = any;
442
443 ASSERT_FALSE(any);
444 ASSERT_FALSE(other);
445 ASSERT_TRUE(any.owner());
446 ASSERT_TRUE(other.owner());
447 ASSERT_FALSE(any.type());
448 ASSERT_FALSE(other.type());
449 ASSERT_EQ(entt::any_cast<int>(&any), nullptr);
450 ASSERT_EQ(entt::any_cast<double>(&other), nullptr);
451 }
452
TEST_F(Any,VoidMoveConstruction)453 TEST_F(Any, VoidMoveConstruction) {
454 entt::any any{std::in_place_type<void>};
455 entt::any other{std::move(any)};
456
457 ASSERT_FALSE(any);
458 ASSERT_FALSE(other);
459 ASSERT_TRUE(any.owner());
460 ASSERT_TRUE(other.owner());
461 ASSERT_FALSE(any.type());
462 ASSERT_FALSE(other.type());
463 ASSERT_EQ(entt::any_cast<int>(&any), nullptr);
464 ASSERT_EQ(entt::any_cast<double>(&other), nullptr);
465 }
466
TEST_F(Any,VoidMoveAssignment)467 TEST_F(Any, VoidMoveAssignment) {
468 entt::any any{std::in_place_type<void>};
469 entt::any other{42};
470
471 other = std::move(any);
472
473 ASSERT_FALSE(any);
474 ASSERT_FALSE(other);
475 ASSERT_TRUE(any.owner());
476 ASSERT_TRUE(other.owner());
477 ASSERT_FALSE(any.type());
478 ASSERT_FALSE(other.type());
479 ASSERT_EQ(entt::any_cast<int>(&any), nullptr);
480 ASSERT_EQ(entt::any_cast<double>(&other), nullptr);
481 }
482
TEST_F(Any,SBOMoveValidButUnspecifiedState)483 TEST_F(Any, SBOMoveValidButUnspecifiedState) {
484 entt::any any{42};
485 entt::any other{std::move(any)};
486 entt::any valid = std::move(other);
487
488 ASSERT_TRUE(any);
489 ASSERT_TRUE(other);
490 ASSERT_TRUE(valid);
491 }
492
TEST_F(Any,NoSBOMoveValidButUnspecifiedState)493 TEST_F(Any, NoSBOMoveValidButUnspecifiedState) {
494 fat instance{.1, .2, .3, .4};
495 entt::any any{instance};
496 entt::any other{std::move(any)};
497 entt::any valid = std::move(other);
498
499 ASSERT_FALSE(any);
500 ASSERT_FALSE(other);
501 ASSERT_TRUE(valid);
502 }
503
TEST_F(Any,VoidMoveValidButUnspecifiedState)504 TEST_F(Any, VoidMoveValidButUnspecifiedState) {
505 entt::any any{std::in_place_type<void>};
506 entt::any other{std::move(any)};
507 entt::any valid = std::move(other);
508
509 ASSERT_FALSE(any);
510 ASSERT_FALSE(other);
511 ASSERT_FALSE(valid);
512 }
513
TEST_F(Any,SBODestruction)514 TEST_F(Any, SBODestruction) {
515 {
516 entt::any any{std::in_place_type<empty>};
517 any.emplace<empty>();
518 any = empty{};
519 entt::any other{std::move(any)};
520 any = std::move(other);
521 }
522
523 ASSERT_EQ(empty::counter, 6);
524 }
525
TEST_F(Any,NoSBODestruction)526 TEST_F(Any, NoSBODestruction) {
527 {
528 entt::any any{std::in_place_type<fat>, 1., 2., 3., 4.};
529 any.emplace<fat>(1., 2., 3., 4.);
530 any = fat{1., 2., 3., 4.};
531 entt::any other{std::move(any)};
532 any = std::move(other);
533 }
534
535 ASSERT_EQ(fat::counter, 4);
536 }
537
TEST_F(Any,VoidDestruction)538 TEST_F(Any, VoidDestruction) {
539 // just let asan tell us if everything is ok here
540 [[maybe_unused]] entt::any any{std::in_place_type<void>};
541 }
542
TEST_F(Any,Emplace)543 TEST_F(Any, Emplace) {
544 entt::any any{};
545 any.emplace<int>(42);
546
547 ASSERT_TRUE(any);
548 ASSERT_TRUE(any.owner());
549 ASSERT_EQ(any.type(), entt::type_id<int>());
550 ASSERT_EQ(entt::any_cast<double>(&any), nullptr);
551 ASSERT_EQ(entt::any_cast<int>(any), 42);
552 }
553
TEST_F(Any,EmplaceVoid)554 TEST_F(Any, EmplaceVoid) {
555 entt::any any{};
556 any.emplace<void>();
557
558 ASSERT_FALSE(any);
559 ASSERT_TRUE(any.owner());
560 ASSERT_FALSE(any.type());
561 }
562
TEST_F(Any,Reset)563 TEST_F(Any, Reset) {
564 entt::any any{42};
565
566 ASSERT_TRUE(any);
567 ASSERT_TRUE(any.owner());
568 ASSERT_EQ(any.type(), entt::type_id<int>());
569
570 any.reset();
571
572 ASSERT_FALSE(any);
573 ASSERT_TRUE(any.owner());
574 ASSERT_EQ(any.type(), entt::type_info{});
575
576 int value = 42;
577 any.emplace<int &>(value);
578
579 ASSERT_TRUE(any);
580 ASSERT_FALSE(any.owner());
581 ASSERT_EQ(any.type(), entt::type_id<int>());
582
583 any.reset();
584
585 ASSERT_FALSE(any);
586 ASSERT_TRUE(any.owner());
587 ASSERT_EQ(any.type(), entt::type_info{});
588 }
589
TEST_F(Any,SBOSwap)590 TEST_F(Any, SBOSwap) {
591 entt::any lhs{'c'};
592 entt::any rhs{42};
593
594 std::swap(lhs, rhs);
595
596 ASSERT_TRUE(lhs.owner());
597 ASSERT_TRUE(rhs.owner());
598
599 ASSERT_EQ(lhs.type(), entt::type_id<int>());
600 ASSERT_EQ(rhs.type(), entt::type_id<char>());
601 ASSERT_EQ(entt::any_cast<char>(&lhs), nullptr);
602 ASSERT_EQ(entt::any_cast<int>(&rhs), nullptr);
603 ASSERT_EQ(entt::any_cast<int>(lhs), 42);
604 ASSERT_EQ(entt::any_cast<char>(rhs), 'c');
605 }
606
TEST_F(Any,NoSBOSwap)607 TEST_F(Any, NoSBOSwap) {
608 entt::any lhs{fat{.1, .2, .3, .4}};
609 entt::any rhs{fat{.4, .3, .2, .1}};
610
611 std::swap(lhs, rhs);
612
613 ASSERT_TRUE(lhs.owner());
614 ASSERT_TRUE(rhs.owner());
615
616 ASSERT_EQ(entt::any_cast<fat>(lhs), (fat{.4, .3, .2, .1}));
617 ASSERT_EQ(entt::any_cast<fat>(rhs), (fat{.1, .2, .3, .4}));
618 }
619
TEST_F(Any,VoidSwap)620 TEST_F(Any, VoidSwap) {
621 entt::any lhs{std::in_place_type<void>};
622 entt::any rhs{std::in_place_type<void>};
623 const auto *pre = lhs.data();
624
625 std::swap(lhs, rhs);
626
627 ASSERT_TRUE(lhs.owner());
628 ASSERT_TRUE(rhs.owner());
629
630 ASSERT_EQ(pre, lhs.data());
631 }
632
TEST_F(Any,SBOWithNoSBOSwap)633 TEST_F(Any, SBOWithNoSBOSwap) {
634 entt::any lhs{fat{.1, .2, .3, .4}};
635 entt::any rhs{'c'};
636
637 std::swap(lhs, rhs);
638
639 ASSERT_TRUE(lhs.owner());
640 ASSERT_TRUE(rhs.owner());
641
642 ASSERT_EQ(lhs.type(), entt::type_id<char>());
643 ASSERT_EQ(rhs.type(), entt::type_id<fat>());
644 ASSERT_EQ(entt::any_cast<fat>(&lhs), nullptr);
645 ASSERT_EQ(entt::any_cast<char>(&rhs), nullptr);
646 ASSERT_EQ(entt::any_cast<char>(lhs), 'c');
647 ASSERT_EQ(entt::any_cast<fat>(rhs), (fat{.1, .2, .3, .4}));
648 }
649
TEST_F(Any,SBOWithRefSwap)650 TEST_F(Any, SBOWithRefSwap) {
651 int value = 3;
652 entt::any lhs{entt::forward_as_any(value)};
653 entt::any rhs{'c'};
654
655 std::swap(lhs, rhs);
656
657 ASSERT_TRUE(lhs.owner());
658 ASSERT_FALSE(rhs.owner());
659
660 ASSERT_EQ(lhs.type(), entt::type_id<char>());
661 ASSERT_EQ(rhs.type(), entt::type_id<int>());
662 ASSERT_EQ(entt::any_cast<int>(&lhs), nullptr);
663 ASSERT_EQ(entt::any_cast<char>(&rhs), nullptr);
664 ASSERT_EQ(entt::any_cast<char>(lhs), 'c');
665 ASSERT_EQ(entt::any_cast<int>(rhs), 3);
666 ASSERT_EQ(rhs.data(), &value);
667 }
668
TEST_F(Any,SBOWithConstRefSwap)669 TEST_F(Any, SBOWithConstRefSwap) {
670 const int value = 3;
671 entt::any lhs{entt::forward_as_any(value)};
672 entt::any rhs{'c'};
673
674 std::swap(lhs, rhs);
675
676 ASSERT_TRUE(lhs.owner());
677 ASSERT_FALSE(rhs.owner());
678
679 ASSERT_EQ(lhs.type(), entt::type_id<char>());
680 ASSERT_EQ(rhs.type(), entt::type_id<int>());
681 ASSERT_EQ(entt::any_cast<int>(&lhs), nullptr);
682 ASSERT_EQ(entt::any_cast<char>(&rhs), nullptr);
683 ASSERT_EQ(entt::any_cast<char>(lhs), 'c');
684 ASSERT_EQ(entt::any_cast<int>(rhs), 3);
685 ASSERT_EQ(rhs.data(), nullptr);
686 ASSERT_EQ(std::as_const(rhs).data(), &value);
687 }
688
TEST_F(Any,SBOWithEmptySwap)689 TEST_F(Any, SBOWithEmptySwap) {
690 entt::any lhs{'c'};
691 entt::any rhs{};
692
693 std::swap(lhs, rhs);
694
695 ASSERT_FALSE(lhs);
696 ASSERT_TRUE(lhs.owner());
697 ASSERT_EQ(rhs.type(), entt::type_id<char>());
698 ASSERT_EQ(entt::any_cast<char>(&lhs), nullptr);
699 ASSERT_EQ(entt::any_cast<double>(&rhs), nullptr);
700 ASSERT_EQ(entt::any_cast<char>(rhs), 'c');
701
702 std::swap(lhs, rhs);
703
704 ASSERT_FALSE(rhs);
705 ASSERT_TRUE(rhs.owner());
706 ASSERT_EQ(lhs.type(), entt::type_id<char>());
707 ASSERT_EQ(entt::any_cast<double>(&lhs), nullptr);
708 ASSERT_EQ(entt::any_cast<char>(&rhs), nullptr);
709 ASSERT_EQ(entt::any_cast<char>(lhs), 'c');
710 }
711
TEST_F(Any,SBOWithVoidSwap)712 TEST_F(Any, SBOWithVoidSwap) {
713 entt::any lhs{'c'};
714 entt::any rhs{std::in_place_type<void>};
715
716 std::swap(lhs, rhs);
717
718 ASSERT_FALSE(lhs);
719 ASSERT_TRUE(lhs.owner());
720 ASSERT_EQ(rhs.type(), entt::type_id<char>());
721 ASSERT_EQ(entt::any_cast<char>(&lhs), nullptr);
722 ASSERT_EQ(entt::any_cast<double>(&rhs), nullptr);
723 ASSERT_EQ(entt::any_cast<char>(rhs), 'c');
724
725 std::swap(lhs, rhs);
726
727 ASSERT_FALSE(rhs);
728 ASSERT_TRUE(rhs.owner());
729 ASSERT_EQ(lhs.type(), entt::type_id<char>());
730 ASSERT_EQ(entt::any_cast<double>(&lhs), nullptr);
731 ASSERT_EQ(entt::any_cast<char>(&rhs), nullptr);
732 ASSERT_EQ(entt::any_cast<char>(lhs), 'c');
733 }
734
TEST_F(Any,NoSBOWithRefSwap)735 TEST_F(Any, NoSBOWithRefSwap) {
736 int value = 3;
737 entt::any lhs{entt::forward_as_any(value)};
738 entt::any rhs{fat{.1, .2, .3, .4}};
739
740 std::swap(lhs, rhs);
741
742 ASSERT_TRUE(lhs.owner());
743 ASSERT_FALSE(rhs.owner());
744
745 ASSERT_EQ(lhs.type(), entt::type_id<fat>());
746 ASSERT_EQ(rhs.type(), entt::type_id<int>());
747 ASSERT_EQ(entt::any_cast<int>(&lhs), nullptr);
748 ASSERT_EQ(entt::any_cast<fat>(&rhs), nullptr);
749 ASSERT_EQ(entt::any_cast<fat>(lhs), (fat{.1, .2, .3, .4}));
750 ASSERT_EQ(entt::any_cast<int>(rhs), 3);
751 ASSERT_EQ(rhs.data(), &value);
752 }
753
TEST_F(Any,NoSBOWithConstRefSwap)754 TEST_F(Any, NoSBOWithConstRefSwap) {
755 const int value = 3;
756 entt::any lhs{entt::forward_as_any(value)};
757 entt::any rhs{fat{.1, .2, .3, .4}};
758
759 std::swap(lhs, rhs);
760
761 ASSERT_TRUE(lhs.owner());
762 ASSERT_FALSE(rhs.owner());
763
764 ASSERT_EQ(lhs.type(), entt::type_id<fat>());
765 ASSERT_EQ(rhs.type(), entt::type_id<int>());
766 ASSERT_EQ(entt::any_cast<int>(&lhs), nullptr);
767 ASSERT_EQ(entt::any_cast<fat>(&rhs), nullptr);
768 ASSERT_EQ(entt::any_cast<fat>(lhs), (fat{.1, .2, .3, .4}));
769 ASSERT_EQ(entt::any_cast<int>(rhs), 3);
770 ASSERT_EQ(rhs.data(), nullptr);
771 ASSERT_EQ(std::as_const(rhs).data(), &value);
772 }
773
TEST_F(Any,NoSBOWithEmptySwap)774 TEST_F(Any, NoSBOWithEmptySwap) {
775 entt::any lhs{fat{.1, .2, .3, .4}};
776 entt::any rhs{};
777
778 std::swap(lhs, rhs);
779
780 ASSERT_FALSE(lhs);
781 ASSERT_TRUE(lhs.owner());
782 ASSERT_EQ(rhs.type(), entt::type_id<fat>());
783 ASSERT_EQ(entt::any_cast<fat>(&lhs), nullptr);
784 ASSERT_EQ(entt::any_cast<double>(&rhs), nullptr);
785 ASSERT_EQ(entt::any_cast<fat>(rhs), (fat{.1, .2, .3, .4}));
786
787 std::swap(lhs, rhs);
788
789 ASSERT_FALSE(rhs);
790 ASSERT_TRUE(rhs.owner());
791 ASSERT_EQ(lhs.type(), entt::type_id<fat>());
792 ASSERT_EQ(entt::any_cast<double>(&lhs), nullptr);
793 ASSERT_EQ(entt::any_cast<fat>(&rhs), nullptr);
794 ASSERT_EQ(entt::any_cast<fat>(lhs), (fat{.1, .2, .3, .4}));
795 }
796
TEST_F(Any,NoSBOWithVoidSwap)797 TEST_F(Any, NoSBOWithVoidSwap) {
798 entt::any lhs{fat{.1, .2, .3, .4}};
799 entt::any rhs{std::in_place_type<void>};
800
801 std::swap(lhs, rhs);
802
803 ASSERT_FALSE(lhs);
804 ASSERT_TRUE(lhs.owner());
805 ASSERT_EQ(rhs.type(), entt::type_id<fat>());
806 ASSERT_EQ(entt::any_cast<fat>(&lhs), nullptr);
807 ASSERT_EQ(entt::any_cast<double>(&rhs), nullptr);
808 ASSERT_EQ(entt::any_cast<fat>(rhs), (fat{.1, .2, .3, .4}));
809
810 std::swap(lhs, rhs);
811
812 ASSERT_FALSE(rhs);
813 ASSERT_TRUE(rhs.owner());
814 ASSERT_EQ(lhs.type(), entt::type_id<fat>());
815 ASSERT_EQ(entt::any_cast<double>(&lhs), nullptr);
816 ASSERT_EQ(entt::any_cast<fat>(&rhs), nullptr);
817 ASSERT_EQ(entt::any_cast<fat>(lhs), (fat{.1, .2, .3, .4}));
818 }
819
TEST_F(Any,AsRef)820 TEST_F(Any, AsRef) {
821 entt::any any{42};
822 auto ref = any.as_ref();
823 auto cref = std::as_const(any).as_ref();
824
825 ASSERT_FALSE(ref.owner());
826 ASSERT_FALSE(cref.owner());
827
828 ASSERT_EQ(entt::any_cast<int>(&any), any.data());
829 ASSERT_EQ(entt::any_cast<int>(&ref), any.data());
830 ASSERT_EQ(entt::any_cast<int>(&cref), nullptr);
831
832 ASSERT_EQ(entt::any_cast<const int>(&any), any.data());
833 ASSERT_EQ(entt::any_cast<const int>(&ref), any.data());
834 ASSERT_EQ(entt::any_cast<const int>(&cref), any.data());
835
836 ASSERT_EQ(entt::any_cast<int>(any), 42);
837 ASSERT_EQ(entt::any_cast<int>(ref), 42);
838 ASSERT_EQ(entt::any_cast<int>(cref), 42);
839
840 ASSERT_EQ(entt::any_cast<const int>(any), 42);
841 ASSERT_EQ(entt::any_cast<const int>(ref), 42);
842 ASSERT_EQ(entt::any_cast<const int>(cref), 42);
843
844 ASSERT_EQ(entt::any_cast<int &>(any), 42);
845 ASSERT_EQ(entt::any_cast<const int &>(any), 42);
846 ASSERT_EQ(entt::any_cast<int &>(ref), 42);
847 ASSERT_EQ(entt::any_cast<const int &>(ref), 42);
848 ASSERT_EQ(entt::any_cast<int>(&cref), nullptr);
849 ASSERT_EQ(entt::any_cast<const int &>(cref), 42);
850
851 entt::any_cast<int &>(any) = 3;
852
853 ASSERT_EQ(entt::any_cast<int>(any), 3);
854 ASSERT_EQ(entt::any_cast<int>(ref), 3);
855 ASSERT_EQ(entt::any_cast<int>(cref), 3);
856
857 std::swap(ref, cref);
858
859 ASSERT_FALSE(ref.owner());
860 ASSERT_FALSE(cref.owner());
861
862 ASSERT_EQ(entt::any_cast<int>(&ref), nullptr);
863 ASSERT_EQ(entt::any_cast<int>(&cref), any.data());
864
865 ref = ref.as_ref();
866 cref = std::as_const(cref).as_ref();
867
868 ASSERT_FALSE(ref.owner());
869 ASSERT_FALSE(cref.owner());
870
871 ASSERT_EQ(entt::any_cast<int>(&ref), nullptr);
872 ASSERT_EQ(entt::any_cast<int>(&cref), nullptr);
873 ASSERT_EQ(entt::any_cast<const int>(&ref), any.data());
874 ASSERT_EQ(entt::any_cast<const int>(&cref), any.data());
875
876 ASSERT_EQ(entt::any_cast<int>(&ref), nullptr);
877 ASSERT_EQ(entt::any_cast<int>(&cref), nullptr);
878
879 ASSERT_EQ(entt::any_cast<const int &>(ref), 3);
880 ASSERT_EQ(entt::any_cast<const int &>(cref), 3);
881
882 ref = 42;
883 cref = 42;
884
885 ASSERT_TRUE(ref.owner());
886 ASSERT_TRUE(cref.owner());
887
888 ASSERT_NE(entt::any_cast<int>(&ref), nullptr);
889 ASSERT_NE(entt::any_cast<int>(&cref), nullptr);
890 ASSERT_EQ(entt::any_cast<int &>(ref), 42);
891 ASSERT_EQ(entt::any_cast<int &>(cref), 42);
892 ASSERT_EQ(entt::any_cast<const int &>(ref), 42);
893 ASSERT_EQ(entt::any_cast<const int &>(cref), 42);
894 ASSERT_NE(entt::any_cast<int>(&ref), any.data());
895 ASSERT_NE(entt::any_cast<int>(&cref), any.data());
896 }
897
TEST_F(Any,Comparable)898 TEST_F(Any, Comparable) {
899 auto test = [](entt::any any, entt::any other) {
900 ASSERT_EQ(any, any);
901 ASSERT_NE(other, any);
902 ASSERT_NE(any, entt::any{});
903
904 ASSERT_TRUE(any == any);
905 ASSERT_FALSE(other == any);
906 ASSERT_TRUE(any != other);
907 ASSERT_TRUE(entt::any{} != any);
908 };
909
910 int value = 42;
911
912 test('c', 'a');
913 test(fat{.1, .2, .3, .4}, fat{.0, .1, .2, .3});
914 test(entt::forward_as_any(value), 3);
915 test(3, entt::make_any<const int &>(value));
916 }
917
TEST_F(Any,NotComparable)918 TEST_F(Any, NotComparable) {
919 auto test = [](const auto &instance) {
920 auto any = entt::forward_as_any(instance);
921
922 ASSERT_EQ(any, any);
923 ASSERT_NE(any, entt::any{instance});
924 ASSERT_NE(entt::any{}, any);
925
926 ASSERT_TRUE(any == any);
927 ASSERT_FALSE(any == entt::any{instance});
928 ASSERT_TRUE(entt::any{} != any);
929 };
930
931 test(not_comparable{});
932 test(std::unordered_map<int, not_comparable>{});
933 test(std::vector<not_comparable>{});
934 }
935
TEST_F(Any,CompareVoid)936 TEST_F(Any, CompareVoid) {
937 entt::any any{std::in_place_type<void>};
938
939 ASSERT_EQ(any, any);
940 ASSERT_EQ(any, entt::any{std::in_place_type<void>});
941 ASSERT_NE(entt::any{'a'}, any);
942 ASSERT_EQ(any, entt::any{});
943
944 ASSERT_TRUE(any == any);
945 ASSERT_TRUE(any == entt::any{std::in_place_type<void>});
946 ASSERT_FALSE(entt::any{'a'} == any);
947 ASSERT_TRUE(any != entt::any{'a'});
948 ASSERT_FALSE(entt::any{} != any);
949 }
950
TEST_F(Any,AnyCast)951 TEST_F(Any, AnyCast) {
952 entt::any any{42};
953 const auto &cany = any;
954
955 ASSERT_EQ(entt::any_cast<char>(&any), nullptr);
956 ASSERT_EQ(entt::any_cast<char>(&cany), nullptr);
957 ASSERT_EQ(*entt::any_cast<int>(&any), 42);
958 ASSERT_EQ(*entt::any_cast<int>(&cany), 42);
959 ASSERT_EQ(entt::any_cast<int &>(any), 42);
960 ASSERT_DEATH(entt::any_cast<double &>(any), "");
961 ASSERT_EQ(entt::any_cast<const int &>(cany), 42);
962 ASSERT_DEATH(entt::any_cast<const double &>(cany), "");
963 ASSERT_EQ(entt::any_cast<int>(entt::any{42}), 42);
964 ASSERT_DEATH(entt::any_cast<double>(entt::any{42}), "");
965 }
966
TEST_F(Any,MakeAny)967 TEST_F(Any, MakeAny) {
968 int value = 42;
969 auto any = entt::make_any<int>(value);
970 auto ext = entt::make_any<int, sizeof(int), alignof(int)>(value);
971 auto ref = entt::make_any<int &>(value);
972
973 ASSERT_TRUE(any);
974 ASSERT_TRUE(ext);
975 ASSERT_TRUE(ref);
976
977 ASSERT_TRUE(any.owner());
978 ASSERT_TRUE(ext.owner());
979 ASSERT_FALSE(ref.owner());
980
981 ASSERT_EQ(entt::any_cast<const int &>(any), 42);
982 ASSERT_EQ(entt::any_cast<const int &>(ext), 42);
983 ASSERT_EQ(entt::any_cast<const int &>(ref), 42);
984
985 ASSERT_EQ(decltype(any)::length, entt::any::length);
986 ASSERT_NE(decltype(ext)::length, entt::any::length);
987 ASSERT_EQ(decltype(ref)::length, entt::any::length);
988
989 ASSERT_NE(any.data(), &value);
990 ASSERT_NE(ext.data(), &value);
991 ASSERT_EQ(ref.data(), &value);
992 }
993
TEST_F(Any,ForwardAsAny)994 TEST_F(Any, ForwardAsAny) {
995 int value = 42;
996 auto any = entt::forward_as_any(std::move(value));
997 auto ref = entt::forward_as_any(value);
998 auto cref = entt::forward_as_any(std::as_const(value));
999
1000 ASSERT_TRUE(any);
1001 ASSERT_TRUE(ref);
1002 ASSERT_TRUE(cref);
1003
1004 ASSERT_TRUE(any.owner());
1005 ASSERT_FALSE(ref.owner());
1006 ASSERT_FALSE(cref.owner());
1007
1008 ASSERT_NE(entt::any_cast<int>(&any), nullptr);
1009 ASSERT_NE(entt::any_cast<int>(&ref), nullptr);
1010 ASSERT_EQ(entt::any_cast<int>(&cref), nullptr);
1011
1012 ASSERT_EQ(entt::any_cast<const int &>(any), 42);
1013 ASSERT_EQ(entt::any_cast<const int &>(ref), 42);
1014 ASSERT_EQ(entt::any_cast<const int &>(cref), 42);
1015
1016 ASSERT_NE(any.data(), &value);
1017 ASSERT_EQ(ref.data(), &value);
1018 }
1019
TEST_F(Any,NotCopyableType)1020 TEST_F(Any, NotCopyableType) {
1021 auto test = [](entt::any any) {
1022 entt::any copy{any};
1023
1024 ASSERT_TRUE(any);
1025 ASSERT_FALSE(copy);
1026
1027 ASSERT_TRUE(any.owner());
1028 ASSERT_TRUE(copy.owner());
1029
1030 copy = any;
1031
1032 ASSERT_TRUE(any);
1033 ASSERT_FALSE(copy);
1034
1035 ASSERT_TRUE(any.owner());
1036 ASSERT_TRUE(copy.owner());
1037 };
1038
1039 test(entt::any{std::in_place_type<not_copyable<1>>});
1040 test(entt::any{std::in_place_type<not_copyable<4>>});
1041 }
1042
TEST_F(Any,Array)1043 TEST_F(Any, Array) {
1044 entt::any any{std::in_place_type<int[1]>};
1045 entt::any copy{any};
1046
1047 ASSERT_TRUE(any);
1048 ASSERT_FALSE(copy);
1049
1050 ASSERT_EQ(any.type(), entt::type_id<int[1]>());
1051 ASSERT_NE(entt::any_cast<int[1]>(&any), nullptr);
1052 ASSERT_EQ(entt::any_cast<int[2]>(&any), nullptr);
1053 ASSERT_EQ(entt::any_cast<int *>(&any), nullptr);
1054
1055 entt::any_cast<int(&)[1]>(any)[0] = 42;
1056
1057 ASSERT_EQ(entt::any_cast<const int(&)[1]>(std::as_const(any))[0], 42);
1058 }
1059
TEST_F(Any,CopyMoveReference)1060 TEST_F(Any, CopyMoveReference) {
1061 int value{};
1062
1063 auto test = [&](auto &&ref) {
1064 value = 3;
1065
1066 auto any = entt::forward_as_any(ref);
1067 entt::any move = std::move(any);
1068 entt::any copy = move;
1069
1070 ASSERT_FALSE(any);
1071 ASSERT_TRUE(move);
1072 ASSERT_TRUE(copy);
1073
1074 ASSERT_FALSE(any.owner());
1075 ASSERT_FALSE(move.owner());
1076 ASSERT_TRUE(copy.owner());
1077
1078 ASSERT_EQ(move.type(), entt::type_id<int>());
1079 ASSERT_EQ(copy.type(), entt::type_id<int>());
1080
1081 ASSERT_EQ(std::as_const(move).data(), &value);
1082 ASSERT_NE(std::as_const(copy).data(), &value);
1083
1084 ASSERT_EQ(entt::any_cast<int>(move), 3);
1085 ASSERT_EQ(entt::any_cast<int>(copy), 3);
1086
1087 value = 42;
1088
1089 ASSERT_EQ(entt::any_cast<const int &>(move), 42);
1090 ASSERT_EQ(entt::any_cast<const int &>(copy), 3);
1091 };
1092
1093 test(value);
1094 test(std::as_const(value));
1095 }
1096
TEST_F(Any,SBOVsZeroedSBOSize)1097 TEST_F(Any, SBOVsZeroedSBOSize) {
1098 entt::any sbo{42};
1099 const auto *broken = sbo.data();
1100 entt::any other = std::move(sbo);
1101
1102 ASSERT_NE(broken, other.data());
1103
1104 entt::basic_any<0u> dyn{42};
1105 const auto *valid = dyn.data();
1106 entt::basic_any<0u> same = std::move(dyn);
1107
1108 ASSERT_EQ(valid, same.data());
1109 }
1110
TEST_F(Any,Alignment)1111 TEST_F(Any, Alignment) {
1112 static constexpr auto alignment = alignof(over_aligned);
1113
1114 auto test = [](auto *target, auto cb) {
1115 const auto *data = target[0].data();
1116
1117 ASSERT_TRUE((reinterpret_cast<std::uintptr_t>(target[0u].data()) % alignment) == 0u);
1118 ASSERT_TRUE((reinterpret_cast<std::uintptr_t>(target[1u].data()) % alignment) == 0u);
1119
1120 std::swap(target[0], target[1]);
1121
1122 ASSERT_TRUE((reinterpret_cast<std::uintptr_t>(target[0u].data()) % alignment) == 0u);
1123 ASSERT_TRUE((reinterpret_cast<std::uintptr_t>(target[1u].data()) % alignment) == 0u);
1124
1125 cb(data, target[1].data());
1126 };
1127
1128 entt::basic_any<alignment> nosbo[2] = { over_aligned{}, over_aligned{} };
1129 test(nosbo, [](auto *pre, auto *post) { ASSERT_EQ(pre, post); });
1130
1131 entt::basic_any<alignment, alignment> sbo[2] = { over_aligned{}, over_aligned{} };
1132 test(sbo, [](auto *pre, auto *post) { ASSERT_NE(pre, post); });
1133 }
1134
TEST_F(Any,AggregatesMustWork)1135 TEST_F(Any, AggregatesMustWork) {
1136 struct aggregate_type { int value; };
1137 // the goal of this test is to enforce the requirements for aggregate types
1138 entt::any{std::in_place_type<aggregate_type>, 42}.emplace<aggregate_type>(42);
1139 }
1140
TEST_F(Any,DeducedArrayType)1141 TEST_F(Any, DeducedArrayType) {
1142 entt::any any{"array of char"};
1143
1144 ASSERT_TRUE(any);
1145 ASSERT_EQ(any.type(), entt::type_id<const char *>());
1146 ASSERT_EQ((strcmp("array of char", entt::any_cast<const char *>(any))), 0);
1147
1148 any = "another array of char";
1149
1150 ASSERT_TRUE(any);
1151 ASSERT_EQ(any.type(), entt::type_id<const char *>());
1152 ASSERT_EQ((strcmp("another array of char", entt::any_cast<const char *>(any))), 0);
1153 }
1154