From fa68b6fb01b9fc9c7859ce078e098dc807cc00bd Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Tue, 7 Feb 2023 02:11:19 +0700 Subject: [PATCH] template is/as for any_type --- develop/singles/headers/meta.hpp/meta_all.hpp | 102 +++++++++++------- develop/untests/meta_types/any_type_tests.cpp | 8 ++ headers/meta.hpp/meta_types.hpp | 20 ++++ headers/meta.hpp/meta_types/any_type.hpp | 82 +++++++------- 4 files changed, 134 insertions(+), 78 deletions(-) diff --git a/develop/singles/headers/meta.hpp/meta_all.hpp b/develop/singles/headers/meta.hpp/meta_all.hpp index eda22ee..612c846 100644 --- a/develop/singles/headers/meta.hpp/meta_all.hpp +++ b/develop/singles/headers/meta.hpp/meta_all.hpp @@ -1998,6 +1998,7 @@ namespace meta_hpp using data_ptr = detail::type_data_base*; any_type() = default; + any_type(data_ptr data); [[nodiscard]] bool is_valid() const noexcept; [[nodiscard]] explicit operator bool() const noexcept; @@ -2021,6 +2022,12 @@ namespace meta_hpp any_type(const reference_type& other) noexcept; any_type(const void_type& other) noexcept; + template < detail::type_family Type > + [[nodiscard]] bool is() const noexcept; + + template < detail::type_family Type > + [[nodiscard]] Type as() const noexcept; + [[nodiscard]] bool is_array() const noexcept; [[nodiscard]] bool is_class() const noexcept; [[nodiscard]] bool is_constructor() const noexcept; @@ -2057,6 +2064,7 @@ namespace meta_hpp class array_type final { public: using data_ptr = detail::array_type_data*; + inline static constexpr type_kind kind{type_kind::array_}; array_type() = default; array_type(data_ptr data); @@ -2079,6 +2087,7 @@ namespace meta_hpp class class_type final { public: using data_ptr = detail::class_type_data*; + inline static constexpr type_kind kind{type_kind::class_}; class_type() = default; class_type(data_ptr data); @@ -2160,6 +2169,7 @@ namespace meta_hpp class constructor_type final { public: using data_ptr = detail::constructor_type_data*; + inline static constexpr type_kind kind{type_kind::constructor_}; constructor_type() = default; constructor_type(data_ptr data); @@ -2184,6 +2194,7 @@ namespace meta_hpp class destructor_type final { public: using data_ptr = detail::destructor_type_data*; + inline static constexpr type_kind kind{type_kind::destructor_}; destructor_type() = default; destructor_type(data_ptr data); @@ -2205,6 +2216,7 @@ namespace meta_hpp class enum_type final { public: using data_ptr = detail::enum_type_data*; + inline static constexpr type_kind kind{type_kind::enum_}; enum_type() = default; enum_type(data_ptr data); @@ -2237,6 +2249,7 @@ namespace meta_hpp class function_type final { public: using data_ptr = detail::function_type_data*; + inline static constexpr type_kind kind{type_kind::function_}; function_type() = default; function_type(data_ptr data); @@ -2261,6 +2274,7 @@ namespace meta_hpp class member_type final { public: using data_ptr = detail::member_type_data*; + inline static constexpr type_kind kind{type_kind::member_}; member_type() = default; member_type(data_ptr data); @@ -2283,6 +2297,7 @@ namespace meta_hpp class method_type final { public: using data_ptr = detail::method_type_data*; + inline static constexpr type_kind kind{type_kind::method_}; method_type() = default; method_type(data_ptr data); @@ -2308,6 +2323,7 @@ namespace meta_hpp class nullptr_type final { public: using data_ptr = detail::nullptr_type_data*; + inline static constexpr type_kind kind{type_kind::nullptr_}; nullptr_type() = default; nullptr_type(data_ptr data); @@ -2326,6 +2342,7 @@ namespace meta_hpp class number_type final { public: using data_ptr = detail::number_type_data*; + inline static constexpr type_kind kind{type_kind::number_}; number_type() = default; number_type(data_ptr data); @@ -2348,6 +2365,7 @@ namespace meta_hpp class pointer_type final { public: using data_ptr = detail::pointer_type_data*; + inline static constexpr type_kind kind{type_kind::pointer_}; pointer_type() = default; pointer_type(data_ptr data); @@ -2369,6 +2387,7 @@ namespace meta_hpp class reference_type final { public: using data_ptr = detail::reference_type_data*; + inline static constexpr type_kind kind{type_kind::reference_}; reference_type() = default; reference_type(data_ptr data); @@ -2390,6 +2409,7 @@ namespace meta_hpp class void_type final { public: using data_ptr = detail::void_type_data*; + inline static constexpr type_kind kind{type_kind::void_}; void_type() = default; void_type(data_ptr data); @@ -7698,6 +7718,9 @@ namespace meta_hpp namespace meta_hpp { + inline any_type::any_type(data_ptr data) + : data_{data} {} + inline bool any_type::is_valid() const noexcept { return data_ != nullptr; } @@ -7757,121 +7780,122 @@ namespace meta_hpp inline any_type::any_type(const void_type& other) noexcept : data_{detail::type_access(other)} {} + template < detail::type_family Type > + bool any_type::is() const noexcept { + if constexpr ( std::is_same_v ) { + return data_ != nullptr; + } else { + return data_ != nullptr && data_->kind == Type::kind; + } + } + + template < detail::type_family Type > + Type any_type::as() const noexcept { + return is() ? Type{static_cast(data_)} : Type{}; + } + inline bool any_type::is_array() const noexcept { - return is_valid() && data_->kind == type_kind::array_; + return is(); } inline bool any_type::is_class() const noexcept { - return is_valid() && data_->kind == type_kind::class_; + return is(); } inline bool any_type::is_constructor() const noexcept { - return is_valid() && data_->kind == type_kind::constructor_; + return is(); } inline bool any_type::is_destructor() const noexcept { - return is_valid() && data_->kind == type_kind::destructor_; + return is(); } inline bool any_type::is_enum() const noexcept { - return is_valid() && data_->kind == type_kind::enum_; + return is(); } inline bool any_type::is_function() const noexcept { - return is_valid() && data_->kind == type_kind::function_; + return is(); } inline bool any_type::is_member() const noexcept { - return is_valid() && data_->kind == type_kind::member_; + return is(); } inline bool any_type::is_method() const noexcept { - return is_valid() && data_->kind == type_kind::method_; + return is(); } inline bool any_type::is_nullptr() const noexcept { - return is_valid() && data_->kind == type_kind::nullptr_; + return is(); } inline bool any_type::is_number() const noexcept { - return is_valid() && data_->kind == type_kind::number_; + return is(); } inline bool any_type::is_pointer() const noexcept { - return is_valid() && data_->kind == type_kind::pointer_; + return is(); } inline bool any_type::is_reference() const noexcept { - return is_valid() && data_->kind == type_kind::reference_; + return is(); } inline bool any_type::is_void() const noexcept { - return is_valid() && data_->kind == type_kind::void_; + return is(); } inline array_type any_type::as_array() const noexcept { - // NOLINTNEXTLINE(*-static-cast-downcast) - return is_array() ? array_type{static_cast(data_)} : array_type{}; + return as(); } inline class_type any_type::as_class() const noexcept { - // NOLINTNEXTLINE(*-static-cast-downcast) - return is_class() ? class_type{static_cast(data_)} : class_type{}; + return as(); } inline constructor_type any_type::as_constructor() const noexcept { - // NOLINTNEXTLINE(*-static-cast-downcast) - return is_constructor() ? constructor_type{static_cast(data_)} : constructor_type{}; + return as(); } inline destructor_type any_type::as_destructor() const noexcept { - // NOLINTNEXTLINE(*-static-cast-downcast) - return is_destructor() ? destructor_type{static_cast(data_)} : destructor_type{}; + return as(); } inline enum_type any_type::as_enum() const noexcept { - // NOLINTNEXTLINE(*-static-cast-downcast) - return is_enum() ? enum_type{static_cast(data_)} : enum_type{}; + return as(); } inline function_type any_type::as_function() const noexcept { - // NOLINTNEXTLINE(*-static-cast-downcast) - return is_function() ? function_type{static_cast(data_)} : function_type{}; + return as(); } inline member_type any_type::as_member() const noexcept { - // NOLINTNEXTLINE(*-static-cast-downcast) - return is_member() ? member_type{static_cast(data_)} : member_type{}; + return as(); } inline method_type any_type::as_method() const noexcept { - // NOLINTNEXTLINE(*-static-cast-downcast) - return is_method() ? method_type{static_cast(data_)} : method_type{}; + return as(); } inline nullptr_type any_type::as_nullptr() const noexcept { - // NOLINTNEXTLINE(*-static-cast-downcast) - return is_nullptr() ? nullptr_type{static_cast(data_)} : nullptr_type{}; + return as(); } inline number_type any_type::as_number() const noexcept { - // NOLINTNEXTLINE(*-static-cast-downcast) - return is_number() ? number_type{static_cast(data_)} : number_type{}; + return as(); } inline pointer_type any_type::as_pointer() const noexcept { - // NOLINTNEXTLINE(*-static-cast-downcast) - return is_pointer() ? pointer_type{static_cast(data_)} : pointer_type{}; + return as(); } inline reference_type any_type::as_reference() const noexcept { - // NOLINTNEXTLINE(*-static-cast-downcast) - return is_reference() ? reference_type{static_cast(data_)} : reference_type{}; + return as(); } inline void_type any_type::as_void() const noexcept { - // NOLINTNEXTLINE(*-static-cast-downcast) - return is_void() ? void_type{static_cast(data_)} : void_type{}; + return as(); } } diff --git a/develop/untests/meta_types/any_type_tests.cpp b/develop/untests/meta_types/any_type_tests.cpp index 0253062..1f851b0 100644 --- a/develop/untests/meta_types/any_type_tests.cpp +++ b/develop/untests/meta_types/any_type_tests.cpp @@ -256,4 +256,12 @@ TEST_CASE("meta/meta_types/any_type") { REQUIRE(specific_type); CHECK(specific_type.get_id() == type.get_id()); } + + SUBCASE("is/as") { + const meta::any_type type{meta::resolve_type()}; + CHECK(type.is()); + + const meta::any_type type2{type.as()}; + CHECK(type2.as() == meta::resolve_type()); + } } diff --git a/headers/meta.hpp/meta_types.hpp b/headers/meta.hpp/meta_types.hpp index 9a818db..57fdc95 100644 --- a/headers/meta.hpp/meta_types.hpp +++ b/headers/meta.hpp/meta_types.hpp @@ -65,6 +65,7 @@ namespace meta_hpp using data_ptr = detail::type_data_base*; any_type() = default; + any_type(data_ptr data); [[nodiscard]] bool is_valid() const noexcept; [[nodiscard]] explicit operator bool() const noexcept; @@ -88,6 +89,12 @@ namespace meta_hpp any_type(const reference_type& other) noexcept; any_type(const void_type& other) noexcept; + template < detail::type_family Type > + [[nodiscard]] bool is() const noexcept; + + template < detail::type_family Type > + [[nodiscard]] Type as() const noexcept; + [[nodiscard]] bool is_array() const noexcept; [[nodiscard]] bool is_class() const noexcept; [[nodiscard]] bool is_constructor() const noexcept; @@ -124,6 +131,7 @@ namespace meta_hpp class array_type final { public: using data_ptr = detail::array_type_data*; + inline static constexpr type_kind kind{type_kind::array_}; array_type() = default; array_type(data_ptr data); @@ -146,6 +154,7 @@ namespace meta_hpp class class_type final { public: using data_ptr = detail::class_type_data*; + inline static constexpr type_kind kind{type_kind::class_}; class_type() = default; class_type(data_ptr data); @@ -227,6 +236,7 @@ namespace meta_hpp class constructor_type final { public: using data_ptr = detail::constructor_type_data*; + inline static constexpr type_kind kind{type_kind::constructor_}; constructor_type() = default; constructor_type(data_ptr data); @@ -251,6 +261,7 @@ namespace meta_hpp class destructor_type final { public: using data_ptr = detail::destructor_type_data*; + inline static constexpr type_kind kind{type_kind::destructor_}; destructor_type() = default; destructor_type(data_ptr data); @@ -272,6 +283,7 @@ namespace meta_hpp class enum_type final { public: using data_ptr = detail::enum_type_data*; + inline static constexpr type_kind kind{type_kind::enum_}; enum_type() = default; enum_type(data_ptr data); @@ -304,6 +316,7 @@ namespace meta_hpp class function_type final { public: using data_ptr = detail::function_type_data*; + inline static constexpr type_kind kind{type_kind::function_}; function_type() = default; function_type(data_ptr data); @@ -328,6 +341,7 @@ namespace meta_hpp class member_type final { public: using data_ptr = detail::member_type_data*; + inline static constexpr type_kind kind{type_kind::member_}; member_type() = default; member_type(data_ptr data); @@ -350,6 +364,7 @@ namespace meta_hpp class method_type final { public: using data_ptr = detail::method_type_data*; + inline static constexpr type_kind kind{type_kind::method_}; method_type() = default; method_type(data_ptr data); @@ -375,6 +390,7 @@ namespace meta_hpp class nullptr_type final { public: using data_ptr = detail::nullptr_type_data*; + inline static constexpr type_kind kind{type_kind::nullptr_}; nullptr_type() = default; nullptr_type(data_ptr data); @@ -393,6 +409,7 @@ namespace meta_hpp class number_type final { public: using data_ptr = detail::number_type_data*; + inline static constexpr type_kind kind{type_kind::number_}; number_type() = default; number_type(data_ptr data); @@ -415,6 +432,7 @@ namespace meta_hpp class pointer_type final { public: using data_ptr = detail::pointer_type_data*; + inline static constexpr type_kind kind{type_kind::pointer_}; pointer_type() = default; pointer_type(data_ptr data); @@ -436,6 +454,7 @@ namespace meta_hpp class reference_type final { public: using data_ptr = detail::reference_type_data*; + inline static constexpr type_kind kind{type_kind::reference_}; reference_type() = default; reference_type(data_ptr data); @@ -457,6 +476,7 @@ namespace meta_hpp class void_type final { public: using data_ptr = detail::void_type_data*; + inline static constexpr type_kind kind{type_kind::void_}; void_type() = default; void_type(data_ptr data); diff --git a/headers/meta.hpp/meta_types/any_type.hpp b/headers/meta.hpp/meta_types/any_type.hpp index 0c19ba6..e89f81f 100644 --- a/headers/meta.hpp/meta_types/any_type.hpp +++ b/headers/meta.hpp/meta_types/any_type.hpp @@ -11,6 +11,9 @@ namespace meta_hpp { + inline any_type::any_type(data_ptr data) + : data_{data} {} + inline bool any_type::is_valid() const noexcept { return data_ != nullptr; } @@ -70,120 +73,121 @@ namespace meta_hpp inline any_type::any_type(const void_type& other) noexcept : data_{detail::type_access(other)} {} + template < detail::type_family Type > + bool any_type::is() const noexcept { + if constexpr ( std::is_same_v ) { + return data_ != nullptr; + } else { + return data_ != nullptr && data_->kind == Type::kind; + } + } + + template < detail::type_family Type > + Type any_type::as() const noexcept { + return is() ? Type{static_cast(data_)} : Type{}; + } + inline bool any_type::is_array() const noexcept { - return is_valid() && data_->kind == type_kind::array_; + return is(); } inline bool any_type::is_class() const noexcept { - return is_valid() && data_->kind == type_kind::class_; + return is(); } inline bool any_type::is_constructor() const noexcept { - return is_valid() && data_->kind == type_kind::constructor_; + return is(); } inline bool any_type::is_destructor() const noexcept { - return is_valid() && data_->kind == type_kind::destructor_; + return is(); } inline bool any_type::is_enum() const noexcept { - return is_valid() && data_->kind == type_kind::enum_; + return is(); } inline bool any_type::is_function() const noexcept { - return is_valid() && data_->kind == type_kind::function_; + return is(); } inline bool any_type::is_member() const noexcept { - return is_valid() && data_->kind == type_kind::member_; + return is(); } inline bool any_type::is_method() const noexcept { - return is_valid() && data_->kind == type_kind::method_; + return is(); } inline bool any_type::is_nullptr() const noexcept { - return is_valid() && data_->kind == type_kind::nullptr_; + return is(); } inline bool any_type::is_number() const noexcept { - return is_valid() && data_->kind == type_kind::number_; + return is(); } inline bool any_type::is_pointer() const noexcept { - return is_valid() && data_->kind == type_kind::pointer_; + return is(); } inline bool any_type::is_reference() const noexcept { - return is_valid() && data_->kind == type_kind::reference_; + return is(); } inline bool any_type::is_void() const noexcept { - return is_valid() && data_->kind == type_kind::void_; + return is(); } inline array_type any_type::as_array() const noexcept { - // NOLINTNEXTLINE(*-static-cast-downcast) - return is_array() ? array_type{static_cast(data_)} : array_type{}; + return as(); } inline class_type any_type::as_class() const noexcept { - // NOLINTNEXTLINE(*-static-cast-downcast) - return is_class() ? class_type{static_cast(data_)} : class_type{}; + return as(); } inline constructor_type any_type::as_constructor() const noexcept { - // NOLINTNEXTLINE(*-static-cast-downcast) - return is_constructor() ? constructor_type{static_cast(data_)} : constructor_type{}; + return as(); } inline destructor_type any_type::as_destructor() const noexcept { - // NOLINTNEXTLINE(*-static-cast-downcast) - return is_destructor() ? destructor_type{static_cast(data_)} : destructor_type{}; + return as(); } inline enum_type any_type::as_enum() const noexcept { - // NOLINTNEXTLINE(*-static-cast-downcast) - return is_enum() ? enum_type{static_cast(data_)} : enum_type{}; + return as(); } inline function_type any_type::as_function() const noexcept { - // NOLINTNEXTLINE(*-static-cast-downcast) - return is_function() ? function_type{static_cast(data_)} : function_type{}; + return as(); } inline member_type any_type::as_member() const noexcept { - // NOLINTNEXTLINE(*-static-cast-downcast) - return is_member() ? member_type{static_cast(data_)} : member_type{}; + return as(); } inline method_type any_type::as_method() const noexcept { - // NOLINTNEXTLINE(*-static-cast-downcast) - return is_method() ? method_type{static_cast(data_)} : method_type{}; + return as(); } inline nullptr_type any_type::as_nullptr() const noexcept { - // NOLINTNEXTLINE(*-static-cast-downcast) - return is_nullptr() ? nullptr_type{static_cast(data_)} : nullptr_type{}; + return as(); } inline number_type any_type::as_number() const noexcept { - // NOLINTNEXTLINE(*-static-cast-downcast) - return is_number() ? number_type{static_cast(data_)} : number_type{}; + return as(); } inline pointer_type any_type::as_pointer() const noexcept { - // NOLINTNEXTLINE(*-static-cast-downcast) - return is_pointer() ? pointer_type{static_cast(data_)} : pointer_type{}; + return as(); } inline reference_type any_type::as_reference() const noexcept { - // NOLINTNEXTLINE(*-static-cast-downcast) - return is_reference() ? reference_type{static_cast(data_)} : reference_type{}; + return as(); } inline void_type any_type::as_void() const noexcept { - // NOLINTNEXTLINE(*-static-cast-downcast) - return is_void() ? void_type{static_cast(data_)} : void_type{}; + return as(); } }