From e4897f709ebc66fa4dcbec8b671286b9dab43ea7 Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Sat, 29 Jan 2022 10:51:25 +0100 Subject: [PATCH] test: merge poly tests in a single file, use typed tests to reduce the boilerplate --- test/CMakeLists.txt | 3 +- test/entt/poly/{poly_defined.cpp => poly.cpp} | 170 +++++++--- test/entt/poly/poly_deduced.cpp | 295 ------------------ 3 files changed, 129 insertions(+), 339 deletions(-) rename test/entt/poly/{poly_defined.cpp => poly.cpp} (55%) delete mode 100644 test/entt/poly/poly_deduced.cpp diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index ca5f154ab..401bb3729 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -223,8 +223,7 @@ SETUP_BASIC_TEST(meta_utility entt/meta/meta_utility.cpp) # Test poly -SETUP_BASIC_TEST(poly_deduced entt/poly/poly_deduced.cpp) -SETUP_BASIC_TEST(poly_defined entt/poly/poly_defined.cpp) +SETUP_BASIC_TEST(poly entt/poly/poly.cpp) # Test process diff --git a/test/entt/poly/poly_defined.cpp b/test/entt/poly/poly.cpp similarity index 55% rename from test/entt/poly/poly_defined.cpp rename to test/entt/poly/poly.cpp index 344250fb4..7ee55856f 100644 --- a/test/entt/poly/poly_defined.cpp +++ b/test/entt/poly/poly.cpp @@ -4,6 +4,51 @@ #include #include +struct Deduced + : entt::type_list<> { + template + struct type: Base { + void incr() { + entt::poly_call<0>(*this); + } + + void set(int v) { + entt::poly_call<1>(*this, v); + } + + int get() const { + return entt::poly_call<2>(*this); + } + + void decr() { + entt::poly_call<3>(*this); + } + + int mul(int v) const { + return static_cast(entt::poly_call<4>(*this, v)); + } + }; + + template + struct members { + static void decr(Type &self) { + self.set(self.get() - 1); + } + + static double mul(const Type &self, double v) { + return v * self.get(); + } + }; + + template + using impl = entt::value_list< + &Type::incr, + &Type::set, + &Type::get, + &members::decr, + &members::mul>; +}; + struct Defined : entt::type_list< void(), @@ -83,15 +128,35 @@ struct impl { int value{}; }; -struct alignas(64u) over_aligned: impl {}; +template +struct Poly: testing::Test { + using basic = entt::poly; + using zeroed = entt::basic_poly; + + struct alignas(64u) over_aligned: impl {}; + static constexpr auto alignment = alignof(over_aligned); + + static inline entt::basic_poly sbo[2] = {over_aligned{}, over_aligned{}}; + static inline entt::basic_poly nosbo[2] = {over_aligned{}, over_aligned{}}; +}; + +template +using PolyDeathTest = Poly; + +using PolyTypes = ::testing::Types; + +TYPED_TEST_SUITE(Poly, PolyTypes); +TYPED_TEST_SUITE(PolyDeathTest, PolyTypes); + +TYPED_TEST(Poly, Functionalities) { + using poly_type = typename TestFixture::basic; -TEST(PolyDefined, Functionalities) { impl instance{}; - entt::poly empty{}; - entt::poly in_place{std::in_place_type, 3}; - entt::poly alias{std::in_place_type, instance}; - entt::poly value{impl{}}; + poly_type empty{}; + poly_type in_place{std::in_place_type, 3}; + poly_type alias{std::in_place_type, instance}; + poly_type value{impl{}}; ASSERT_FALSE(empty); ASSERT_TRUE(in_place); @@ -119,7 +184,7 @@ TEST(PolyDefined, Functionalities) { ASSERT_TRUE(empty); ASSERT_EQ(empty->get(), 3); - entt::poly ref = in_place.as_ref(); + poly_type ref = in_place.as_ref(); ASSERT_TRUE(ref); ASSERT_NE(ref.data(), nullptr); @@ -128,17 +193,17 @@ TEST(PolyDefined, Functionalities) { ASSERT_EQ(ref.type(), entt::type_id()); ASSERT_EQ(ref->get(), 3); - entt::poly null{}; + poly_type null{}; std::swap(empty, null); ASSERT_FALSE(empty); - entt::poly copy = in_place; + poly_type copy = in_place; ASSERT_TRUE(copy); ASSERT_EQ(copy->get(), 3); - entt::poly move = std::move(copy); + poly_type move = std::move(copy); ASSERT_TRUE(move); ASSERT_TRUE(copy); @@ -150,8 +215,10 @@ TEST(PolyDefined, Functionalities) { ASSERT_EQ(move.type(), entt::type_id()); } -TEST(PolyDefined, Owned) { - entt::poly poly{impl{}}; +TYPED_TEST(Poly, Owned) { + using poly_type = typename TestFixture::basic; + + poly_type poly{impl{}}; auto *ptr = static_cast(poly.data()); ASSERT_TRUE(poly); @@ -174,9 +241,11 @@ TEST(PolyDefined, Owned) { ASSERT_EQ(poly->mul(3), 3); } -TEST(PolyDefined, Reference) { +TYPED_TEST(Poly, Reference) { + using poly_type = typename TestFixture::basic; + impl instance{}; - entt::poly poly{std::in_place_type, instance}; + poly_type poly{std::in_place_type, instance}; ASSERT_TRUE(poly); ASSERT_NE(poly.data(), nullptr); @@ -198,9 +267,11 @@ TEST(PolyDefined, Reference) { ASSERT_EQ(poly->mul(3), 3); } -TEST(PolyDefined, ConstReference) { +TYPED_TEST(Poly, ConstReference) { + using poly_type = typename TestFixture::basic; + impl instance{}; - entt::poly poly{std::in_place_type, instance}; + poly_type poly{std::in_place_type, instance}; ASSERT_TRUE(poly); ASSERT_EQ(poly.data(), nullptr); @@ -217,16 +288,20 @@ TEST(PolyDefined, ConstReference) { ASSERT_EQ(poly->mul(3), 0); } -TEST(PolyDefinedDeathTest, ConstReference) { +TYPED_TEST(PolyDeathTest, ConstReference) { + using poly_type = typename TestFixture::basic; + impl instance{}; - entt::poly poly{std::in_place_type, instance}; + poly_type poly{std::in_place_type, instance}; ASSERT_TRUE(poly); ASSERT_DEATH(poly->set(1), ""); } -TEST(PolyDefined, AsRef) { - entt::poly poly{impl{}}; +TYPED_TEST(Poly, AsRef) { + using poly_type = typename TestFixture::basic; + + poly_type poly{impl{}}; auto ref = poly.as_ref(); auto cref = std::as_const(poly).as_ref(); @@ -256,16 +331,19 @@ TEST(PolyDefined, AsRef) { ASSERT_NE(cref.data(), nullptr); } -TEST(PolyDefined, SBOVsZeroedSBOSize) { - entt::poly sbo{impl{}}; +TYPED_TEST(Poly, SBOVsZeroedSBOSize) { + using poly_type = typename TestFixture::basic; + using zeroed_type = typename TestFixture::zeroed; + + poly_type sbo{impl{}}; const auto broken = sbo.data(); - entt::poly other = std::move(sbo); + poly_type other = std::move(sbo); ASSERT_NE(broken, other.data()); - entt::basic_poly dyn{impl{}}; + zeroed_type dyn{impl{}}; const auto valid = dyn.data(); - entt::basic_poly same = std::move(dyn); + zeroed_type same = std::move(dyn); ASSERT_EQ(valid, same.data()); @@ -275,26 +353,34 @@ TEST(PolyDefined, SBOVsZeroedSBOSize) { ASSERT_EQ(same->get(), 1); } -TEST(PolyDefined, Alignment) { - static constexpr auto alignment = alignof(over_aligned); +TYPED_TEST(Poly, SboAlignment) { + using poly_type = typename TestFixture::basic; - auto test = [](auto *target, auto cb) { - const auto *data = target[0].data(); + const auto *data = TestFixture::sbo[0].data(); - ASSERT_TRUE((reinterpret_cast(target[0u].data()) % alignment) == 0u); - ASSERT_TRUE((reinterpret_cast(target[1u].data()) % alignment) == 0u); + ASSERT_TRUE((reinterpret_cast(TestFixture::sbo[0u].data()) % alignment) == 0u); + ASSERT_TRUE((reinterpret_cast(TestFixture::sbo[1u].data()) % alignment) == 0u); - std::swap(target[0], target[1]); + std::swap(TestFixture::sbo[0], TestFixture::sbo[1]); - ASSERT_TRUE((reinterpret_cast(target[0u].data()) % alignment) == 0u); - ASSERT_TRUE((reinterpret_cast(target[1u].data()) % alignment) == 0u); + ASSERT_TRUE((reinterpret_cast(TestFixture::sbo[0u].data()) % alignment) == 0u); + ASSERT_TRUE((reinterpret_cast(TestFixture::sbo[1u].data()) % alignment) == 0u); - cb(data, target[1].data()); - }; - - entt::basic_poly nosbo[2] = {over_aligned{}, over_aligned{}}; - test(nosbo, [](auto *pre, auto *post) { ASSERT_EQ(pre, post); }); - - entt::basic_poly sbo[2] = {over_aligned{}, over_aligned{}}; - test(sbo, [](auto *pre, auto *post) { ASSERT_NE(pre, post); }); + ASSERT_NE(data, TestFixture::sbo[1].data()); +} + +TYPED_TEST(Poly, NoSboAlignment) { + using poly_type = typename TestFixture::basic; + + const auto *data = TestFixture::nosbo[0].data(); + + ASSERT_TRUE((reinterpret_cast(TestFixture::nosbo[0u].data()) % alignment) == 0u); + ASSERT_TRUE((reinterpret_cast(TestFixture::nosbo[1u].data()) % alignment) == 0u); + + std::swap(TestFixture::nosbo[0], TestFixture::nosbo[1]); + + ASSERT_TRUE((reinterpret_cast(TestFixture::nosbo[0u].data()) % alignment) == 0u); + ASSERT_TRUE((reinterpret_cast(TestFixture::nosbo[1u].data()) % alignment) == 0u); + + ASSERT_EQ(data, TestFixture::nosbo[1].data()); } diff --git a/test/entt/poly/poly_deduced.cpp b/test/entt/poly/poly_deduced.cpp deleted file mode 100644 index df679b950..000000000 --- a/test/entt/poly/poly_deduced.cpp +++ /dev/null @@ -1,295 +0,0 @@ -#include -#include -#include -#include -#include - -struct Deduced - : entt::type_list<> { - template - struct type: Base { - void incr() { - entt::poly_call<0>(*this); - } - - void set(int v) { - entt::poly_call<1>(*this, v); - } - - int get() const { - return entt::poly_call<2>(*this); - } - - void decr() { - entt::poly_call<3>(*this); - } - - int mul(int v) const { - return static_cast(entt::poly_call<4>(*this, v)); - } - }; - - template - struct members { - static void decr(Type &self) { - self.set(self.get() - 1); - } - - static double mul(const Type &self, double v) { - return v * self.get(); - } - }; - - template - using impl = entt::value_list< - &Type::incr, - &Type::set, - &Type::get, - &members::decr, - &members::mul>; -}; - -struct impl { - impl() = default; - - impl(int v) - : value{v} {} - - void incr() { - ++value; - } - - void set(int v) { - value = v; - } - - int get() const { - return value; - } - - void decrement() { - --value; - } - - double multiply(double v) const { - return v * value; - } - - int value{}; -}; - -struct alignas(64u) over_aligned: impl {}; - -TEST(PolyDeduced, Functionalities) { - impl instance{}; - - entt::poly empty{}; - entt::poly in_place{std::in_place_type, 3}; - entt::poly alias{std::in_place_type, instance}; - entt::poly value{impl{}}; - - ASSERT_FALSE(empty); - ASSERT_TRUE(in_place); - ASSERT_TRUE(alias); - ASSERT_TRUE(value); - - ASSERT_EQ(empty.type(), entt::type_id()); - ASSERT_EQ(in_place.type(), entt::type_id()); - ASSERT_EQ(alias.type(), entt::type_id()); - ASSERT_EQ(value.type(), entt::type_id()); - - ASSERT_EQ(alias.data(), &instance); - ASSERT_EQ(std::as_const(alias).data(), &instance); - - empty = impl{}; - - ASSERT_TRUE(empty); - ASSERT_NE(empty.data(), nullptr); - ASSERT_NE(std::as_const(empty).data(), nullptr); - ASSERT_EQ(empty.type(), entt::type_id()); - ASSERT_EQ(empty->get(), 0); - - empty.template emplace(3); - - ASSERT_TRUE(empty); - ASSERT_EQ(empty->get(), 3); - - entt::poly ref = in_place.as_ref(); - - ASSERT_TRUE(ref); - ASSERT_NE(ref.data(), nullptr); - ASSERT_EQ(ref.data(), in_place.data()); - ASSERT_EQ(std::as_const(ref).data(), std::as_const(in_place).data()); - ASSERT_EQ(ref.type(), entt::type_id()); - ASSERT_EQ(ref->get(), 3); - - entt::poly null{}; - std::swap(empty, null); - - ASSERT_FALSE(empty); - - entt::poly copy = in_place; - - ASSERT_TRUE(copy); - ASSERT_EQ(copy->get(), 3); - - entt::poly move = std::move(copy); - - ASSERT_TRUE(move); - ASSERT_TRUE(copy); - ASSERT_EQ(move->get(), 3); - - move.reset(); - - ASSERT_FALSE(move); - ASSERT_EQ(move.type(), entt::type_id()); -} - -TEST(PolyDeduced, Owned) { - entt::poly poly{impl{}}; - auto *ptr = static_cast(poly.data()); - - ASSERT_TRUE(poly); - ASSERT_NE(poly.data(), nullptr); - ASSERT_NE(std::as_const(poly).data(), nullptr); - ASSERT_EQ(ptr->value, 0); - ASSERT_EQ(poly->get(), 0); - - poly->set(1); - poly->incr(); - - ASSERT_EQ(ptr->value, 2); - ASSERT_EQ(poly->get(), 2); - ASSERT_EQ(poly->mul(3), 6); - - poly->decr(); - - ASSERT_EQ(ptr->value, 1); - ASSERT_EQ(poly->get(), 1); - ASSERT_EQ(poly->mul(3), 3); -} - -TEST(PolyDeduced, Reference) { - impl instance{}; - entt::poly poly{std::in_place_type, instance}; - - ASSERT_TRUE(poly); - ASSERT_NE(poly.data(), nullptr); - ASSERT_NE(std::as_const(poly).data(), nullptr); - ASSERT_EQ(instance.value, 0); - ASSERT_EQ(poly->get(), 0); - - poly->set(1); - poly->incr(); - - ASSERT_EQ(instance.value, 2); - ASSERT_EQ(poly->get(), 2); - ASSERT_EQ(poly->mul(3), 6); - - poly->decr(); - - ASSERT_EQ(instance.value, 1); - ASSERT_EQ(poly->get(), 1); - ASSERT_EQ(poly->mul(3), 3); -} - -TEST(PolyDeduced, ConstReference) { - impl instance{}; - entt::poly poly{std::in_place_type, instance}; - - ASSERT_TRUE(poly); - ASSERT_EQ(poly.data(), nullptr); - ASSERT_NE(std::as_const(poly).data(), nullptr); - ASSERT_EQ(instance.value, 0); - ASSERT_EQ(poly->get(), 0); - - ASSERT_EQ(instance.value, 0); - ASSERT_EQ(poly->get(), 0); - ASSERT_EQ(poly->mul(3), 0); - - ASSERT_EQ(instance.value, 0); - ASSERT_EQ(poly->get(), 0); - ASSERT_EQ(poly->mul(3), 0); -} - -TEST(PolyDeducedDeathTest, ConstReference) { - impl instance{}; - entt::poly poly{std::in_place_type, instance}; - - ASSERT_TRUE(poly); - ASSERT_DEATH(poly->set(1), ""); -} - -TEST(PolyDeduced, AsRef) { - entt::poly poly{impl{}}; - auto ref = poly.as_ref(); - auto cref = std::as_const(poly).as_ref(); - - ASSERT_NE(poly.data(), nullptr); - ASSERT_NE(ref.data(), nullptr); - ASSERT_EQ(cref.data(), nullptr); - ASSERT_NE(std::as_const(cref).data(), nullptr); - - std::swap(ref, cref); - - ASSERT_EQ(ref.data(), nullptr); - ASSERT_NE(std::as_const(ref).data(), nullptr); - ASSERT_NE(cref.data(), nullptr); - - ref = ref.as_ref(); - cref = std::as_const(cref).as_ref(); - - ASSERT_EQ(ref.data(), nullptr); - ASSERT_NE(std::as_const(ref).data(), nullptr); - ASSERT_EQ(cref.data(), nullptr); - ASSERT_NE(std::as_const(cref).data(), nullptr); - - ref = impl{}; - cref = impl{}; - - ASSERT_NE(ref.data(), nullptr); - ASSERT_NE(cref.data(), nullptr); -} - -TEST(PolyDeduced, SBOVsZeroedSBOSize) { - entt::poly sbo{impl{}}; - const auto broken = sbo.data(); - entt::poly other = std::move(sbo); - - ASSERT_NE(broken, other.data()); - - entt::basic_poly dyn{impl{}}; - const auto valid = dyn.data(); - entt::basic_poly same = std::move(dyn); - - ASSERT_EQ(valid, same.data()); - - // everything works as expected - same->incr(); - - ASSERT_EQ(same->get(), 1); -} - -TEST(PolyDeduced, Alignment) { - static constexpr auto alignment = alignof(over_aligned); - - auto test = [](auto *target, auto cb) { - const auto *data = target[0].data(); - - ASSERT_TRUE((reinterpret_cast(target[0u].data()) % alignment) == 0u); - ASSERT_TRUE((reinterpret_cast(target[1u].data()) % alignment) == 0u); - - std::swap(target[0], target[1]); - - ASSERT_TRUE((reinterpret_cast(target[0u].data()) % alignment) == 0u); - ASSERT_TRUE((reinterpret_cast(target[1u].data()) % alignment) == 0u); - - cb(data, target[1].data()); - }; - - entt::basic_poly nosbo[2] = {over_aligned{}, over_aligned{}}; - test(nosbo, [](auto *pre, auto *post) { ASSERT_EQ(pre, post); }); - - entt::basic_poly sbo[2] = {over_aligned{}, over_aligned{}}; - test(sbo, [](auto *pre, auto *post) { ASSERT_NE(pre, post); }); -}