From 4bfde4b1fb388811cc0b58eb0f2ba570b4a6ba37 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sun, 12 Feb 2023 02:15:27 +0700 Subject: [PATCH] safe_invoke, safe_get_as, safe_create --- .../manuals/meta_manuals/member_manual.cpp | 2 +- .../manuals/meta_manuals/variable_manual.cpp | 2 +- develop/singles/headers/meta.hpp/meta_all.hpp | 310 +++++++++++++----- develop/untests/meta_states/ctor_tests.cpp | 38 +++ develop/untests/meta_states/evalue_tests.cpp | 10 + .../untests/meta_states/function_tests.cpp | 32 +- develop/untests/meta_states/member_tests.cpp | 93 ++++-- develop/untests/meta_states/method_tests.cpp | 272 +++++++-------- .../untests/meta_states/variable_tests.cpp | 83 +++-- .../untests/meta_types/enum_type_tests.cpp | 24 +- develop/untests/meta_utilities/arg2_tests.cpp | 42 +-- develop/untests/meta_utilities/arg3_tests.cpp | 24 +- develop/untests/meta_utilities/arg4_tests.cpp | 20 +- develop/untests/meta_utilities/arg5_tests.cpp | 22 +- develop/untests/meta_utilities/arg7_tests.cpp | 6 +- develop/untests/meta_utilities/arg_tests.cpp | 6 +- develop/untests/meta_utilities/inst_tests.cpp | 6 +- .../untests/meta_utilities/value5_tests.cpp | 20 +- headers/.clangd | 1 + headers/meta.hpp/meta_base/exceptions.hpp | 7 - .../meta_detail/value_utilities/uarg.hpp | 2 +- .../meta_detail/value_utilities/uinst.hpp | 2 +- headers/meta.hpp/meta_states.hpp | 43 ++- headers/meta.hpp/meta_states/constructor.hpp | 50 ++- headers/meta.hpp/meta_states/evalue.hpp | 22 +- headers/meta.hpp/meta_states/function.hpp | 20 +- headers/meta.hpp/meta_states/member.hpp | 66 +++- headers/meta.hpp/meta_states/method.hpp | 27 +- headers/meta.hpp/meta_states/variable.hpp | 37 ++- headers/meta.hpp/meta_types.hpp | 7 +- headers/meta.hpp/meta_types/class_type.hpp | 14 +- headers/meta.hpp/meta_types/enum_type.hpp | 13 +- 32 files changed, 851 insertions(+), 472 deletions(-) diff --git a/develop/manuals/meta_manuals/member_manual.cpp b/develop/manuals/meta_manuals/member_manual.cpp index 0d61fa9..3b69174 100644 --- a/develop/manuals/meta_manuals/member_manual.cpp +++ b/develop/manuals/meta_manuals/member_manual.cpp @@ -65,7 +65,7 @@ TEST_CASE("meta/meta_manuals/member/usage") { CHECK(ivec2_x_typed_value == 42); // also, we can change the member value, of course - ivec2_x.set(v, 11); + CHECK(ivec2_x.safe_set(v, 11)); // checks the result of our manipulations CHECK(v.x == 11); diff --git a/develop/manuals/meta_manuals/variable_manual.cpp b/develop/manuals/meta_manuals/variable_manual.cpp index 1cf6e65..58f5258 100644 --- a/develop/manuals/meta_manuals/variable_manual.cpp +++ b/develop/manuals/meta_manuals/variable_manual.cpp @@ -40,7 +40,7 @@ TEST_CASE("meta/meta_manuals/variable/usage") { CHECK(pi_variable_value.get_as() == doctest::Approx(3.14).epsilon(0.01)); // we can change variable values, but only non-const - CHECK_THROWS(pi_variable.set(6.0)); + CHECK_FALSE(pi_variable.safe_set(6.0)); // prints all variables in the scope fmt::print("* {}\n", constants_scope.get_name()); diff --git a/develop/singles/headers/meta.hpp/meta_all.hpp b/develop/singles/headers/meta.hpp/meta_all.hpp index 62232ff..9ff6491 100644 --- a/develop/singles/headers/meta.hpp/meta_all.hpp +++ b/develop/singles/headers/meta.hpp/meta_all.hpp @@ -309,13 +309,6 @@ namespace meta_hpp::detail # define META_HPP_THROW(...) std::abort() #endif -#define META_HPP_THROW_IF(yesno, ...) \ - do { \ - if ( yesno ) { \ - META_HPP_THROW(__VA_ARGS__); \ - } \ - } while ( false ) - namespace meta_hpp::detail { #if !defined(META_HPP_NO_EXCEPTIONS) @@ -2307,8 +2300,11 @@ namespace meta_hpp [[nodiscard]] std::string_view value_to_name(Enum value) const noexcept; [[nodiscard]] uvalue name_to_value(std::string_view name) const noexcept; - template < typename T > - [[nodiscard]] T name_to_value_as(std::string_view name) const; + template < detail::enum_kind Enum > + [[nodiscard]] Enum name_to_value_as(std::string_view name) const; + + template < detail::enum_kind Enum > + [[nodiscard]] std::optional safe_name_to_value_as(std::string_view name) const noexcept; }; class function_type final : public type_base { @@ -3160,9 +3156,15 @@ namespace meta_hpp template < typename... Args > [[nodiscard]] uvalue create(Args&&... args) const; + template < typename... Args > + [[nodiscard]] std::optional safe_create(Args&&... args) const; + template < typename... Args > uvalue create_at(void* mem, Args&&... args) const; + template < typename... Args > + std::optional safe_create_at(void* mem, Args&&... args) const; + template < typename... Args > [[nodiscard]] bool is_invocable_with() const noexcept; @@ -3195,11 +3197,17 @@ namespace meta_hpp [[nodiscard]] const uvalue& get_value() const noexcept; [[nodiscard]] const uvalue& get_underlying_value() const noexcept; - template < typename T > - [[nodiscard]] T get_value_as() const; + template < detail::enum_kind Enum > + [[nodiscard]] Enum get_value_as() const; - template < typename T > - [[nodiscard]] T get_underlying_value_as() const; + template < detail::enum_kind Enum > + [[nodiscard]] std::optional safe_get_value_as() const noexcept; + + template < detail::number_kind Number > + [[nodiscard]] Number get_underlying_value_as() const; + + template < detail::number_kind Number > + [[nodiscard]] std::optional safe_get_underlying_value_as() const noexcept; }; class function final : public state_base { @@ -3212,6 +3220,9 @@ namespace meta_hpp template < typename... Args > uvalue invoke(Args&&... args) const; + template < typename... Args > + std::optional safe_invoke(Args&&... args) const; + template < typename... Args > uvalue operator()(Args&&... args) const; @@ -3235,12 +3246,21 @@ namespace meta_hpp template < typename Instance > [[nodiscard]] uvalue get(Instance&& instance) const; + template < typename Instance > + [[nodiscard]] std::optional safe_get(Instance&& instance) const; + template < typename T, typename Instance > [[nodiscard]] T get_as(Instance&& instance) const; + template < typename T, typename Instance > + [[nodiscard]] std::optional safe_get_as(Instance&& instance) const; + template < typename Instance, typename Value > void set(Instance&& instance, Value&& value) const; + template < typename Instance, typename Value > + bool safe_set(Instance&& instance, Value&& value) const; + template < typename Instance > [[nodiscard]] uvalue operator()(Instance&& instance) const; @@ -3270,6 +3290,9 @@ namespace meta_hpp template < typename Instance, typename... Args > uvalue invoke(Instance&& instance, Args&&... args) const; + template < typename Instance, typename... Args > + std::optional safe_invoke(Instance&& instance, Args&&... args) const; + template < typename Instance, typename... Args > uvalue operator()(Instance&& instance, Args&&... args) const; @@ -3314,12 +3337,20 @@ namespace meta_hpp [[nodiscard]] uvalue get() const; + [[nodiscard]] std::optional safe_get() const; + template < typename T > [[nodiscard]] T get_as() const; + template < typename T > + [[nodiscard]] std::optional safe_get_as() const; + template < typename Value > void set(Value&& value) const; + template < typename Value > + bool safe_set(Value&& value) const; + [[nodiscard]] uvalue operator()() const; template < typename Value > @@ -5407,7 +5438,7 @@ namespace meta_hpp::detail template < typename To > // NOLINTNEXTLINE(*-cognitive-complexity) To uarg::cast() const { - META_HPP_THROW_IF(!can_cast_to(), "bad argument cast"); + META_HPP_ASSERT(can_cast_to() && "bad argument cast"); using to_raw_type_cv = std::remove_reference_t; using to_raw_type = std::remove_cv_t; @@ -5578,16 +5609,16 @@ namespace meta_hpp::detail static_assert(as_copy || as_void || ref_as_ptr); - META_HPP_THROW_IF( // - args.size() != ft::arity, - "an attempt to call a function with an incorrect arity" + META_HPP_ASSERT( // + args.size() == ft::arity // + && "an attempt to call a function with an incorrect arity" ); return std::invoke( [ function_ptr, args ](std::index_sequence)->uvalue { - META_HPP_THROW_IF( // - !(... && args[Is].can_cast_to>()), - "an attempt to call a function with incorrect argument types" + META_HPP_ASSERT( // + (... && args[Is].can_cast_to>()) // + && "an attempt to call a function with incorrect argument types" ); if constexpr ( std::is_void_v ) { @@ -5697,6 +5728,14 @@ namespace meta_hpp } } + template < typename... Args > + std::optional function::safe_invoke(Args&&... args) const { + if ( is_invocable_with(std::forward(args)...) ) { + return invoke(std::forward(args)...); + } + return std::nullopt; + } + template < typename... Args > uvalue function::operator()(Args&&... args) const { return invoke(std::forward(args)...); @@ -5904,7 +5943,7 @@ namespace meta_hpp::detail { template < inst_class_ref_kind Q > decltype(auto) uinst::cast() const { - META_HPP_THROW_IF(!can_cast_to(), "bad instance cast"); + META_HPP_ASSERT(can_cast_to() && "bad instance cast"); using inst_class_cv = std::remove_reference_t; using inst_class = std::remove_cv_t; @@ -6004,12 +6043,12 @@ namespace meta_hpp::detail static_assert(as_copy || as_ptr || as_ref_wrap); - META_HPP_THROW_IF( // - !inst.can_cast_to(), - "an attempt to get a member with an incorrect instance type" - ); - if ( inst.is_inst_const() ) { + META_HPP_ASSERT( // + inst.can_cast_to() // + && "an attempt to get a member with an incorrect instance type" + ); + auto&& return_value = inst.cast().*member_ptr; if constexpr ( as_copy ) { @@ -6024,6 +6063,11 @@ namespace meta_hpp::detail return uvalue{std::ref(return_value)}; } } else { + META_HPP_ASSERT( // + inst.can_cast_to() // + && "an attempt to get a member with an incorrect instance type" + ); + auto&& return_value = inst.cast().*member_ptr; if constexpr ( as_copy ) { @@ -6058,21 +6102,21 @@ namespace meta_hpp::detail using value_type = typename mt::value_type; if constexpr ( std::is_const_v ) { - META_HPP_THROW("an attempt to set a constant member"); + META_HPP_ASSERT(false && "an attempt to set a constant member"); } else { - META_HPP_THROW_IF( // - inst.is_inst_const(), - "an attempt to set a member with an const instance type" + META_HPP_ASSERT( // + !inst.is_inst_const() // + && "an attempt to set a member with an const instance type" ); - META_HPP_THROW_IF( // - !inst.can_cast_to(), - "an attempt to set a member with an incorrect instance type" + META_HPP_ASSERT( // + inst.can_cast_to() // + && "an attempt to set a member with an incorrect instance type" ); - META_HPP_THROW_IF( // - !arg.can_cast_to(), - "an attempt to set a member with an incorrect argument type" + META_HPP_ASSERT( // + arg.can_cast_to() // + && "an attempt to set a member with an incorrect argument type" ); inst.cast().*member_ptr = arg.cast(); @@ -6085,8 +6129,13 @@ namespace meta_hpp::detail using class_type = typename mt::class_type; using value_type = typename mt::value_type; - return !std::is_const_v && !inst.is_inst_const() && inst.can_cast_to() - && arg.can_cast_to(); + if constexpr ( std::is_const_v ) { + return false; + } else { + return !inst.is_inst_const() // + && inst.can_cast_to() // + && arg.can_cast_to(); // + } } } @@ -6151,11 +6200,24 @@ namespace meta_hpp return state_->getter(vinst); } + template < typename Instance > + std::optional member::safe_get(Instance&& instance) const { + if ( is_gettable_with(std::forward(instance)) ) { + return get(std::forward(instance)); + } + return std::nullopt; + } + template < typename T, typename Instance > T member::get_as(Instance&& instance) const { return get(std::forward(instance)).template get_as(); } + template < typename T, typename Instance > + std::optional member::safe_get_as(Instance&& instance) const { + return safe_get(std::forward(instance)).value_or(uvalue{}).template safe_get_as(); + } + template < typename Instance, typename Value > void member::set(Instance&& instance, Value&& value) const { using namespace detail; @@ -6164,6 +6226,15 @@ namespace meta_hpp state_->setter(vinst, vvalue); } + template < typename Instance, typename Value > + bool member::safe_set(Instance&& instance, Value&& value) const { + if ( is_settable_with(std::forward(instance), std::forward(value)) ) { + set(std::forward(instance), std::forward(value)); + return true; + } + return false; + } + template < typename Instance > uvalue member::operator()(Instance&& instance) const { return get(std::forward(instance)); @@ -6269,21 +6340,20 @@ namespace meta_hpp::detail static_assert(as_copy || as_void || ref_as_ptr); - META_HPP_THROW_IF( // - args.size() != mt::arity, - "an attempt to call a method with an incorrect arity" + META_HPP_ASSERT( // + args.size() == mt::arity // + && "an attempt to call a method with an incorrect arity" ); - - META_HPP_THROW_IF( // - !inst.can_cast_to(), - "an attempt to call a method with an incorrect instance type" + META_HPP_ASSERT( // + inst.can_cast_to() // + && "an attempt to call a method with an incorrect instance type" ); return std::invoke( [ method_ptr, &inst, args ](std::index_sequence)->uvalue { - META_HPP_THROW_IF( // - !(... && args[Is].can_cast_to>()), - "an attempt to call a method with incorrect argument types" + META_HPP_ASSERT( // + (... && args[Is].can_cast_to>()) // + && "an attempt to call a method with incorrect argument types" ); if constexpr ( std::is_void_v ) { @@ -6402,6 +6472,14 @@ namespace meta_hpp } } + template < typename Instance, typename... Args > + std::optional method::safe_invoke(Instance&& instance, Args&&... args) const { + if ( is_invocable_with(std::forward(instance), std::forward(args)...) ) { + return invoke(std::forward(instance), std::forward(args)...); + } + return std::nullopt; + } + template < typename Instance, typename... Args > uvalue method::operator()(Instance&& instance, Args&&... args) const { return invoke(std::forward(instance), std::forward(args)...); @@ -6677,16 +6755,16 @@ namespace meta_hpp::detail static_assert(as_object || as_raw_ptr || as_shared_ptr); - META_HPP_THROW_IF( // - args.size() != ct::arity, - "an attempt to call a constructor with an incorrect arity" + META_HPP_ASSERT( // + args.size() == ct::arity // + && "an attempt to call a constructor with an incorrect arity" ); return std::invoke( [args](std::index_sequence)->uvalue { - META_HPP_THROW_IF( // - !(... && args[Is].can_cast_to>()), - "an attempt to call a constructor with incorrect argument types" + META_HPP_ASSERT( // + (... && args[Is].can_cast_to>()) // + && "an attempt to call a constructor with incorrect argument types" ); if constexpr ( as_object ) { @@ -6694,11 +6772,11 @@ namespace meta_hpp::detail } if constexpr ( as_raw_ptr ) { - return uvalue{std::make_unique(args[Is].cast>()...).release()}; + return std::make_unique(args[Is].cast>()...).release(); } if constexpr ( as_shared_ptr ) { - return uvalue{std::make_shared(args[Is].cast>()...)}; + return std::make_shared(args[Is].cast>()...); } }, std::make_index_sequence() @@ -6711,22 +6789,22 @@ namespace meta_hpp::detail using class_type = typename ct::class_type; using argument_types = typename ct::argument_types; - META_HPP_THROW_IF( // - args.size() != ct::arity, - "an attempt to call a constructor with an incorrect arity" + META_HPP_ASSERT( // + args.size() == ct::arity // + && "an attempt to call a constructor with an incorrect arity" ); return std::invoke( [ mem, args ](std::index_sequence)->uvalue { - META_HPP_THROW_IF( // - !(... && args[Is].can_cast_to>()), - "an attempt to call a constructor with incorrect argument types" + META_HPP_ASSERT( // + (... && args[Is].can_cast_to>()) // + && "an attempt to call a constructor with incorrect argument types" ); - return uvalue{std::construct_at( // - static_cast(mem), + return std::construct_at( // + static_cast(mem), // args[Is].cast>()... - )}; + ); }, std::make_index_sequence() ); @@ -6819,6 +6897,14 @@ namespace meta_hpp } } + template < typename... Args > + std::optional constructor::safe_create(Args&&... args) const { + if ( is_invocable_with(std::forward(args)...) ) { + return create(std::forward(args)...); + } + return std::nullopt; + } + template < typename... Args > uvalue constructor::create_at(void* mem, Args&&... args) const { if constexpr ( sizeof...(Args) > 0 ) { @@ -6830,6 +6916,14 @@ namespace meta_hpp } } + template < typename... Args > + std::optional constructor::safe_create_at(void* mem, Args&&... args) const { + if ( is_invocable_with(std::forward(args)...) ) { + return create_at(mem, std::forward(args)...); + } + return std::nullopt; + } + template < typename... Args > bool constructor::is_invocable_with() const noexcept { if constexpr ( sizeof...(Args) > 0 ) { @@ -7005,16 +7099,21 @@ namespace meta_hpp } inline uvalue enum_type::name_to_value(std::string_view name) const noexcept { - if ( const evalue& value = get_evalue(name); value ) { + if ( const evalue& value = get_evalue(name) ) { return value.get_value(); } return uvalue{}; } - template < typename T > - T enum_type::name_to_value_as(std::string_view name) const { - return name_to_value(name).get_as(); + template < detail::enum_kind Enum > + Enum enum_type::name_to_value_as(std::string_view name) const { + return name_to_value(name).get_as(); + } + + template < detail::enum_kind Enum > + std::optional enum_type::safe_name_to_value_as(std::string_view name) const noexcept { + return name_to_value(name).safe_get_as(); } } @@ -7051,14 +7150,24 @@ namespace meta_hpp return state_->underlying_value; } - template < typename T > - T evalue::get_value_as() const { - return get_value().get_as(); + template < detail::enum_kind Enum > + Enum evalue::get_value_as() const { + return get_value().get_as(); } - template < typename T > - T evalue::get_underlying_value_as() const { - return get_underlying_value().get_as(); + template < detail::enum_kind Enum > + std::optional evalue::safe_get_value_as() const noexcept { + return get_value().safe_get_as(); + } + + template < detail::number_kind Number > + Number evalue::get_underlying_value_as() const { + return get_underlying_value().get_as(); + } + + template < detail::number_kind Number > + std::optional evalue::safe_get_underlying_value_as() const noexcept { + return get_underlying_value().safe_get_as(); } } @@ -7125,12 +7234,13 @@ namespace meta_hpp::detail using data_type = typename pt::data_type; if constexpr ( std::is_const_v ) { - META_HPP_THROW("an attempt to set a constant variable"); + META_HPP_ASSERT(false && "an attempt to set a constant variable"); } else { - META_HPP_THROW_IF( // - !arg.can_cast_to(), - "an attempt to set a variable with an incorrect argument type" + META_HPP_ASSERT( // + arg.can_cast_to() // + && "an attempt to set a variable with an incorrect argument type" ); + *variable_ptr = arg.cast(); } } @@ -7140,7 +7250,11 @@ namespace meta_hpp::detail using pt = pointer_traits; using data_type = typename pt::data_type; - return !std::is_const_v && arg.can_cast_to(); + if constexpr ( std::is_const_v ) { + return false; + } else { + return arg.can_cast_to(); + } } } @@ -7196,9 +7310,18 @@ namespace meta_hpp return state_->getter(); } + inline std::optional variable::safe_get() const { + return state_->getter(); + } + template < typename T > T variable::get_as() const { - return get().get_as(); + return get().template get_as(); + } + + template < typename T > + std::optional variable::safe_get_as() const { + return safe_get().value_or(uvalue{}).template safe_get_as(); } template < typename Value > @@ -7208,6 +7331,15 @@ namespace meta_hpp state_->setter(vvalue); } + template < typename Value > + bool variable::safe_set(Value&& value) const { + if ( is_settable_with(std::forward(value)) ) { + set(std::forward(value)); + return true; + } + return false; + } + inline uvalue variable::operator()() const { return get(); } @@ -7227,7 +7359,7 @@ namespace meta_hpp template < typename Value > bool variable::is_settable_with(Value&& value) const noexcept { using namespace detail; - const uarg vvalue{std::forward(value)}; + const uarg_base vvalue{std::forward(value)}; return state_->is_settable_with(vvalue); } } @@ -7396,7 +7528,7 @@ namespace meta_hpp } for ( const class_type& base : data_->bases ) { - if ( const function& function = base.get_function(name); function ) { + if ( const function& function = base.get_function(name) ) { return function; } } @@ -7412,7 +7544,7 @@ namespace meta_hpp } for ( const class_type& base : data_->bases ) { - if ( const member& member = base.get_member(name); member ) { + if ( const member& member = base.get_member(name) ) { return member; } } @@ -7428,7 +7560,7 @@ namespace meta_hpp } for ( const class_type& base : data_->bases ) { - if ( const method& method = base.get_method(name); method ) { + if ( const method& method = base.get_method(name) ) { return method; } } @@ -7442,7 +7574,7 @@ namespace meta_hpp } for ( const class_type& base : data_->bases ) { - if ( const any_type& type = base.get_typedef(name); type ) { + if ( const any_type& type = base.get_typedef(name) ) { return type; } } @@ -7458,7 +7590,7 @@ namespace meta_hpp } for ( const class_type& base : data_->bases ) { - if ( const variable& variable = base.get_variable(name); variable ) { + if ( const variable& variable = base.get_variable(name) ) { return variable; } } @@ -7528,7 +7660,7 @@ namespace meta_hpp } for ( const class_type& base : data_->bases ) { - if ( const function& function = base.get_function_with(name, first, last); function ) { + if ( const function& function = base.get_function_with(name, first, last) ) { return function; } } @@ -7567,7 +7699,7 @@ namespace meta_hpp } for ( const class_type& base : data_->bases ) { - if ( const method& method = base.get_method_with(name, first, last); method ) { + if ( const method& method = base.get_method_with(name, first, last) ) { return method; } } diff --git a/develop/untests/meta_states/ctor_tests.cpp b/develop/untests/meta_states/ctor_tests.cpp index cfb5e38..7b69590 100644 --- a/develop/untests/meta_states/ctor_tests.cpp +++ b/develop/untests/meta_states/ctor_tests.cpp @@ -162,6 +162,25 @@ TEST_CASE("meta/meta_states/ctor/as_object") { CHECK(clazz_t::copy_constructor_counter == 0); } + SUBCASE("int_safe") { + const meta::constructor ctor = clazz_type.get_constructor_with(); + REQUIRE(ctor); + { + std::optional v{ctor.safe_create(42.0)}; + CHECK_FALSE(v); + + CHECK(clazz_t::constructor_counter == 0); + } + { + std::optional v{ctor.safe_create(42)}; + CHECK(v); + + CHECK(clazz_t::constructor_counter == 1); + CHECK(v->get_type() == meta::resolve_type()); + CHECK(v->get_as().i == 42); + } + } + SUBCASE("int/inplace") { { const meta::uvalue v = clazz_type @@ -179,6 +198,25 @@ TEST_CASE("meta/meta_states/ctor/as_object") { CHECK(clazz_t::copy_constructor_counter == 0); } + SUBCASE("safe_int/inplace") { + const meta::constructor ctor = clazz_type.get_constructor_with(); + REQUIRE(ctor); + { + std::optional v{ctor.safe_create_at(clazz_mem, 42.0)}; + CHECK_FALSE(v); + + CHECK(clazz_t::constructor_counter == 0); + } + { + std::optional v{ctor.safe_create_at(clazz_mem, 42)}; + CHECK(v); + + CHECK(clazz_t::constructor_counter == 1); + CHECK(v->get_type() == meta::resolve_type()); + CHECK(v->get_as()->i == 42); + } + } + SUBCASE("clazz_t&&") { { const meta::constructor ctor = clazz_type.get_constructor_with(); diff --git a/develop/untests/meta_states/evalue_tests.cpp b/develop/untests/meta_states/evalue_tests.cpp index edbbee6..a6b5b42 100644 --- a/develop/untests/meta_states/evalue_tests.cpp +++ b/develop/untests/meta_states/evalue_tests.cpp @@ -15,6 +15,8 @@ namespace blue = 0x0000FF, white = red | green | blue, }; + + enum another_color {}; } TEST_CASE("meta/meta_states/evalue") { @@ -61,5 +63,13 @@ TEST_CASE("meta/meta_states/evalue") { CHECK(evalue.get_underlying_value().get_as() == meta::detail::to_underlying(color::green)); CHECK(evalue.get_underlying_value_as() == meta::detail::to_underlying(color::green)); CHECK(evalue.get_underlying_value().get_type() == color_type.get_underlying_type()); + + CHECK_THROWS(std::ignore = evalue.get_value_as()); + CHECK_FALSE(evalue.safe_get_value_as()); + CHECK(evalue.safe_get_value_as() == color::green); + + CHECK_THROWS(std::ignore = evalue.get_underlying_value_as()); + CHECK_FALSE(evalue.safe_get_underlying_value_as()); + CHECK(evalue.safe_get_underlying_value_as() == meta::detail::to_underlying(color::green)); } } diff --git a/develop/untests/meta_states/function_tests.cpp b/develop/untests/meta_states/function_tests.cpp index 1165f7e..8fd3a42 100644 --- a/develop/untests/meta_states/function_tests.cpp +++ b/develop/untests/meta_states/function_tests.cpp @@ -82,11 +82,11 @@ TEST_CASE("meta/meta_states/function") { CHECK(func.is_invocable_with()); CHECK(func.is_invocable_with()); - CHECK_THROWS(func.invoke()); - CHECK_THROWS(func.invoke(42)); - CHECK_THROWS(func.invoke(ivec2{}, 42)); - CHECK_THROWS(func.invoke(42, ivec2{})); - CHECK_THROWS(func.invoke(ivec2{}, ivec2{}, 42)); + CHECK_FALSE(func.safe_invoke()); + CHECK_FALSE(func.safe_invoke(42)); + CHECK_FALSE(func.safe_invoke(ivec2{}, 42)); + CHECK_FALSE(func.safe_invoke(42, ivec2{})); + CHECK_FALSE(func.safe_invoke(ivec2{}, ivec2{}, 42)); CHECK(func.invoke(ivec2{1,2}, ivec2{3,4})); CHECK(func.invoke(ivec2{1,2}, ivec2{3,4}).get_as() == ivec2{4,6}); @@ -109,9 +109,9 @@ TEST_CASE("meta/meta_states/function") { CHECK(func.is_invocable_with()); CHECK(func.is_invocable_with()); - CHECK_THROWS(func.invoke()); - CHECK_THROWS(func.invoke(42)); - CHECK_THROWS(func.invoke(ivec2{}, 42)); + CHECK_FALSE(func.safe_invoke()); + CHECK_FALSE(func.safe_invoke(42)); + CHECK_FALSE(func.safe_invoke(ivec2{}, 42)); CHECK(func.invoke(ivec2{2,3})); CHECK(func.invoke(ivec2{2,3}).get_as() == 13); @@ -148,13 +148,13 @@ TEST_CASE("meta/meta_states/function") { CHECK(func1.invoke(bounded_arr).get_as() == 10); CHECK(func1.invoke(unbounded_arr).get_as() == 10); - CHECK_THROWS(func1.invoke(bounded_const_arr)); - CHECK_THROWS(func1.invoke(unbounded_const_arr)); + CHECK_FALSE(func1.safe_invoke(bounded_const_arr)); + CHECK_FALSE(func1.safe_invoke(unbounded_const_arr)); CHECK(func1.invoke(meta::uvalue{bounded_arr}).get_as() == 10); CHECK(func1.invoke(meta::uvalue{unbounded_arr}).get_as() == 10); - CHECK_THROWS(func1.invoke(meta::uvalue{bounded_const_arr})); - CHECK_THROWS(func1.invoke(meta::uvalue{unbounded_const_arr})); + CHECK_FALSE(func1.safe_invoke(meta::uvalue{bounded_const_arr})); + CHECK_FALSE(func1.safe_invoke(meta::uvalue{unbounded_const_arr})); static_assert(std::is_invocable_v); static_assert(std::is_invocable_v); @@ -173,13 +173,13 @@ TEST_CASE("meta/meta_states/function") { CHECK(func2.invoke(bounded_arr).get_as() == 10); CHECK(func2.invoke(unbounded_arr).get_as() == 10); - CHECK_THROWS(func2.invoke(bounded_const_arr)); - CHECK_THROWS(func2.invoke(unbounded_const_arr)); + CHECK_FALSE(func2.safe_invoke(bounded_const_arr)); + CHECK_FALSE(func2.safe_invoke(unbounded_const_arr)); CHECK(func2.invoke(meta::uvalue{bounded_arr}).get_as() == 10); CHECK(func2.invoke(meta::uvalue{unbounded_arr}).get_as() == 10); - CHECK_THROWS(func2.invoke(meta::uvalue{bounded_const_arr})); - CHECK_THROWS(func2.invoke(meta::uvalue{unbounded_const_arr})); + CHECK_FALSE(func2.safe_invoke(meta::uvalue{bounded_const_arr})); + CHECK_FALSE(func2.safe_invoke(meta::uvalue{unbounded_const_arr})); static_assert(std::is_invocable_v); static_assert(std::is_invocable_v); diff --git a/develop/untests/meta_states/member_tests.cpp b/develop/untests/meta_states/member_tests.cpp index 0d78626..2b338ad 100644 --- a/develop/untests/meta_states/member_tests.cpp +++ b/develop/untests/meta_states/member_tests.cpp @@ -105,10 +105,8 @@ TEST_CASE("meta/meta_states/member") { CHECK(vm(std::move(v)).get_as() == 1); CHECK(vm(std::move(std::as_const(v))).get_as() == 1); - CHECK_THROWS(std::ignore = vm.get(v2)); - CHECK_THROWS(std::ignore = vm.get(&v2)); - CHECK_THROWS(std::ignore = vm(v2)); - CHECK_THROWS(std::ignore = vm(&v2)); + CHECK_FALSE(vm.safe_get(v2)); + CHECK_FALSE(vm.safe_get(&v2)); } { @@ -150,24 +148,19 @@ TEST_CASE("meta/meta_states/member") { { vm.set(v, 10); CHECK(vm.get(v).get_as() == 10); vm.set(&v, 100); CHECK(vm.get(v).get_as() == 100); - CHECK_THROWS(vm.set(std::as_const(v), 11)); CHECK(vm.get(v).get_as() == 100); - CHECK_THROWS(vm.set(&std::as_const(v), 11)); CHECK(vm.get(v).get_as() == 100); + CHECK_FALSE(vm.safe_set(std::as_const(v), 11)); CHECK(vm.get(v).get_as() == 100); + CHECK_FALSE(vm.safe_set(&std::as_const(v), 11)); CHECK(vm.get(v).get_as() == 100); vm.set(std::move(v), 12); CHECK(vm.get(v).get_as() == 12); - CHECK_THROWS(vm.set(std::move(std::as_const(v)), 13)); CHECK(vm.get(v).get_as() == 12); + CHECK_FALSE(vm.safe_set(std::move(std::as_const(v)), 13)); CHECK(vm.get(v).get_as() == 12); vm(v, 13); CHECK(vm(v).get_as() == 13); vm(&v, 130); CHECK(vm(v).get_as() == 130); - CHECK_THROWS(vm(std::as_const(v), 14)); CHECK(vm(v).get_as() == 130); - CHECK_THROWS(vm(std::as_const(v), 14)); CHECK(vm(v).get_as() == 130); vm(std::move(v), 15); CHECK(vm(v).get_as() == 15); - CHECK_THROWS(vm(std::move(std::as_const(v)), 16)); CHECK(vm(v).get_as() == 15); - CHECK_THROWS(vm.set(v2, 17)); - CHECK_THROWS(vm.set(&v2, 17)); - CHECK_THROWS(vm(v2, 17)); - CHECK_THROWS(vm(&v2, 17)); + CHECK_FALSE(vm.safe_set(v2, 17)); + CHECK_FALSE(vm.safe_set(&v2, 17)); CHECK(vm(v).get_as() == 15); } } @@ -220,10 +213,8 @@ TEST_CASE("meta/meta_states/member") { CHECK(vm(std::move(v)).get_as() == 2); CHECK(vm(std::move(std::as_const(v))).get_as() == 2); - CHECK_THROWS(std::ignore = vm.get(v2)); - CHECK_THROWS(std::ignore = vm.get(&v2)); - CHECK_THROWS(std::ignore = vm(v2)); - CHECK_THROWS(std::ignore = vm(&v2)); + CHECK_FALSE(vm.safe_get(v2)); + CHECK_FALSE(vm.safe_get(&v2)); } { @@ -259,24 +250,15 @@ TEST_CASE("meta/meta_states/member") { } { - CHECK_THROWS(vm.set(v, 10)); CHECK(vm.get(v).get_as() == 2); - CHECK_THROWS(vm.set(&v, 10)); CHECK(vm.get(v).get_as() == 2); - CHECK_THROWS(vm.set(std::as_const(v), 11)); CHECK(vm.get(v).get_as() == 2); - CHECK_THROWS(vm.set(&std::as_const(v), 11)); CHECK(vm.get(v).get_as() == 2); - CHECK_THROWS(vm.set(std::move(v), 12)); CHECK(vm.get(v).get_as() == 2); - CHECK_THROWS(vm.set(std::move(std::as_const(v)), 16)); CHECK(vm.get(v).get_as() == 2); + CHECK_FALSE(vm.safe_set(v, 10)); CHECK(vm.get(v).get_as() == 2); + CHECK_FALSE(vm.safe_set(&v, 10)); CHECK(vm.get(v).get_as() == 2); + CHECK_FALSE(vm.safe_set(std::as_const(v), 11)); CHECK(vm.get(v).get_as() == 2); + CHECK_FALSE(vm.safe_set(&std::as_const(v), 11)); CHECK(vm.get(v).get_as() == 2); + CHECK_FALSE(vm.safe_set(std::move(v), 12)); CHECK(vm.get(v).get_as() == 2); + CHECK_FALSE(vm.safe_set(std::move(std::as_const(v)), 16)); CHECK(vm.get(v).get_as() == 2); - CHECK_THROWS(vm(v, 13)); CHECK(vm(v).get_as() == 2); - CHECK_THROWS(vm(&v, 13)); CHECK(vm(v).get_as() == 2); - CHECK_THROWS(vm(std::as_const(v), 14)); CHECK(vm(v).get_as() == 2); - CHECK_THROWS(vm(&std::as_const(v), 14)); CHECK(vm(v).get_as() == 2); - CHECK_THROWS(vm(std::move(v), 15)); CHECK(vm(v).get_as() == 2); - CHECK_THROWS(vm(std::move(std::as_const(v)), 16)); CHECK(vm(v).get_as() == 2); - - CHECK_THROWS(vm.set(v2, 17)); - CHECK_THROWS(vm.set(&v2, 17)); - CHECK_THROWS(vm(v2, 17)); - CHECK_THROWS(vm(&v2, 17)); + CHECK_FALSE(vm.safe_set(v2, 17)); + CHECK_FALSE(vm.safe_set(&v2, 17)); CHECK(vm(v).get_as() == 2); } } @@ -322,4 +304,45 @@ TEST_CASE("meta/meta_states/member") { CHECK(vm.get_as(v).get() == v.unique_int_member); } } + + SUBCASE("safe_get") { + meta::member vm = clazz_1_type.get_member("int_member"); + REQUIRE(vm); + + clazz_1 v; + clazz_2 v2; + + CHECK(vm.safe_get(v)); + CHECK(vm.safe_get(v)->get_as() == 1); + CHECK_FALSE(vm.safe_get(v2)); + } + + SUBCASE("safe_get_as") { + meta::member vm = clazz_1_type.get_member("int_member"); + REQUIRE(vm); + + clazz_1 v; + clazz_2 v2; + + CHECK(vm.safe_get_as(v) == 1); + CHECK_FALSE(vm.safe_get_as(v)); + + CHECK_FALSE(vm.safe_get_as(v2)); + CHECK_FALSE(vm.safe_get_as(v2)); + } + + SUBCASE("safe_set") { + meta::member vm = clazz_1_type.get_member("int_member"); + REQUIRE(vm); + + clazz_1 v; + clazz_2 v2; + + CHECK(vm.safe_set(v, 10)); + CHECK(vm.get_as(v) == 10); + + CHECK_FALSE(vm.safe_set(v, 20.0)); + CHECK_FALSE(vm.safe_set(v2, 20)); + CHECK(vm.get_as(v) == 10); + } } diff --git a/develop/untests/meta_states/method_tests.cpp b/develop/untests/meta_states/method_tests.cpp index d4f77f4..7896505 100644 --- a/develop/untests/meta_states/method_tests.cpp +++ b/develop/untests/meta_states/method_tests.cpp @@ -149,14 +149,14 @@ TEST_CASE("meta/meta_states/method") { meta::uvalue clv{cl}; CHECK(mi.invoke(cl).get_as() == 1); - CHECK_THROWS(mi.invoke(std::as_const(cl))); + CHECK_FALSE(mi.safe_invoke(std::as_const(cl))); CHECK(mi.invoke(std::move(cl)).get_as() == 1); - CHECK_THROWS(mi.invoke(std::move(std::as_const(cl)))); + CHECK_FALSE(mi.safe_invoke(std::move(std::as_const(cl)))); CHECK(mi.invoke(clv).get_as() == 1); - CHECK_THROWS(mi.invoke(std::as_const(clv))); + CHECK_FALSE(mi.safe_invoke(std::as_const(clv))); CHECK(mi.invoke(std::move(clv)).get_as() == 1); - CHECK_THROWS(mi.invoke(std::move(std::as_const(clv)))); + CHECK_FALSE(mi.safe_invoke(std::move(std::as_const(clv)))); } { @@ -178,15 +178,15 @@ TEST_CASE("meta/meta_states/method") { CHECK(mi.invoke(std::move(cl1v)).get_as() == 1); CHECK(mi.invoke(std::move(std::as_const(cl1v))).get_as() == 1); - CHECK_THROWS(mi.invoke(cl2)); - CHECK_THROWS(mi.invoke(std::as_const(cl2))); - CHECK_THROWS(mi.invoke(std::move(cl2))); - CHECK_THROWS(mi.invoke(std::move(std::as_const(cl2)))); + CHECK_FALSE(mi.safe_invoke(cl2)); + CHECK_FALSE(mi.safe_invoke(std::as_const(cl2))); + CHECK_FALSE(mi.safe_invoke(std::move(cl2))); + CHECK_FALSE(mi.safe_invoke(std::move(std::as_const(cl2)))); - CHECK_THROWS(mi.invoke(cl2v)); - CHECK_THROWS(mi.invoke(std::as_const(cl2v))); - CHECK_THROWS(mi.invoke(std::move(cl2v))); - CHECK_THROWS(mi.invoke(std::move(std::as_const(cl2v)))); + CHECK_FALSE(mi.safe_invoke(cl2v)); + CHECK_FALSE(mi.safe_invoke(std::as_const(cl2v))); + CHECK_FALSE(mi.safe_invoke(std::move(cl2v))); + CHECK_FALSE(mi.safe_invoke(std::move(std::as_const(cl2v)))); } static_assert(std::is_invocable_v); @@ -235,14 +235,14 @@ TEST_CASE("meta/meta_states/method") { meta::uvalue clv{cl}; CHECK(mi.invoke(cl).get_as() == 2); - CHECK_THROWS(mi.invoke(std::as_const(cl))); + CHECK_FALSE(mi.safe_invoke(std::as_const(cl))); CHECK(mi.invoke(std::move(cl)).get_as() == 2); - CHECK_THROWS(mi.invoke(std::move(std::as_const(cl)))); + CHECK_FALSE(mi.safe_invoke(std::move(std::as_const(cl)))); CHECK(mi.invoke(clv).get_as() == 2); - CHECK_THROWS(mi.invoke(std::as_const(clv))); + CHECK_FALSE(mi.safe_invoke(std::as_const(clv))); CHECK(mi.invoke(std::move(clv)).get_as() == 2); - CHECK_THROWS(mi.invoke(std::move(std::as_const(clv)))); + CHECK_FALSE(mi.safe_invoke(std::move(std::as_const(clv)))); } { @@ -264,15 +264,15 @@ TEST_CASE("meta/meta_states/method") { CHECK(mi.invoke(std::move(cl1v)).get_as() == 2); CHECK(mi.invoke(std::move(std::as_const(cl1v))).get_as() == 2); - CHECK_THROWS(mi.invoke(cl2)); - CHECK_THROWS(mi.invoke(std::as_const(cl2))); - CHECK_THROWS(mi.invoke(std::move(cl2))); - CHECK_THROWS(mi.invoke(std::move(std::as_const(cl2)))); + CHECK_FALSE(mi.safe_invoke(cl2)); + CHECK_FALSE(mi.safe_invoke(std::as_const(cl2))); + CHECK_FALSE(mi.safe_invoke(std::move(cl2))); + CHECK_FALSE(mi.safe_invoke(std::move(std::as_const(cl2)))); - CHECK_THROWS(mi.invoke(cl2v)); - CHECK_THROWS(mi.invoke(std::as_const(cl2v))); - CHECK_THROWS(mi.invoke(std::move(cl2v))); - CHECK_THROWS(mi.invoke(std::move(std::as_const(cl2v)))); + CHECK_FALSE(mi.safe_invoke(cl2v)); + CHECK_FALSE(mi.safe_invoke(std::as_const(cl2v))); + CHECK_FALSE(mi.safe_invoke(std::move(cl2v))); + CHECK_FALSE(mi.safe_invoke(std::move(std::as_const(cl2v)))); } static_assert(std::is_invocable_v); @@ -488,14 +488,14 @@ TEST_CASE("meta/meta_states/method") { meta::uvalue clv{cl}; CHECK(mi.invoke(cl).get_as() == 5); - CHECK_THROWS(mi.invoke(std::as_const(cl))); - CHECK_THROWS(mi.invoke(std::move(cl))); - CHECK_THROWS(mi.invoke(std::move(std::as_const(cl)))); + CHECK_FALSE(mi.safe_invoke(std::as_const(cl))); + CHECK_FALSE(mi.safe_invoke(std::move(cl))); + CHECK_FALSE(mi.safe_invoke(std::move(std::as_const(cl)))); CHECK(mi.invoke(clv).get_as() == 5); - CHECK_THROWS(mi.invoke(std::as_const(clv))); - CHECK_THROWS(mi.invoke(std::move(clv))); - CHECK_THROWS(mi.invoke(std::move(std::as_const(clv)))); + CHECK_FALSE(mi.safe_invoke(std::as_const(clv))); + CHECK_FALSE(mi.safe_invoke(std::move(clv))); + CHECK_FALSE(mi.safe_invoke(std::move(std::as_const(clv)))); } { @@ -517,15 +517,15 @@ TEST_CASE("meta/meta_states/method") { CHECK(mi.invoke(std::move(cl1v)).get_as() == 5); CHECK(mi.invoke(std::move(std::as_const(cl1v))).get_as() == 5); - CHECK_THROWS(mi.invoke(cl2)); - CHECK_THROWS(mi.invoke(std::as_const(cl2))); - CHECK_THROWS(mi.invoke(std::move(cl2))); - CHECK_THROWS(mi.invoke(std::move(std::as_const(cl2)))); + CHECK_FALSE(mi.safe_invoke(cl2)); + CHECK_FALSE(mi.safe_invoke(std::as_const(cl2))); + CHECK_FALSE(mi.safe_invoke(std::move(cl2))); + CHECK_FALSE(mi.safe_invoke(std::move(std::as_const(cl2)))); - CHECK_THROWS(mi.invoke(cl2v)); - CHECK_THROWS(mi.invoke(std::as_const(cl2v))); - CHECK_THROWS(mi.invoke(std::move(cl2v))); - CHECK_THROWS(mi.invoke(std::move(std::as_const(cl2v)))); + CHECK_FALSE(mi.safe_invoke(cl2v)); + CHECK_FALSE(mi.safe_invoke(std::as_const(cl2v))); + CHECK_FALSE(mi.safe_invoke(std::move(cl2v))); + CHECK_FALSE(mi.safe_invoke(std::move(std::as_const(cl2v)))); } static_assert(std::is_invocable_v); @@ -569,14 +569,14 @@ TEST_CASE("meta/meta_states/method") { meta::uvalue clv{cl}; CHECK(mi.invoke(cl).get_as() == 6); - CHECK_THROWS(mi.invoke(std::as_const(cl))); - CHECK_THROWS(mi.invoke(std::move(cl))); - CHECK_THROWS(mi.invoke(std::move(std::as_const(cl)))); + CHECK_FALSE(mi.safe_invoke(std::as_const(cl))); + CHECK_FALSE(mi.safe_invoke(std::move(cl))); + CHECK_FALSE(mi.safe_invoke(std::move(std::as_const(cl)))); CHECK(mi.invoke(clv).get_as() == 6); - CHECK_THROWS(mi.invoke(std::as_const(clv))); - CHECK_THROWS(mi.invoke(std::move(clv))); - CHECK_THROWS(mi.invoke(std::move(std::as_const(clv)))); + CHECK_FALSE(mi.safe_invoke(std::as_const(clv))); + CHECK_FALSE(mi.safe_invoke(std::move(clv))); + CHECK_FALSE(mi.safe_invoke(std::move(std::as_const(clv)))); } { @@ -598,15 +598,15 @@ TEST_CASE("meta/meta_states/method") { CHECK(mi.invoke(std::move(cl1v)).get_as() == 6); CHECK(mi.invoke(std::move(std::as_const(cl1v))).get_as() == 6); - CHECK_THROWS(mi.invoke(cl2)); - CHECK_THROWS(mi.invoke(std::as_const(cl2))); - CHECK_THROWS(mi.invoke(std::move(cl2))); - CHECK_THROWS(mi.invoke(std::move(std::as_const(cl2)))); + CHECK_FALSE(mi.safe_invoke(cl2)); + CHECK_FALSE(mi.safe_invoke(std::as_const(cl2))); + CHECK_FALSE(mi.safe_invoke(std::move(cl2))); + CHECK_FALSE(mi.safe_invoke(std::move(std::as_const(cl2)))); - CHECK_THROWS(mi.invoke(cl2v)); - CHECK_THROWS(mi.invoke(std::as_const(cl2v))); - CHECK_THROWS(mi.invoke(std::move(cl2v))); - CHECK_THROWS(mi.invoke(std::move(std::as_const(cl2v)))); + CHECK_FALSE(mi.safe_invoke(cl2v)); + CHECK_FALSE(mi.safe_invoke(std::as_const(cl2v))); + CHECK_FALSE(mi.safe_invoke(std::move(cl2v))); + CHECK_FALSE(mi.safe_invoke(std::move(std::as_const(cl2v)))); } static_assert(std::is_invocable_v); @@ -811,15 +811,15 @@ TEST_CASE("meta/meta_states/method") { derived_clazz cl; meta::uvalue clv{cl}; - CHECK_THROWS(mi.invoke(cl)); - CHECK_THROWS(mi.invoke(std::as_const(cl))); + CHECK_FALSE(mi.safe_invoke(cl)); + CHECK_FALSE(mi.safe_invoke(std::as_const(cl))); CHECK(mi.invoke(std::move(cl)).get_as() == 9); - CHECK_THROWS(mi.invoke(std::move(std::as_const(cl)))); + CHECK_FALSE(mi.safe_invoke(std::move(std::as_const(cl)))); - CHECK_THROWS(mi.invoke(clv)); - CHECK_THROWS(mi.invoke(std::as_const(clv))); + CHECK_FALSE(mi.safe_invoke(clv)); + CHECK_FALSE(mi.safe_invoke(std::as_const(clv))); CHECK(mi.invoke(std::move(clv)).get_as() == 9); - CHECK_THROWS(mi.invoke(std::move(std::as_const(clv)))); + CHECK_FALSE(mi.safe_invoke(std::move(std::as_const(clv)))); } { @@ -831,25 +831,25 @@ TEST_CASE("meta/meta_states/method") { meta::uvalue cl1v{cl1}; meta::uvalue cl2v{cl2}; - CHECK_THROWS(mi.invoke(cl1)); - CHECK_THROWS(mi.invoke(std::as_const(cl1))); - CHECK_THROWS(mi.invoke(std::move(cl1))); - CHECK_THROWS(mi.invoke(std::move(std::as_const(cl1)))); + CHECK_FALSE(mi.safe_invoke(cl1)); + CHECK_FALSE(mi.safe_invoke(std::as_const(cl1))); + CHECK_FALSE(mi.safe_invoke(std::move(cl1))); + CHECK_FALSE(mi.safe_invoke(std::move(std::as_const(cl1)))); - CHECK_THROWS(mi.invoke(cl1v)); - CHECK_THROWS(mi.invoke(std::as_const(cl1v))); - CHECK_THROWS(mi.invoke(std::move(cl1v))); - CHECK_THROWS(mi.invoke(std::move(std::as_const(cl1v)))); + CHECK_FALSE(mi.safe_invoke(cl1v)); + CHECK_FALSE(mi.safe_invoke(std::as_const(cl1v))); + CHECK_FALSE(mi.safe_invoke(std::move(cl1v))); + CHECK_FALSE(mi.safe_invoke(std::move(std::as_const(cl1v)))); - CHECK_THROWS(mi.invoke(cl2)); - CHECK_THROWS(mi.invoke(std::as_const(cl2))); - CHECK_THROWS(mi.invoke(std::move(cl2))); - CHECK_THROWS(mi.invoke(std::move(std::as_const(cl2)))); + CHECK_FALSE(mi.safe_invoke(cl2)); + CHECK_FALSE(mi.safe_invoke(std::as_const(cl2))); + CHECK_FALSE(mi.safe_invoke(std::move(cl2))); + CHECK_FALSE(mi.safe_invoke(std::move(std::as_const(cl2)))); - CHECK_THROWS(mi.invoke(cl2v)); - CHECK_THROWS(mi.invoke(std::as_const(cl2v))); - CHECK_THROWS(mi.invoke(std::move(cl2v))); - CHECK_THROWS(mi.invoke(std::move(std::as_const(cl2v)))); + CHECK_FALSE(mi.safe_invoke(cl2v)); + CHECK_FALSE(mi.safe_invoke(std::as_const(cl2v))); + CHECK_FALSE(mi.safe_invoke(std::move(cl2v))); + CHECK_FALSE(mi.safe_invoke(std::move(std::as_const(cl2v)))); } static_assert(!std::is_invocable_v); @@ -892,15 +892,15 @@ TEST_CASE("meta/meta_states/method") { derived_clazz cl; meta::uvalue clv{cl}; - CHECK_THROWS(mi.invoke(cl)); - CHECK_THROWS(mi.invoke(std::as_const(cl))); + CHECK_FALSE(mi.safe_invoke(cl)); + CHECK_FALSE(mi.safe_invoke(std::as_const(cl))); CHECK(mi.invoke(std::move(cl)).get_as() == 10); - CHECK_THROWS(mi.invoke(std::move(std::as_const(cl)))); + CHECK_FALSE(mi.safe_invoke(std::move(std::as_const(cl)))); - CHECK_THROWS(mi.invoke(clv)); - CHECK_THROWS(mi.invoke(std::as_const(clv))); + CHECK_FALSE(mi.safe_invoke(clv)); + CHECK_FALSE(mi.safe_invoke(std::as_const(clv))); CHECK(mi.invoke(std::move(clv)).get_as() == 10); - CHECK_THROWS(mi.invoke(std::move(std::as_const(clv)))); + CHECK_FALSE(mi.safe_invoke(std::move(std::as_const(clv)))); } { @@ -912,25 +912,25 @@ TEST_CASE("meta/meta_states/method") { meta::uvalue cl1v{cl1}; meta::uvalue cl2v{cl2}; - CHECK_THROWS(mi.invoke(cl1)); - CHECK_THROWS(mi.invoke(std::as_const(cl1))); - CHECK_THROWS(mi.invoke(std::move(cl1))); - CHECK_THROWS(mi.invoke(std::move(std::as_const(cl1)))); + CHECK_FALSE(mi.safe_invoke(cl1)); + CHECK_FALSE(mi.safe_invoke(std::as_const(cl1))); + CHECK_FALSE(mi.safe_invoke(std::move(cl1))); + CHECK_FALSE(mi.safe_invoke(std::move(std::as_const(cl1)))); - CHECK_THROWS(mi.invoke(cl1v)); - CHECK_THROWS(mi.invoke(std::as_const(cl1v))); - CHECK_THROWS(mi.invoke(std::move(cl1v))); - CHECK_THROWS(mi.invoke(std::move(std::as_const(cl1v)))); + CHECK_FALSE(mi.safe_invoke(cl1v)); + CHECK_FALSE(mi.safe_invoke(std::as_const(cl1v))); + CHECK_FALSE(mi.safe_invoke(std::move(cl1v))); + CHECK_FALSE(mi.safe_invoke(std::move(std::as_const(cl1v)))); - CHECK_THROWS(mi.invoke(cl2)); - CHECK_THROWS(mi.invoke(std::as_const(cl2))); - CHECK_THROWS(mi.invoke(std::move(cl2))); - CHECK_THROWS(mi.invoke(std::move(std::as_const(cl2)))); + CHECK_FALSE(mi.safe_invoke(cl2)); + CHECK_FALSE(mi.safe_invoke(std::as_const(cl2))); + CHECK_FALSE(mi.safe_invoke(std::move(cl2))); + CHECK_FALSE(mi.safe_invoke(std::move(std::as_const(cl2)))); - CHECK_THROWS(mi.invoke(cl2v)); - CHECK_THROWS(mi.invoke(std::as_const(cl2v))); - CHECK_THROWS(mi.invoke(std::move(cl2v))); - CHECK_THROWS(mi.invoke(std::move(std::as_const(cl2v)))); + CHECK_FALSE(mi.safe_invoke(cl2v)); + CHECK_FALSE(mi.safe_invoke(std::as_const(cl2v))); + CHECK_FALSE(mi.safe_invoke(std::move(cl2v))); + CHECK_FALSE(mi.safe_invoke(std::move(std::as_const(cl2v)))); } static_assert(!std::is_invocable_v); @@ -973,13 +973,13 @@ TEST_CASE("meta/meta_states/method") { derived_clazz cl; meta::uvalue clv{cl}; - CHECK_THROWS(mi.invoke(cl)); - CHECK_THROWS(mi.invoke(std::as_const(cl))); + CHECK_FALSE(mi.safe_invoke(cl)); + CHECK_FALSE(mi.safe_invoke(std::as_const(cl))); CHECK(mi.invoke(std::move(cl)).get_as() == 11); CHECK(mi.invoke(std::move(std::as_const(cl))).get_as() == 11); - CHECK_THROWS(mi.invoke(clv)); - CHECK_THROWS(mi.invoke(std::as_const(clv))); + CHECK_FALSE(mi.safe_invoke(clv)); + CHECK_FALSE(mi.safe_invoke(std::as_const(clv))); CHECK(mi.invoke(std::move(clv)).get_as() == 11); CHECK(mi.invoke(std::move(std::as_const(clv))).get_as() == 11); } @@ -993,25 +993,25 @@ TEST_CASE("meta/meta_states/method") { meta::uvalue cl1v{cl1}; meta::uvalue cl2v{cl2}; - CHECK_THROWS(mi.invoke(cl1)); - CHECK_THROWS(mi.invoke(std::as_const(cl1))); - CHECK_THROWS(mi.invoke(std::move(cl1))); - CHECK_THROWS(mi.invoke(std::move(std::as_const(cl1)))); + CHECK_FALSE(mi.safe_invoke(cl1)); + CHECK_FALSE(mi.safe_invoke(std::as_const(cl1))); + CHECK_FALSE(mi.safe_invoke(std::move(cl1))); + CHECK_FALSE(mi.safe_invoke(std::move(std::as_const(cl1)))); - CHECK_THROWS(mi.invoke(cl1v)); - CHECK_THROWS(mi.invoke(std::as_const(cl1v))); - CHECK_THROWS(mi.invoke(std::move(cl1v))); - CHECK_THROWS(mi.invoke(std::move(std::as_const(cl1v)))); + CHECK_FALSE(mi.safe_invoke(cl1v)); + CHECK_FALSE(mi.safe_invoke(std::as_const(cl1v))); + CHECK_FALSE(mi.safe_invoke(std::move(cl1v))); + CHECK_FALSE(mi.safe_invoke(std::move(std::as_const(cl1v)))); - CHECK_THROWS(mi.invoke(cl2)); - CHECK_THROWS(mi.invoke(std::as_const(cl2))); - CHECK_THROWS(mi.invoke(std::move(cl2))); - CHECK_THROWS(mi.invoke(std::move(std::as_const(cl2)))); + CHECK_FALSE(mi.safe_invoke(cl2)); + CHECK_FALSE(mi.safe_invoke(std::as_const(cl2))); + CHECK_FALSE(mi.safe_invoke(std::move(cl2))); + CHECK_FALSE(mi.safe_invoke(std::move(std::as_const(cl2)))); - CHECK_THROWS(mi.invoke(cl2v)); - CHECK_THROWS(mi.invoke(std::as_const(cl2v))); - CHECK_THROWS(mi.invoke(std::move(cl2v))); - CHECK_THROWS(mi.invoke(std::move(std::as_const(cl2v)))); + CHECK_FALSE(mi.safe_invoke(cl2v)); + CHECK_FALSE(mi.safe_invoke(std::as_const(cl2v))); + CHECK_FALSE(mi.safe_invoke(std::move(cl2v))); + CHECK_FALSE(mi.safe_invoke(std::move(std::as_const(cl2v)))); } static_assert(!std::is_invocable_v); @@ -1054,13 +1054,13 @@ TEST_CASE("meta/meta_states/method") { derived_clazz cl; meta::uvalue clv{cl}; - CHECK_THROWS(mi.invoke(cl)); - CHECK_THROWS(mi.invoke(std::as_const(cl))); + CHECK_FALSE(mi.safe_invoke(cl)); + CHECK_FALSE(mi.safe_invoke(std::as_const(cl))); CHECK(mi.invoke(std::move(cl)).get_as() == 12); CHECK(mi.invoke(std::move(std::as_const(cl))).get_as() == 12); - CHECK_THROWS(mi.invoke(clv)); - CHECK_THROWS(mi.invoke(std::as_const(clv))); + CHECK_FALSE(mi.safe_invoke(clv)); + CHECK_FALSE(mi.safe_invoke(std::as_const(clv))); CHECK(mi.invoke(std::move(clv)).get_as() == 12); CHECK(mi.invoke(std::move(std::as_const(clv))).get_as() == 12); } @@ -1074,25 +1074,25 @@ TEST_CASE("meta/meta_states/method") { meta::uvalue cl1v{cl1}; meta::uvalue cl2v{cl2}; - CHECK_THROWS(mi.invoke(cl1)); - CHECK_THROWS(mi.invoke(std::as_const(cl1))); - CHECK_THROWS(mi.invoke(std::move(cl1))); - CHECK_THROWS(mi.invoke(std::move(std::as_const(cl1)))); + CHECK_FALSE(mi.safe_invoke(cl1)); + CHECK_FALSE(mi.safe_invoke(std::as_const(cl1))); + CHECK_FALSE(mi.safe_invoke(std::move(cl1))); + CHECK_FALSE(mi.safe_invoke(std::move(std::as_const(cl1)))); - CHECK_THROWS(mi.invoke(cl1v)); - CHECK_THROWS(mi.invoke(std::as_const(cl1v))); - CHECK_THROWS(mi.invoke(std::move(cl1v))); - CHECK_THROWS(mi.invoke(std::move(std::as_const(cl1v)))); + CHECK_FALSE(mi.safe_invoke(cl1v)); + CHECK_FALSE(mi.safe_invoke(std::as_const(cl1v))); + CHECK_FALSE(mi.safe_invoke(std::move(cl1v))); + CHECK_FALSE(mi.safe_invoke(std::move(std::as_const(cl1v)))); - CHECK_THROWS(mi.invoke(cl2)); - CHECK_THROWS(mi.invoke(std::as_const(cl2))); - CHECK_THROWS(mi.invoke(std::move(cl2))); - CHECK_THROWS(mi.invoke(std::move(std::as_const(cl2)))); + CHECK_FALSE(mi.safe_invoke(cl2)); + CHECK_FALSE(mi.safe_invoke(std::as_const(cl2))); + CHECK_FALSE(mi.safe_invoke(std::move(cl2))); + CHECK_FALSE(mi.safe_invoke(std::move(std::as_const(cl2)))); - CHECK_THROWS(mi.invoke(cl2v)); - CHECK_THROWS(mi.invoke(std::as_const(cl2v))); - CHECK_THROWS(mi.invoke(std::move(cl2v))); - CHECK_THROWS(mi.invoke(std::move(std::as_const(cl2v)))); + CHECK_FALSE(mi.safe_invoke(cl2v)); + CHECK_FALSE(mi.safe_invoke(std::as_const(cl2v))); + CHECK_FALSE(mi.safe_invoke(std::move(cl2v))); + CHECK_FALSE(mi.safe_invoke(std::move(std::as_const(cl2v)))); } static_assert(!std::is_invocable_v); diff --git a/develop/untests/meta_states/variable_tests.cpp b/develop/untests/meta_states/variable_tests.cpp index 0e9a86f..d28e2d1 100644 --- a/develop/untests/meta_states/variable_tests.cpp +++ b/develop/untests/meta_states/variable_tests.cpp @@ -23,27 +23,23 @@ namespace }; struct clazz_1 { - static int int_variable; - static const int const_int_variable; + inline static int int_variable{1}; + inline static const int const_int_variable{2}; - static int& ref_int_variable; - static const int& const_ref_int_variable; + inline static int& ref_int_variable = int_variable; + inline static const int& const_ref_int_variable = const_int_variable; - static unique_int unique_int_variable; - static const unique_int const_unique_int_variable; + inline static unique_int unique_int_variable{}; + inline static const unique_int const_unique_int_variable{}; + + static void reset() { + int_variable = 1; + unique_int_variable = unique_int{}; + } }; - - int clazz_1::int_variable = 1; - const int clazz_1::const_int_variable = 2; - - int& clazz_1::ref_int_variable = clazz_1::int_variable; - const int& clazz_1::const_ref_int_variable = clazz_1::const_int_variable; - - unique_int clazz_1::unique_int_variable; - const unique_int clazz_1::const_unique_int_variable; } -TEST_CASE("meta/meta_states/variable") { +TEST_CASE("meta/meta_states/variable/_") { namespace meta = meta_hpp; meta::class_() @@ -59,6 +55,12 @@ TEST_CASE("meta/meta_states/variable") { // .variable_("const_unique_int_variable", &clazz_1::const_unique_int_variable) .variable_("const_unique_int_variable_as_ptr", &clazz_1::const_unique_int_variable, meta::variable_policy::as_pointer) .variable_("const_unique_int_variable_as_ref", &clazz_1::const_unique_int_variable, meta::variable_policy::as_reference_wrapper); +} + +TEST_CASE("meta/meta_states/variable") { + namespace meta = meta_hpp; + + clazz_1::reset(); const meta::class_type clazz_1_type = meta::resolve_type(); REQUIRE(clazz_1_type); @@ -122,8 +124,7 @@ TEST_CASE("meta/meta_states/variable") { CHECK_FALSE(vm.is_settable_with()); CHECK_FALSE(vm.is_settable_with(1.0)); - CHECK_THROWS(vm.set(10)); CHECK(vm.get_as() == 2); - CHECK_THROWS(vm(10)); CHECK(vm().get_as() == 2); + CHECK_FALSE(vm.safe_set(10)); CHECK(vm.get_as() == 2); } SUBCASE("ref int") { @@ -133,8 +134,8 @@ TEST_CASE("meta/meta_states/variable") { CHECK(vm.get_type() == meta::resolve_type(&clazz_1::ref_int_variable)); CHECK(vm.get_name() == "ref_int_variable"); - CHECK(vm.get_as() == 11); - CHECK(vm().get_as() == 11); + CHECK(vm.get_as() == 1); + CHECK(vm().get_as() == 1); CHECK(vm.is_settable_with()); CHECK(vm.is_settable_with()); @@ -170,8 +171,7 @@ TEST_CASE("meta/meta_states/variable") { CHECK_FALSE(vm.is_settable_with()); CHECK_FALSE(vm.is_settable_with(1.0)); - CHECK_THROWS(vm.set(10)); CHECK(vm.get_as() == 2); - CHECK_THROWS(vm(11)); CHECK(vm().get_as() == 2); + CHECK_FALSE(vm.safe_set(10)); CHECK(vm.get_as() == 2); } SUBCASE("unique_int_variable_as_ptr") { @@ -189,7 +189,7 @@ TEST_CASE("meta/meta_states/variable") { { unique_int nv{12}; - CHECK_THROWS(vm.set(nv)); + CHECK_FALSE(vm.safe_set(nv)); CHECK(clazz_1::unique_int_variable.i == 11); } } @@ -210,7 +210,7 @@ TEST_CASE("meta/meta_states/variable") { { unique_int nv{14}; - CHECK_THROWS(vm.set(nv)); + CHECK_FALSE(vm.safe_set(nv)); CHECK(clazz_1::unique_int_variable.i == 13); } } @@ -224,8 +224,8 @@ TEST_CASE("meta/meta_states/variable") { { unique_int nv{11}; - CHECK_THROWS(vm.set(nv)); - CHECK_THROWS(vm.set(std::move(nv))); + CHECK_FALSE(vm.safe_set(nv)); + CHECK_FALSE(vm.safe_set(std::move(nv))); CHECK(clazz_1::const_unique_int_variable.i == 42); } } @@ -240,9 +240,36 @@ TEST_CASE("meta/meta_states/variable") { { unique_int nv{12}; - CHECK_THROWS(vm.set(nv)); - CHECK_THROWS(vm.set(std::move(nv))); + CHECK_FALSE(vm.safe_set(nv)); + CHECK_FALSE(vm.safe_set(std::move(nv))); CHECK(clazz_1::const_unique_int_variable.i == 42); } } + + SUBCASE("safe_get") { + meta::variable vm = clazz_1_type.get_variable("int_variable"); + REQUIRE(vm); + + CHECK(vm.safe_get()); + CHECK(vm.safe_get()->get_as() == 1); + } + + SUBCASE("safe_get_as") { + meta::variable vm = clazz_1_type.get_variable("int_variable"); + REQUIRE(vm); + + CHECK(vm.safe_get_as() == 1); + CHECK_FALSE(vm.safe_get_as()); + } + + SUBCASE("safe_set") { + meta::variable vm = clazz_1_type.get_variable("int_variable"); + REQUIRE(vm); + + CHECK(vm.safe_set(10)); + CHECK(vm.get_as() == 10); + + CHECK_FALSE(vm.safe_set(unique_int{})); + CHECK(vm.get_as() == 10); + } } diff --git a/develop/untests/meta_types/enum_type_tests.cpp b/develop/untests/meta_types/enum_type_tests.cpp index f48178c..6aa5faa 100644 --- a/develop/untests/meta_types/enum_type_tests.cpp +++ b/develop/untests/meta_types/enum_type_tests.cpp @@ -151,13 +151,21 @@ TEST_CASE("meta/meta_types/enum_type") { REQUIRE(color_type.name_to_value("blue")); CHECK(color_type.name_to_value("blue").get_as() == color::blue); CHECK(color_type.name_to_value_as("blue") == color::blue); - CHECK_THROWS(std::ignore = color_type.name_to_value_as("blue")); + CHECK_THROWS(std::ignore = color_type.name_to_value_as("blue")); } { REQUIRE_FALSE(color_type.name_to_value("yellow")); CHECK_THROWS(std::ignore = color_type.name_to_value_as("yellow")); - CHECK_THROWS(std::ignore = color_type.name_to_value_as("yellow")); + CHECK_THROWS(std::ignore = color_type.name_to_value_as("yellow")); + } + + { + REQUIRE(color_type.safe_name_to_value_as("blue")); + CHECK(color_type.safe_name_to_value_as("blue") == color::blue); + + CHECK_FALSE(color_type.safe_name_to_value_as("blue")); + CHECK_FALSE(color_type.safe_name_to_value_as("yellow")); } } @@ -169,13 +177,21 @@ TEST_CASE("meta/meta_types/enum_type") { REQUIRE(ecolor_type.name_to_value("blue")); CHECK(ecolor_type.name_to_value("blue").get_as() == ecolor_blue); CHECK(ecolor_type.name_to_value_as("blue") == ecolor_blue); - CHECK_THROWS(std::ignore = ecolor_type.name_to_value_as("blue")); + CHECK_THROWS(std::ignore = ecolor_type.name_to_value_as("blue")); } { REQUIRE_FALSE(ecolor_type.name_to_value("yellow")); CHECK_THROWS(std::ignore = ecolor_type.name_to_value_as("yellow")); - CHECK_THROWS(std::ignore = ecolor_type.name_to_value_as("yellow")); + CHECK_THROWS(std::ignore = ecolor_type.name_to_value_as("yellow")); + } + + { + REQUIRE(ecolor_type.safe_name_to_value_as("blue")); + CHECK(ecolor_type.safe_name_to_value_as("blue") == ecolor_blue); + + CHECK_FALSE(ecolor_type.safe_name_to_value_as("blue")); + CHECK_FALSE(ecolor_type.safe_name_to_value_as("yellow")); } } } diff --git a/develop/untests/meta_utilities/arg2_tests.cpp b/develop/untests/meta_utilities/arg2_tests.cpp index d41f329..2bf9c26 100644 --- a/develop/untests/meta_utilities/arg2_tests.cpp +++ b/develop/untests/meta_utilities/arg2_tests.cpp @@ -114,8 +114,8 @@ TEST_CASE("meta/meta_utilities/arg2/cast") { CHECK(uarg{LV()}.cast().f() == 1); CHECK(uarg{LV()}.cast().f() == 1); CHECK(uarg{LV()}.cast().f() == 1); - CHECK_THROWS(std::ignore = uarg{LV()}.cast()); - CHECK_THROWS(std::ignore = uarg{LV()}.cast()); + // CHECK_THROWS(std::ignore = uarg{LV()}.cast()); + // CHECK_THROWS(std::ignore = uarg{LV()}.cast()); CHECK(A::copy_ctors_ == 2); CHECK(A::move_ctors_ == 0); @@ -134,10 +134,10 @@ TEST_CASE("meta/meta_utilities/arg2/cast") { CHECK(uarg{CLV()}.cast().f() == 1); CHECK(uarg{CLV()}.cast().f() == 1); - CHECK_THROWS(std::ignore = uarg{CLV()}.cast()); + // CHECK_THROWS(std::ignore = uarg{CLV()}.cast()); CHECK(uarg{CLV()}.cast().f() == 1); - CHECK_THROWS(std::ignore = uarg{CLV()}.cast()); - CHECK_THROWS(std::ignore = uarg{CLV()}.cast()); + // CHECK_THROWS(std::ignore = uarg{CLV()}.cast()); + // CHECK_THROWS(std::ignore = uarg{CLV()}.cast()); CHECK(A::copy_ctors_ == 2); CHECK(A::move_ctors_ == 0); @@ -156,7 +156,7 @@ TEST_CASE("meta/meta_utilities/arg2/cast") { CHECK(uarg{XV()}.cast().f() == 1); CHECK(uarg{XV()}.cast().f() == 1); - CHECK_THROWS(std::ignore = uarg{XV()}.cast()); + // CHECK_THROWS(std::ignore = uarg{XV()}.cast()); CHECK(uarg{XV()}.cast().f() == 1); CHECK(uarg{XV()}.cast().f() == 1); CHECK(uarg{XV()}.cast().f() == 1); @@ -178,9 +178,9 @@ TEST_CASE("meta/meta_utilities/arg2/cast") { CHECK(uarg{CXV()}.cast().f() == 1); CHECK(uarg{CXV()}.cast().f() == 1); - CHECK_THROWS(std::ignore = uarg{CXV()}.cast()); + // CHECK_THROWS(std::ignore = uarg{CXV()}.cast()); CHECK(uarg{CXV()}.cast().f() == 1); - CHECK_THROWS(std::ignore = uarg{CXV()}.cast()); + // CHECK_THROWS(std::ignore = uarg{CXV()}.cast()); CHECK(uarg{CXV()}.cast().f() == 1); CHECK(A::copy_ctors_ == 2); @@ -200,7 +200,7 @@ TEST_CASE("meta/meta_utilities/arg2/cast") { CHECK(uarg{PRV()}.cast().f() == 1); CHECK(uarg{PRV()}.cast().f() == 1); - CHECK_THROWS(std::ignore = uarg{PRV()}.cast()); + // CHECK_THROWS(std::ignore = uarg{PRV()}.cast()); CHECK(uarg{PRV()}.cast().f() == 1); CHECK(uarg{PRV()}.cast().f() == 1); CHECK(uarg{PRV()}.cast().f() == 1); @@ -222,9 +222,9 @@ TEST_CASE("meta/meta_utilities/arg2/cast") { CHECK(uarg{CPRV()}.cast().f() == 1); CHECK(uarg{CPRV()}.cast().f() == 1); - CHECK_THROWS(std::ignore = uarg{CPRV()}.cast()); + // CHECK_THROWS(std::ignore = uarg{CPRV()}.cast()); CHECK(uarg{CPRV()}.cast().f() == 1); - CHECK_THROWS(std::ignore = uarg{CPRV()}.cast()); + // CHECK_THROWS(std::ignore = uarg{CPRV()}.cast()); CHECK(uarg{CPRV()}.cast().f() == 1); CHECK(A::copy_ctors_ == 2); @@ -249,8 +249,8 @@ TEST_CASE("meta/meta_utilities/arg2/cast") { CHECK(uarg{LV_CPTR()}.can_cast_to()); CHECK(uarg{LV_CPTR()}.can_cast_to()); - CHECK_THROWS(std::ignore = uarg{LV_CPTR()}.cast()); - CHECK_THROWS(std::ignore = uarg{LV_CPTR()}.cast()); + // CHECK_THROWS(std::ignore = uarg{LV_CPTR()}.cast()); + // CHECK_THROWS(std::ignore = uarg{LV_CPTR()}.cast()); CHECK(uarg{LV_CPTR()}.cast()->f() == 1); CHECK(uarg{LV_CPTR()}.cast()->f() == 1); } @@ -273,8 +273,8 @@ TEST_CASE("meta/meta_utilities/arg2/cast") { CHECK(uarg{CLV_CPTR()}.can_cast_to()); CHECK(uarg{CLV_CPTR()}.can_cast_to()); - CHECK_THROWS(std::ignore = uarg{CLV_CPTR()}.cast()); - CHECK_THROWS(std::ignore = uarg{CLV_CPTR()}.cast()); + // CHECK_THROWS(std::ignore = uarg{CLV_CPTR()}.cast()); + // CHECK_THROWS(std::ignore = uarg{CLV_CPTR()}.cast()); CHECK(uarg{CLV_CPTR()}.cast()->f() == 1); CHECK(uarg{CLV_CPTR()}.cast()->f() == 1); } @@ -297,8 +297,8 @@ TEST_CASE("meta/meta_utilities/arg2/cast") { CHECK(uarg{XV_CPTR()}.can_cast_to()); CHECK(uarg{XV_CPTR()}.can_cast_to()); - CHECK_THROWS(std::ignore = uarg{XV_CPTR()}.cast()); - CHECK_THROWS(std::ignore = uarg{XV_CPTR()}.cast()); + // CHECK_THROWS(std::ignore = uarg{XV_CPTR()}.cast()); + // CHECK_THROWS(std::ignore = uarg{XV_CPTR()}.cast()); CHECK(uarg{XV_CPTR()}.cast()->f() == 1); CHECK(uarg{XV_CPTR()}.cast()->f() == 1); } @@ -321,8 +321,8 @@ TEST_CASE("meta/meta_utilities/arg2/cast") { CHECK(uarg{CXV_CPTR()}.can_cast_to()); CHECK(uarg{CXV_CPTR()}.can_cast_to()); - CHECK_THROWS(std::ignore = uarg{CXV_CPTR()}.cast()); - CHECK_THROWS(std::ignore = uarg{CXV_CPTR()}.cast()); + // CHECK_THROWS(std::ignore = uarg{CXV_CPTR()}.cast()); + // CHECK_THROWS(std::ignore = uarg{CXV_CPTR()}.cast()); CHECK(uarg{CXV_CPTR()}.cast()->f() == 1); CHECK(uarg{CXV_CPTR()}.cast()->f() == 1); } @@ -345,8 +345,8 @@ TEST_CASE("meta/meta_utilities/arg2/cast") { CHECK(uarg{PRV_CPTR()}.can_cast_to()); CHECK(uarg{PRV_CPTR()}.can_cast_to()); - CHECK_THROWS(std::ignore = uarg{PRV_CPTR()}.cast()); - CHECK_THROWS(std::ignore = uarg{PRV_CPTR()}.cast()); + // CHECK_THROWS(std::ignore = uarg{PRV_CPTR()}.cast()); + // CHECK_THROWS(std::ignore = uarg{PRV_CPTR()}.cast()); CHECK(uarg{PRV_CPTR()}.cast()->f() == 1); CHECK(uarg{PRV_CPTR()}.cast()->f() == 1); } diff --git a/develop/untests/meta_utilities/arg3_tests.cpp b/develop/untests/meta_utilities/arg3_tests.cpp index 3b8e441..a228cd2 100644 --- a/develop/untests/meta_utilities/arg3_tests.cpp +++ b/develop/untests/meta_utilities/arg3_tests.cpp @@ -82,47 +82,47 @@ TEST_CASE("meta/meta_utilities/arg3/cast") { CHECK_FALSE(uarg{LV()}.can_cast_to()); CHECK_FALSE(uarg{LV()}.can_cast_to()); - CHECK_THROWS(std::ignore = uarg{LV()}.cast()); - CHECK_THROWS(std::ignore = uarg{LV()}.cast()); + // CHECK_THROWS(std::ignore = uarg{LV()}.cast()); + // CHECK_THROWS(std::ignore = uarg{LV()}.cast()); } SUBCASE("CLV") { CHECK_FALSE(uarg{CLV()}.can_cast_to()); CHECK_FALSE(uarg{CLV()}.can_cast_to()); - CHECK_THROWS(std::ignore = uarg{CLV()}.cast()); - CHECK_THROWS(std::ignore = uarg{CLV()}.cast()); + // CHECK_THROWS(std::ignore = uarg{CLV()}.cast()); + // CHECK_THROWS(std::ignore = uarg{CLV()}.cast()); } SUBCASE("XV") { CHECK_FALSE(uarg{XV()}.can_cast_to()); CHECK_FALSE(uarg{XV()}.can_cast_to()); - CHECK_THROWS(std::ignore = uarg{XV()}.cast()); - CHECK_THROWS(std::ignore = uarg{XV()}.cast()); + // CHECK_THROWS(std::ignore = uarg{XV()}.cast()); + // CHECK_THROWS(std::ignore = uarg{XV()}.cast()); } SUBCASE("CXV") { CHECK_FALSE(uarg{CXV()}.can_cast_to()); CHECK_FALSE(uarg{CXV()}.can_cast_to()); - CHECK_THROWS(std::ignore = uarg{CXV()}.cast()); - CHECK_THROWS(std::ignore = uarg{CXV()}.cast()); + // CHECK_THROWS(std::ignore = uarg{CXV()}.cast()); + // CHECK_THROWS(std::ignore = uarg{CXV()}.cast()); } SUBCASE("PRV") { CHECK_FALSE(uarg{PRV()}.can_cast_to()); CHECK_FALSE(uarg{PRV()}.can_cast_to()); - CHECK_THROWS(std::ignore = uarg{PRV()}.cast()); - CHECK_THROWS(std::ignore = uarg{PRV()}.cast()); + // CHECK_THROWS(std::ignore = uarg{PRV()}.cast()); + // CHECK_THROWS(std::ignore = uarg{PRV()}.cast()); } SUBCASE("CPRV") { CHECK_FALSE(uarg{CPRV()}.can_cast_to()); CHECK_FALSE(uarg{CPRV()}.can_cast_to()); - CHECK_THROWS(std::ignore = uarg{CPRV()}.cast()); - CHECK_THROWS(std::ignore = uarg{CPRV()}.cast()); + // CHECK_THROWS(std::ignore = uarg{CPRV()}.cast()); + // CHECK_THROWS(std::ignore = uarg{CPRV()}.cast()); } } diff --git a/develop/untests/meta_utilities/arg4_tests.cpp b/develop/untests/meta_utilities/arg4_tests.cpp index c35e440..921c0f0 100644 --- a/develop/untests/meta_utilities/arg4_tests.cpp +++ b/develop/untests/meta_utilities/arg4_tests.cpp @@ -89,8 +89,8 @@ TEST_CASE("meta/meta_utilities/arg4/cast") { CHECK(uarg{LV_CPTR()}.can_cast_to()); CHECK(uarg{LV_CPTR()}.can_cast_to()); - CHECK_THROWS(std::ignore = uarg{LV_CPTR()}.cast()); - CHECK_THROWS(std::ignore = uarg{LV_CPTR()}.cast()); + // CHECK_THROWS(std::ignore = uarg{LV_CPTR()}.cast()); + // CHECK_THROWS(std::ignore = uarg{LV_CPTR()}.cast()); CHECK(*uarg{LV_CPTR()}.cast() == 42); CHECK(*uarg{LV_CPTR()}.cast() == 42); } @@ -101,8 +101,8 @@ TEST_CASE("meta/meta_utilities/arg4/cast") { CHECK(uarg{CLV_CPTR()}.can_cast_to()); CHECK(uarg{CLV_CPTR()}.can_cast_to()); - CHECK_THROWS(std::ignore = uarg{CLV_CPTR()}.cast()); - CHECK_THROWS(std::ignore = uarg{CLV_CPTR()}.cast()); + // CHECK_THROWS(std::ignore = uarg{CLV_CPTR()}.cast()); + // CHECK_THROWS(std::ignore = uarg{CLV_CPTR()}.cast()); CHECK(*uarg{CLV_CPTR()}.cast() == 42); CHECK(*uarg{CLV_CPTR()}.cast() == 42); } @@ -113,8 +113,8 @@ TEST_CASE("meta/meta_utilities/arg4/cast") { CHECK(uarg{XV_CPTR()}.can_cast_to()); CHECK(uarg{XV_CPTR()}.can_cast_to()); - CHECK_THROWS(std::ignore = uarg{XV_CPTR()}.cast()); - CHECK_THROWS(std::ignore = uarg{XV_CPTR()}.cast()); + // CHECK_THROWS(std::ignore = uarg{XV_CPTR()}.cast()); + // CHECK_THROWS(std::ignore = uarg{XV_CPTR()}.cast()); CHECK(*uarg{XV_CPTR()}.cast() == 42); CHECK(*uarg{XV_CPTR()}.cast() == 42); } @@ -125,8 +125,8 @@ TEST_CASE("meta/meta_utilities/arg4/cast") { CHECK(uarg{CXV_CPTR()}.can_cast_to()); CHECK(uarg{CXV_CPTR()}.can_cast_to()); - CHECK_THROWS(std::ignore = uarg{CXV_CPTR()}.cast()); - CHECK_THROWS(std::ignore = uarg{CXV_CPTR()}.cast()); + // CHECK_THROWS(std::ignore = uarg{CXV_CPTR()}.cast()); + // CHECK_THROWS(std::ignore = uarg{CXV_CPTR()}.cast()); CHECK(*uarg{CXV_CPTR()}.cast() == 42); CHECK(*uarg{CXV_CPTR()}.cast() == 42); } @@ -137,8 +137,8 @@ TEST_CASE("meta/meta_utilities/arg4/cast") { CHECK(uarg{PRV_CPTR()}.can_cast_to()); CHECK(uarg{PRV_CPTR()}.can_cast_to()); - CHECK_THROWS(std::ignore = uarg{PRV_CPTR()}.cast()); - CHECK_THROWS(std::ignore = uarg{PRV_CPTR()}.cast()); + // CHECK_THROWS(std::ignore = uarg{PRV_CPTR()}.cast()); + // CHECK_THROWS(std::ignore = uarg{PRV_CPTR()}.cast()); CHECK(*uarg{PRV_CPTR()}.cast() == 42); CHECK(*uarg{PRV_CPTR()}.cast() == 42); } diff --git a/develop/untests/meta_utilities/arg5_tests.cpp b/develop/untests/meta_utilities/arg5_tests.cpp index 0c410fd..1c27dd5 100644 --- a/develop/untests/meta_utilities/arg5_tests.cpp +++ b/develop/untests/meta_utilities/arg5_tests.cpp @@ -85,9 +85,9 @@ TEST_CASE("meta/meta_utilities/arg5/cast") { CHECK_FALSE(uarg(arr).can_cast_to()); CHECK(uarg(arr).can_cast_to()); - CHECK_THROWS(std::ignore = uarg(arr).cast()); + // CHECK_THROWS(std::ignore = uarg(arr).cast()); CHECK(uarg(arr).cast() == static_cast(arr)); - CHECK_THROWS(std::ignore = uarg(arr).cast()); + // CHECK_THROWS(std::ignore = uarg(arr).cast()); CHECK(uarg(arr).cast() == static_cast(arr)); } @@ -125,9 +125,9 @@ TEST_CASE("meta/meta_utilities/arg5/cast") { CHECK_FALSE(uarg(arr).can_cast_to()); CHECK(uarg(arr).can_cast_to()); - CHECK_THROWS(std::ignore = uarg(arr).cast()); + // CHECK_THROWS(std::ignore = uarg(arr).cast()); CHECK(uarg(arr).cast() == static_cast(arr)); - CHECK_THROWS(std::ignore = uarg(arr).cast()); + // CHECK_THROWS(std::ignore = uarg(arr).cast()); CHECK(uarg(arr).cast() == static_cast(arr)); } @@ -164,9 +164,9 @@ TEST_CASE("meta/meta_utilities/arg5/cast") { static_assert(!std::is_invocable_v); static_assert(std::is_invocable_v); - CHECK_THROWS(std::ignore = uarg(CLV()).cast()); + // CHECK_THROWS(std::ignore = uarg(CLV()).cast()); CHECK(uarg(CLV()).cast() == static_cast(src)); - CHECK_THROWS(std::ignore = uarg(CLV()).cast()); + // CHECK_THROWS(std::ignore = uarg(CLV()).cast()); CHECK(uarg(CLV()).cast() == static_cast(src)); } @@ -194,9 +194,9 @@ TEST_CASE("meta/meta_utilities/arg5/cast") { static_assert(!std::is_invocable_v); static_assert(std::is_invocable_v); - CHECK_THROWS(std::ignore = uarg(CXV()).cast()); + // CHECK_THROWS(std::ignore = uarg(CXV()).cast()); CHECK(uarg(CXV()).cast() == static_cast(src)); - CHECK_THROWS(std::ignore = uarg(CXV()).cast()); + // CHECK_THROWS(std::ignore = uarg(CXV()).cast()); CHECK(uarg(CXV()).cast() == static_cast(src)); } } @@ -244,11 +244,11 @@ TEST_CASE("meta/meta_utilities/arg5/cast") { CHECK_FALSE(uarg{&arr}.can_cast_to()); CHECK(uarg{&arr}.can_cast_to()); - CHECK_THROWS(std::ignore = &uarg{arr}.cast()); + // CHECK_THROWS(std::ignore = &uarg{arr}.cast()); CHECK(&uarg{arr}.cast() == &arr); - CHECK_THROWS(std::ignore = uarg{&arr}.cast()); + // CHECK_THROWS(std::ignore = uarg{&arr}.cast()); CHECK(uarg{&arr}.cast() == &arr); - CHECK_THROWS(std::ignore = uarg{&arr}.cast()); + // CHECK_THROWS(std::ignore = uarg{&arr}.cast()); CHECK(uarg{&arr}.cast() == &arr); } } diff --git a/develop/untests/meta_utilities/arg7_tests.cpp b/develop/untests/meta_utilities/arg7_tests.cpp index cd4b5e0..2e43ed0 100644 --- a/develop/untests/meta_utilities/arg7_tests.cpp +++ b/develop/untests/meta_utilities/arg7_tests.cpp @@ -73,7 +73,7 @@ TEST_CASE("meta/meta_utilities/arg7/cast/to_void") { CHECK_FALSE(uarg{&i}.can_cast_to()); CHECK(uarg{&i}.can_cast_to()); - CHECK_THROWS(std::ignore = uarg{&i}.cast()); + // CHECK_THROWS(std::ignore = uarg{&i}.cast()); CHECK(uarg{&i}.cast() == &i); } @@ -99,7 +99,7 @@ TEST_CASE("meta/meta_utilities/arg7/cast/to_void") { CHECK_FALSE(uarg{&d}.can_cast_to()); CHECK(uarg{&d}.can_cast_to()); - CHECK_THROWS(std::ignore = uarg{&d}.cast()); + // CHECK_THROWS(std::ignore = uarg{&d}.cast()); CHECK(uarg{&d}.cast() == &d); } @@ -125,7 +125,7 @@ TEST_CASE("meta/meta_utilities/arg7/cast/to_void") { CHECK_FALSE(uarg{arr}.can_cast_to()); CHECK(uarg{arr}.can_cast_to()); - CHECK_THROWS(std::ignore = uarg{arr}.cast()); + // CHECK_THROWS(std::ignore = uarg{arr}.cast()); CHECK(uarg{arr}.cast() == &arr); } } diff --git a/develop/untests/meta_utilities/arg_tests.cpp b/develop/untests/meta_utilities/arg_tests.cpp index 200fc4d..ace207c 100644 --- a/develop/untests/meta_utilities/arg_tests.cpp +++ b/develop/untests/meta_utilities/arg_tests.cpp @@ -83,10 +83,10 @@ namespace } else {\ CHECK_FALSE(uarg{FromValue}.can_cast_to());\ CHECK_FALSE(uarg_base{type_list{}}.can_cast_to());\ - CHECK_THROWS(std::ignore = uarg{FromValue}.cast());\ + /*CHECK_THROWS(std::ignore = uarg{FromValue}.cast());*/\ \ CHECK_FALSE(f_state.is_invocable_with());\ - CHECK_THROWS(f_state.invoke(FromValue));\ + CHECK_FALSE(f_state.safe_invoke(FromValue));\ }\ } @@ -104,7 +104,7 @@ namespace } else {\ CHECK_FALSE(f_state.is_invocable_with());\ CHECK_FALSE(f_state.is_invocable_with(FromValue));\ - CHECK_THROWS(f_state.invoke(FromValue));\ + CHECK_FALSE(f_state.safe_invoke(FromValue));\ }\ } diff --git a/develop/untests/meta_utilities/inst_tests.cpp b/develop/untests/meta_utilities/inst_tests.cpp index 26f67eb..2c94aaf 100644 --- a/develop/untests/meta_utilities/inst_tests.cpp +++ b/develop/untests/meta_utilities/inst_tests.cpp @@ -43,10 +43,10 @@ namespace } else {\ CHECK_FALSE(uinst{Inst}.can_cast_to());\ CHECK_FALSE(uinst_base{type_list{}}.can_cast_to());\ - CHECK_THROWS(std::ignore = uinst{Inst}.cast());\ + /*CHECK_THROWS(std::ignore = uinst{Inst}.cast());*/\ \ CHECK_FALSE(m_state.is_invocable_with());\ - CHECK_THROWS(m_state.invoke(Inst));\ + CHECK_FALSE(m_state.safe_invoke(Inst));\ }\ } @@ -64,7 +64,7 @@ namespace } else {\ CHECK_FALSE(m_state.is_invocable_with());\ CHECK_FALSE(m_state.is_invocable_with(FromValue));\ - CHECK_THROWS(m_state.invoke(FromValue));\ + CHECK_FALSE(m_state.safe_invoke(FromValue));\ }\ } diff --git a/develop/untests/meta_utilities/value5_tests.cpp b/develop/untests/meta_utilities/value5_tests.cpp index 6cdd479..e43697b 100644 --- a/develop/untests/meta_utilities/value5_tests.cpp +++ b/develop/untests/meta_utilities/value5_tests.cpp @@ -76,11 +76,11 @@ TEST_CASE("meta/meta_utilities/value5/safe_get_as") { REQUIRE(v2.safe_get_as()); REQUIRE(*v2.safe_get_as()); - CHECK(*v2.safe_get_as() == &v); + CHECK(v2.safe_get_as() == &v); REQUIRE(v2.safe_get_as()); REQUIRE(*v2.safe_get_as()); - CHECK(*v2.safe_get_as() == &v); + CHECK(v2.safe_get_as() == &v); CHECK_FALSE(v2.safe_get_as()); CHECK_FALSE(v2.safe_get_as()); @@ -92,11 +92,11 @@ TEST_CASE("meta/meta_utilities/value5/safe_get_as") { REQUIRE(v2.safe_get_as()); REQUIRE(*v2.safe_get_as()); - CHECK(*v2.safe_get_as() == &v); + CHECK(v2.safe_get_as() == &v); REQUIRE(v2.safe_get_as()); REQUIRE(*v2.safe_get_as()); - CHECK(*v2.safe_get_as() == &v); + CHECK(v2.safe_get_as() == &v); CHECK_FALSE(v2.safe_get_as()); CHECK_FALSE(v2.safe_get_as()); @@ -113,7 +113,7 @@ TEST_CASE("meta/meta_utilities/value5/safe_get_as") { REQUIRE(v2.safe_get_as()); REQUIRE(*v2.safe_get_as()); - CHECK(*v2.safe_get_as() == &v); + CHECK(v2.safe_get_as() == &v); CHECK_FALSE(v2.safe_get_as()); CHECK_FALSE(v2.safe_get_as()); @@ -127,7 +127,7 @@ TEST_CASE("meta/meta_utilities/value5/safe_get_as") { REQUIRE(v2.safe_get_as()); REQUIRE(*v2.safe_get_as()); - CHECK(*v2.safe_get_as() == &v); + CHECK(v2.safe_get_as() == &v); CHECK_FALSE(v2.safe_get_as()); CHECK_FALSE(v2.safe_get_as()); @@ -140,13 +140,13 @@ TEST_CASE("meta/meta_utilities/value5/safe_get_as") { ivec2 v{1,2}; meta::uvalue v2{&v}; REQUIRE(std::move(v2).safe_get_as()); - CHECK(*std::move(v2).safe_get_as() == &v); + CHECK(std::move(v2).safe_get_as() == &v); } { ivec2 v{1,2}; const meta::uvalue v2{&v}; REQUIRE(std::move(v2).safe_get_as()); - CHECK(*std::move(v2).safe_get_as() == &v); + CHECK(std::move(v2).safe_get_as() == &v); } } @@ -156,14 +156,14 @@ TEST_CASE("meta/meta_utilities/value5/safe_get_as") { meta::uvalue v2{&v}; CHECK_FALSE(std::move(v2).safe_get_as()); REQUIRE(std::move(v2).safe_get_as()); - CHECK(*std::move(v2).safe_get_as() == &v); + CHECK(std::move(v2).safe_get_as() == &v); } { const ivec2 v{1,2}; const meta::uvalue v2{&v}; CHECK_FALSE(std::move(v2).safe_get_as()); REQUIRE(std::move(v2).safe_get_as()); - CHECK(*std::move(v2).safe_get_as() == &v); + CHECK(std::move(v2).safe_get_as() == &v); } } } diff --git a/headers/.clangd b/headers/.clangd index 944708c..2e16106 100644 --- a/headers/.clangd +++ b/headers/.clangd @@ -22,6 +22,7 @@ Diagnostics: - readability-identifier-length - readability-named-parameter - readability-redundant-access-specifiers + - readability-simplify-boolean-expr CompileFlags: CompilationDatabase: ../develop/.cdb diff --git a/headers/meta.hpp/meta_base/exceptions.hpp b/headers/meta.hpp/meta_base/exceptions.hpp index b76e826..056303a 100644 --- a/headers/meta.hpp/meta_base/exceptions.hpp +++ b/headers/meta.hpp/meta_base/exceptions.hpp @@ -20,13 +20,6 @@ # define META_HPP_THROW(...) std::abort() #endif -#define META_HPP_THROW_IF(yesno, ...) \ - do { \ - if ( yesno ) { \ - META_HPP_THROW(__VA_ARGS__); \ - } \ - } while ( false ) - namespace meta_hpp::detail { #if !defined(META_HPP_NO_EXCEPTIONS) diff --git a/headers/meta.hpp/meta_detail/value_utilities/uarg.hpp b/headers/meta.hpp/meta_detail/value_utilities/uarg.hpp index de39217..c68a889 100644 --- a/headers/meta.hpp/meta_detail/value_utilities/uarg.hpp +++ b/headers/meta.hpp/meta_detail/value_utilities/uarg.hpp @@ -234,7 +234,7 @@ namespace meta_hpp::detail template < typename To > // NOLINTNEXTLINE(*-cognitive-complexity) To uarg::cast() const { - META_HPP_THROW_IF(!can_cast_to(), "bad argument cast"); + META_HPP_ASSERT(can_cast_to() && "bad argument cast"); using to_raw_type_cv = std::remove_reference_t; using to_raw_type = std::remove_cv_t; diff --git a/headers/meta.hpp/meta_detail/value_utilities/uinst.hpp b/headers/meta.hpp/meta_detail/value_utilities/uinst.hpp index 1fd67f9..10a8b92 100644 --- a/headers/meta.hpp/meta_detail/value_utilities/uinst.hpp +++ b/headers/meta.hpp/meta_detail/value_utilities/uinst.hpp @@ -183,7 +183,7 @@ namespace meta_hpp::detail { template < inst_class_ref_kind Q > decltype(auto) uinst::cast() const { - META_HPP_THROW_IF(!can_cast_to(), "bad instance cast"); + META_HPP_ASSERT(can_cast_to() && "bad instance cast"); using inst_class_cv = std::remove_reference_t; using inst_class = std::remove_cv_t; diff --git a/headers/meta.hpp/meta_states.hpp b/headers/meta.hpp/meta_states.hpp index 8f75d8b..5c8b39e 100644 --- a/headers/meta.hpp/meta_states.hpp +++ b/headers/meta.hpp/meta_states.hpp @@ -176,9 +176,15 @@ namespace meta_hpp template < typename... Args > [[nodiscard]] uvalue create(Args&&... args) const; + template < typename... Args > + [[nodiscard]] std::optional safe_create(Args&&... args) const; + template < typename... Args > uvalue create_at(void* mem, Args&&... args) const; + template < typename... Args > + std::optional safe_create_at(void* mem, Args&&... args) const; + template < typename... Args > [[nodiscard]] bool is_invocable_with() const noexcept; @@ -211,11 +217,17 @@ namespace meta_hpp [[nodiscard]] const uvalue& get_value() const noexcept; [[nodiscard]] const uvalue& get_underlying_value() const noexcept; - template < typename T > - [[nodiscard]] T get_value_as() const; + template < detail::enum_kind Enum > + [[nodiscard]] Enum get_value_as() const; - template < typename T > - [[nodiscard]] T get_underlying_value_as() const; + template < detail::enum_kind Enum > + [[nodiscard]] std::optional safe_get_value_as() const noexcept; + + template < detail::number_kind Number > + [[nodiscard]] Number get_underlying_value_as() const; + + template < detail::number_kind Number > + [[nodiscard]] std::optional safe_get_underlying_value_as() const noexcept; }; class function final : public state_base { @@ -228,6 +240,9 @@ namespace meta_hpp template < typename... Args > uvalue invoke(Args&&... args) const; + template < typename... Args > + std::optional safe_invoke(Args&&... args) const; + template < typename... Args > uvalue operator()(Args&&... args) const; @@ -251,12 +266,21 @@ namespace meta_hpp template < typename Instance > [[nodiscard]] uvalue get(Instance&& instance) const; + template < typename Instance > + [[nodiscard]] std::optional safe_get(Instance&& instance) const; + template < typename T, typename Instance > [[nodiscard]] T get_as(Instance&& instance) const; + template < typename T, typename Instance > + [[nodiscard]] std::optional safe_get_as(Instance&& instance) const; + template < typename Instance, typename Value > void set(Instance&& instance, Value&& value) const; + template < typename Instance, typename Value > + bool safe_set(Instance&& instance, Value&& value) const; + template < typename Instance > [[nodiscard]] uvalue operator()(Instance&& instance) const; @@ -286,6 +310,9 @@ namespace meta_hpp template < typename Instance, typename... Args > uvalue invoke(Instance&& instance, Args&&... args) const; + template < typename Instance, typename... Args > + std::optional safe_invoke(Instance&& instance, Args&&... args) const; + template < typename Instance, typename... Args > uvalue operator()(Instance&& instance, Args&&... args) const; @@ -330,12 +357,20 @@ namespace meta_hpp [[nodiscard]] uvalue get() const; + [[nodiscard]] std::optional safe_get() const; + template < typename T > [[nodiscard]] T get_as() const; + template < typename T > + [[nodiscard]] std::optional safe_get_as() const; + template < typename Value > void set(Value&& value) const; + template < typename Value > + bool safe_set(Value&& value) const; + [[nodiscard]] uvalue operator()() const; template < typename Value > diff --git a/headers/meta.hpp/meta_states/constructor.hpp b/headers/meta.hpp/meta_states/constructor.hpp index e41f5e6..856c48b 100644 --- a/headers/meta.hpp/meta_states/constructor.hpp +++ b/headers/meta.hpp/meta_states/constructor.hpp @@ -32,16 +32,16 @@ namespace meta_hpp::detail static_assert(as_object || as_raw_ptr || as_shared_ptr); - META_HPP_THROW_IF( // - args.size() != ct::arity, - "an attempt to call a constructor with an incorrect arity" + META_HPP_ASSERT( // + args.size() == ct::arity // + && "an attempt to call a constructor with an incorrect arity" ); return std::invoke( [args](std::index_sequence)->uvalue { - META_HPP_THROW_IF( // - !(... && args[Is].can_cast_to>()), - "an attempt to call a constructor with incorrect argument types" + META_HPP_ASSERT( // + (... && args[Is].can_cast_to>()) // + && "an attempt to call a constructor with incorrect argument types" ); if constexpr ( as_object ) { @@ -49,11 +49,11 @@ namespace meta_hpp::detail } if constexpr ( as_raw_ptr ) { - return uvalue{std::make_unique(args[Is].cast>()...).release()}; + return std::make_unique(args[Is].cast>()...).release(); } if constexpr ( as_shared_ptr ) { - return uvalue{std::make_shared(args[Is].cast>()...)}; + return std::make_shared(args[Is].cast>()...); } }, std::make_index_sequence() @@ -66,22 +66,22 @@ namespace meta_hpp::detail using class_type = typename ct::class_type; using argument_types = typename ct::argument_types; - META_HPP_THROW_IF( // - args.size() != ct::arity, - "an attempt to call a constructor with an incorrect arity" + META_HPP_ASSERT( // + args.size() == ct::arity // + && "an attempt to call a constructor with an incorrect arity" ); return std::invoke( [ mem, args ](std::index_sequence)->uvalue { - META_HPP_THROW_IF( // - !(... && args[Is].can_cast_to>()), - "an attempt to call a constructor with incorrect argument types" + META_HPP_ASSERT( // + (... && args[Is].can_cast_to>()) // + && "an attempt to call a constructor with incorrect argument types" ); - return uvalue{std::construct_at( // - static_cast(mem), + return std::construct_at( // + static_cast(mem), // args[Is].cast>()... - )}; + ); }, std::make_index_sequence() ); @@ -174,6 +174,14 @@ namespace meta_hpp } } + template < typename... Args > + std::optional constructor::safe_create(Args&&... args) const { + if ( is_invocable_with(std::forward(args)...) ) { + return create(std::forward(args)...); + } + return std::nullopt; + } + template < typename... Args > uvalue constructor::create_at(void* mem, Args&&... args) const { if constexpr ( sizeof...(Args) > 0 ) { @@ -185,6 +193,14 @@ namespace meta_hpp } } + template < typename... Args > + std::optional constructor::safe_create_at(void* mem, Args&&... args) const { + if ( is_invocable_with(std::forward(args)...) ) { + return create_at(mem, std::forward(args)...); + } + return std::nullopt; + } + template < typename... Args > bool constructor::is_invocable_with() const noexcept { if constexpr ( sizeof...(Args) > 0 ) { diff --git a/headers/meta.hpp/meta_states/evalue.hpp b/headers/meta.hpp/meta_states/evalue.hpp index 4da26b9..fac5026 100644 --- a/headers/meta.hpp/meta_states/evalue.hpp +++ b/headers/meta.hpp/meta_states/evalue.hpp @@ -44,13 +44,23 @@ namespace meta_hpp return state_->underlying_value; } - template < typename T > - T evalue::get_value_as() const { - return get_value().get_as(); + template < detail::enum_kind Enum > + Enum evalue::get_value_as() const { + return get_value().get_as(); } - template < typename T > - T evalue::get_underlying_value_as() const { - return get_underlying_value().get_as(); + template < detail::enum_kind Enum > + std::optional evalue::safe_get_value_as() const noexcept { + return get_value().safe_get_as(); + } + + template < detail::number_kind Number > + Number evalue::get_underlying_value_as() const { + return get_underlying_value().get_as(); + } + + template < detail::number_kind Number > + std::optional evalue::safe_get_underlying_value_as() const noexcept { + return get_underlying_value().safe_get_as(); } } diff --git a/headers/meta.hpp/meta_states/function.hpp b/headers/meta.hpp/meta_states/function.hpp index e2c0852..59cd7fc 100644 --- a/headers/meta.hpp/meta_states/function.hpp +++ b/headers/meta.hpp/meta_states/function.hpp @@ -34,16 +34,16 @@ namespace meta_hpp::detail static_assert(as_copy || as_void || ref_as_ptr); - META_HPP_THROW_IF( // - args.size() != ft::arity, - "an attempt to call a function with an incorrect arity" + META_HPP_ASSERT( // + args.size() == ft::arity // + && "an attempt to call a function with an incorrect arity" ); return std::invoke( [ function_ptr, args ](std::index_sequence)->uvalue { - META_HPP_THROW_IF( // - !(... && args[Is].can_cast_to>()), - "an attempt to call a function with incorrect argument types" + META_HPP_ASSERT( // + (... && args[Is].can_cast_to>()) // + && "an attempt to call a function with incorrect argument types" ); if constexpr ( std::is_void_v ) { @@ -153,6 +153,14 @@ namespace meta_hpp } } + template < typename... Args > + std::optional function::safe_invoke(Args&&... args) const { + if ( is_invocable_with(std::forward(args)...) ) { + return invoke(std::forward(args)...); + } + return std::nullopt; + } + template < typename... Args > uvalue function::operator()(Args&&... args) const { return invoke(std::forward(args)...); diff --git a/headers/meta.hpp/meta_states/member.hpp b/headers/meta.hpp/meta_states/member.hpp index a8b1b9c..6c8b6f3 100644 --- a/headers/meta.hpp/meta_states/member.hpp +++ b/headers/meta.hpp/meta_states/member.hpp @@ -33,12 +33,12 @@ namespace meta_hpp::detail static_assert(as_copy || as_ptr || as_ref_wrap); - META_HPP_THROW_IF( // - !inst.can_cast_to(), - "an attempt to get a member with an incorrect instance type" - ); - if ( inst.is_inst_const() ) { + META_HPP_ASSERT( // + inst.can_cast_to() // + && "an attempt to get a member with an incorrect instance type" + ); + auto&& return_value = inst.cast().*member_ptr; if constexpr ( as_copy ) { @@ -53,6 +53,11 @@ namespace meta_hpp::detail return uvalue{std::ref(return_value)}; } } else { + META_HPP_ASSERT( // + inst.can_cast_to() // + && "an attempt to get a member with an incorrect instance type" + ); + auto&& return_value = inst.cast().*member_ptr; if constexpr ( as_copy ) { @@ -87,21 +92,21 @@ namespace meta_hpp::detail using value_type = typename mt::value_type; if constexpr ( std::is_const_v ) { - META_HPP_THROW("an attempt to set a constant member"); + META_HPP_ASSERT(false && "an attempt to set a constant member"); } else { - META_HPP_THROW_IF( // - inst.is_inst_const(), - "an attempt to set a member with an const instance type" + META_HPP_ASSERT( // + !inst.is_inst_const() // + && "an attempt to set a member with an const instance type" ); - META_HPP_THROW_IF( // - !inst.can_cast_to(), - "an attempt to set a member with an incorrect instance type" + META_HPP_ASSERT( // + inst.can_cast_to() // + && "an attempt to set a member with an incorrect instance type" ); - META_HPP_THROW_IF( // - !arg.can_cast_to(), - "an attempt to set a member with an incorrect argument type" + META_HPP_ASSERT( // + arg.can_cast_to() // + && "an attempt to set a member with an incorrect argument type" ); inst.cast().*member_ptr = arg.cast(); @@ -114,8 +119,13 @@ namespace meta_hpp::detail using class_type = typename mt::class_type; using value_type = typename mt::value_type; - return !std::is_const_v && !inst.is_inst_const() && inst.can_cast_to() - && arg.can_cast_to(); + if constexpr ( std::is_const_v ) { + return false; + } else { + return !inst.is_inst_const() // + && inst.can_cast_to() // + && arg.can_cast_to(); // + } } } @@ -180,11 +190,24 @@ namespace meta_hpp return state_->getter(vinst); } + template < typename Instance > + std::optional member::safe_get(Instance&& instance) const { + if ( is_gettable_with(std::forward(instance)) ) { + return get(std::forward(instance)); + } + return std::nullopt; + } + template < typename T, typename Instance > T member::get_as(Instance&& instance) const { return get(std::forward(instance)).template get_as(); } + template < typename T, typename Instance > + std::optional member::safe_get_as(Instance&& instance) const { + return safe_get(std::forward(instance)).value_or(uvalue{}).template safe_get_as(); + } + template < typename Instance, typename Value > void member::set(Instance&& instance, Value&& value) const { using namespace detail; @@ -193,6 +216,15 @@ namespace meta_hpp state_->setter(vinst, vvalue); } + template < typename Instance, typename Value > + bool member::safe_set(Instance&& instance, Value&& value) const { + if ( is_settable_with(std::forward(instance), std::forward(value)) ) { + set(std::forward(instance), std::forward(value)); + return true; + } + return false; + } + template < typename Instance > uvalue member::operator()(Instance&& instance) const { return get(std::forward(instance)); diff --git a/headers/meta.hpp/meta_states/method.hpp b/headers/meta.hpp/meta_states/method.hpp index 900d49c..94fa64c 100644 --- a/headers/meta.hpp/meta_states/method.hpp +++ b/headers/meta.hpp/meta_states/method.hpp @@ -36,21 +36,20 @@ namespace meta_hpp::detail static_assert(as_copy || as_void || ref_as_ptr); - META_HPP_THROW_IF( // - args.size() != mt::arity, - "an attempt to call a method with an incorrect arity" + META_HPP_ASSERT( // + args.size() == mt::arity // + && "an attempt to call a method with an incorrect arity" ); - - META_HPP_THROW_IF( // - !inst.can_cast_to(), - "an attempt to call a method with an incorrect instance type" + META_HPP_ASSERT( // + inst.can_cast_to() // + && "an attempt to call a method with an incorrect instance type" ); return std::invoke( [ method_ptr, &inst, args ](std::index_sequence)->uvalue { - META_HPP_THROW_IF( // - !(... && args[Is].can_cast_to>()), - "an attempt to call a method with incorrect argument types" + META_HPP_ASSERT( // + (... && args[Is].can_cast_to>()) // + && "an attempt to call a method with incorrect argument types" ); if constexpr ( std::is_void_v ) { @@ -169,6 +168,14 @@ namespace meta_hpp } } + template < typename Instance, typename... Args > + std::optional method::safe_invoke(Instance&& instance, Args&&... args) const { + if ( is_invocable_with(std::forward(instance), std::forward(args)...) ) { + return invoke(std::forward(instance), std::forward(args)...); + } + return std::nullopt; + } + template < typename Instance, typename... Args > uvalue method::operator()(Instance&& instance, Args&&... args) const { return invoke(std::forward(instance), std::forward(args)...); diff --git a/headers/meta.hpp/meta_states/variable.hpp b/headers/meta.hpp/meta_states/variable.hpp index f204f8f..e9ee592 100644 --- a/headers/meta.hpp/meta_states/variable.hpp +++ b/headers/meta.hpp/meta_states/variable.hpp @@ -52,12 +52,13 @@ namespace meta_hpp::detail using data_type = typename pt::data_type; if constexpr ( std::is_const_v ) { - META_HPP_THROW("an attempt to set a constant variable"); + META_HPP_ASSERT(false && "an attempt to set a constant variable"); } else { - META_HPP_THROW_IF( // - !arg.can_cast_to(), - "an attempt to set a variable with an incorrect argument type" + META_HPP_ASSERT( // + arg.can_cast_to() // + && "an attempt to set a variable with an incorrect argument type" ); + *variable_ptr = arg.cast(); } } @@ -67,7 +68,11 @@ namespace meta_hpp::detail using pt = pointer_traits; using data_type = typename pt::data_type; - return !std::is_const_v && arg.can_cast_to(); + if constexpr ( std::is_const_v ) { + return false; + } else { + return arg.can_cast_to(); + } } } @@ -123,9 +128,18 @@ namespace meta_hpp return state_->getter(); } + inline std::optional variable::safe_get() const { + return state_->getter(); + } + template < typename T > T variable::get_as() const { - return get().get_as(); + return get().template get_as(); + } + + template < typename T > + std::optional variable::safe_get_as() const { + return safe_get().value_or(uvalue{}).template safe_get_as(); } template < typename Value > @@ -135,6 +149,15 @@ namespace meta_hpp state_->setter(vvalue); } + template < typename Value > + bool variable::safe_set(Value&& value) const { + if ( is_settable_with(std::forward(value)) ) { + set(std::forward(value)); + return true; + } + return false; + } + inline uvalue variable::operator()() const { return get(); } @@ -154,7 +177,7 @@ namespace meta_hpp template < typename Value > bool variable::is_settable_with(Value&& value) const noexcept { using namespace detail; - const uarg vvalue{std::forward(value)}; + const uarg_base vvalue{std::forward(value)}; return state_->is_settable_with(vvalue); } } diff --git a/headers/meta.hpp/meta_types.hpp b/headers/meta.hpp/meta_types.hpp index 66784ca..8cc0b9e 100644 --- a/headers/meta.hpp/meta_types.hpp +++ b/headers/meta.hpp/meta_types.hpp @@ -247,8 +247,11 @@ namespace meta_hpp [[nodiscard]] std::string_view value_to_name(Enum value) const noexcept; [[nodiscard]] uvalue name_to_value(std::string_view name) const noexcept; - template < typename T > - [[nodiscard]] T name_to_value_as(std::string_view name) const; + template < detail::enum_kind Enum > + [[nodiscard]] Enum name_to_value_as(std::string_view name) const; + + template < detail::enum_kind Enum > + [[nodiscard]] std::optional safe_name_to_value_as(std::string_view name) const noexcept; }; class function_type final : public type_base { diff --git a/headers/meta.hpp/meta_types/class_type.hpp b/headers/meta.hpp/meta_types/class_type.hpp index 3e85a24..03bea02 100644 --- a/headers/meta.hpp/meta_types/class_type.hpp +++ b/headers/meta.hpp/meta_types/class_type.hpp @@ -182,7 +182,7 @@ namespace meta_hpp } for ( const class_type& base : data_->bases ) { - if ( const function& function = base.get_function(name); function ) { + if ( const function& function = base.get_function(name) ) { return function; } } @@ -198,7 +198,7 @@ namespace meta_hpp } for ( const class_type& base : data_->bases ) { - if ( const member& member = base.get_member(name); member ) { + if ( const member& member = base.get_member(name) ) { return member; } } @@ -214,7 +214,7 @@ namespace meta_hpp } for ( const class_type& base : data_->bases ) { - if ( const method& method = base.get_method(name); method ) { + if ( const method& method = base.get_method(name) ) { return method; } } @@ -228,7 +228,7 @@ namespace meta_hpp } for ( const class_type& base : data_->bases ) { - if ( const any_type& type = base.get_typedef(name); type ) { + if ( const any_type& type = base.get_typedef(name) ) { return type; } } @@ -244,7 +244,7 @@ namespace meta_hpp } for ( const class_type& base : data_->bases ) { - if ( const variable& variable = base.get_variable(name); variable ) { + if ( const variable& variable = base.get_variable(name) ) { return variable; } } @@ -314,7 +314,7 @@ namespace meta_hpp } for ( const class_type& base : data_->bases ) { - if ( const function& function = base.get_function_with(name, first, last); function ) { + if ( const function& function = base.get_function_with(name, first, last) ) { return function; } } @@ -353,7 +353,7 @@ namespace meta_hpp } for ( const class_type& base : data_->bases ) { - if ( const method& method = base.get_method_with(name, first, last); method ) { + if ( const method& method = base.get_method_with(name, first, last) ) { return method; } } diff --git a/headers/meta.hpp/meta_types/enum_type.hpp b/headers/meta.hpp/meta_types/enum_type.hpp index a7cd9fa..232ee4d 100644 --- a/headers/meta.hpp/meta_types/enum_type.hpp +++ b/headers/meta.hpp/meta_types/enum_type.hpp @@ -66,15 +66,20 @@ namespace meta_hpp } inline uvalue enum_type::name_to_value(std::string_view name) const noexcept { - if ( const evalue& value = get_evalue(name); value ) { + if ( const evalue& value = get_evalue(name) ) { return value.get_value(); } return uvalue{}; } - template < typename T > - T enum_type::name_to_value_as(std::string_view name) const { - return name_to_value(name).get_as(); + template < detail::enum_kind Enum > + Enum enum_type::name_to_value_as(std::string_view name) const { + return name_to_value(name).get_as(); + } + + template < detail::enum_kind Enum > + std::optional enum_type::safe_name_to_value_as(std::string_view name) const noexcept { + return name_to_value(name).safe_get_as(); } }