From 89e47e538861fe799725861f6821dfd1a9075f0e Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sun, 4 Jul 2021 01:34:18 +0700 Subject: [PATCH] delete default value ctor --- headers/meta.hpp/meta_function_info.hpp | 10 +++--- headers/meta.hpp/meta_method_info.hpp | 20 +++++------ headers/meta.hpp/meta_value.hpp | 44 ++++++++++++++++++++++--- untests/meta_examples.cpp | 8 ++--- untests/meta_function_tests.cpp | 6 ++-- untests/meta_method_tests.cpp | 18 +++++----- 6 files changed, 71 insertions(+), 35 deletions(-) diff --git a/headers/meta.hpp/meta_function_info.hpp b/headers/meta.hpp/meta_function_info.hpp index 443b3bb..06dbaf2 100644 --- a/headers/meta.hpp/meta_function_info.hpp +++ b/headers/meta.hpp/meta_function_info.hpp @@ -28,7 +28,7 @@ namespace meta_hpp::function_detail : function_traits {}; template < auto Function, std::size_t... Is > - value invoke(value* args, std::index_sequence) { + std::optional invoke(value* args, std::index_sequence) { using ft = function_traits; using return_type = typename ft::return_type; using argument_types = typename ft::argument_types; @@ -43,7 +43,7 @@ namespace meta_hpp::function_detail if constexpr ( std::is_void_v ) { std::invoke(Function, *std::get(typed_arguments)...); - return value{}; + return std::nullopt; } else { return_type return_value = std::invoke(Function, *std::get(typed_arguments)...); @@ -52,7 +52,7 @@ namespace meta_hpp::function_detail } template < auto Function > - value invoke(value* args, std::size_t arg_count) { + std::optional invoke(value* args, std::size_t arg_count) { using ft = function_traits; if ( arg_count != ft::arity ) { @@ -84,7 +84,7 @@ namespace meta_hpp } template < typename... Args > - value invoke(Args&&... args) const { + std::optional invoke(Args&&... args) const { std::array vargs{{std::forward(args)...}}; return invoke_(vargs.data(), vargs.size()); } @@ -118,7 +118,7 @@ namespace meta_hpp private: family_id fid_; std::string id_; - value(*invoke_)(value*, std::size_t); + std::optional(*invoke_)(value*, std::size_t); std::map> datas_; }; } diff --git a/headers/meta.hpp/meta_method_info.hpp b/headers/meta.hpp/meta_method_info.hpp index 8025b44..6f31031 100644 --- a/headers/meta.hpp/meta_method_info.hpp +++ b/headers/meta.hpp/meta_method_info.hpp @@ -40,7 +40,7 @@ namespace meta_hpp::method_detail : method_traits {}; template < auto Method, std::size_t... Is > - value invoke([[maybe_unused]] void* instance, value* args, std::index_sequence) { + std::optional invoke([[maybe_unused]] void* instance, value* args, std::index_sequence) { using mt = method_traits; using return_type = typename mt::return_type; using instance_type = typename mt::instance_type; @@ -57,7 +57,7 @@ namespace meta_hpp::method_detail std::invoke(Method, std::ref(*static_cast(instance)), *std::get(typed_arguments)...); - return value{}; + return std::nullopt; } else { return_type return_value = std::invoke(Method, std::ref(*static_cast(instance)), @@ -67,7 +67,7 @@ namespace meta_hpp::method_detail } template < auto Method > - value invoke(void* instance, value* args, std::size_t arg_count) { + std::optional invoke(void* instance, value* args, std::size_t arg_count) { using mt = method_traits; if ( arg_count != mt::arity ) { @@ -78,7 +78,7 @@ namespace meta_hpp::method_detail } template < auto Method, std::size_t... Is > - value cinvoke([[maybe_unused]] const void* instance, value* args, std::index_sequence) { + std::optional cinvoke([[maybe_unused]] const void* instance, value* args, std::index_sequence) { using mt = method_traits; using return_type = typename mt::return_type; using instance_type = typename mt::instance_type; @@ -96,7 +96,7 @@ namespace meta_hpp::method_detail std::invoke(Method, std::ref(*static_cast(instance)), *std::get(typed_arguments)...); - return value{}; + return std::nullopt; } else { return_type return_value = std::invoke(Method, std::ref(*static_cast(instance)), @@ -109,7 +109,7 @@ namespace meta_hpp::method_detail } template < auto Method > - value cinvoke(const void* instance, value* args, std::size_t arg_count) { + std::optional cinvoke(const void* instance, value* args, std::size_t arg_count) { using mt = method_traits; if ( arg_count != mt::arity ) { @@ -141,13 +141,13 @@ namespace meta_hpp } template < typename... Args > - value invoke(void* instance, Args&&... args) const { + std::optional invoke(void* instance, Args&&... args) const { std::array vargs{{std::forward(args)...}}; return invoke_(instance, vargs.data(), vargs.size()); } template < typename... Args > - value invoke(const void* instance, Args&&... args) const { + std::optional invoke(const void* instance, Args&&... args) const { std::array vargs{{std::forward(args)...}}; return cinvoke_(instance, vargs.data(), vargs.size()); } @@ -182,8 +182,8 @@ namespace meta_hpp private: family_id fid_; std::string id_; - value(*invoke_)(void*, value*, std::size_t); - value(*cinvoke_)(const void*, value*, std::size_t); + std::optional(*invoke_)(void*, value*, std::size_t); + std::optional(*cinvoke_)(const void*, value*, std::size_t); std::map> datas_; }; } diff --git a/headers/meta.hpp/meta_value.hpp b/headers/meta.hpp/meta_value.hpp index f4f7552..3676cc1 100644 --- a/headers/meta.hpp/meta_value.hpp +++ b/headers/meta.hpp/meta_value.hpp @@ -12,28 +12,60 @@ namespace meta_hpp { class value { public: - value() = default; + value() = delete; + + value(value&&) = default; + value(const value&) = default; + + value& operator=(value&&) = default; + value& operator=(const value&) = default; template < typename T > value(T&& value) : raw_{std::forward(value)} {} + template < typename T > + value& operator=(T&& value) noexcept { + raw_ = std::forward(value); + return *this; + } + template < typename T, typename... Args > value(std::in_place_type_t, Args&&... args) : raw_{std::in_place_type, std::forward(args)...} {} + template < typename T, typename U, typename... Args > + value(std::in_place_type_t, std::initializer_list ilist, Args&&... args) + : raw_{std::in_place_type, ilist, std::forward(args)...} {} + + void swap(value& other) noexcept { + raw_.swap(other.raw_); + } + template < typename T > - auto cast() const { + T cast() && { + return std::any_cast(std::move(raw_)); + } + + template < typename T > + T cast() & { return std::any_cast(raw_); } template < typename T > - auto try_cast() noexcept { + T cast() const & { + return std::any_cast(raw_); + } + + template < typename T > + std::add_pointer_t + try_cast() noexcept { return std::any_cast(&raw_); } template < typename T > - auto try_cast() const noexcept { + std::add_pointer_t> + try_cast() const noexcept { return std::any_cast(&raw_); } public: @@ -60,4 +92,8 @@ namespace meta_hpp private: std::any raw_; }; + + inline void swap(value& l, value& r) noexcept { + l.swap(r); + } } diff --git a/untests/meta_examples.cpp b/untests/meta_examples.cpp index d12d5fd..8c97308 100644 --- a/untests/meta_examples.cpp +++ b/untests/meta_examples.cpp @@ -133,18 +133,18 @@ TEST_CASE("meta/examples/simple") { ivec2 v2{1,2}; CHECK(ivec2_x_info.get(&v2).cast() == 1); CHECK(ivec2_y_info.get(&v2).cast() == 2); - CHECK(ivec2_dot_info.invoke(&v2, v2).cast() == 5); - CHECK(ivec2_length2_info.invoke(&v2).cast() == 5); + CHECK(ivec2_dot_info.invoke(&v2, v2)->cast() == 5); + CHECK(ivec2_length2_info.invoke(&v2)->cast() == 5); } { - ivec2 v = iadd2_info.invoke(ivec2{1,2}, ivec2{3,4}).cast(); + ivec2 v = iadd2_info.invoke(ivec2{1,2}, ivec2{3,4})->cast(); CHECK(v.x == 4); CHECK(v.y == 6); } { - ivec3 v = iadd3_info.invoke(ivec3{1,2,3}, ivec3{3,4,5}).cast(); + ivec3 v = iadd3_info.invoke(ivec3{1,2,3}, ivec3{3,4,5})->cast(); CHECK(v.x == 4); CHECK(v.y == 6); CHECK(v.z == 8); diff --git a/untests/meta_function_tests.cpp b/untests/meta_function_tests.cpp index 5884233..05f23f2 100644 --- a/untests/meta_function_tests.cpp +++ b/untests/meta_function_tests.cpp @@ -55,17 +55,17 @@ TEST_CASE("meta/function") { } SUBCASE("int_return") { - CHECK(int_f_void_info.invoke().cast() == 1); + CHECK(int_f_void_info.invoke()->cast() == 1); CHECK_THROWS_AS(int_f_void_info.invoke(1), std::logic_error); CHECK_THROWS_AS(int_f_int_info.invoke(), std::logic_error); - CHECK(int_f_int_info.invoke(1).cast() == 1); + CHECK(int_f_int_info.invoke(1)->cast() == 1); CHECK_THROWS_AS(int_f_int_info.invoke(1.f), std::logic_error); CHECK_THROWS_AS(int_f_int_info.invoke(1, 2), std::logic_error); CHECK_THROWS_AS(int_f_int2_info.invoke(), std::logic_error); CHECK_THROWS_AS(int_f_int2_info.invoke(1), std::logic_error); - CHECK(int_f_int2_info.invoke(1, 2).cast() == 3); + CHECK(int_f_int2_info.invoke(1, 2)->cast() == 3); CHECK_THROWS_AS(int_f_int2_info.invoke(1.f, 2), std::logic_error); CHECK_THROWS_AS(int_f_int2_info.invoke(1, 2.f), std::logic_error); CHECK_THROWS_AS(int_f_int2_info.invoke(1, 2, 3), std::logic_error); diff --git a/untests/meta_method_tests.cpp b/untests/meta_method_tests.cpp index 2192b6e..62b069d 100644 --- a/untests/meta_method_tests.cpp +++ b/untests/meta_method_tests.cpp @@ -75,17 +75,17 @@ TEST_CASE("meta/non_const_method") { SUBCASE("int_return") { clazz instance; - CHECK(int_f_void_info.invoke(&instance).cast() == 1); + CHECK(int_f_void_info.invoke(&instance)->cast() == 1); CHECK_THROWS_AS(int_f_void_info.invoke(&instance, 1), std::logic_error); CHECK_THROWS_AS(int_f_int_info.invoke(&instance), std::logic_error); - CHECK(int_f_int_info.invoke(&instance, 1).cast() == 1); + CHECK(int_f_int_info.invoke(&instance, 1)->cast() == 1); CHECK_THROWS_AS(int_f_int_info.invoke(&instance, 1.f), std::logic_error); CHECK_THROWS_AS(int_f_int_info.invoke(&instance, 1, 2), std::logic_error); CHECK_THROWS_AS(int_f_int2_info.invoke(&instance), std::logic_error); CHECK_THROWS_AS(int_f_int2_info.invoke(&instance, 1), std::logic_error); - CHECK(int_f_int2_info.invoke(&instance, 1, 2).cast() == 3); + CHECK(int_f_int2_info.invoke(&instance, 1, 2)->cast() == 3); CHECK_THROWS_AS(int_f_int2_info.invoke(&instance, 1.f, 2), std::logic_error); CHECK_THROWS_AS(int_f_int2_info.invoke(&instance, 1, 2.f), std::logic_error); CHECK_THROWS_AS(int_f_int2_info.invoke(&instance, 1, 2, 3), std::logic_error); @@ -143,24 +143,24 @@ TEST_CASE("meta/const_method") { SUBCASE("int_return") { clazz instance; - CHECK(int_f_void_info.invoke(&instance).cast() == 1); + CHECK(int_f_void_info.invoke(&instance)->cast() == 1); CHECK_THROWS_AS(int_f_void_info.invoke(&instance, 1), std::logic_error); CHECK_THROWS_AS(int_f_int_info.invoke(&instance), std::logic_error); - CHECK(int_f_int_info.invoke(&instance, 1).cast() == 1); + CHECK(int_f_int_info.invoke(&instance, 1)->cast() == 1); CHECK_THROWS_AS(int_f_int_info.invoke(&instance, 1.f), std::logic_error); CHECK_THROWS_AS(int_f_int_info.invoke(&instance, 1, 2), std::logic_error); CHECK_THROWS_AS(int_f_int2_info.invoke(&instance), std::logic_error); CHECK_THROWS_AS(int_f_int2_info.invoke(&instance, 1), std::logic_error); - CHECK(int_f_int2_info.invoke(&instance, 1, 2).cast() == 3); + CHECK(int_f_int2_info.invoke(&instance, 1, 2)->cast() == 3); CHECK_THROWS_AS(int_f_int2_info.invoke(&instance, 1.f, 2), std::logic_error); CHECK_THROWS_AS(int_f_int2_info.invoke(&instance, 1, 2.f), std::logic_error); CHECK_THROWS_AS(int_f_int2_info.invoke(&instance, 1, 2, 3), std::logic_error); const clazz& cinstance = instance; - CHECK(int_f_void_info.invoke(&cinstance).cast() == 1); - CHECK(int_f_int_info.invoke(&cinstance, 1).cast() == 1); - CHECK(int_f_int2_info.invoke(&cinstance, 1, 2).cast() == 3); + CHECK(int_f_void_info.invoke(&cinstance)->cast() == 1); + CHECK(int_f_int_info.invoke(&cinstance, 1)->cast() == 1); + CHECK(int_f_int2_info.invoke(&cinstance, 1, 2)->cast() == 3); } }