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