From 1b6d0dbd26f068c1fbd7c72168485ce1ed51cc1e Mon Sep 17 00:00:00 2001 From: Ricardo Antunes Date: Sat, 7 Oct 2023 00:17:20 +0100 Subject: [PATCH] refactor(reflection): Constructible has* --- .../core/reflection/traits/constructible.hpp | 24 +++++++--- .../reflection/traits/constructible/main.cpp | 2 +- .../reflection/traits/constructible/page.md | 8 ---- .../core/reflection/traits/constructible.cpp | 46 +++++++++---------- .../tests/reflection/traits/constructible.cpp | 15 +++--- .../tests/reflection/traits/constructible.hpp | 9 ++-- 6 files changed, 57 insertions(+), 47 deletions(-) diff --git a/core/include/cubos/core/reflection/traits/constructible.hpp b/core/include/cubos/core/reflection/traits/constructible.hpp index a269bf1fe..abf494744 100644 --- a/core/include/cubos/core/reflection/traits/constructible.hpp +++ b/core/include/cubos/core/reflection/traits/constructible.hpp @@ -83,26 +83,38 @@ namespace cubos::core::reflection /// @return Alignment of the type in bytes. std::size_t alignment() const; + /// @brief Checks if default construction is supported. + /// @return Whether the operation is supported. + bool hasDefaultConstruct() const; + + /// @brief Checks if copy construction is supported. + /// @return Whether the operation is supported. + bool hasCopyConstruct() const; + + /// @brief Checks if move construction is supported. + /// @return Whether the operation is supported. + bool hasMoveConstruct() const; + /// @brief Destructs an instance of the type. /// @param instance Pointer to the instance to destruct. void destruct(void* instance) const; /// @brief Default constructs an instance of the type. + /// @note Aborts if @ref hasDefaultConstruct() returns false. /// @param instance Pointer to the location to construct the instance at. - /// @return Whether default construction is supported. - bool defaultConstruct(void* instance) const; + void defaultConstruct(void* instance) const; /// @brief Copy constructs an instance of the type. + /// @note Aborts if @ref hasCopyConstruct() returns false. /// @param instance Pointer to the location to construct the instance at. /// @param other Pointer to the instance to copy construct from. - /// @return Whether copy construction is supported. - bool copyConstruct(void* instance, const void* other) const; + void copyConstruct(void* instance, const void* other) const; /// @brief Move constructs an instance of the type. + /// @note Aborts if @ref hasMoveConstruct() returns false. /// @param instance Pointer to the location to construct the instance at. /// @param other Pointer to the instance to move construct from. - /// @return Whether move construction is supported. - bool moveConstruct(void* instance, void* other) const; + void moveConstruct(void* instance, void* other) const; private: std::size_t mSize; diff --git a/core/samples/reflection/traits/constructible/main.cpp b/core/samples/reflection/traits/constructible/main.cpp index 4e6780f33..bd7c1d482 100644 --- a/core/samples/reflection/traits/constructible/main.cpp +++ b/core/samples/reflection/traits/constructible/main.cpp @@ -36,7 +36,7 @@ int main() /// [Creating a default instance] // Allocate memory for the instance and default-construct it. void* instance = operator new(constructible.size()); - CUBOS_ASSERT(constructible.defaultConstruct(instance)); + constructible.defaultConstruct(instance); CUBOS_ASSERT(static_cast(instance)->value == 1.0F); /// [Creating a default instance] diff --git a/core/samples/reflection/traits/constructible/page.md b/core/samples/reflection/traits/constructible/page.md index 31b223701..a44e2f531 100644 --- a/core/samples/reflection/traits/constructible/page.md +++ b/core/samples/reflection/traits/constructible/page.md @@ -29,14 +29,6 @@ constructor stored in the trait: @snippet reflection/traits/constructible/main.cpp Creating a default instance -The @ref cubos::core::reflection::ConstructibleTrait::defaultConstruct -"defaultConstruct" method returns a boolean which indicates if the type has a -default constructor or not. In this case, since we added the default -constructor to the trait, it will return `true`. - -This could be useful, for example, to fallback from using `moveConstruct` to -`copyConstruct`, if the first isn't available. - Don't forget to destroy the instance manually when you're done with it: @snippet reflection/traits/constructible/main.cpp Destroying the instance diff --git a/core/src/cubos/core/reflection/traits/constructible.cpp b/core/src/cubos/core/reflection/traits/constructible.cpp index dbb136366..1fff81022 100644 --- a/core/src/cubos/core/reflection/traits/constructible.cpp +++ b/core/src/cubos/core/reflection/traits/constructible.cpp @@ -45,40 +45,40 @@ std::size_t ConstructibleTrait::alignment() const return mAlignment; } -void ConstructibleTrait::destruct(void* instance) const +bool ConstructibleTrait::hasDefaultConstruct() const { - mDestructor(instance); + return mDefaultConstructor != nullptr; } -bool ConstructibleTrait::defaultConstruct(void* instance) const +bool ConstructibleTrait::hasCopyConstruct() const { - if (mDefaultConstructor != nullptr) - { - mDefaultConstructor(instance); - return true; - } + return mCopyConstructor != nullptr; +} - return false; +bool ConstructibleTrait::hasMoveConstruct() const +{ + return mMoveConstructor != nullptr; } -bool ConstructibleTrait::copyConstruct(void* instance, const void* other) const +void ConstructibleTrait::destruct(void* instance) const { - if (mCopyConstructor != nullptr) - { - mCopyConstructor(instance, other); - return true; - } + mDestructor(instance); +} - return false; +void ConstructibleTrait::defaultConstruct(void* instance) const +{ + CUBOS_ASSERT(this->hasDefaultConstruct()); + mDefaultConstructor(instance); } -bool ConstructibleTrait::moveConstruct(void* instance, void* other) const +void ConstructibleTrait::copyConstruct(void* instance, const void* other) const { - if (mMoveConstructor != nullptr) - { - mMoveConstructor(instance, other); - return true; - } + CUBOS_ASSERT(this->hasCopyConstruct()); + mCopyConstructor(instance, other); +} - return false; +void ConstructibleTrait::moveConstruct(void* instance, void* other) const +{ + CUBOS_ASSERT(this->hasMoveConstruct()); + mMoveConstructor(instance, other); } diff --git a/core/tests/reflection/traits/constructible.cpp b/core/tests/reflection/traits/constructible.cpp index 22e048501..d70a1da1c 100644 --- a/core/tests/reflection/traits/constructible.cpp +++ b/core/tests/reflection/traits/constructible.cpp @@ -49,9 +49,9 @@ TEST_CASE("reflection::ConstructibleTrait") auto trait = ConstructibleTrait::typed().build(); DetectDestructor detector{}; - CHECK_FALSE(trait.defaultConstruct(ptr)); - CHECK_FALSE(trait.copyConstruct(ptr, &detector)); - CHECK_FALSE(trait.moveConstruct(ptr, &detector)); + CHECK_FALSE(trait.hasDefaultConstruct()); + CHECK_FALSE(trait.hasCopyConstruct()); + CHECK_FALSE(trait.hasMoveConstruct()); operator delete(ptr); } @@ -61,7 +61,8 @@ TEST_CASE("reflection::ConstructibleTrait") auto* ptr = operator new(sizeof(SimpleConstructible)); auto trait = ConstructibleTrait::typed().withDefaultConstructor().build(); - REQUIRE(trait.defaultConstruct(ptr)); + REQUIRE(trait.hasDefaultConstruct()); + trait.defaultConstruct(ptr); auto* simple = static_cast(ptr); CHECK(simple->value == SimpleConstructible::DEFAULT); @@ -77,7 +78,8 @@ TEST_CASE("reflection::ConstructibleTrait") auto trait = ConstructibleTrait::typed().withCopyConstructor().build(); SimpleConstructible copied{}; copied.value = 1; - REQUIRE(trait.copyConstruct(ptr, &copied)); + REQUIRE(trait.hasCopyConstruct()); + trait.copyConstruct(ptr, &copied); auto* simple = static_cast(ptr); CHECK(simple->value == copied.value); @@ -97,7 +99,8 @@ TEST_CASE("reflection::ConstructibleTrait") // the flag is not set when 'moved' is destructed. { DetectDestructor moved{&destroyed}; - REQUIRE(trait.moveConstruct(ptr, &moved)); + REQUIRE(trait.hasMoveConstruct()); + trait.moveConstruct(ptr, &moved); REQUIRE_FALSE(destroyed); } diff --git a/core/tests/reflection/traits/constructible.hpp b/core/tests/reflection/traits/constructible.hpp index 52419aaec..b0eac4b42 100644 --- a/core/tests/reflection/traits/constructible.hpp +++ b/core/tests/reflection/traits/constructible.hpp @@ -35,7 +35,8 @@ static void testDefaultConstructible() auto& constructible = type.get(); auto* instance = operator new(constructible.size()); - REQUIRE(constructible.defaultConstruct(instance)); + REQUIRE(constructible.hasDefaultConstruct()); + constructible.defaultConstruct(instance); if constexpr (std::equality_comparable) { @@ -57,7 +58,8 @@ static void testCopyConstructible(const T& valueToCopy) auto& constructible = type.get(); auto* instance = operator new(constructible.size()); - REQUIRE(constructible.copyConstruct(instance, &valueToCopy)); + REQUIRE(constructible.hasCopyConstruct()); + constructible.copyConstruct(instance, &valueToCopy); if constexpr (std::equality_comparable) { @@ -79,7 +81,8 @@ static void testMoveConstructible(T& valueToMove) auto& constructible = type.get(); auto* instance = operator new(constructible.size()); - REQUIRE(constructible.moveConstruct(instance, &valueToMove)); + REQUIRE(constructible.hasMoveConstruct()); + constructible.moveConstruct(instance, &valueToMove); constructible.destruct(instance); operator delete(instance);