From b414e71d8f709277147b56ac2a7419dbf16421da Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 21 Jan 2022 22:01:57 +0700 Subject: [PATCH] add value return policy --- CMakeLists.txt | 1 + TODO.md | 3 +- headers/meta.hpp/meta_registry.hpp | 101 +++++++++--------- headers/meta.hpp/meta_registry/class_bind.hpp | 43 ++++---- headers/meta.hpp/meta_registry/scope_bind.hpp | 14 +-- headers/meta.hpp/meta_states.hpp | 98 ++++++++++++----- headers/meta.hpp/meta_states/ctor.hpp | 61 +++++++---- headers/meta.hpp/meta_states/evalue.hpp | 12 +-- headers/meta.hpp/meta_states/function.hpp | 61 +++++++---- headers/meta.hpp/meta_states/member.hpp | 89 +++++++++------ headers/meta.hpp/meta_states/method.hpp | 60 +++++++---- headers/meta.hpp/meta_states/scope.hpp | 7 +- headers/meta.hpp/meta_states/variable.hpp | 50 ++++++--- headers/meta.hpp/meta_utilities/vinvoke.hpp | 30 +++--- untests/meta_states/ctor_tests.cpp | 67 ++++++++++++ untests/meta_states/member_tests.cpp | 48 ++++++++- untests/meta_states/variable_tests.cpp | 88 ++++++++++++++- untests/meta_utilities/arg_tests.cpp | 4 +- untests/meta_utilities/inst_tests.cpp | 4 +- 19 files changed, 601 insertions(+), 240 deletions(-) create mode 100644 untests/meta_states/ctor_tests.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index ba9fe16..f69d397 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,6 +31,7 @@ target_compile_options(${PROJECT_NAME} -Wno-exit-time-destructors -Wno-extra-semi-stmt -Wno-float-equal + -Wno-global-constructors -Wno-padded -Wno-reserved-identifier -Wno-shadow-field diff --git a/TODO.md b/TODO.md index af4fed2..51d0971 100644 --- a/TODO.md +++ b/TODO.md @@ -1,7 +1,6 @@ # meta.hpp -- add array value access -- add return value policy +- add dtors - add meta exception class; - void value? - all string to hash? diff --git a/headers/meta.hpp/meta_registry.hpp b/headers/meta.hpp/meta_registry.hpp index 47efb89..52b365a 100644 --- a/headers/meta.hpp/meta_registry.hpp +++ b/headers/meta.hpp/meta_registry.hpp @@ -9,68 +9,63 @@ #include "meta_base.hpp" #include "meta_states.hpp" -namespace meta_hpp::detail -{ - template < typename Class, typename... Args > - concept class_bind_ctor_kind = - class_kind && - requires(Args&&... args) { { Class{std::forward(args)...} }; }; - - template < typename Class, typename Base > - concept class_bind_base_kind = - class_kind && class_kind && - stdex::derived_from; - - template < typename Class, typename Function > - concept class_bind_function_kind = - class_kind && function_kind; - - template < typename Class, typename Member > - concept class_bind_member_kind = - class_kind && member_kind && - stdex::same_as::class_type>; - - template < typename Class, typename Method > - concept class_bind_method_kind = - class_kind && method_kind && - stdex::same_as::class_type>; - - template < typename Class, typename Pointer > - concept class_bind_variable_kind = - class_kind && pointer_kind; -} - namespace meta_hpp { + namespace detail + { + template < typename Class, typename... Args > + concept class_bind_ctor_kind = + class_kind && + requires(Args&&... args) { { Class{std::forward(args)...} }; }; + + template < typename Class, typename Base > + concept class_bind_base_kind = + class_kind && class_kind && + stdex::derived_from; + + template < typename Class, typename Member > + concept class_bind_member_kind = + class_kind && member_kind && + stdex::same_as::class_type>; + + template < typename Class, typename Method > + concept class_bind_method_kind = + class_kind && method_kind && + stdex::same_as::class_type>; + } + template < detail::class_kind Class > class class_bind final { public: explicit class_bind(); operator class_type() const noexcept; - template < typename... Args > - requires detail::class_bind_ctor_kind - class_bind& ctor_(); + template < typename... Args + , ctor_policy_kind Policy = ctor_policy::as_object > + class_bind& ctor_(Policy = Policy{}) + requires detail::class_bind_ctor_kind; template < detail::class_kind Base > - requires detail::class_bind_base_kind - class_bind& base_(); + class_bind& base_() + requires detail::class_bind_base_kind; - template < detail::function_kind Function > - requires detail::class_bind_function_kind - class_bind& function_(std::string name, Function function); + template < detail::function_kind Function + , function_policy_kind Policy = function_policy::as_copy > + class_bind& function_(std::string name, Function function, Policy = Policy{}); - template < detail::member_kind Member > - requires detail::class_bind_member_kind - class_bind& member_(std::string name, Member member); + template < detail::member_kind Member + , member_policy_kind Policy = member_policy::as_copy > + class_bind& member_(std::string name, Member member, Policy = Policy{}) + requires detail::class_bind_member_kind; - template < detail::method_kind Method > - requires detail::class_bind_method_kind - class_bind& method_(std::string name, Method method); + template < detail::method_kind Method + , method_policy_kind Policy = method_policy::as_copy > + class_bind& method_(std::string name, Method method, Policy = Policy{}) + requires detail::class_bind_method_kind; - template < detail::pointer_kind Pointer > - requires detail::class_bind_variable_kind - class_bind& variable_(std::string name, Pointer pointer); + template < detail::pointer_kind Pointer + , variable_policy_kind Policy = variable_policy::as_copy > + class_bind& variable_(std::string name, Pointer pointer, Policy = Policy{}); private: detail::class_type_data_ptr data_; }; @@ -107,11 +102,13 @@ namespace meta_hpp template < detail::enum_kind Enum > scope_bind& enum_(std::string name); - template < detail::function_kind Function > - scope_bind& function_(std::string name, Function function); + template < detail::function_kind Function + , function_policy_kind Policy = function_policy::as_copy > + scope_bind& function_(std::string name, Function function, Policy = Policy{}); - template < detail::pointer_kind Pointer > - scope_bind& variable_(std::string name, Pointer pointer); + template < detail::pointer_kind Pointer + , variable_policy_kind Policy = variable_policy::as_copy > + scope_bind& variable_(std::string name, Pointer pointer, Policy = Policy{}); private: detail::scope_state_ptr state_; }; diff --git a/headers/meta.hpp/meta_registry/class_bind.hpp b/headers/meta.hpp/meta_registry/class_bind.hpp index 9dc1554..5f5b811 100644 --- a/headers/meta.hpp/meta_registry/class_bind.hpp +++ b/headers/meta.hpp/meta_registry/class_bind.hpp @@ -21,18 +21,21 @@ namespace meta_hpp } template < detail::class_kind Class > - template < typename... Args > + template < typename... Args, ctor_policy_kind Policy > + // NOLINTNEXTLINE(readability-named-parameter) + class_bind& class_bind::ctor_(Policy) requires detail::class_bind_ctor_kind - class_bind& class_bind::ctor_() { - auto ctor_state = detail::ctor_state::make(); + { + auto ctor_state = detail::ctor_state::make(); data_->ctors.emplace(ctor_state->index, std::move(ctor_state)); return *this; } template < detail::class_kind Class > template < detail::class_kind Base > + class_bind& class_bind::base_() requires detail::class_bind_base_kind - class_bind& class_bind::base_() { + { data_->bases.emplace(resolve_type()); data_->bases_info.emplace(resolve_type(), detail::class_type_data::base_info{ .upcast = +[](void* derived) -> void* { @@ -43,37 +46,41 @@ namespace meta_hpp } template < detail::class_kind Class > - template < detail::function_kind Function > - requires detail::class_bind_function_kind - class_bind& class_bind::function_(std::string name, Function function) { - auto function_state = detail::function_state::make(std::move(name), std::move(function)); + template < detail::function_kind Function, function_policy_kind Policy > + // NOLINTNEXTLINE(readability-named-parameter) + class_bind& class_bind::function_(std::string name, Function function, Policy) { + auto function_state = detail::function_state::make(std::move(name), std::move(function)); data_->functions.emplace(function_state->index, std::move(function_state)); return *this; } template < detail::class_kind Class > - template < detail::member_kind Member > + template < detail::member_kind Member, member_policy_kind Policy > + // NOLINTNEXTLINE(readability-named-parameter) + class_bind& class_bind::member_(std::string name, Member member, Policy) requires detail::class_bind_member_kind - class_bind& class_bind::member_(std::string name, Member member) { - auto member_state = detail::member_state::make(std::move(name), std::move(member)); + { + auto member_state = detail::member_state::make(std::move(name), std::move(member)); data_->members.emplace(member_state->index, std::move(member_state)); return *this; } template < detail::class_kind Class > - template < detail::method_kind Method > + template < detail::method_kind Method, method_policy_kind Policy > + // NOLINTNEXTLINE(readability-named-parameter) + class_bind& class_bind::method_(std::string name, Method method, Policy) requires detail::class_bind_method_kind - class_bind& class_bind::method_(std::string name, Method method) { - auto method_state = detail::method_state::make(std::move(name), std::move(method)); + { + auto method_state = detail::method_state::make(std::move(name), std::move(method)); data_->methods.emplace(method_state->index, std::move(method_state)); return *this; } template < detail::class_kind Class > - template < detail::pointer_kind Pointer > - requires detail::class_bind_variable_kind - class_bind& class_bind::variable_(std::string name, Pointer pointer) { - auto variable_state = detail::variable_state::make(std::move(name), std::move(pointer)); + template < detail::pointer_kind Pointer, variable_policy_kind Policy > + // NOLINTNEXTLINE(readability-named-parameter) + class_bind& class_bind::variable_(std::string name, Pointer pointer, Policy) { + auto variable_state = detail::variable_state::make(std::move(name), std::move(pointer)); data_->variables.emplace(variable_state->index, std::move(variable_state)); return *this; } diff --git a/headers/meta.hpp/meta_registry/scope_bind.hpp b/headers/meta.hpp/meta_registry/scope_bind.hpp index 453a19a..e31b32d 100644 --- a/headers/meta.hpp/meta_registry/scope_bind.hpp +++ b/headers/meta.hpp/meta_registry/scope_bind.hpp @@ -35,16 +35,18 @@ namespace meta_hpp return *this; } - template < detail::function_kind Function > - scope_bind& scope_bind::function_(std::string name, Function function) { - auto function_state = detail::function_state::make(std::move(name), std::move(function)); + template < detail::function_kind Function, function_policy_kind Policy > + // NOLINTNEXTLINE(readability-named-parameter) + scope_bind& scope_bind::function_(std::string name, Function function, Policy) { + auto function_state = detail::function_state::make(std::move(name), std::move(function)); state_->functions.emplace(function_state->index, std::move(function_state)); return *this; } - template < detail::pointer_kind Pointer > - scope_bind& scope_bind::variable_(std::string name, Pointer pointer) { - auto variable_state = detail::variable_state::make(std::move(name), std::move(pointer)); + template < detail::pointer_kind Pointer, variable_policy_kind Policy > + // NOLINTNEXTLINE(readability-named-parameter) + scope_bind& scope_bind::variable_(std::string name, Pointer pointer, Policy) { + auto variable_state = detail::variable_state::make(std::move(name), std::move(pointer)); state_->variables.emplace(variable_state->index, std::move(variable_state)); return *this; } diff --git a/headers/meta.hpp/meta_states.hpp b/headers/meta.hpp/meta_states.hpp index 8af4685..c8f5bc7 100644 --- a/headers/meta.hpp/meta_states.hpp +++ b/headers/meta.hpp/meta_states.hpp @@ -57,6 +57,74 @@ namespace meta_hpp } } +namespace meta_hpp +{ + namespace ctor_policy + { + struct as_object final {}; + struct as_raw_pointer final {}; + struct as_shared_pointer final {}; + } + + namespace function_policy + { + struct as_copy final {}; + struct discard_return final {}; + struct return_reference_as_pointer final {}; + } + + namespace member_policy + { + struct as_copy final {}; + struct as_pointer final {}; + struct as_reference_wrapper final {}; + }; + + namespace method_policy + { + struct as_copy final {}; + struct discard_return final {}; + struct return_reference_as_pointer final {}; + }; + + namespace variable_policy + { + struct as_copy final {}; + struct as_pointer final {}; + struct as_reference_wrapper final {}; + }; + + template < typename Policy > + concept ctor_policy_kind = + detail::stdex::same_as || + detail::stdex::same_as || + detail::stdex::same_as; + + template < typename Policy > + concept function_policy_kind = + detail::stdex::same_as || + detail::stdex::same_as || + detail::stdex::same_as; + + template < typename Policy > + concept member_policy_kind = + detail::stdex::same_as || + detail::stdex::same_as || + detail::stdex::same_as; + + template < typename Policy > + concept method_policy_kind = + detail::stdex::same_as || + detail::stdex::same_as || + detail::stdex::same_as; + + template < typename Policy > + concept variable_policy_kind = + detail::stdex::same_as || + detail::stdex::same_as || + detail::stdex::same_as; +} + namespace meta_hpp { class ctor final { @@ -267,10 +335,7 @@ namespace meta_hpp::detail const invoke_impl invoke; const is_invocable_with_impl is_invocable_with; - template < class_kind Class, typename... Args > - explicit ctor_state(ctor_index index, type_list, type_list); - - template < class_kind Class, typename... Args > + template < ctor_policy_kind Policy, class_kind Class, typename... Args > [[nodiscard]] static ctor_state_ptr make(); }; @@ -279,9 +344,6 @@ namespace meta_hpp::detail const value enum_value; const value underlying_value; - template < enum_kind Enum > - explicit evalue_state(evalue_index index, Enum value); - template < enum_kind Enum > [[nodiscard]] static evalue_state_ptr make(std::string name, Enum value); }; @@ -294,10 +356,7 @@ namespace meta_hpp::detail const invoke_impl invoke; const is_invocable_with_impl is_invocable_with; - template < function_kind Function > - explicit function_state(function_index index, Function function); - - template < function_kind Function > + template < function_policy_kind Policy, function_kind Function > [[nodiscard]] static function_state_ptr make(std::string name, Function function); }; @@ -314,10 +373,7 @@ namespace meta_hpp::detail const is_gettable_with_impl is_gettable_with; const is_settable_with_impl is_settable_with; - template < member_kind Member > - explicit member_state(member_index index, Member member); - - template < member_kind Member > + template < member_policy_kind Policy, member_kind Member > [[nodiscard]] static member_state_ptr make(std::string name, Member member); }; @@ -329,10 +385,7 @@ namespace meta_hpp::detail const invoke_impl invoke; const is_invocable_with_impl is_invocable_with; - template < method_kind Method > - explicit method_state(method_index index, Method method); - - template < method_kind Method > + template < method_policy_kind Policy, method_kind Method > [[nodiscard]] static method_state_ptr make(std::string name, Method method); }; @@ -344,8 +397,6 @@ namespace meta_hpp::detail function_map functions; variable_map variables; - explicit scope_state(scope_index index); - [[nodiscard]] static scope_state_ptr make(std::string name); [[nodiscard]] static scope_state_ptr get_static(std::string_view name); }; @@ -360,10 +411,7 @@ namespace meta_hpp::detail const setter_impl setter; const is_settable_with_impl is_settable_with; - template < pointer_kind Pointer > - explicit variable_state(variable_index index, Pointer pointer); - - template < pointer_kind Pointer > + template < variable_policy_kind Policy, pointer_kind Pointer > [[nodiscard]] static variable_state_ptr make(std::string name, Pointer pointer); }; } diff --git a/headers/meta.hpp/meta_states/ctor.hpp b/headers/meta.hpp/meta_states/ctor.hpp index 203695c..9726713 100644 --- a/headers/meta.hpp/meta_states/ctor.hpp +++ b/headers/meta.hpp/meta_states/ctor.hpp @@ -13,29 +13,55 @@ namespace meta_hpp::detail { - template < class_kind Class, typename... Args > - value vargs_invoke(std::span args) { + template < ctor_policy_kind Policy, class_kind Class, typename... Args > + value raw_ctor_invoke(std::span args) { using ct = ctor_traits; using class_type = typename ct::class_type; using argument_types = typename ct::argument_types; + constexpr bool as_object = + stdex::copy_constructible && + stdex::same_as; + + constexpr bool as_raw_ptr = + stdex::same_as; + + constexpr bool as_shared_ptr = + stdex::same_as; + + static_assert(as_object || as_raw_ptr || as_shared_ptr); + if ( args.size() != ct::arity ) { throw std::logic_error("an attempt to call a constructor with an incorrect arity"); } + return std::invoke([ + args // NOLINTNEXTLINE(readability-named-parameter) - return std::invoke([&args](std::index_sequence){ + ](std::index_sequence) -> value { if ( !(... && (args.data() + Is)->can_cast_to>()) ) { throw std::logic_error("an attempt to call a constructor with incorrect argument types"); } - class_type return_value{(args.data() + Is)->cast>()...}; - return value{std::forward(return_value)}; + if constexpr ( as_object ) { + class_type return_value{(args.data() + Is)->cast>()...}; + return value{std::move(return_value)}; + } + + if constexpr ( as_raw_ptr ) { + auto return_value{std::make_unique((args.data() + Is)->cast>()...)}; + return value{return_value.release()}; + } + + if constexpr ( as_shared_ptr ) { + auto return_value{std::make_shared((args.data() + Is)->cast>()...)}; + return value{std::move(return_value)}; + } }, std::make_index_sequence()); } template < class_kind Class, typename... Args > - bool vargs_is_invocable_with(std::span args) { + bool raw_ctor_is_invocable_with(std::span args) { using ct = ctor_traits; using argument_types = typename ct::argument_types; @@ -44,7 +70,7 @@ namespace meta_hpp::detail } // NOLINTNEXTLINE(readability-named-parameter) - return std::invoke([&args](std::index_sequence){ + return std::invoke([args](std::index_sequence){ return (... && (args.data() + Is)->can_cast_to>()); }, std::make_index_sequence()); } @@ -52,32 +78,29 @@ namespace meta_hpp::detail namespace meta_hpp::detail { - template < class_kind Class, typename... Args > + template < ctor_policy_kind Policy, class_kind Class, typename... Args > ctor_state::invoke_impl make_ctor_invoke() { using namespace std::placeholders; - return std::bind(&vargs_invoke, _1); + return std::bind(&raw_ctor_invoke, _1); } template < class_kind Class, typename... Args > ctor_state::is_invocable_with_impl make_ctor_is_invocable_with() { using namespace std::placeholders; - return std::bind(&vargs_is_invocable_with, _1); + return std::bind(&raw_ctor_is_invocable_with, _1); } } namespace meta_hpp::detail { - template < class_kind Class, typename... Args > - // NOLINTNEXTLINE(readability-named-parameter) - ctor_state::ctor_state(ctor_index index, type_list, type_list) - : index{std::move(index)} - , invoke{make_ctor_invoke()} - , is_invocable_with{make_ctor_is_invocable_with()} {} - - template < class_kind Class, typename... Args > + template < ctor_policy_kind Policy, class_kind Class, typename... Args > ctor_state_ptr ctor_state::make() { ctor_index index{ctor_type_data::get_static()}; - return std::make_shared(std::move(index), type_list{}, type_list{}); + return std::make_shared(ctor_state{ + .index{std::move(index)}, + .invoke{make_ctor_invoke()}, + .is_invocable_with{make_ctor_is_invocable_with()}, + }); } } diff --git a/headers/meta.hpp/meta_states/evalue.hpp b/headers/meta.hpp/meta_states/evalue.hpp index df4328d..73c4a41 100644 --- a/headers/meta.hpp/meta_states/evalue.hpp +++ b/headers/meta.hpp/meta_states/evalue.hpp @@ -13,16 +13,14 @@ namespace meta_hpp::detail { - template < enum_kind Enum > - evalue_state::evalue_state(evalue_index index, Enum value) - : index{std::move(index)} - , enum_value{value} - , underlying_value{stdex::to_underlying(value)} {} - template < enum_kind Enum > evalue_state_ptr evalue_state::make(std::string name, Enum value) { evalue_index index{enum_type_data::get_static(), std::move(name)}; - return std::make_shared(std::move(index), std::move(value)); + return std::make_shared(evalue_state{ + .index{std::move(index)}, + .enum_value{value}, + .underlying_value{stdex::to_underlying(value)}, + }); } } diff --git a/headers/meta.hpp/meta_states/function.hpp b/headers/meta.hpp/meta_states/function.hpp index 02447a8..3f5154b 100644 --- a/headers/meta.hpp/meta_states/function.hpp +++ b/headers/meta.hpp/meta_states/function.hpp @@ -13,38 +13,59 @@ namespace meta_hpp::detail { - template < function_kind Function > - std::optional vargs_invoke(Function function, std::span args) { + template < function_policy_kind Policy, function_kind Function > + std::optional raw_function_invoke(Function function, std::span args) { using ft = function_traits; using return_type = typename ft::return_type; using argument_types = typename ft::argument_types; + constexpr bool as_copy = + stdex::copy_constructible && + stdex::same_as; + + constexpr bool as_void = + std::is_void_v || + stdex::same_as; + + constexpr bool ref_as_ptr = + std::is_reference_v && + stdex::same_as; + + static_assert(as_copy || as_void || ref_as_ptr); + if ( args.size() != ft::arity ) { throw std::logic_error("an attempt to call a function with an incorrect arity"); } + return std::invoke([ + args, function = std::move(function) // NOLINTNEXTLINE(readability-named-parameter) - return std::invoke([function = std::move(function), &args](std::index_sequence){ + ](std::index_sequence) -> std::optional { if ( !(... && (args.data() + Is)->can_cast_to>()) ) { throw std::logic_error("an attempt to call a function with incorrect argument types"); } - if constexpr ( std::is_void_v ) { - std::invoke( + if constexpr ( as_void ) { + std::ignore = std::invoke( std::move(function), (args.data() + Is)->cast>()...); return std::nullopt; } else { - return_type return_value{std::invoke( + return_type&& return_value = std::invoke( std::move(function), - (args.data() + Is)->cast>()...)}; - return value{std::forward(return_value)}; + (args.data() + Is)->cast>()...); + + if constexpr ( ref_as_ptr ) { + return value{std::addressof(return_value)}; + } else { + return value{std::forward(return_value)}; + } } }, std::make_index_sequence()); } template < function_kind Function > - bool vargs_is_invocable_with(std::span args) { + bool raw_function_is_invocable_with(std::span args) { using ft = function_traits; using argument_types = typename ft::argument_types; @@ -53,7 +74,7 @@ namespace meta_hpp::detail } // NOLINTNEXTLINE(readability-named-parameter) - return std::invoke([&args](std::index_sequence){ + return std::invoke([args](std::index_sequence){ return (... && (args.data() + Is)->can_cast_to>()); }, std::make_index_sequence()); } @@ -61,31 +82,29 @@ namespace meta_hpp::detail namespace meta_hpp::detail { - template < function_kind Function > + template < function_policy_kind Policy, function_kind Function > function_state::invoke_impl make_function_invoke(Function function) { using namespace std::placeholders; - return std::bind(&vargs_invoke, std::move(function), _1); + return std::bind(&raw_function_invoke, std::move(function), _1); } template < function_kind Function > function_state::is_invocable_with_impl make_function_is_invocable_with() { using namespace std::placeholders; - return std::bind(&vargs_is_invocable_with, _1); + return std::bind(&raw_function_is_invocable_with, _1); } } namespace meta_hpp::detail { - template < function_kind Function > - function_state::function_state(function_index index, Function function) - : index{std::move(index)} - , invoke{make_function_invoke(std::move(function))} - , is_invocable_with{make_function_is_invocable_with()} {} - - template < function_kind Function > + template < function_policy_kind Policy, function_kind Function > function_state_ptr function_state::make(std::string name, Function function) { function_index index{function_type_data::get_static(), std::move(name)}; - return std::make_shared(std::move(index), std::move(function)); + return std::make_shared(function_state{ + .index{std::move(index)}, + .invoke{make_function_invoke(std::move(function))}, + .is_invocable_with{make_function_is_invocable_with()}, + }); } } diff --git a/headers/meta.hpp/meta_states/member.hpp b/headers/meta.hpp/meta_states/member.hpp index 73243b3..50287ab 100644 --- a/headers/meta.hpp/meta_states/member.hpp +++ b/headers/meta.hpp/meta_states/member.hpp @@ -13,30 +13,65 @@ namespace meta_hpp::detail { - template < member_kind Member > - value vargs_invoke(Member member, const inst& inst) { + template < member_policy_kind Policy, member_kind Member > + value raw_member_getter(Member member, const inst& inst) { using mt = member_traits; using class_type = typename mt::class_type; using value_type = typename mt::value_type; - using qualified_type = const class_type; + constexpr bool as_copy = + stdex::copy_constructible && + stdex::same_as; - if ( !inst.can_cast_to() ) { + constexpr bool as_ptr = + stdex::same_as; + + constexpr bool as_ref_wrap = + stdex::same_as; + + static_assert(as_copy || as_ptr || as_ref_wrap); + + if ( !inst.can_cast_to() ) { throw std::logic_error("an attempt to get a member with an incorrect instance type"); } - value_type return_value{std::invoke(std::move(member), inst.cast())}; - return value{std::forward(return_value)}; + if ( inst.is_const() ) { + auto&& return_value = std::invoke(std::move(member), inst.cast()); + + if constexpr ( as_copy ) { + return value{std::forward(return_value)}; + } + + if constexpr ( as_ptr ) { + return value{std::addressof(return_value)}; + } + + if constexpr ( as_ref_wrap ) { + return value{std::ref(return_value)}; + } + } else { + auto&& return_value = std::invoke(std::move(member), inst.cast()); + + if constexpr ( as_copy ) { + return value{std::forward(return_value)}; + } + + if constexpr ( as_ptr ) { + return value{std::addressof(return_value)}; + } + + if constexpr ( as_ref_wrap ) { + return value{std::ref(return_value)}; + } + } } template < member_kind Member > - bool vargs_is_invocable_with(const inst_base& inst) { + bool raw_member_is_gettable_with(const inst_base& inst) { using mt = member_traits; using class_type = typename mt::class_type; - using qualified_type = const class_type; - - return inst.can_cast_to(); + return inst.can_cast_to(); } } @@ -48,8 +83,6 @@ namespace meta_hpp::detail using class_type = typename mt::class_type; using value_type = typename mt::value_type; - using qualified_type = class_type; - if constexpr ( std::is_const_v ) { throw std::logic_error("an attempt to set a constant member"); } else { @@ -57,7 +90,7 @@ namespace meta_hpp::detail throw std::logic_error("an attempt to set a member with an const instance type"); } - if ( !inst.can_cast_to() ) { + if ( !inst.can_cast_to() ) { throw std::logic_error("an attempt to set a member with an incorrect instance type"); } @@ -65,7 +98,7 @@ namespace meta_hpp::detail throw std::logic_error("an attempt to set a member with an incorrect argument type"); } - std::invoke(std::move(member), inst.cast()) = arg.cast(); + std::invoke(std::move(member), inst.cast()) = arg.cast(); } } @@ -75,27 +108,25 @@ namespace meta_hpp::detail using class_type = typename mt::class_type; using value_type = typename mt::value_type; - using qualified_type = class_type; - return !std::is_const_v && !inst.is_const() - && inst.can_cast_to() + && inst.can_cast_to() && arg.can_cast_to(); } } namespace meta_hpp::detail { - template < member_kind Member > + template < member_policy_kind Policy, member_kind Member > member_state::getter_impl make_member_getter(Member member) { using namespace std::placeholders; - return std::bind(&vargs_invoke, std::move(member), _1); + return std::bind(&raw_member_getter, std::move(member), _1); } template < member_kind Member > member_state::is_gettable_with_impl make_member_is_gettable_with() { using namespace std::placeholders; - return std::bind(&vargs_is_invocable_with, _1); + return std::bind(&raw_member_is_gettable_with, _1); } template < member_kind Member > @@ -113,18 +144,16 @@ namespace meta_hpp::detail namespace meta_hpp::detail { - template < member_kind Member > - member_state::member_state(member_index index, Member member) - : index{std::move(index)} - , getter{make_member_getter(std::move(member))} - , setter{make_member_setter(std::move(member))} - , is_gettable_with{make_member_is_gettable_with()} - , is_settable_with{make_member_is_settable_with()} {} - - template < member_kind Member > + template < member_policy_kind Policy, member_kind Member > member_state_ptr member_state::make(std::string name, Member member) { member_index index{member_type_data::get_static(), std::move(name)}; - return std::make_shared(std::move(index), std::move(member)); + return std::make_shared(member_state{ + .index{std::move(index)}, + .getter{make_member_getter(std::move(member))}, + .setter{make_member_setter(std::move(member))}, + .is_gettable_with{make_member_is_gettable_with()}, + .is_settable_with{make_member_is_settable_with()}, + }); } } diff --git a/headers/meta.hpp/meta_states/method.hpp b/headers/meta.hpp/meta_states/method.hpp index 0ea9b00..1f2c1f8 100644 --- a/headers/meta.hpp/meta_states/method.hpp +++ b/headers/meta.hpp/meta_states/method.hpp @@ -13,13 +13,27 @@ namespace meta_hpp::detail { - template < method_kind Method > - std::optional vargs_invoke(Method method, const inst& inst, std::span args) { + template < method_policy_kind Policy, method_kind Method > + std::optional raw_method_invoke(Method method, const inst& inst, std::span args) { using mt = method_traits; using return_type = typename mt::return_type; using qualified_type = typename mt::qualified_type; using argument_types = typename mt::argument_types; + constexpr bool as_copy = + stdex::copy_constructible && + stdex::same_as; + + constexpr bool as_void = + std::is_void_v || + stdex::same_as; + + constexpr bool ref_as_ptr = + std::is_reference_v && + stdex::same_as; + + static_assert(as_copy || as_void || ref_as_ptr); + if ( args.size() != mt::arity ) { throw std::logic_error("an attempt to call a method with an incorrect arity"); } @@ -28,30 +42,38 @@ namespace meta_hpp::detail throw std::logic_error("an attempt to call a method with an incorrect instance type"); } + return std::invoke([ + &inst, &args, + method = std::move(method) // NOLINTNEXTLINE(readability-named-parameter) - return std::invoke([method = std::move(method), &inst, &args](std::index_sequence){ + ](std::index_sequence) -> std::optional { if ( !(... && (args.data() + Is)->can_cast_to>()) ) { throw std::logic_error("an attempt to call a method with incorrect argument types"); } - if constexpr ( std::is_void_v ) { - std::invoke( + if constexpr ( as_void ) { + std::ignore = std::invoke( std::move(method), inst.cast(), (args.data() + Is)->cast>()...); return std::nullopt; } else { - return_type return_value{std::invoke( + return_type&& return_value = std::invoke( std::move(method), inst.cast(), - (args.data() + Is)->cast>()...)}; - return value{std::forward(return_value)}; + (args.data() + Is)->cast>()...); + + if constexpr ( ref_as_ptr ) { + return value{std::addressof(return_value)}; + } else { + return value{std::forward(return_value)}; + } } }, std::make_index_sequence()); } template < method_kind Method > - bool vargs_is_invocable_with(const inst_base& inst, std::span args) { + bool raw_method_is_invocable_with(const inst_base& inst, std::span args) { using mt = method_traits; using qualified_type = typename mt::qualified_type; using argument_types = typename mt::argument_types; @@ -73,31 +95,29 @@ namespace meta_hpp::detail namespace meta_hpp::detail { - template < method_kind Method > + template < method_policy_kind Policy, method_kind Method > method_state::invoke_impl make_method_invoke(Method method) { using namespace std::placeholders; - return std::bind(&vargs_invoke, std::move(method), _1, _2); + return std::bind(&raw_method_invoke, std::move(method), _1, _2); } template < method_kind Method > method_state::is_invocable_with_impl make_method_is_invocable_with() { using namespace std::placeholders; - return std::bind(&vargs_is_invocable_with, _1, _2); + return std::bind(&raw_method_is_invocable_with, _1, _2); } } namespace meta_hpp::detail { - template < method_kind Method > - method_state::method_state(method_index index, Method method) - : index{std::move(index)} - , invoke{make_method_invoke(std::move(method))} - , is_invocable_with{make_method_is_invocable_with()} {} - - template < method_kind Method > + template < method_policy_kind Policy, method_kind Method > method_state_ptr method_state::make(std::string name, Method method) { method_index index{method_type_data::get_static(), std::move(name)}; - return std::make_shared(std::move(index), std::move(method)); + return std::make_shared(method_state{ + .index{std::move(index)}, + .invoke{make_method_invoke(std::move(method))}, + .is_invocable_with{make_method_is_invocable_with()}, + }); } } diff --git a/headers/meta.hpp/meta_states/scope.hpp b/headers/meta.hpp/meta_states/scope.hpp index 2a04f19..49b4016 100644 --- a/headers/meta.hpp/meta_states/scope.hpp +++ b/headers/meta.hpp/meta_states/scope.hpp @@ -11,12 +11,11 @@ namespace meta_hpp::detail { - inline scope_state::scope_state(scope_index index) - : index{std::move(index)} {} - inline scope_state_ptr scope_state::make(std::string name) { scope_index index{std::move(name)}; - return std::make_shared(std::move(index)); + return std::make_shared(scope_state{ + .index{std::move(index)}, + }); } inline scope_state_ptr scope_state::get_static(std::string_view name) { diff --git a/headers/meta.hpp/meta_states/variable.hpp b/headers/meta.hpp/meta_states/variable.hpp index 0bb8b3c..52e404f 100644 --- a/headers/meta.hpp/meta_states/variable.hpp +++ b/headers/meta.hpp/meta_states/variable.hpp @@ -13,13 +13,36 @@ namespace meta_hpp::detail { - template < pointer_kind Pointer > + template < variable_policy_kind Policy, pointer_kind Pointer > value raw_variable_getter(Pointer pointer) { using pt = pointer_traits; using data_type = typename pt::data_type; - data_type return_value{*pointer}; - return value{std::forward(return_value)}; + constexpr bool as_copy = + stdex::copy_constructible && + stdex::same_as; + + constexpr bool as_ptr = + stdex::same_as; + + constexpr bool as_ref_wrap = + stdex::same_as; + + static_assert(as_copy || as_ptr || as_ref_wrap); + + auto&& return_value = *pointer; + + if constexpr ( as_copy ) { + return value{std::forward(return_value)}; + } + + if constexpr ( as_ptr ) { + return value{std::addressof(return_value)}; + } + + if constexpr ( as_ref_wrap) { + return value{std::ref(return_value)}; + } } template < pointer_kind Pointer > @@ -33,7 +56,6 @@ namespace meta_hpp::detail if ( !arg.can_cast_to() ) { throw std::logic_error("an attempt to set a variable with an incorrect argument type"); } - *pointer = arg.cast(); } } @@ -50,10 +72,10 @@ namespace meta_hpp::detail namespace meta_hpp::detail { - template < pointer_kind Pointer > + template < variable_policy_kind Policy, pointer_kind Pointer > variable_state::getter_impl make_variable_getter(Pointer pointer) { using namespace std::placeholders; - return std::bind(&raw_variable_getter, pointer); + return std::bind(&raw_variable_getter, pointer); } template < pointer_kind Pointer > @@ -71,17 +93,15 @@ namespace meta_hpp::detail namespace meta_hpp::detail { - template < pointer_kind Pointer > - variable_state::variable_state(variable_index index, Pointer pointer) - : index{std::move(index)} - , getter{make_variable_getter(pointer)} - , setter{make_variable_setter(pointer)} - , is_settable_with{make_variable_is_settable_with()} {} - - template < pointer_kind Pointer > + template < variable_policy_kind Policy, pointer_kind Pointer > variable_state_ptr variable_state::make(std::string name, Pointer pointer) { variable_index index{pointer_type_data::get_static(), std::move(name)}; - return std::make_shared(index, pointer); + return std::make_shared(variable_state{ + .index{std::move(index)}, + .getter{make_variable_getter(std::move(pointer))}, + .setter{make_variable_setter(std::move(pointer))}, + .is_settable_with{make_variable_is_settable_with()}, + }); } } diff --git a/headers/meta.hpp/meta_utilities/vinvoke.hpp b/headers/meta.hpp/meta_utilities/vinvoke.hpp index 65c49c1..66cb0ef 100644 --- a/headers/meta.hpp/meta_utilities/vinvoke.hpp +++ b/headers/meta.hpp/meta_utilities/vinvoke.hpp @@ -22,9 +22,9 @@ namespace meta_hpp using namespace detail; if constexpr ( sizeof...(Args) > 0 ) { const std::array vargs{arg{std::forward(args)}...}; - return vargs_invoke(std::forward(function), vargs); + return raw_function_invoke(std::forward(function), vargs); } else { - return vargs_invoke(std::forward(function), {}); + return raw_function_invoke(std::forward(function), {}); } } } @@ -40,7 +40,7 @@ namespace meta_hpp std::optional invoke(Member&& member, Instance&& instance) { using namespace detail; const inst vinst{std::forward(instance)}; - return vargs_invoke(std::forward(member), vinst); + return raw_member_getter(std::forward(member), vinst); } } @@ -57,9 +57,9 @@ namespace meta_hpp const inst vinst{std::forward(instance)}; if constexpr ( sizeof...(Args) > 0 ) { const std::array vargs{arg{std::forward(args)}...}; - return vargs_invoke(std::forward(method), vinst, vargs); + return raw_method_invoke(std::forward(method), vinst, vargs); } else { - return vargs_invoke(std::forward(method), vinst, {}); + return raw_method_invoke(std::forward(method), vinst, {}); } } } @@ -81,9 +81,9 @@ namespace meta_hpp if constexpr ( sizeof...(Args) > 0 ) { using namespace detail; const std::array vargs{arg_base{type_list{}}...}; - return vargs_is_invocable_with(vargs); + return raw_function_is_invocable_with(vargs); } else { - return vargs_is_invocable_with({}); + return raw_function_is_invocable_with({}); } } @@ -92,9 +92,9 @@ namespace meta_hpp if constexpr ( sizeof...(Args) > 0 ) { using namespace detail; const std::array vargs{arg_base{std::forward(args)}...}; - return vargs_is_invocable_with(vargs); + return raw_function_is_invocable_with(vargs); } else { - return vargs_is_invocable_with({}); + return raw_function_is_invocable_with({}); } } } @@ -131,14 +131,14 @@ namespace meta_hpp bool is_invocable_with() { using namespace detail; const inst_base vinst{type_list{}}; - return vargs_is_invocable_with(vinst); + return raw_member_is_gettable_with(vinst); } template < detail::member_kind Member, typename Instance > bool is_invocable_with(Instance&& instance) { using namespace detail; const inst_base vinst{std::forward(instance)}; - return vargs_is_invocable_with(vinst); + return raw_member_is_gettable_with(vinst); } } @@ -150,9 +150,9 @@ namespace meta_hpp const inst_base vinst{type_list{}}; if constexpr ( sizeof...(Args) > 0 ) { const std::array vargs{arg_base{type_list{}}...}; - return vargs_is_invocable_with(vinst, vargs); + return raw_method_is_invocable_with(vinst, vargs); } else { - return vargs_is_invocable_with(vinst, {}); + return raw_method_is_invocable_with(vinst, {}); } } @@ -162,9 +162,9 @@ namespace meta_hpp const inst_base vinst{std::forward(instance)}; if constexpr ( sizeof...(Args) > 0 ) { const std::array vargs{arg_base{std::forward(args)}...}; - return vargs_is_invocable_with(vinst, vargs); + return raw_method_is_invocable_with(vinst, vargs); } else { - return vargs_is_invocable_with(vinst, {}); + return raw_method_is_invocable_with(vinst, {}); } } } diff --git a/untests/meta_states/ctor_tests.cpp b/untests/meta_states/ctor_tests.cpp new file mode 100644 index 0000000..3318d39 --- /dev/null +++ b/untests/meta_states/ctor_tests.cpp @@ -0,0 +1,67 @@ +/******************************************************************************* + * This file is part of the "https://github.com/blackmatov/meta.hpp" + * For conditions of distribution and use, see copyright notice in LICENSE.md + * Copyright (C) 2021, by Matvey Cherevko (blackmatov@gmail.com) + ******************************************************************************/ + +#include "../meta_untests.hpp" + +namespace +{ + struct clazz_1 { + int i{}; + clazz_1(int i) : i{i} {} + }; + + struct clazz_2 { + int i{}; + clazz_2(int i) : i{i} {} + }; + + struct clazz_3 { + int i{}; + clazz_3(int i) : i{i} {} + }; +} + +TEST_CASE("meta/meta_states/ctor") { + namespace meta = meta_hpp; + + meta::class_() + .ctor_(meta::ctor_policy::as_object{}); + + meta::class_() + .ctor_(meta::ctor_policy::as_raw_pointer{}); + + meta::class_() + .ctor_(meta::ctor_policy::as_shared_pointer{}); + + SUBCASE("clazz_1") { + const meta::class_type clazz_type = meta::resolve_type(); + REQUIRE(clazz_type); + + const meta::value v = clazz_type.create(10).value(); + CHECK(v.get_type() == meta::resolve_type()); + CHECK(v.cast().i == 10); + } + + SUBCASE("clazz_2") { + const meta::class_type clazz_type = meta::resolve_type(); + REQUIRE(clazz_type); + + const meta::value v = clazz_type.create(20).value(); + CHECK(v.get_type() == meta::resolve_type()); + CHECK(v.cast()->i == 20); + + //TODO: dtor!!! + } + + SUBCASE("clazz_3") { + const meta::class_type clazz_type = meta::resolve_type(); + REQUIRE(clazz_type); + + const meta::value v = clazz_type.create(30).value(); + CHECK(v.get_type() == meta::resolve_type>()); + CHECK(v.cast>()->i == 30); + } +} diff --git a/untests/meta_states/member_tests.cpp b/untests/meta_states/member_tests.cpp index 78346e9..e1e13bc 100644 --- a/untests/meta_states/member_tests.cpp +++ b/untests/meta_states/member_tests.cpp @@ -11,6 +11,7 @@ namespace struct clazz_1 { int int_member = 1; const int const_int_member = 2; + std::unique_ptr unique_int_member = std::make_unique(42); }; struct clazz_2 {}; @@ -21,7 +22,10 @@ TEST_CASE("meta/meta_states/member") { meta::class_() .member_("int_member", &clazz_1::int_member) - .member_("const_int_member", &clazz_1::const_int_member); + .member_("const_int_member", &clazz_1::const_int_member) + // .member_("unique_int_member", &clazz_1::unique_int_member) + .member_("unique_int_member_as_ptr", &clazz_1::unique_int_member, meta::member_policy::as_pointer{}) + .member_("unique_int_member_as_ref", &clazz_1::unique_int_member, meta::member_policy::as_reference_wrapper{}); const meta::class_type clazz_1_type = meta::resolve_type(); REQUIRE(clazz_1_type); @@ -211,4 +215,46 @@ TEST_CASE("meta/meta_states/member") { CHECK(vm(v) == 2); } } + + SUBCASE("unique_int_member_as_ptr") { + meta::member vm = clazz_1_type.get_member("unique_int_member_as_ptr"); + REQUIRE(vm); + + CHECK(vm.get_type() == meta::resolve_type(&clazz_1::unique_int_member)); + CHECK(vm.get_name() == "unique_int_member_as_ptr"); + + { + clazz_1 v; + CHECK(vm.get(v).get_type() == meta::resolve_type*>()); + CHECK(vm.get(v) == std::addressof(v.unique_int_member)); + } + + { + const clazz_1 v; + CHECK(vm.get(v).get_type() == meta::resolve_type*>()); + CHECK(vm.get(v) == std::addressof(v.unique_int_member)); + } + } + + SUBCASE("unique_int_member_as_ref") { + meta::member vm = clazz_1_type.get_member("unique_int_member_as_ref"); + REQUIRE(vm); + + CHECK(vm.get_type() == meta::resolve_type(&clazz_1::unique_int_member)); + CHECK(vm.get_name() == "unique_int_member_as_ref"); + + { + clazz_1 v; + using ref_t = std::reference_wrapper>; + CHECK(vm.get(v).get_type() == meta::resolve_type()); + CHECK(vm.get(v).try_cast()->get() == v.unique_int_member); + } + + { + const clazz_1 v; + using ref_t = std::reference_wrapper>; + CHECK(vm.get(v).get_type() == meta::resolve_type()); + CHECK(vm.get(v).try_cast()->get() == v.unique_int_member); + } + } } diff --git a/untests/meta_states/variable_tests.cpp b/untests/meta_states/variable_tests.cpp index 6f7bc1e..ce9e824 100644 --- a/untests/meta_states/variable_tests.cpp +++ b/untests/meta_states/variable_tests.cpp @@ -14,6 +14,9 @@ namespace static int& ref_int_variable; static const int& const_ref_int_variable; + + static std::unique_ptr unique_int_variable; + static const std::unique_ptr const_unique_int_variable; }; int clazz_1::int_variable = 1; @@ -21,6 +24,9 @@ namespace int& clazz_1::ref_int_variable = clazz_1::int_variable; const int& clazz_1::const_ref_int_variable = clazz_1::const_int_variable; + + std::unique_ptr clazz_1::unique_int_variable = std::make_unique(42); + const std::unique_ptr clazz_1::const_unique_int_variable = std::make_unique(42); } TEST_CASE("meta/meta_states/variable") { @@ -30,7 +36,15 @@ TEST_CASE("meta/meta_states/variable") { .variable_("int_variable", &clazz_1::int_variable) .variable_("const_int_variable", &clazz_1::const_int_variable) .variable_("ref_int_variable", &clazz_1::ref_int_variable) - .variable_("const_ref_int_variable", &clazz_1::const_ref_int_variable); + .variable_("const_ref_int_variable", &clazz_1::const_ref_int_variable) + + // .variable_("unique_int_variable", &clazz_1::unique_int_variable) + .variable_("unique_int_variable_as_ptr", &clazz_1::unique_int_variable, meta::variable_policy::as_pointer{}) + .variable_("unique_int_variable_as_ref", &clazz_1::unique_int_variable, meta::variable_policy::as_reference_wrapper{}) + + // .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{}); const meta::class_type clazz_1_type = meta::resolve_type(); REQUIRE(clazz_1_type); @@ -145,4 +159,76 @@ TEST_CASE("meta/meta_states/variable") { CHECK_THROWS(vm.set(10)); CHECK(vm.get() == 2); CHECK_THROWS(vm(11)); CHECK(vm() == 2); } + + SUBCASE("unique_int_variable_as_ptr") { + meta::variable vm = clazz_1_type.get_variable("unique_int_variable_as_ptr"); + REQUIRE(vm); + + CHECK(vm.get().get_type() == meta::resolve_type*>()); + CHECK(vm.get() == std::addressof(clazz_1::unique_int_variable)); + + { + auto nv = std::make_unique(11); + CHECK_NOTHROW(vm.set(std::move(nv))); + CHECK(*clazz_1::unique_int_variable == 11); + } + + { + auto nv = std::make_unique(12); + CHECK_THROWS(vm.set(nv)); + CHECK(*clazz_1::unique_int_variable == 11); + } + } + + SUBCASE("unique_int_variable_as_ref") { + meta::variable vm = clazz_1_type.get_variable("unique_int_variable_as_ref"); + REQUIRE(vm); + + using ref_t = std::reference_wrapper>; + CHECK(vm.get().get_type() == meta::resolve_type()); + CHECK(vm.get().try_cast()->get() == clazz_1::unique_int_variable); + + { + auto nv = std::make_unique(13); + CHECK_NOTHROW(vm.set(std::move(nv))); + CHECK(*clazz_1::unique_int_variable == 13); + } + + { + auto nv = std::make_unique(14); + CHECK_THROWS(vm.set(nv)); + CHECK(*clazz_1::unique_int_variable == 13); + } + } + + SUBCASE("const_unique_int_variable_as_ptr") { + meta::variable vm = clazz_1_type.get_variable("const_unique_int_variable_as_ptr"); + REQUIRE(vm); + + CHECK(vm.get().get_type() == meta::resolve_type*>()); + CHECK(vm.get() == std::addressof(clazz_1::const_unique_int_variable)); + + { + auto nv = std::make_unique(11); + CHECK_THROWS(vm.set(nv)); + CHECK_THROWS(vm.set(std::move(nv))); + CHECK(*clazz_1::const_unique_int_variable == 42); + } + } + + SUBCASE("const_unique_int_variable_as_ref") { + meta::variable vm = clazz_1_type.get_variable("const_unique_int_variable_as_ref"); + REQUIRE(vm); + + using ref_t = std::reference_wrapper>; + CHECK(vm.get().get_type() == meta::resolve_type()); + CHECK(vm.get().try_cast()->get() == clazz_1::const_unique_int_variable); + + { + auto nv = std::make_unique(12); + CHECK_THROWS(vm.set(nv)); + CHECK_THROWS(vm.set(std::move(nv))); + CHECK(*clazz_1::const_unique_int_variable == 42); + } + } } diff --git a/untests/meta_utilities/arg_tests.cpp b/untests/meta_utilities/arg_tests.cpp index f69ae43..ed1e59a 100644 --- a/untests/meta_utilities/arg_tests.cpp +++ b/untests/meta_utilities/arg_tests.cpp @@ -70,7 +70,7 @@ namespace {\ using namespace meta::detail;\ auto function_ptr = meta::select(&FName);\ - meta::function f_state{function_state::make("", function_ptr)};\ + meta::function f_state{function_state::make("", function_ptr)};\ \ if ( std::is_invocable_v ) {\ CHECK(arg{FromValue}.can_cast_to());\ @@ -94,7 +94,7 @@ namespace {\ using namespace meta::detail;\ auto function_ptr = meta::select(&FName);\ - meta::function f_state{function_state::make("", function_ptr)};\ + meta::function f_state{function_state::make("", function_ptr)};\ \ if ( std::is_invocable_v ) {\ CHECK(f_state.is_invocable_with());\ diff --git a/untests/meta_utilities/inst_tests.cpp b/untests/meta_utilities/inst_tests.cpp index 5bfe24f..90b73d9 100644 --- a/untests/meta_utilities/inst_tests.cpp +++ b/untests/meta_utilities/inst_tests.cpp @@ -30,7 +30,7 @@ namespace {\ using namespace meta::detail;\ auto method_ptr = meta::select(&clazz::FName);\ - meta::method m_state{method_state::make("", method_ptr)};\ + meta::method m_state{method_state::make("", method_ptr)};\ \ if ( std::is_invocable_v ) {\ CHECK(inst{Inst}.can_cast_to());\ @@ -54,7 +54,7 @@ namespace {\ using namespace meta::detail;\ auto method_ptr = meta::select(&clazz::FName);\ - meta::method m_state{method_state::make("", method_ptr)};\ + meta::method m_state{method_state::make("", method_ptr)};\ \ if ( std::is_invocable_v ) {\ CHECK(m_state.is_invocable_with());\