#include #include #include #include #include #include struct fat { double value[4]; inline static int counter = 0; ~fat() { ++counter; } bool operator==(const fat &other) const { return std::equal(std::begin(value), std::end(value), std::begin(other.value), std::end(other.value)); } }; struct empty { inline static int counter = 0; ~empty() { ++counter; } }; struct not_comparable { bool operator==(const not_comparable &) const = delete; }; TEST(Any, SBO) { entt::any any{'c'}; ASSERT_TRUE(any); ASSERT_EQ(any.type(), entt::type_id()); ASSERT_EQ(entt::any_cast(&any), nullptr); ASSERT_EQ(entt::any_cast(any), 'c'); } TEST(Any, NoSBO) { fat instance{{.1, .2, .3, .4}}; entt::any any{instance}; ASSERT_TRUE(any); ASSERT_EQ(any.type(), entt::type_id()); ASSERT_EQ(entt::any_cast(&any), nullptr); ASSERT_EQ(entt::any_cast(any), instance); } TEST(Any, Empty) { entt::any any{}; ASSERT_FALSE(any); ASSERT_FALSE(any.type()); ASSERT_EQ(entt::any_cast(&any), nullptr); ASSERT_EQ(any.data(), nullptr); } TEST(Any, SBOInPlaceTypeConstruction) { entt::any any{std::in_place_type, 42}; ASSERT_TRUE(any); ASSERT_EQ(any.type(), entt::type_id()); ASSERT_EQ(entt::any_cast(&any), nullptr); ASSERT_EQ(entt::any_cast(any), 42); auto other = as_ref(any); ASSERT_TRUE(other); ASSERT_EQ(other.type(), entt::type_id()); ASSERT_EQ(entt::any_cast(other), 42); ASSERT_EQ(other.data(), any.data()); } TEST(Any, SBOAsRefConstruction) { int value = 42; entt::any any{std::ref(value)}; ASSERT_TRUE(any); ASSERT_EQ(any.type(), entt::type_id()); ASSERT_EQ(entt::any_cast(&any), nullptr); ASSERT_EQ(entt::any_cast(&any), &value); ASSERT_EQ(entt::any_cast(&any), &value); ASSERT_EQ(entt::any_cast(&std::as_const(any)), &value); ASSERT_EQ(entt::any_cast(&std::as_const(any)), &value); ASSERT_EQ(entt::any_cast(any), 42); ASSERT_EQ(entt::any_cast(any), 42); ASSERT_EQ(any.data(), &value); ASSERT_EQ(std::as_const(any).data(), &value); auto other = as_ref(any); ASSERT_TRUE(other); ASSERT_EQ(other.type(), entt::type_id()); ASSERT_EQ(entt::any_cast(other), 42); ASSERT_EQ(other.data(), any.data()); } TEST(Any, SBOAsConstRefConstruction) { int value = 42; entt::any any{std::cref(value)}; ASSERT_TRUE(any); ASSERT_EQ(any.type(), entt::type_id()); ASSERT_EQ(entt::any_cast(&any), nullptr); ASSERT_EQ(entt::any_cast(&any), &value); ASSERT_EQ(entt::any_cast(&any), nullptr); ASSERT_EQ(entt::any_cast(&std::as_const(any)), &value); ASSERT_EQ(entt::any_cast(&std::as_const(any)), &value); ASSERT_EQ(entt::any_cast(any), 42); ASSERT_EQ(entt::any_cast(any), 42); ASSERT_EQ(any.data(), nullptr); ASSERT_EQ(std::as_const(any).data(), &value); auto other = as_ref(any); ASSERT_TRUE(other); ASSERT_EQ(other.type(), entt::type_id()); ASSERT_EQ(entt::any_cast(other), 42); ASSERT_EQ(other.data(), any.data()); } TEST(Any, SBOCopyConstruction) { entt::any any{42}; entt::any other{any}; ASSERT_TRUE(any); ASSERT_TRUE(other); ASSERT_EQ(any.type(), entt::type_id()); ASSERT_EQ(other.type(), entt::type_id()); ASSERT_EQ(entt::any_cast(&other), nullptr); ASSERT_EQ(entt::any_cast(other), 42); } TEST(Any, SBOCopyAssignment) { entt::any any{42}; entt::any other{3}; other = any; ASSERT_TRUE(any); ASSERT_TRUE(other); ASSERT_EQ(any.type(), entt::type_id()); ASSERT_EQ(other.type(), entt::type_id()); ASSERT_EQ(entt::any_cast(&other), nullptr); ASSERT_EQ(entt::any_cast(other), 42); } TEST(Any, SBOMoveConstruction) { entt::any any{42}; entt::any other{std::move(any)}; ASSERT_FALSE(any); ASSERT_TRUE(other); ASSERT_FALSE(any.type()); ASSERT_EQ(other.type(), entt::type_id()); ASSERT_EQ(entt::any_cast(&other), nullptr); ASSERT_EQ(entt::any_cast(other), 42); } TEST(Any, SBOMoveAssignment) { entt::any any{42}; entt::any other{3}; other = std::move(any); ASSERT_FALSE(any); ASSERT_TRUE(other); ASSERT_FALSE(any.type()); ASSERT_EQ(other.type(), entt::type_id()); ASSERT_EQ(entt::any_cast(&other), nullptr); ASSERT_EQ(entt::any_cast(other), 42); } TEST(Any, SBODirectAssignment) { entt::any any{}; any = 42; ASSERT_TRUE(any); ASSERT_EQ(any.type(), entt::type_id()); ASSERT_EQ(entt::any_cast(&any), nullptr); ASSERT_EQ(entt::any_cast(any), 42); } TEST(Any, NoSBOInPlaceTypeConstruction) { fat instance{{.1, .2, .3, .4}}; entt::any any{std::in_place_type, instance}; ASSERT_TRUE(any); ASSERT_EQ(any.type(), entt::type_id()); ASSERT_EQ(entt::any_cast(&any), nullptr); ASSERT_EQ(entt::any_cast(any), instance); auto other = as_ref(any); ASSERT_TRUE(other); ASSERT_EQ(other.type(), entt::type_id()); ASSERT_EQ(entt::any_cast(other), (fat{{.1, .2, .3, .4}})); ASSERT_EQ(other.data(), any.data()); } TEST(Any, NoSBOAsRefConstruction) { fat instance{{.1, .2, .3, .4}}; entt::any any{std::ref(instance)}; ASSERT_TRUE(any); ASSERT_EQ(any.type(), entt::type_id()); ASSERT_EQ(entt::any_cast(&any), nullptr); ASSERT_EQ(entt::any_cast(&any), &instance); ASSERT_EQ(entt::any_cast(&any), &instance); ASSERT_EQ(entt::any_cast(&std::as_const(any)), &instance); ASSERT_EQ(entt::any_cast(&std::as_const(any)), &instance); ASSERT_EQ(entt::any_cast(any), instance); ASSERT_EQ(entt::any_cast(any), instance); ASSERT_EQ(any.data(), &instance); ASSERT_EQ(std::as_const(any).data(), &instance); auto other = as_ref(any); ASSERT_TRUE(other); ASSERT_EQ(other.type(), entt::type_id()); ASSERT_EQ(entt::any_cast(other), (fat{{.1, .2, .3, .4}})); ASSERT_EQ(other.data(), any.data()); } TEST(Any, NoSBOAsConstRefConstruction) { fat instance{{.1, .2, .3, .4}}; entt::any any{std::cref(instance)}; ASSERT_TRUE(any); ASSERT_EQ(any.type(), entt::type_id()); ASSERT_EQ(entt::any_cast(&any), nullptr); ASSERT_EQ(entt::any_cast(&any), &instance); ASSERT_EQ(entt::any_cast(&any), nullptr); ASSERT_EQ(entt::any_cast(&std::as_const(any)), &instance); ASSERT_EQ(entt::any_cast(&std::as_const(any)), &instance); ASSERT_EQ(entt::any_cast(any), instance); ASSERT_EQ(entt::any_cast(any), instance); ASSERT_EQ(any.data(), nullptr); ASSERT_EQ(std::as_const(any).data(), &instance); auto other = as_ref(any); ASSERT_TRUE(other); ASSERT_EQ(other.type(), entt::type_id()); ASSERT_EQ(entt::any_cast(other), (fat{{.1, .2, .3, .4}})); ASSERT_EQ(other.data(), any.data()); } TEST(Any, NoSBOCopyConstruction) { fat instance{{.1, .2, .3, .4}}; entt::any any{instance}; entt::any other{any}; ASSERT_TRUE(any); ASSERT_TRUE(other); ASSERT_EQ(any.type(), entt::type_id()); ASSERT_EQ(other.type(), entt::type_id()); ASSERT_EQ(entt::any_cast(&other), nullptr); ASSERT_EQ(entt::any_cast(other), instance); } TEST(Any, NoSBOCopyAssignment) { fat instance{{.1, .2, .3, .4}}; entt::any any{instance}; entt::any other{3}; other = any; ASSERT_TRUE(any); ASSERT_TRUE(other); ASSERT_EQ(any.type(), entt::type_id()); ASSERT_EQ(other.type(), entt::type_id()); ASSERT_EQ(entt::any_cast(&other), nullptr); ASSERT_EQ(entt::any_cast(other), instance); } TEST(Any, NoSBOMoveConstruction) { fat instance{{.1, .2, .3, .4}}; entt::any any{instance}; entt::any other{std::move(any)}; ASSERT_FALSE(any); ASSERT_TRUE(other); ASSERT_EQ(other.type(), entt::type_id()); ASSERT_EQ(entt::any_cast(&other), nullptr); ASSERT_EQ(entt::any_cast(other), instance); } TEST(Any, NoSBOMoveAssignment) { fat instance{{.1, .2, .3, .4}}; entt::any any{instance}; entt::any other{3}; other = std::move(any); ASSERT_FALSE(any); ASSERT_TRUE(other); ASSERT_EQ(other.type(), entt::type_id()); ASSERT_EQ(entt::any_cast(&other), nullptr); ASSERT_EQ(entt::any_cast(other), instance); } TEST(Any, NoSBODirectAssignment) { fat instance{{.1, .2, .3, .4}}; entt::any any{}; any = instance; ASSERT_TRUE(any); ASSERT_EQ(any.type(), entt::type_id()); ASSERT_EQ(entt::any_cast(&any), nullptr); ASSERT_EQ(entt::any_cast(any), instance); } TEST(Any, VoidInPlaceTypeConstruction) { entt::any any{std::in_place_type}; ASSERT_FALSE(any); ASSERT_FALSE(any.type()); ASSERT_EQ(entt::any_cast(&any), nullptr); } TEST(Any, VoidCopyConstruction) { entt::any any{std::in_place_type}; entt::any other{any}; ASSERT_FALSE(any); ASSERT_FALSE(other); ASSERT_FALSE(any.type()); ASSERT_FALSE(other.type()); ASSERT_EQ(entt::any_cast(&any), nullptr); ASSERT_EQ(entt::any_cast(&other), nullptr); } TEST(Any, VoidCopyAssignment) { entt::any any{std::in_place_type}; entt::any other{std::in_place_type}; other = any; ASSERT_FALSE(any); ASSERT_FALSE(other); ASSERT_FALSE(any.type()); ASSERT_FALSE(other.type()); ASSERT_EQ(entt::any_cast(&any), nullptr); ASSERT_EQ(entt::any_cast(&other), nullptr); } TEST(Any, VoidMoveConstruction) { entt::any any{std::in_place_type}; entt::any other{std::move(any)}; ASSERT_FALSE(any); ASSERT_FALSE(other); ASSERT_FALSE(any.type()); ASSERT_FALSE(other.type()); ASSERT_EQ(entt::any_cast(&any), nullptr); ASSERT_EQ(entt::any_cast(&other), nullptr); } TEST(Any, VoidMoveAssignment) { entt::any any{std::in_place_type}; entt::any other{std::in_place_type}; other = std::move(any); ASSERT_FALSE(any); ASSERT_FALSE(other); ASSERT_FALSE(any.type()); ASSERT_FALSE(other.type()); ASSERT_EQ(entt::any_cast(&any), nullptr); ASSERT_EQ(entt::any_cast(&other), nullptr); } TEST(Any, SBOMoveInvalidate) { entt::any any{42}; entt::any other{std::move(any)}; entt::any valid = std::move(other); ASSERT_FALSE(any); ASSERT_FALSE(other); ASSERT_TRUE(valid); } TEST(Any, NoSBOMoveInvalidate) { fat instance{{.1, .2, .3, .4}}; entt::any any{instance}; entt::any other{std::move(any)}; entt::any valid = std::move(other); ASSERT_FALSE(any); ASSERT_FALSE(other); ASSERT_TRUE(valid); } TEST(Any, VoidMoveInvalidate) { entt::any any{std::in_place_type}; entt::any other{std::move(any)}; entt::any valid = std::move(other); ASSERT_FALSE(any); ASSERT_FALSE(other); ASSERT_FALSE(valid); } TEST(Any, SBODestruction) { { entt::any any{empty{}}; empty::counter = 0; } ASSERT_EQ(empty::counter, 1); } TEST(Any, NoSBODestruction) { { entt::any any{fat{}}; fat::counter = 0; } ASSERT_EQ(fat::counter, 1); } TEST(Any, VoidDestruction) { // just let asan tell us if everything is ok here [[maybe_unused]] entt::any any{std::in_place_type}; } TEST(Any, Emplace) { entt::any any{}; any.emplace(42); ASSERT_TRUE(any); ASSERT_EQ(any.type(), entt::type_id()); ASSERT_EQ(entt::any_cast(&any), nullptr); ASSERT_EQ(entt::any_cast(any), 42); } TEST(Any, EmplaceVoid) { entt::any any{}; any.emplace(); ASSERT_FALSE(any); ASSERT_FALSE(any.type()); } TEST(Any, SBOSwap) { entt::any lhs{'c'}; entt::any rhs{42}; std::swap(lhs, rhs); ASSERT_EQ(lhs.type(), entt::type_id()); ASSERT_EQ(rhs.type(), entt::type_id()); ASSERT_EQ(entt::any_cast(&lhs), nullptr); ASSERT_EQ(entt::any_cast(&rhs), nullptr); ASSERT_EQ(entt::any_cast(lhs), 42); ASSERT_EQ(entt::any_cast(rhs), 'c'); } TEST(Any, NoSBOSwap) { entt::any lhs{fat{{.1, .2, .3, .4}}}; entt::any rhs{fat{{.4, .3, .2, .1}}}; std::swap(lhs, rhs); ASSERT_EQ(entt::any_cast(lhs), (fat{{.4, .3, .2, .1}})); ASSERT_EQ(entt::any_cast(rhs), (fat{{.1, .2, .3, .4}})); } TEST(Any, VoidSwap) { entt::any lhs{std::in_place_type}; entt::any rhs{std::in_place_type}; const auto *pre = lhs.data(); std::swap(lhs, rhs); ASSERT_EQ(pre, lhs.data()); } TEST(Any, SBOWithNoSBOSwap) { entt::any lhs{fat{{.1, .2, .3, .4}}}; entt::any rhs{'c'}; std::swap(lhs, rhs); ASSERT_EQ(lhs.type(), entt::type_id()); ASSERT_EQ(rhs.type(), entt::type_id()); ASSERT_EQ(entt::any_cast(&lhs), nullptr); ASSERT_EQ(entt::any_cast(&rhs), nullptr); ASSERT_EQ(entt::any_cast(lhs), 'c'); ASSERT_EQ(entt::any_cast(rhs), (fat{{.1, .2, .3, .4}})); } TEST(Any, SBOWithRefSwap) { int value = 3; entt::any lhs{std::ref(value)}; entt::any rhs{'c'}; std::swap(lhs, rhs); ASSERT_EQ(lhs.type(), entt::type_id()); ASSERT_EQ(rhs.type(), entt::type_id()); ASSERT_EQ(entt::any_cast(&lhs), nullptr); ASSERT_EQ(entt::any_cast(&rhs), nullptr); ASSERT_EQ(entt::any_cast(lhs), 'c'); ASSERT_EQ(entt::any_cast(rhs), 3); ASSERT_EQ(rhs.data(), &value); } TEST(Any, SBOWithConstRefSwap) { int value = 3; entt::any lhs{std::cref(value)}; entt::any rhs{'c'}; std::swap(lhs, rhs); ASSERT_EQ(lhs.type(), entt::type_id()); ASSERT_EQ(rhs.type(), entt::type_id()); ASSERT_EQ(entt::any_cast(&lhs), nullptr); ASSERT_EQ(entt::any_cast(&rhs), nullptr); ASSERT_EQ(entt::any_cast(lhs), 'c'); ASSERT_EQ(entt::any_cast(rhs), 3); ASSERT_EQ(rhs.data(), nullptr); ASSERT_EQ(std::as_const(rhs).data(), &value); } TEST(Any, SBOWithEmptySwap) { entt::any lhs{'c'}; entt::any rhs{}; std::swap(lhs, rhs); ASSERT_FALSE(lhs); ASSERT_EQ(rhs.type(), entt::type_id()); ASSERT_EQ(entt::any_cast(&lhs), nullptr); ASSERT_EQ(entt::any_cast(&rhs), nullptr); ASSERT_EQ(entt::any_cast(rhs), 'c'); std::swap(lhs, rhs); ASSERT_FALSE(rhs); ASSERT_EQ(lhs.type(), entt::type_id()); ASSERT_EQ(entt::any_cast(&lhs), nullptr); ASSERT_EQ(entt::any_cast(&rhs), nullptr); ASSERT_EQ(entt::any_cast(lhs), 'c'); } TEST(Any, SBOWithVoidSwap) { entt::any lhs{'c'}; entt::any rhs{std::in_place_type}; std::swap(lhs, rhs); ASSERT_FALSE(lhs); ASSERT_EQ(rhs.type(), entt::type_id()); ASSERT_EQ(entt::any_cast(&lhs), nullptr); ASSERT_EQ(entt::any_cast(&rhs), nullptr); ASSERT_EQ(entt::any_cast(rhs), 'c'); std::swap(lhs, rhs); ASSERT_FALSE(rhs); ASSERT_EQ(lhs.type(), entt::type_id()); ASSERT_EQ(entt::any_cast(&lhs), nullptr); ASSERT_EQ(entt::any_cast(&rhs), nullptr); ASSERT_EQ(entt::any_cast(lhs), 'c'); } TEST(Any, NoSBOWithRefSwap) { int value = 3; entt::any lhs{std::ref(value)}; entt::any rhs{fat{{.1, .2, .3, .4}}}; std::swap(lhs, rhs); ASSERT_EQ(lhs.type(), entt::type_id()); ASSERT_EQ(rhs.type(), entt::type_id()); ASSERT_EQ(entt::any_cast(&lhs), nullptr); ASSERT_EQ(entt::any_cast(&rhs), nullptr); ASSERT_EQ(entt::any_cast(lhs), (fat{{.1, .2, .3, .4}})); ASSERT_EQ(entt::any_cast(rhs), 3); ASSERT_EQ(rhs.data(), &value); } TEST(Any, NoSBOWithConstRefSwap) { int value = 3; entt::any lhs{std::cref(value)}; entt::any rhs{fat{{.1, .2, .3, .4}}}; std::swap(lhs, rhs); ASSERT_EQ(lhs.type(), entt::type_id()); ASSERT_EQ(rhs.type(), entt::type_id()); ASSERT_EQ(entt::any_cast(&lhs), nullptr); ASSERT_EQ(entt::any_cast(&rhs), nullptr); ASSERT_EQ(entt::any_cast(lhs), (fat{{.1, .2, .3, .4}})); ASSERT_EQ(entt::any_cast(rhs), 3); ASSERT_EQ(rhs.data(), nullptr); ASSERT_EQ(std::as_const(rhs).data(), &value); } TEST(Any, NoSBOWithEmptySwap) { entt::any lhs{fat{{.1, .2, .3, .4}}}; entt::any rhs{}; std::swap(lhs, rhs); ASSERT_FALSE(lhs); ASSERT_EQ(rhs.type(), entt::type_id()); ASSERT_EQ(entt::any_cast(&lhs), nullptr); ASSERT_EQ(entt::any_cast(&rhs), nullptr); ASSERT_EQ(entt::any_cast(rhs), (fat{{.1, .2, .3, .4}})); std::swap(lhs, rhs); ASSERT_FALSE(rhs); ASSERT_EQ(lhs.type(), entt::type_id()); ASSERT_EQ(entt::any_cast(&lhs), nullptr); ASSERT_EQ(entt::any_cast(&rhs), nullptr); ASSERT_EQ(entt::any_cast(lhs), (fat{{.1, .2, .3, .4}})); } TEST(Any, NoSBOWithVoidSwap) { entt::any lhs{fat{{.1, .2, .3, .4}}}; entt::any rhs{std::in_place_type}; std::swap(lhs, rhs); ASSERT_FALSE(lhs); ASSERT_EQ(rhs.type(), entt::type_id()); ASSERT_EQ(entt::any_cast(&lhs), nullptr); ASSERT_EQ(entt::any_cast(&rhs), nullptr); ASSERT_EQ(entt::any_cast(rhs), (fat{{.1, .2, .3, .4}})); std::swap(lhs, rhs); ASSERT_FALSE(rhs); ASSERT_EQ(lhs.type(), entt::type_id()); ASSERT_EQ(entt::any_cast(&lhs), nullptr); ASSERT_EQ(entt::any_cast(&rhs), nullptr); ASSERT_EQ(entt::any_cast(lhs), (fat{{.1, .2, .3, .4}})); } TEST(Any, AsRef) { entt::any any{42}; auto ref = as_ref(any); auto cref = as_ref(std::as_const(any)); ASSERT_EQ(entt::any_cast(&any), any.data()); ASSERT_EQ(entt::any_cast(&ref), any.data()); ASSERT_EQ(entt::any_cast(&cref), nullptr); ASSERT_EQ(entt::any_cast(&any), any.data()); ASSERT_EQ(entt::any_cast(&ref), any.data()); ASSERT_EQ(entt::any_cast(&cref), any.data()); ASSERT_EQ(entt::any_cast(any), 42); ASSERT_EQ(entt::any_cast(ref), 42); ASSERT_EQ(entt::any_cast(cref), 42); ASSERT_EQ(entt::any_cast(any), 42); ASSERT_EQ(entt::any_cast(ref), 42); ASSERT_EQ(entt::any_cast(cref), 42); ASSERT_EQ(entt::any_cast(any), 42); ASSERT_EQ(entt::any_cast(any), 42); ASSERT_EQ(entt::any_cast(ref), 42); ASSERT_EQ(entt::any_cast(ref), 42); ASSERT_DEATH(entt::any_cast(cref), ".*"); ASSERT_EQ(entt::any_cast(cref), 42); entt::any_cast(any) = 3; ASSERT_EQ(entt::any_cast(any), 3); ASSERT_EQ(entt::any_cast(ref), 3); ASSERT_EQ(entt::any_cast(cref), 3); std::swap(ref, cref); ASSERT_EQ(entt::any_cast(&ref), nullptr); ASSERT_EQ(entt::any_cast(&cref), any.data()); ref = as_ref(ref); cref = as_ref(std::as_const(cref)); ASSERT_EQ(entt::any_cast(&ref), nullptr); ASSERT_EQ(entt::any_cast(&cref), nullptr); ASSERT_EQ(entt::any_cast(&ref), any.data()); ASSERT_EQ(entt::any_cast(&cref), any.data()); ASSERT_DEATH(entt::any_cast(ref), ".*"); ASSERT_DEATH(entt::any_cast(cref), ".*"); ASSERT_EQ(entt::any_cast(ref), 3); ASSERT_EQ(entt::any_cast(cref), 3); ref = 42; cref = 42; ASSERT_NE(entt::any_cast(&ref), nullptr); ASSERT_NE(entt::any_cast(&cref), nullptr); ASSERT_EQ(entt::any_cast(ref), 42); ASSERT_EQ(entt::any_cast(cref), 42); ASSERT_EQ(entt::any_cast(ref), 42); ASSERT_EQ(entt::any_cast(cref), 42); ASSERT_NE(entt::any_cast(&ref), any.data()); ASSERT_NE(entt::any_cast(&cref), any.data()); } TEST(Any, Comparable) { auto test = [](entt::any any, entt::any other) { ASSERT_EQ(any, any); ASSERT_NE(other, any); ASSERT_NE(any, entt::any{}); ASSERT_TRUE(any == any); ASSERT_FALSE(other == any); ASSERT_TRUE(any != other); ASSERT_TRUE(entt::any{} != any); }; int value = 42; test('c', 'a'); test(fat{{.1, .2, .3, .4}}, fat{{.0, .1, .2, .3}}); test(std::ref(value), 3); test(3, std::cref(value)); } TEST(Any, NotComparable) { auto test = [](const auto &instance) { entt::any any{std::cref(instance)}; ASSERT_EQ(any, any); ASSERT_NE(any, entt::any{instance}); ASSERT_NE(entt::any{}, any); ASSERT_TRUE(any == any); ASSERT_FALSE(any == entt::any{instance}); ASSERT_TRUE(entt::any{} != any); }; test(not_comparable{}); test(std::unordered_map{}); test(std::vector{}); } TEST(Any, CompareVoid) { entt::any any{std::in_place_type}; ASSERT_EQ(any, any); ASSERT_EQ(any, entt::any{std::in_place_type}); ASSERT_NE(entt::any{'a'}, any); ASSERT_EQ(any, entt::any{}); ASSERT_TRUE(any == any); ASSERT_TRUE(any == entt::any{std::in_place_type}); ASSERT_FALSE(entt::any{'a'} == any); ASSERT_TRUE(any != entt::any{'a'}); ASSERT_FALSE(entt::any{} != any); } TEST(Any, AnyCast) { entt::any any{42}; const auto &cany = any; ASSERT_EQ(entt::any_cast(&any), nullptr); ASSERT_EQ(entt::any_cast(&cany), nullptr); ASSERT_EQ(*entt::any_cast(&any), 42); ASSERT_EQ(*entt::any_cast(&cany), 42); ASSERT_EQ(entt::any_cast(any), 42); ASSERT_EQ(entt::any_cast(cany), 42); ASSERT_EQ(entt::any_cast(42), 42); } TEST(Any, NonCopyableType) { entt::any any{std::in_place_type>, new int{42}}; entt::any copy{any}; ASSERT_TRUE(any); ASSERT_FALSE(copy); copy = any; ASSERT_TRUE(any); ASSERT_FALSE(copy); }