From 8d35be593dd48885f292440b8c8add2b81538055 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Wed, 30 Jun 2021 00:23:37 +0700 Subject: [PATCH 001/233] first dirty proof of concept --- headers/meta.hpp/meta.hpp | 14 +- headers/meta.hpp/meta_class.hpp | 141 +++++++++++++ headers/meta.hpp/meta_field.hpp | 120 +++++++++++ headers/meta.hpp/meta_function.hpp | 125 ++++++++++++ headers/meta.hpp/meta_fwd.hpp | 99 ++++++++++ headers/meta.hpp/meta_method.hpp | 186 ++++++++++++++++++ headers/meta.hpp/meta_namespace.hpp | 121 ++++++++++++ headers/meta.hpp/meta_registry.hpp | 46 +++++ headers/meta.hpp/meta_value.hpp | 38 ++++ headers/meta.hpp/meta_variable.hpp | 116 +++++++++++ untests/meta_class_tests.cpp | 107 ++++++++++ untests/meta_examples.cpp | 142 +++++++++++++ untests/meta_field_tests.cpp | 63 ++++++ untests/meta_function_tests.cpp | 73 +++++++ untests/meta_method_tests.cpp | 166 ++++++++++++++++ untests/meta_namespace_tests.cpp | 68 +++++++ untests/meta_registry_tests.cpp | 67 +++++++ untests/meta_tests.cpp | 16 -- .../{meta_tests.hpp => meta_value_tests.cpp} | 9 +- untests/meta_variable_tests.cpp | 93 +++++++++ 20 files changed, 1788 insertions(+), 22 deletions(-) create mode 100644 headers/meta.hpp/meta_class.hpp create mode 100644 headers/meta.hpp/meta_field.hpp create mode 100644 headers/meta.hpp/meta_function.hpp create mode 100644 headers/meta.hpp/meta_fwd.hpp create mode 100644 headers/meta.hpp/meta_method.hpp create mode 100644 headers/meta.hpp/meta_namespace.hpp create mode 100644 headers/meta.hpp/meta_registry.hpp create mode 100644 headers/meta.hpp/meta_value.hpp create mode 100644 headers/meta.hpp/meta_variable.hpp create mode 100644 untests/meta_class_tests.cpp create mode 100644 untests/meta_examples.cpp create mode 100644 untests/meta_field_tests.cpp create mode 100644 untests/meta_function_tests.cpp create mode 100644 untests/meta_method_tests.cpp create mode 100644 untests/meta_namespace_tests.cpp create mode 100644 untests/meta_registry_tests.cpp delete mode 100644 untests/meta_tests.cpp rename untests/{meta_tests.hpp => meta_value_tests.cpp} (79%) create mode 100644 untests/meta_variable_tests.cpp diff --git a/headers/meta.hpp/meta.hpp b/headers/meta.hpp/meta.hpp index bae8590..5a55fac 100644 --- a/headers/meta.hpp/meta.hpp +++ b/headers/meta.hpp/meta.hpp @@ -6,6 +6,14 @@ #pragma once -namespace meta_hpp -{ -} +#include "meta_fwd.hpp" + +#include "meta_value.hpp" +#include "meta_registry.hpp" + +#include "meta_class.hpp" +#include "meta_field.hpp" +#include "meta_function.hpp" +#include "meta_method.hpp" +#include "meta_namespace.hpp" +#include "meta_variable.hpp" diff --git a/headers/meta.hpp/meta_class.hpp b/headers/meta.hpp/meta_class.hpp new file mode 100644 index 0000000..134431f --- /dev/null +++ b/headers/meta.hpp/meta_class.hpp @@ -0,0 +1,141 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "meta_fwd.hpp" + +#include "meta_field.hpp" +#include "meta_function.hpp" +#include "meta_method.hpp" +#include "meta_variable.hpp" + +namespace meta_hpp +{ + class class_info { + public: + class_info() = delete; + + class_info(class_info&&) = default; + class_info(const class_info&) = default; + + class_info& operator=(class_info&&) = default; + class_info& operator=(const class_info&) = default; + + class_info(std::string id) + : id_(std::move(id)) {} + + const std::string& id() const noexcept { + return id_; + } + + std::optional get_class(std::string_view id) const { + return detail::find_opt(classes_, id); + } + + std::optional get_field(std::string_view id) const { + return detail::find_opt(fields_, id); + } + + std::optional get_function(std::string_view id) const { + return detail::find_opt(functions_, id); + } + + std::optional get_method(std::string_view id) const { + return detail::find_opt(methods_, id); + } + + std::optional get_variable(std::string_view id) const { + return detail::find_opt(variables_, id); + } + private: + friend class namespace_info; + template < typename Class > friend class class_; + friend class namespace_; + private: + void merge_with_(const class_info& other) { + detail::merge_with(classes_, other.classes_, &class_info::merge_with_); + detail::merge_with(fields_, other.fields_, &field_info::merge_with_); + detail::merge_with(functions_, other.functions_, &function_info::merge_with_); + detail::merge_with(methods_, other.methods_, &method_info::merge_with_); + detail::merge_with(variables_, other.variables_, &variable_info::merge_with_); + } + private: + std::string id_; + std::map> classes_; + std::map> fields_; + std::map> functions_; + std::map> methods_; + std::map> variables_; + }; +} + +namespace meta_hpp +{ + template < typename Class > + class class_ { + public: + explicit class_(std::string id) + : info_(std::move(id)) {} + + const class_info& info() const noexcept { + return info_; + } + + template < typename... Internals > + class_& operator()(Internals&&...internals) { + (add_(std::forward(internals)), ...); + return *this; + } + private: + template < typename InternalClass > + void add_(const class_& internal) { + detail::merge_with( + info_.classes_, + internal.info().id(), + internal.info(), + &class_info::merge_with_); + } + + template < auto InternalField > + void add_(const field_& internal) { + detail::merge_with( + info_.fields_, + internal.info().id(), + internal.info(), + &field_info::merge_with_); + } + + template < auto InternalFunction > + void add_(const function_& internal) { + detail::merge_with( + info_.functions_, + internal.info().id(), + internal.info(), + &function_info::merge_with_); + } + + template < auto InternalMethod > + void add_(const method_& internal) { + detail::merge_with( + info_.methods_, + internal.info().id(), + internal.info(), + &method_info::merge_with_); + } + + template < auto InternalVariable > + void add_(const variable_& internal) { + detail::merge_with( + info_.variables_, + internal.info().id(), + internal.info(), + &variable_info::merge_with_); + } + private: + class_info info_; + }; +} diff --git a/headers/meta.hpp/meta_field.hpp b/headers/meta.hpp/meta_field.hpp new file mode 100644 index 0000000..e42cce6 --- /dev/null +++ b/headers/meta.hpp/meta_field.hpp @@ -0,0 +1,120 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "meta_fwd.hpp" + +#include "meta_value.hpp" + +namespace meta_hpp::field_detail +{ + template < typename Field > + struct field_traits; + + template < typename T, typename Base > + struct field_traits { + static constexpr bool is_const = false; + using value_type = T; + using instance_type = Base; + }; + + template < typename T, typename Base > + struct field_traits { + static constexpr bool is_const = true; + using value_type = T; + using instance_type = Base; + }; + + template < auto Field > + value getter(const void* instance) { + using ft = field_traits; + using value_type = typename ft::value_type; + using instance_type = typename ft::instance_type; + + auto instance_ptr = static_cast(instance); + value_type typed_value = std::invoke(Field, *instance_ptr); + + return value{std::move(typed_value)}; + } + + template < auto Field > + void setter(void* instance, value value) { + using ft = field_traits; + using value_type = typename ft::value_type; + using instance_type = typename ft::instance_type; + + if constexpr ( !ft::is_const ) { + auto instance_ptr = static_cast(instance); + std::invoke(Field, *instance_ptr) = value.cast(); + } else { + throw std::logic_error("an attempt to change a constant field"); + } + } +} + +namespace meta_hpp +{ + class field_info { + public: + field_info() = delete; + + field_info(field_info&&) = default; + field_info(const field_info&) = default; + + field_info& operator=(field_info&&) = default; + field_info& operator=(const field_info&) = default; + + field_info(std::string id) + : id_(std::move(id)) {} + + const std::string& id() const noexcept { + return id_; + } + public: + value get(const void* instance) const { + return getter_(instance); + } + + template < typename Value > + void set(void* instance, Value&& value) const { + return setter_(instance, std::forward(value)); + } + private: + friend class class_info; + template < typename Class > friend class class_; + template < auto Field > friend class field_; + private: + void merge_with_(const field_info& other) { + (void)other; + } + private: + std::string id_; + value(*getter_)(const void*); + void(*setter_)(void*, value); + }; +} + +namespace meta_hpp +{ + template < auto Field > + class field_ { + public: + static_assert(std::is_member_object_pointer_v); + + explicit field_(std::string id) + : info_(std::move(id)) { + info_.getter_ = &field_detail::getter; + info_.setter_ = &field_detail::setter; + } + + const field_info& info() const noexcept { + return info_; + } + private: + field_info info_; + }; +} diff --git a/headers/meta.hpp/meta_function.hpp b/headers/meta.hpp/meta_function.hpp new file mode 100644 index 0000000..81680f9 --- /dev/null +++ b/headers/meta.hpp/meta_function.hpp @@ -0,0 +1,125 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "meta_fwd.hpp" + +#include "meta_value.hpp" + +namespace meta_hpp::function_detail +{ + template < typename Function > + struct function_traits; + + template < typename R, typename... Args > + struct function_traits { + static constexpr std::size_t arity = sizeof...(Args); + using return_type = R; + using argument_types = std::tuple; + }; + + template < typename R, typename... Args > + struct function_traits + : function_traits {}; + + template < auto Function, std::size_t... Is > + value invoke(value* args, std::index_sequence) { + using ft = function_traits; + using return_type = typename ft::return_type; + using argument_types = typename ft::argument_types; + + auto typed_arguments = std::make_tuple( + (args + Is)->try_cast>()...); + + if ( !(std::get(typed_arguments) && ...) ) { + throw std::logic_error("an attempt to call a function with incorrect argument types"); + } + + if constexpr ( std::is_void_v ) { + std::invoke(Function, + *std::get(typed_arguments)...); + return value{}; + } else { + return_type return_value = std::invoke(Function, + *std::get(typed_arguments)...); + return value{std::move(return_value)}; + } + } + + template < auto Function > + value invoke(value* args, std::size_t arg_count) { + using ft = function_traits; + + if ( arg_count != ft::arity ) { + throw std::logic_error("an attempt to call a function with an incorrect arity"); + } + + return invoke(args, std::make_index_sequence()); + } +} + +namespace meta_hpp +{ + class function_info { + public: + function_info() = delete; + + function_info(function_info&&) = default; + function_info(const function_info&) = default; + + function_info& operator=(function_info&&) = default; + function_info& operator=(const function_info&) = default; + + function_info(std::string id) + : id_(std::move(id)) {} + + const std::string& id() const noexcept { + return id_; + } + public: + template < typename... Args > + value invoke(Args&&... args) const { + std::array vargs{{std::forward(args)...}}; + return invoke_(vargs.data(), vargs.size()); + } + private: + friend class class_info; + friend class namespace_info; + + template < typename Class > friend class class_; + friend class namespace_; + + template < auto Function > friend class function_; + private: + void merge_with_(const function_info& other) { + (void)other; + } + private: + std::string id_; + value(*invoke_)(value*, std::size_t); + }; +} + +namespace meta_hpp +{ + template < auto Function > + class function_ { + public: + static_assert(std::is_function_v>); + + explicit function_(std::string id) + : info_(std::move(id)) { + info_.invoke_ = &function_detail::invoke; + } + + const function_info& info() const noexcept { + return info_; + } + private: + function_info info_; + }; +} diff --git a/headers/meta.hpp/meta_fwd.hpp b/headers/meta.hpp/meta_fwd.hpp new file mode 100644 index 0000000..cc304c8 --- /dev/null +++ b/headers/meta.hpp/meta_fwd.hpp @@ -0,0 +1,99 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace meta_hpp +{ + class value; + class registry; + + class class_info; + class field_info; + class function_info; + class method_info; + class namespace_info; + class variable_info; + + template < typename Class > + class class_; + + template < auto Field > + class field_; + + template < auto Function > + class function_; + + template < auto Method > + class method_; + + class namespace_; + + template < auto Variable > + class variable_; +} + +namespace meta_hpp +{ + template < typename Signature > + constexpr auto select(Signature* f) noexcept { + return f; + } + + template < typename Signature, typename Base > + constexpr auto select(Signature Base::*f) noexcept { + return f; + } + + template < typename R, typename Base, typename... Args > + constexpr auto select_const(R (Base::*f)(Args...) const) noexcept { + return f; + } + + template < typename R, typename Base, typename... Args > + constexpr auto select_non_const(R(Base::*f)(Args...)) noexcept { + return f; + } +} + +namespace meta_hpp::detail +{ + template < typename K, typename V, typename C, typename K2 > + std::optional find_opt(const std::map& src, K2&& key) { + if ( auto iter = src.find(key); iter != src.end() ) { + return iter->second; + } + return std::nullopt; + } + + template < typename K, typename V, typename C, typename K2, typename V2, typename F > + void merge_with(std::map& dst, K2&& key, V2&& value, F&& f) { + if ( auto iter = dst.find(key); iter != dst.end() ) { + std::invoke(std::forward(f), iter->second, std::forward(value)); + } else { + dst.emplace(std::forward(key), std::forward(value)); + } + } + + template < typename K, typename V, typename C, typename F > + void merge_with(std::map& dst, const std::map& src, F&& f) { + for ( auto [key, value] : src ) { + merge_with(dst, key, value, f); + } + } +} diff --git a/headers/meta.hpp/meta_method.hpp b/headers/meta.hpp/meta_method.hpp new file mode 100644 index 0000000..2d908ca --- /dev/null +++ b/headers/meta.hpp/meta_method.hpp @@ -0,0 +1,186 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "meta_fwd.hpp" + +#include "meta_value.hpp" + +namespace meta_hpp::method_detail +{ + template < typename Method > + struct method_traits; + + template < typename R, typename Base, typename... Args > + struct method_traits { + static constexpr bool is_const = false; + static constexpr std::size_t arity = sizeof...(Args); + using return_type = R; + using instance_type = Base; + using argument_types = std::tuple; + }; + + template < typename R, typename Base, typename... Args > + struct method_traits + : method_traits { + static constexpr bool is_const = true; + }; + + template < typename R, typename Base, typename... Args > + struct method_traits + : method_traits {}; + + template < typename R, typename Base, typename... Args > + struct method_traits + : method_traits {}; + + template < auto Method, std::size_t... Is > + value invoke(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; + using argument_types = typename mt::argument_types; + + auto typed_arguments = std::make_tuple( + (args + Is)->try_cast>()...); + + if ( !(std::get(typed_arguments) && ...) ) { + throw std::logic_error("an attempt to call a method with incorrect argument types"); + } + + if constexpr ( std::is_void_v ) { + std::invoke(Method, + std::ref(*static_cast(instance)), + *std::get(typed_arguments)...); + return value{}; + } else { + return_type return_value = std::invoke(Method, + std::ref(*static_cast(instance)), + *std::get(typed_arguments)...); + return value{std::move(return_value)}; + } + } + + template < auto Method > + value invoke(void* instance, value* args, std::size_t arg_count) { + using mt = method_traits; + + if ( arg_count != mt::arity ) { + throw std::logic_error("an attempt to call a method with an incorrect arity"); + } + + return invoke(instance, args, std::make_index_sequence()); + } + + template < auto Method, std::size_t... Is > + value cinvoke(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; + using argument_types = typename mt::argument_types; + + auto typed_arguments = std::make_tuple( + (args + Is)->try_cast>()...); + + if ( !(std::get(typed_arguments) && ...) ) { + throw std::logic_error("an attempt to call a method with incorrect argument types"); + } + + if constexpr ( mt::is_const ) { + if constexpr ( std::is_void_v ) { + std::invoke(Method, + std::ref(*static_cast(instance)), + *std::get(typed_arguments)...); + return value{}; + } else { + return_type return_value = std::invoke(Method, + std::ref(*static_cast(instance)), + *std::get(typed_arguments)...); + return value{std::move(return_value)}; + } + } else { + throw std::logic_error("an attempt to call a non-constant method by constant instance"); + } + } + + template < auto Method > + value cinvoke(const void* instance, value* args, std::size_t arg_count) { + using mt = method_traits; + + if ( arg_count != mt::arity ) { + throw std::logic_error("an attempt to call a method with a different arity"); + } + + return cinvoke(instance, args, std::make_index_sequence()); + } +} + +namespace meta_hpp +{ + class method_info { + public: + method_info() = delete; + + method_info(method_info&&) = default; + method_info(const method_info&) = default; + + method_info& operator=(method_info&&) = default; + method_info& operator=(const method_info&) = default; + + method_info(std::string id) + : id_(std::move(id)) {} + + const std::string& id() const noexcept { + return id_; + } + public: + template < typename... Args > + value 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::array vargs{{std::forward(args)...}}; + return cinvoke_(instance, vargs.data(), vargs.size()); + } + private: + friend class class_info; + template < typename Class > friend class class_; + template < auto Method > friend class method_; + private: + void merge_with_(const method_info& other) { + (void)other; + } + private: + std::string id_; + value(*invoke_)(void*, value*, std::size_t); + value(*cinvoke_)(const void*, value*, std::size_t); + }; +} + +namespace meta_hpp +{ + template < auto Method > + class method_ { + public: + static_assert(std::is_member_function_pointer_v); + + explicit method_(std::string id) + : info_(std::move(id)) { + info_.invoke_ = &method_detail::invoke; + info_.cinvoke_ = &method_detail::cinvoke; + } + + const method_info& info() const noexcept { + return info_; + } + private: + method_info info_; + }; +} diff --git a/headers/meta.hpp/meta_namespace.hpp b/headers/meta.hpp/meta_namespace.hpp new file mode 100644 index 0000000..895e1e4 --- /dev/null +++ b/headers/meta.hpp/meta_namespace.hpp @@ -0,0 +1,121 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "meta_fwd.hpp" + +#include "meta_class.hpp" +#include "meta_function.hpp" +#include "meta_variable.hpp" + +namespace meta_hpp +{ + class namespace_info { + public: + namespace_info() = delete; + + namespace_info(namespace_info&&) = default; + namespace_info(const namespace_info&) = default; + + namespace_info& operator=(namespace_info&&) = default; + namespace_info& operator=(const namespace_info&) = default; + + namespace_info(std::string id) + : id_(std::move(id)) {} + + const std::string& id() const noexcept { + return id_; + } + + std::optional get_class(std::string_view id) const { + return detail::find_opt(classes_, id); + } + + std::optional get_function(std::string_view id) const { + return detail::find_opt(functions_, id); + } + + std::optional get_namespace(std::string_view id) const { + return detail::find_opt(namespaces_, id); + } + + std::optional get_variable(std::string_view id) const { + return detail::find_opt(variables_, id); + } + private: + friend class namespace_; + private: + void merge_with_(const namespace_info& other) { + detail::merge_with(classes_, other.classes_, &class_info::merge_with_); + detail::merge_with(functions_, other.functions_, &function_info::merge_with_); + detail::merge_with(namespaces_, other.namespaces_, &namespace_info::merge_with_); + detail::merge_with(variables_, other.variables_, &variable_info::merge_with_); + } + private: + std::string id_; + std::map> classes_; + std::map> functions_; + std::map> namespaces_; + std::map> variables_; + }; +} + +namespace meta_hpp +{ + class namespace_ { + public: + explicit namespace_(std::string id) + : info_(std::move(id)) {} + + const namespace_info& info() const noexcept { + return info_; + } + + template < typename... Internals > + namespace_& operator()(Internals&&...internals) { + (add_(std::forward(internals)), ...); + return *this; + } + private: + template < typename InternalClass > + void add_(const class_& internal) { + detail::merge_with( + info_.classes_, + internal.info().id(), + internal.info(), + &class_info::merge_with_); + } + + template < auto InternalFunction > + void add_(const function_& internal) { + detail::merge_with( + info_.functions_, + internal.info().id(), + internal.info(), + &function_info::merge_with_); + } + + void add_(const namespace_& internal) { + detail::merge_with( + info_.namespaces_, + internal.info().id(), + internal.info(), + &namespace_info::merge_with_); + } + + template < auto Internalvariable > + void add_(const variable_& internal) { + detail::merge_with( + info_.variables_, + internal.info().id(), + internal.info(), + &variable_info::merge_with_); + } + private: + namespace_info info_; + }; +} diff --git a/headers/meta.hpp/meta_registry.hpp b/headers/meta.hpp/meta_registry.hpp new file mode 100644 index 0000000..b2f43ce --- /dev/null +++ b/headers/meta.hpp/meta_registry.hpp @@ -0,0 +1,46 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "meta_fwd.hpp" + +#include "meta_class.hpp" +#include "meta_function.hpp" +#include "meta_namespace.hpp" +#include "meta_variable.hpp" + +namespace meta_hpp +{ + class registry { + public: + registry() = default; + + template < typename... Internals > + registry& operator()(Internals&&...internals) { + default_namespace_(std::forward(internals)...); + return *this; + } + + std::optional get_class(std::string_view id) const { + return default_namespace_.info().get_class(id); + } + + std::optional get_function(std::string_view id) const { + return default_namespace_.info().get_function(id); + } + + std::optional get_namespace(std::string_view id) const { + return default_namespace_.info().get_namespace(id); + } + + std::optional get_variable(std::string_view id) const { + return default_namespace_.info().get_variable(id); + } + private: + namespace_ default_namespace_{""}; + }; +} diff --git a/headers/meta.hpp/meta_value.hpp b/headers/meta.hpp/meta_value.hpp new file mode 100644 index 0000000..b059626 --- /dev/null +++ b/headers/meta.hpp/meta_value.hpp @@ -0,0 +1,38 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "meta_fwd.hpp" + +namespace meta_hpp +{ + class value { + public: + value() = default; + + template < typename T > + value(T&& value) + : raw_{std::forward(value)} {} + + template < typename T > + auto cast() const { + return std::any_cast(raw_); + } + + template < typename T > + auto try_cast() noexcept { + return std::any_cast(&raw_); + } + + template < typename T > + auto try_cast() const noexcept { + return std::any_cast(&raw_); + } + private: + std::any raw_; + }; +} diff --git a/headers/meta.hpp/meta_variable.hpp b/headers/meta.hpp/meta_variable.hpp new file mode 100644 index 0000000..6698570 --- /dev/null +++ b/headers/meta.hpp/meta_variable.hpp @@ -0,0 +1,116 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "meta_fwd.hpp" + +#include "meta_value.hpp" + +namespace meta_hpp::variable_detail +{ + template < typename Variable > + struct variable_traits; + + template < typename T > + struct variable_traits { + static constexpr bool is_const = false; + using value_type = T; + }; + + template < typename T > + struct variable_traits { + static constexpr bool is_const = true; + using value_type = T; + }; + + template < auto Variable > + value getter() { + using vt = variable_traits; + using value_type = typename vt::value_type; + + value_type typed_value = *Variable; + + return value{std::move(typed_value)}; + } + + template < auto Variable > + void setter(value value) { + using vt = variable_traits; + using value_type = typename vt::value_type; + + if constexpr ( !vt::is_const ) { + *Variable = value.cast(); + } else { + throw std::logic_error("an attempt to change a constant variable"); + } + } +} + +namespace meta_hpp +{ + class variable_info { + public: + variable_info() = delete; + + variable_info(variable_info&&) = default; + variable_info(const variable_info&) = default; + + variable_info& operator=(variable_info&&) = default; + variable_info& operator=(const variable_info&) = default; + + variable_info(std::string id) + : id_(std::move(id)) {} + + const std::string& id() const noexcept { + return id_; + } + public: + value get() const { + return getter_(); + } + + template < typename Value > + void set(Value&& value) const { + return setter_(std::forward(value)); + } + private: + friend class class_info; + friend class namespace_info; + template < typename Class > friend class class_; + friend class namespace_; + template < auto Variable > friend class variable_; + private: + void merge_with_(const variable_info& other) { + (void)other; + } + private: + std::string id_; + value(*getter_)(); + void(*setter_)(value); + }; +} + +namespace meta_hpp +{ + template < auto Variable > + class variable_ { + public: + static_assert(std::is_pointer_v); + + explicit variable_(std::string id) + : info_(std::move(id)) { + info_.getter_ = &variable_detail::getter; + info_.setter_ = &variable_detail::setter; + } + + const variable_info& info() const noexcept { + return info_; + } + private: + variable_info info_; + }; +} diff --git a/untests/meta_class_tests.cpp b/untests/meta_class_tests.cpp new file mode 100644 index 0000000..d399e53 --- /dev/null +++ b/untests/meta_class_tests.cpp @@ -0,0 +1,107 @@ +/******************************************************************************* + * 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 +#include "doctest/doctest.hpp" + +namespace +{ + class clazz { + public: + class clazz2 { + }; + + int field{1}; + const int cfield{2}; + + static int func(int a) { return a; } + + int method(int a) { return a; } + int cmethod(int a) const { return a; } + + static int variable; + static const int cvariable; + }; + + int clazz::variable{1}; + const int clazz::cvariable{2}; +} + +TEST_CASE("meta/class") { + namespace meta = meta_hpp; + + meta::class_ class_{"clazz"}; + const meta::class_& cclass_ = class_; + const meta::class_info& clazz_info = cclass_.info(); + + CHECK_FALSE(clazz_info.get_class("clazz2")); + CHECK_FALSE(clazz_info.get_field("field")); + CHECK_FALSE(clazz_info.get_field("cfield")); + CHECK_FALSE(clazz_info.get_function("func")); + CHECK_FALSE(clazz_info.get_method("method")); + CHECK_FALSE(clazz_info.get_method("cmethod")); + CHECK_FALSE(clazz_info.get_variable("variable")); + CHECK_FALSE(clazz_info.get_variable("cvariable")); + + class_( + meta::class_("clazz2"), + meta::field_<&clazz::field>("field"), + meta::field_<&clazz::cfield>("cfield"), + meta::function_<&clazz::func>("func"), + meta::method_<&clazz::method>("method"), + meta::method_<&clazz::cmethod>("cmethod"), + meta::variable_<&clazz::variable>("variable"), + meta::variable_<&clazz::cvariable>("cvariable")); + + CHECK(clazz_info.get_class("clazz2")); + CHECK(clazz_info.get_field("field")); + CHECK(clazz_info.get_field("cfield")); + CHECK(clazz_info.get_function("func")); + CHECK(clazz_info.get_method("method")); + CHECK(clazz_info.get_method("cmethod")); + CHECK(clazz_info.get_variable("variable")); + CHECK(clazz_info.get_variable("cvariable")); + + { + meta::class_info clazz2_info = clazz_info.get_class("clazz2").value(); + CHECK(clazz2_info.id() == "clazz2"); + } + + { + meta::field_info field_info = clazz_info.get_field("field").value(); + CHECK(field_info.id() == "field"); + } + + { + meta::field_info cfield_info = clazz_info.get_field("cfield").value(); + CHECK(cfield_info.id() == "cfield"); + } + + { + meta::function_info function_info = clazz_info.get_function("func").value(); + CHECK(function_info.id() == "func"); + } + + { + meta::method_info method_info = clazz_info.get_method("method").value(); + CHECK(method_info.id() == "method"); + } + + { + meta::method_info cmethod_info = clazz_info.get_method("cmethod").value(); + CHECK(cmethod_info.id() == "cmethod"); + } + + { + meta::variable_info variable_info = clazz_info.get_variable("variable").value(); + CHECK(variable_info.id() == "variable"); + } + + { + meta::variable_info cvariable_info = clazz_info.get_variable("cvariable").value(); + CHECK(cvariable_info.id() == "cvariable"); + } +} diff --git a/untests/meta_examples.cpp b/untests/meta_examples.cpp new file mode 100644 index 0000000..4df1896 --- /dev/null +++ b/untests/meta_examples.cpp @@ -0,0 +1,142 @@ +/******************************************************************************* + * 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 +#include "doctest/doctest.hpp" + +namespace +{ + class ivec2 { + public: + int x{}; + int y{}; + + ivec2() = default; + explicit ivec2(int v): x{v}, y{v} {} + ivec2(int x, int y): x{x}, y{y} {} + + int dot(ivec2 other) const { + return x * other.x + y * other.y; + } + + int length2() const { + return dot(*this); + } + }; + + class ivec3 { + public: + int x{}; + int y{}; + int z{}; + + ivec3() = default; + explicit ivec3(int v): x{v}, y{v}, z{v} {} + ivec3(int x, int y, int z): x{x}, y{y}, z{z} {} + + int dot(ivec3 other) const { + return x * other.x + y * other.y + z * other.z; + } + + int length2() const { + return dot(*this); + } + }; + + ivec2 add(ivec2 l, ivec2 r) { + return {l.x + r.x, l.y + r.y}; + } + + ivec3 add(ivec3 l, ivec3 r) { + return {l.x + r.x, l.y + r.y, l.z + r.z}; + } +} + +TEST_CASE("meta/examples/ivec2") { + SUBCASE("ctors") { + CHECK(ivec2{}.x == 0); + CHECK(ivec2{}.y == 0); + + CHECK(ivec2{1}.x == 1); + CHECK(ivec2{1}.y == 1); + + CHECK(ivec2{2,3}.x == 2); + CHECK(ivec2{2,3}.y == 3); + } +} + +TEST_CASE("meta/examples/ivec3") { + SUBCASE("ctors") { + CHECK(ivec3{}.x == 0); + CHECK(ivec3{}.y == 0); + CHECK(ivec3{}.z == 0); + + CHECK(ivec3{1}.x == 1); + CHECK(ivec3{1}.y == 1); + CHECK(ivec3{1}.z == 1); + + CHECK(ivec3{2,3,4}.x == 2); + CHECK(ivec3{2,3,4}.y == 3); + CHECK(ivec3{2,3,4}.z == 4); + } +} + +TEST_CASE("meta/examples/simple") { + namespace meta = meta_hpp; + + auto registry = meta::registry{}( + meta::namespace_("vmath")( + meta::class_("ivec2")( + meta::field_<&ivec2::x>("x"), + meta::field_<&ivec2::y>("y"), + meta::method_<&ivec2::dot>("dot"), + meta::method_<&ivec2::length2>("length2") + ), + meta::class_("ivec3")( + meta::field_<&ivec3::x>("x"), + meta::field_<&ivec3::y>("y"), + meta::field_<&ivec3::z>("z"), + meta::method_<&ivec3::dot>("dot"), + meta::method_<&ivec3::length2>("length2") + ), + meta::function_(&add)>("iadd2"), + meta::function_(&add)>("iadd3") + ) + ); + + meta::namespace_info vmath_info = registry.get_namespace("vmath").value(); + + meta::class_info ivec2_info = vmath_info.get_class("ivec2").value(); + meta::field_info ivec2_x_info = ivec2_info.get_field("x").value(); + meta::field_info ivec2_y_info = ivec2_info.get_field("y").value(); + + meta::method_info ivec2_dot_info = ivec2_info.get_method("dot").value(); + meta::method_info ivec2_length2_info = ivec2_info.get_method("length2").value(); + + meta::function_info iadd2_info = vmath_info.get_function("iadd2").value(); + meta::function_info iadd3_info = vmath_info.get_function("iadd3").value(); + + { + 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); + } + + { + 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(); + CHECK(v.x == 4); + CHECK(v.y == 6); + CHECK(v.z == 8); + } +} diff --git a/untests/meta_field_tests.cpp b/untests/meta_field_tests.cpp new file mode 100644 index 0000000..05adcf6 --- /dev/null +++ b/untests/meta_field_tests.cpp @@ -0,0 +1,63 @@ +/******************************************************************************* + * 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 +#include "doctest/doctest.hpp" + +namespace +{ + class clazz { + public: + int field{1}; + const int cfield{2}; + }; +} + +TEST_CASE("meta/field") { + namespace meta = meta_hpp; + + meta::field_<&clazz::field> field_{"field"}; + meta::field_<&clazz::cfield> cfield_{"cfield"}; + + const meta::field_info& field_info = field_.info(); + const meta::field_info& cfield_info = cfield_.info(); + + { + clazz instance; + + CHECK(instance.field == 1); + CHECK(field_info.get(&instance).cast() == 1); + CHECK(field_info.get(&std::as_const(instance)).cast() == 1); + + CHECK_NOTHROW(field_info.set(&instance, 3)); + + CHECK(instance.field == 3); + CHECK(field_info.get(&instance).cast() == 3); + CHECK(field_info.get(&std::as_const(instance)).cast() == 3); + } + + { + clazz instance; + + CHECK(instance.cfield == 2); + CHECK(cfield_info.get(&instance).cast() == 2); + CHECK(cfield_info.get(&std::as_const(instance)).cast() == 2); + + CHECK_THROWS_AS(cfield_info.set(&instance, 4), std::logic_error); + + CHECK(instance.cfield == 2); + CHECK(cfield_info.get(&instance).cast() == 2); + CHECK(cfield_info.get(&std::as_const(instance)).cast() == 2); + } + + { + clazz instance; + + instance.field = 5; + CHECK(field_info.get(&instance).cast() == 5); + CHECK(field_info.get(&std::as_const(instance)).cast() == 5); + } +} diff --git a/untests/meta_function_tests.cpp b/untests/meta_function_tests.cpp new file mode 100644 index 0000000..d599fa1 --- /dev/null +++ b/untests/meta_function_tests.cpp @@ -0,0 +1,73 @@ +/******************************************************************************* + * 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 +#include "doctest/doctest.hpp" + +namespace +{ + void void_f_void() noexcept {} + void void_f_int(int a) { (void)a; } + void void_f_int2(int a, int b) { (void)a; (void)b; } + + int int_f_void() noexcept { return 1; } + int int_f_int(int a) { return a; } + int int_f_int2(int a, int b) { return a + b; } +} + +TEST_CASE("meta/function") { + namespace meta = meta_hpp; + + meta::function_<&void_f_void> void_f_void_function_("void_f_void"); + meta::function_<&void_f_int> void_f_int_function_("void_f_int"); + meta::function_<&void_f_int2> void_f_int2_function_("void_f_int2"); + + meta::function_<&int_f_void> int_f_void_function_("int_f_void"); + meta::function_<&int_f_int> int_f_int_function_("int_f_int"); + meta::function_<&int_f_int2> int_f_int2_function_("int_f_int2"); + + const meta::function_info& void_f_void_info = void_f_void_function_.info(); + const meta::function_info& void_f_int_info = void_f_int_function_.info(); + const meta::function_info& void_f_int2_info = void_f_int2_function_.info(); + + const meta::function_info& int_f_void_info = int_f_void_function_.info(); + const meta::function_info& int_f_int_info = int_f_int_function_.info(); + const meta::function_info& int_f_int2_info = int_f_int2_function_.info(); + + SUBCASE("void_return") { + CHECK_NOTHROW(void_f_void_info.invoke()); + CHECK_THROWS_AS(void_f_void_info.invoke(1), std::logic_error); + + CHECK_THROWS_AS(void_f_int_info.invoke(), std::logic_error); + CHECK_NOTHROW(void_f_int_info.invoke(1)); + CHECK_THROWS_AS(void_f_int_info.invoke(1.f), std::logic_error); + CHECK_THROWS_AS(void_f_int_info.invoke(1, 2), std::logic_error); + + CHECK_THROWS_AS(void_f_int2_info.invoke(), std::logic_error); + CHECK_THROWS_AS(void_f_int2_info.invoke(1), std::logic_error); + CHECK_NOTHROW(void_f_int2_info.invoke(1, 2)); + CHECK_THROWS_AS(void_f_int2_info.invoke(1.f, 2), std::logic_error); + CHECK_THROWS_AS(void_f_int2_info.invoke(1, 2.f), std::logic_error); + CHECK_THROWS_AS(void_f_int2_info.invoke(1, 2, 3), std::logic_error); + } + + SUBCASE("int_return") { + 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_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_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 new file mode 100644 index 0000000..19011e2 --- /dev/null +++ b/untests/meta_method_tests.cpp @@ -0,0 +1,166 @@ +/******************************************************************************* + * 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 +#include "doctest/doctest.hpp" + +namespace +{ + class clazz { + public: + void void_f_void() noexcept {} + void void_f_int(int a) { (void)a; } + void void_f_int2(int a, int b) { (void)a; (void)b; } + + int int_f_void() noexcept { return 1; } + int int_f_int(int a) { return a; } + int int_f_int2(int a, int b) { return a + b; } + + void const_void_f_void() const noexcept {} + void const_void_f_int(int a) const { (void)a; } + void const_void_f_int2(int a, int b) const { (void)a; (void)b; } + + int const_int_f_void() const noexcept { return 1; } + int const_int_f_int(int a) const { return a; } + int const_int_f_int2(int a, int b) const { return a + b; } + }; +} + +TEST_CASE("meta/non_const_method") { + namespace meta = meta_hpp; + + meta::method_<&clazz::void_f_void> void_f_void_method_("void_f_void"); + meta::method_<&clazz::void_f_int> void_f_int_method_("void_f_int"); + meta::method_<&clazz::void_f_int2> void_f_int2_method_("void_f_int2"); + + meta::method_<&clazz::int_f_void> int_f_void_method_("int_f_void"); + meta::method_<&clazz::int_f_int> int_f_int_method_("int_f_int"); + meta::method_<&clazz::int_f_int2> int_f_int2_method_("int_f_int2"); + + const meta::method_info& void_f_void_info = void_f_void_method_.info(); + const meta::method_info& void_f_int_info = void_f_int_method_.info(); + const meta::method_info& void_f_int2_info = void_f_int2_method_.info(); + + const meta::method_info& int_f_void_info = int_f_void_method_.info(); + const meta::method_info& int_f_int_info = int_f_int_method_.info(); + const meta::method_info& int_f_int2_info = int_f_int2_method_.info(); + + SUBCASE("void_return") { + clazz instance; + + CHECK_NOTHROW(void_f_void_info.invoke(&instance)); + CHECK_THROWS_AS(void_f_void_info.invoke(&instance, 1), std::logic_error); + + CHECK_THROWS_AS(void_f_int_info.invoke(&instance), std::logic_error); + CHECK_NOTHROW(void_f_int_info.invoke(&instance, 1)); + CHECK_THROWS_AS(void_f_int_info.invoke(&instance, 1.f), std::logic_error); + CHECK_THROWS_AS(void_f_int_info.invoke(&instance, 1, 2), std::logic_error); + + CHECK_THROWS_AS(void_f_int2_info.invoke(&instance), std::logic_error); + CHECK_THROWS_AS(void_f_int2_info.invoke(&instance, 1), std::logic_error); + CHECK_NOTHROW(void_f_int2_info.invoke(&instance, 1, 2)); + CHECK_THROWS_AS(void_f_int2_info.invoke(&instance, 1.f, 2), std::logic_error); + CHECK_THROWS_AS(void_f_int2_info.invoke(&instance, 1, 2.f), std::logic_error); + CHECK_THROWS_AS(void_f_int2_info.invoke(&instance, 1, 2, 3), std::logic_error); + + const clazz& cinstance = instance; + CHECK_THROWS_AS(void_f_void_info.invoke(&cinstance), std::logic_error); + CHECK_THROWS_AS(void_f_int_info.invoke(&cinstance, 1), std::logic_error); + CHECK_THROWS_AS(void_f_int2_info.invoke(&cinstance, 1, 2), std::logic_error); + } + + SUBCASE("int_return") { + clazz instance; + + 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_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_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_THROWS_AS(int_f_void_info.invoke(&cinstance), std::logic_error); + CHECK_THROWS_AS(int_f_int_info.invoke(&cinstance, 1), std::logic_error); + CHECK_THROWS_AS(int_f_int2_info.invoke(&cinstance, 1, 2), std::logic_error); + } +} + +TEST_CASE("meta/const_method") { + namespace meta = meta_hpp; + + meta::method_<&clazz::const_void_f_void> void_f_void_method_("void_f_void"); + meta::method_<&clazz::const_void_f_int> void_f_int_method_("void_f_int"); + meta::method_<&clazz::const_void_f_int2> void_f_int2_method_("void_f_int2"); + + meta::method_<&clazz::const_int_f_void> int_f_void_method_("int_f_void"); + meta::method_<&clazz::const_int_f_int> int_f_int_method_("int_f_int"); + meta::method_<&clazz::const_int_f_int2> int_f_int2_method_("int_f_int2"); + + const meta::method_info& void_f_void_info = void_f_void_method_.info(); + const meta::method_info& void_f_int_info = void_f_int_method_.info(); + const meta::method_info& void_f_int2_info = void_f_int2_method_.info(); + + const meta::method_info& int_f_void_info = int_f_void_method_.info(); + const meta::method_info& int_f_int_info = int_f_int_method_.info(); + const meta::method_info& int_f_int2_info = int_f_int2_method_.info(); + + SUBCASE("void_return") { + clazz instance; + + CHECK_NOTHROW(void_f_void_info.invoke(&instance)); + CHECK_THROWS_AS(void_f_void_info.invoke(&instance, 1), std::logic_error); + + CHECK_THROWS_AS(void_f_int_info.invoke(&instance), std::logic_error); + CHECK_NOTHROW(void_f_int_info.invoke(&instance, 1)); + CHECK_THROWS_AS(void_f_int_info.invoke(&instance, 1.f), std::logic_error); + CHECK_THROWS_AS(void_f_int_info.invoke(&instance, 1, 2), std::logic_error); + + CHECK_THROWS_AS(void_f_int2_info.invoke(&instance), std::logic_error); + CHECK_THROWS_AS(void_f_int2_info.invoke(&instance, 1), std::logic_error); + CHECK_NOTHROW(void_f_int2_info.invoke(&instance, 1, 2)); + CHECK_THROWS_AS(void_f_int2_info.invoke(&instance, 1.f, 2), std::logic_error); + CHECK_THROWS_AS(void_f_int2_info.invoke(&instance, 1, 2.f), std::logic_error); + CHECK_THROWS_AS(void_f_int2_info.invoke(&instance, 1, 2, 3), std::logic_error); + + const clazz& cinstance = instance; + CHECK_NOTHROW(void_f_void_info.invoke(&cinstance)); + CHECK_NOTHROW(void_f_int_info.invoke(&cinstance, 1)); + CHECK_NOTHROW(void_f_int2_info.invoke(&cinstance, 1, 2)); + } + + SUBCASE("int_return") { + clazz instance; + + 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_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_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); + } +} diff --git a/untests/meta_namespace_tests.cpp b/untests/meta_namespace_tests.cpp new file mode 100644 index 0000000..146d71c --- /dev/null +++ b/untests/meta_namespace_tests.cpp @@ -0,0 +1,68 @@ +/******************************************************************************* + * 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 +#include "doctest/doctest.hpp" + +namespace +{ + class clazz {}; + int func(int a) { return a; } + int variable{1}; + const int cvariable{2}; +} + +TEST_CASE("meta/namespace") { + namespace meta = meta_hpp; + + meta::namespace_ namespace_{"ns"}; + const meta::namespace_& cnamespace_ = namespace_; + const meta::namespace_info& ns_info = cnamespace_.info(); + + CHECK_FALSE(ns_info.get_class("clazz")); + CHECK_FALSE(ns_info.get_function("func")); + CHECK_FALSE(ns_info.get_namespace("ns")); + CHECK_FALSE(ns_info.get_variable("variable")); + CHECK_FALSE(ns_info.get_variable("cvariable")); + + namespace_( + meta::class_("clazz"), + meta::function_<&func>("func"), + meta::namespace_("ns2"), + meta::variable_<&variable>("variable"), + meta::variable_<&cvariable>("cvariable")); + + CHECK(ns_info.get_class("clazz")); + CHECK(ns_info.get_function("func")); + CHECK(ns_info.get_namespace("ns2")); + CHECK(ns_info.get_variable("variable")); + CHECK(ns_info.get_variable("cvariable")); + + { + meta::class_info clazz_info = ns_info.get_class("clazz").value(); + CHECK(clazz_info.id() == "clazz"); + } + + { + meta::function_info clazz_info = ns_info.get_function("func").value(); + CHECK(clazz_info.id() == "func"); + } + + { + meta::namespace_info namespace_info = ns_info.get_namespace("ns2").value(); + CHECK(namespace_info.id() == "ns2"); + } + + { + meta::variable_info variable_info = ns_info.get_variable("variable").value(); + CHECK(variable_info.id() == "variable"); + } + + { + meta::variable_info cvariable_info = ns_info.get_variable("cvariable").value(); + CHECK(cvariable_info.id() == "cvariable"); + } +} diff --git a/untests/meta_registry_tests.cpp b/untests/meta_registry_tests.cpp new file mode 100644 index 0000000..e62fc43 --- /dev/null +++ b/untests/meta_registry_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 +#include "doctest/doctest.hpp" + +namespace +{ + class clazz {}; + int func(int a) { return a; } + int variable{1}; + const int cvariable{2}; +} + +TEST_CASE("meta/registry") { + namespace meta = meta_hpp; + + meta::registry registry; + const meta::registry& cregistry = registry; + + CHECK_FALSE(cregistry.get_class("clazz")); + CHECK_FALSE(cregistry.get_function("func")); + CHECK_FALSE(cregistry.get_namespace("ns")); + CHECK_FALSE(cregistry.get_variable("variable")); + CHECK_FALSE(cregistry.get_variable("cvariable")); + + registry( + meta::class_("clazz"), + meta::function_<&func>("func"), + meta::namespace_("ns"), + meta::variable_<&variable>("variable"), + meta::variable_<&cvariable>("cvariable")); + + CHECK(cregistry.get_class("clazz")); + CHECK(cregistry.get_function("func")); + CHECK(cregistry.get_namespace("ns")); + CHECK(cregistry.get_variable("variable")); + CHECK(cregistry.get_variable("cvariable")); + + { + meta::class_info clazz_info = cregistry.get_class("clazz").value(); + CHECK(clazz_info.id() == "clazz"); + } + + { + meta::function_info clazz_info = cregistry.get_function("func").value(); + CHECK(clazz_info.id() == "func"); + } + + { + meta::namespace_info namespace_info = cregistry.get_namespace("ns").value(); + CHECK(namespace_info.id() == "ns"); + } + + { + meta::variable_info variable_info = cregistry.get_variable("variable").value(); + CHECK(variable_info.id() == "variable"); + } + + { + meta::variable_info cvariable_info = cregistry.get_variable("cvariable").value(); + CHECK(cvariable_info.id() == "cvariable"); + } +} diff --git a/untests/meta_tests.cpp b/untests/meta_tests.cpp deleted file mode 100644 index 8f5b33a..0000000 --- a/untests/meta_tests.cpp +++ /dev/null @@ -1,16 +0,0 @@ -/******************************************************************************* - * 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_tests.hpp" - -namespace -{ - using namespace meta_hpp; - using namespace meta_tests; -} - -TEST_CASE("meta") { -} diff --git a/untests/meta_tests.hpp b/untests/meta_value_tests.cpp similarity index 79% rename from untests/meta_tests.hpp rename to untests/meta_value_tests.cpp index 2b0e426..f01d424 100644 --- a/untests/meta_tests.hpp +++ b/untests/meta_value_tests.cpp @@ -4,10 +4,13 @@ * Copyright (C) 2021, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ -#include +#include #include "doctest/doctest.hpp" -namespace meta_tests +namespace { - using namespace meta_hpp; +} + +TEST_CASE("meta/value") { + namespace meta = meta_hpp; } diff --git a/untests/meta_variable_tests.cpp b/untests/meta_variable_tests.cpp new file mode 100644 index 0000000..e70a55b --- /dev/null +++ b/untests/meta_variable_tests.cpp @@ -0,0 +1,93 @@ +/******************************************************************************* + * 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 +#include "doctest/doctest.hpp" + +namespace +{ + int variable{1}; + const int cvariable{2}; + + class clazz { + public: + static int variable; + static const int cvariable; + }; + + int clazz::variable{1}; + const int clazz::cvariable{2}; +} + +TEST_CASE("meta/variable") { + namespace meta = meta_hpp; + + SUBCASE("in_namespace") { + meta::variable_<&variable> variable_{"variable"}; + meta::variable_<&cvariable> cvariable_{"cvariable"}; + + const meta::variable_info& variable_info = variable_.info(); + const meta::variable_info& cvariable_info = cvariable_.info(); + + { + CHECK(variable == 1); + CHECK(variable_info.get().cast() == 1); + + CHECK_NOTHROW(variable_info.set(3)); + + CHECK(variable == 3); + CHECK(variable_info.get().cast() == 3); + } + + { + CHECK(cvariable == 2); + CHECK(cvariable_info.get().cast() == 2); + + CHECK_THROWS_AS(cvariable_info.set(4), std::logic_error); + + CHECK(cvariable == 2); + CHECK(cvariable_info.get().cast() == 2); + } + + { + variable = 5; + CHECK(variable_info.get().cast() == 5); + } + } + + SUBCASE("in_class") { + meta::variable_<&clazz::variable> variable_{"variable"}; + meta::variable_<&clazz::cvariable> cvariable_{"cvariable"}; + + const meta::variable_info& variable_info = variable_.info(); + const meta::variable_info& cvariable_info = cvariable_.info(); + + { + CHECK(clazz::variable == 1); + CHECK(variable_info.get().cast() == 1); + + CHECK_NOTHROW(variable_info.set(3)); + + CHECK(clazz::variable == 3); + CHECK(variable_info.get().cast() == 3); + } + + { + CHECK(clazz::cvariable == 2); + CHECK(cvariable_info.get().cast() == 2); + + CHECK_THROWS_AS(cvariable_info.set(4), std::logic_error); + + CHECK(clazz::cvariable == 2); + CHECK(cvariable_info.get().cast() == 2); + } + + { + clazz::variable = 5; + CHECK(variable_info.get().cast() == 5); + } + } +} From d76fee1b83c04b32d50fa59d416d81b23bf313dd Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Wed, 30 Jun 2021 00:42:21 +0700 Subject: [PATCH 002/233] fix warnings --- headers/meta.hpp/meta_field.hpp | 7 +++---- headers/meta.hpp/meta_function.hpp | 2 +- headers/meta.hpp/meta_method.hpp | 8 ++++---- headers/meta.hpp/meta_variable.hpp | 2 -- 4 files changed, 8 insertions(+), 11 deletions(-) diff --git a/headers/meta.hpp/meta_field.hpp b/headers/meta.hpp/meta_field.hpp index e42cce6..1cba987 100644 --- a/headers/meta.hpp/meta_field.hpp +++ b/headers/meta.hpp/meta_field.hpp @@ -23,10 +23,9 @@ namespace meta_hpp::field_detail }; template < typename T, typename Base > - struct field_traits { + struct field_traits + : field_traits { static constexpr bool is_const = true; - using value_type = T; - using instance_type = Base; }; template < auto Field > @@ -42,7 +41,7 @@ namespace meta_hpp::field_detail } template < auto Field > - void setter(void* instance, value value) { + void setter([[maybe_unused]] void* instance, value value) { using ft = field_traits; using value_type = typename ft::value_type; using instance_type = typename ft::instance_type; diff --git a/headers/meta.hpp/meta_function.hpp b/headers/meta.hpp/meta_function.hpp index 81680f9..e11b333 100644 --- a/headers/meta.hpp/meta_function.hpp +++ b/headers/meta.hpp/meta_function.hpp @@ -32,7 +32,7 @@ namespace meta_hpp::function_detail using return_type = typename ft::return_type; using argument_types = typename ft::argument_types; - auto typed_arguments = std::make_tuple( + [[maybe_unused]] auto typed_arguments = std::make_tuple( (args + Is)->try_cast>()...); if ( !(std::get(typed_arguments) && ...) ) { diff --git a/headers/meta.hpp/meta_method.hpp b/headers/meta.hpp/meta_method.hpp index 2d908ca..8ce683a 100644 --- a/headers/meta.hpp/meta_method.hpp +++ b/headers/meta.hpp/meta_method.hpp @@ -39,13 +39,13 @@ namespace meta_hpp::method_detail : method_traits {}; template < auto Method, std::size_t... Is > - value invoke(void* instance, value* args, std::index_sequence) { + value 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; using argument_types = typename mt::argument_types; - auto typed_arguments = std::make_tuple( + [[maybe_unused]] auto typed_arguments = std::make_tuple( (args + Is)->try_cast>()...); if ( !(std::get(typed_arguments) && ...) ) { @@ -77,13 +77,13 @@ namespace meta_hpp::method_detail } template < auto Method, std::size_t... Is > - value cinvoke(const void* instance, value* args, std::index_sequence) { + value 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; using argument_types = typename mt::argument_types; - auto typed_arguments = std::make_tuple( + [[maybe_unused]] auto typed_arguments = std::make_tuple( (args + Is)->try_cast>()...); if ( !(std::get(typed_arguments) && ...) ) { diff --git a/headers/meta.hpp/meta_variable.hpp b/headers/meta.hpp/meta_variable.hpp index 6698570..0b840a6 100644 --- a/headers/meta.hpp/meta_variable.hpp +++ b/headers/meta.hpp/meta_variable.hpp @@ -99,8 +99,6 @@ namespace meta_hpp template < auto Variable > class variable_ { public: - static_assert(std::is_pointer_v); - explicit variable_(std::string id) : info_(std::move(id)) { info_.getter_ = &variable_detail::getter; From 9518b3207ea389082927919439d55b01fc26a2cb Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Wed, 30 Jun 2021 00:56:11 +0700 Subject: [PATCH 003/233] update doctest to 2.4.6 version --- untests/doctest/doctest.h | 886 ++++++++++++++++++++++++++------------ 1 file changed, 603 insertions(+), 283 deletions(-) diff --git a/untests/doctest/doctest.h b/untests/doctest/doctest.h index acbe6cd..42eb039 100644 --- a/untests/doctest/doctest.h +++ b/untests/doctest/doctest.h @@ -4,7 +4,7 @@ // // doctest.h - the lightest feature-rich C++ single-header testing framework for unit tests and TDD // -// Copyright (c) 2016-2020 Viktor Kirilov +// Copyright (c) 2016-2021 Viktor Kirilov // // Distributed under the MIT Software License // See accompanying file LICENSE.txt or copy at @@ -48,8 +48,8 @@ #define DOCTEST_VERSION_MAJOR 2 #define DOCTEST_VERSION_MINOR 4 -#define DOCTEST_VERSION_PATCH 1 -#define DOCTEST_VERSION_STR "2.4.1" +#define DOCTEST_VERSION_PATCH 6 +#define DOCTEST_VERSION_STR "2.4.6" #define DOCTEST_VERSION \ (DOCTEST_VERSION_MAJOR * 10000 + DOCTEST_VERSION_MINOR * 100 + DOCTEST_VERSION_PATCH) @@ -354,7 +354,7 @@ DOCTEST_MSVC_SUPPRESS_WARNING(26812) // Prefer 'enum class' over 'enum' #define DOCTEST_GLOBAL_NO_WARNINGS(var) \ DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wglobal-constructors") \ DOCTEST_CLANG_SUPPRESS_WARNING("-Wunused-variable") \ - static int var DOCTEST_UNUSED // NOLINT(fuchsia-statically-constructed-objects,cert-err58-cpp) + static const int var DOCTEST_UNUSED // NOLINT(fuchsia-statically-constructed-objects,cert-err58-cpp) #define DOCTEST_GLOBAL_NO_WARNINGS_END() DOCTEST_CLANG_SUPPRESS_WARNING_POP #ifndef DOCTEST_BREAK_INTO_DEBUGGER @@ -362,16 +362,16 @@ DOCTEST_MSVC_SUPPRESS_WARNING(26812) // Prefer 'enum class' over 'enum' #ifdef DOCTEST_PLATFORM_LINUX #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64)) // Break at the location of the failing check if possible -#define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("int $3\n" : :) +#define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("int $3\n" : :) // NOLINT (hicpp-no-assembler) #else #include #define DOCTEST_BREAK_INTO_DEBUGGER() raise(SIGTRAP) #endif #elif defined(DOCTEST_PLATFORM_MAC) -#if defined(__x86_64) || defined(__x86_64__) || defined(__amd64__) -#define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("int $3\n" : :) +#if defined(__x86_64) || defined(__x86_64__) || defined(__amd64__) || defined(__i386) +#define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("int $3\n" : :) // NOLINT (hicpp-no-assembler) #else -#define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("brk #0"); +#define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("brk #0"); // NOLINT (hicpp-no-assembler) #endif #elif DOCTEST_MSVC #define DOCTEST_BREAK_INTO_DEBUGGER() __debugbreak() @@ -656,12 +656,14 @@ DOCTEST_INTERFACE const char* skipPathFromFilename(const char* file); struct DOCTEST_INTERFACE TestCaseData { - String m_file; // the file in which the test was registered + String m_file; // the file in which the test was registered (using String - see #350) unsigned m_line; // the line where the test was registered const char* m_name; // name of the test case const char* m_test_suite; // the test suite in which the test was added const char* m_description; bool m_skip; + bool m_no_breaks; + bool m_no_output; bool m_may_fail; bool m_should_fail; int m_expected_failures; @@ -715,12 +717,18 @@ struct DOCTEST_INTERFACE IContextScope virtual void stringify(std::ostream*) const = 0; }; +namespace detail { + struct DOCTEST_INTERFACE TestCase; +} // namespace detail + struct ContextOptions //!OCLINT too many fields { std::ostream* cout; // stdout stream - std::cout by default std::ostream* cerr; // stderr stream - std::cerr by default String binary_name; // the test binary name + const detail::TestCase* currentTest = nullptr; + // == parameters from the command line String out; // output filename String order_by; // how tests should be ordered @@ -747,6 +755,7 @@ struct ContextOptions //!OCLINT too many fields bool gnu_file_line; // if line numbers should be surrounded with :x: and not (x): bool no_path_in_filenames; // if the path to files should be removed from the output bool no_line_numbers; // if source code line numbers should be omitted from the output + bool no_debug_output; // no output in the debug console when a debugger is attached bool no_skipped_summary; // don't print "skipped" in the summary !!! UNDOCUMENTED !!! bool no_time_in_output; // omit any time/timestamps from output !!! UNDOCUMENTED !!! @@ -772,6 +781,29 @@ namespace detail { template struct remove_reference { typedef T type; }; template struct remove_reference { typedef T type; }; + template U declval(int); + + template T declval(long); + + template auto declval() DOCTEST_NOEXCEPT -> decltype(declval(0)) ; + + template struct is_lvalue_reference { const static bool value=false; }; + template struct is_lvalue_reference { const static bool value=true; }; + + template + inline T&& forward(typename remove_reference::type& t) DOCTEST_NOEXCEPT + { + return static_cast(t); + } + + template + inline T&& forward(typename remove_reference::type&& t) DOCTEST_NOEXCEPT + { + static_assert(!is_lvalue_reference::value, + "Can not forward an rvalue as an lvalue."); + return static_cast(t); + } + template struct remove_const { typedef T type; }; template struct remove_const { typedef T type; }; #ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS @@ -806,7 +838,7 @@ namespace detail { } // namespace has_insertion_operator_impl template - using has_insertion_operator = has_insertion_operator_impl::check; + using has_insertion_operator = has_insertion_operator_impl::check; DOCTEST_INTERFACE void my_memcpy(void* dest, const void* src, unsigned num); @@ -1035,13 +1067,24 @@ namespace detail { template String stringifyBinaryExpr(const DOCTEST_REF_WRAP(L) lhs, const char* op, const DOCTEST_REF_WRAP(R) rhs) { + // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) return toString(lhs) + op + toString(rhs); } +#if DOCTEST_CLANG && DOCTEST_CLANG < DOCTEST_COMPILER(3, 6, 0) +DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wunused-comparison") +#endif + +// This will check if there is any way it could find a operator like member or friend and uses it. +// If not it doesn't find the operator or if the operator at global scope is defined after +// this template, the template won't be instantiated due to SFINAE. Once the template is not +// instantiated it can look for global operator using normal conversions. +#define SFINAE_OP(ret,op) decltype(doctest::detail::declval() op doctest::detail::declval(),static_cast(0)) + #define DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(op, op_str, op_macro) \ template \ - DOCTEST_NOINLINE Result operator op(const DOCTEST_REF_WRAP(R) rhs) { \ - bool res = op_macro(lhs, rhs); \ + DOCTEST_NOINLINE SFINAE_OP(Result,op) operator op(R&& rhs) { \ + bool res = op_macro(doctest::detail::forward(lhs), doctest::detail::forward(rhs)); \ if(m_at & assertType::is_false) \ res = !res; \ if(!res || doctest::getContextOptions()->success) \ @@ -1122,6 +1165,7 @@ namespace detail { #define DOCTEST_COMPARISON_RETURN_TYPE bool #else // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING #define DOCTEST_COMPARISON_RETURN_TYPE typename enable_if::value || can_use_op::value, bool>::type + // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) inline bool eq(const char* lhs, const char* rhs) { return String(lhs) == String(rhs); } inline bool ne(const char* lhs, const char* rhs) { return String(lhs) != String(rhs); } inline bool lt(const char* lhs, const char* rhs) { return String(lhs) < String(rhs); } @@ -1168,12 +1212,16 @@ namespace detail { L lhs; assertType::Enum m_at; - explicit Expression_lhs(L in, assertType::Enum at) - : lhs(in) + explicit Expression_lhs(L&& in, assertType::Enum at) + : lhs(doctest::detail::forward(in)) , m_at(at) {} DOCTEST_NOINLINE operator Result() { - bool res = !!lhs; +// this is needed only foc MSVC 2015: +// https://ci.appveyor.com/project/onqtam/doctest/builds/38181202 +DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4800) // 'int': forcing value to bool + bool res = static_cast(lhs); +DOCTEST_MSVC_SUPPRESS_WARNING_POP if(m_at & assertType::is_false) //!OCLINT bitwise operator in conditional res = !res; @@ -1182,6 +1230,10 @@ namespace detail { return Result(res); } + /* This is required for user-defined conversions from Expression_lhs to L */ + //operator L() const { return lhs; } + operator L() const { return lhs; } + // clang-format off DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(==, " == ", DOCTEST_CMP_EQ) //!OCLINT bitwise operator in conditional DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(!=, " != ", DOCTEST_CMP_NE) //!OCLINT bitwise operator in conditional @@ -1222,6 +1274,10 @@ namespace detail { #endif // DOCTEST_CONFIG_NO_COMPARISON_WARNING_SUPPRESSION +#if DOCTEST_CLANG && DOCTEST_CLANG < DOCTEST_COMPILER(3, 6, 0) +DOCTEST_CLANG_SUPPRESS_WARNING_POP +#endif + struct DOCTEST_INTERFACE ExpressionDecomposer { assertType::Enum m_at; @@ -1233,8 +1289,8 @@ namespace detail { // https://github.com/catchorg/Catch2/issues/870 // https://github.com/catchorg/Catch2/issues/565 template - Expression_lhs operator<<(const DOCTEST_REF_WRAP(L) operand) { - return Expression_lhs(operand, m_at); + Expression_lhs operator<<(L &&operand) { + return Expression_lhs(doctest::detail::forward(operand), m_at); } }; @@ -1243,6 +1299,8 @@ namespace detail { const char* m_test_suite; const char* m_description; bool m_skip; + bool m_no_breaks; + bool m_no_output; bool m_may_fail; bool m_should_fail; int m_expected_failures; @@ -1521,7 +1579,7 @@ namespace detail { template class ContextScope : public ContextScopeBase { - const L &lambda_; + const L lambda_; public: explicit ContextScope(const L &lambda) : lambda_(lambda) {} @@ -1541,12 +1599,24 @@ namespace detail { MessageBuilder() = delete; ~MessageBuilder(); + // the preferred way of chaining parameters for stringification template - MessageBuilder& operator<<(const T& in) { + MessageBuilder& operator,(const T& in) { toStream(m_stream, in); return *this; } + // kept here just for backwards-compatibility - the comma operator should be preferred now + template + MessageBuilder& operator<<(const T& in) { return this->operator,(in); } + + // the `,` operator has the lowest operator precedence - if `<<` is used by the user then + // the `,` operator will be called last which is not what we want and thus the `*` operator + // is used first (has higher operator precedence compared to `<<`) so that we guarantee that + // an operator of the MessageBuilder class is called first before the rest of the parameters + template + MessageBuilder& operator*(const T& in) { return this->operator,(in); } + bool log(); void react(); }; @@ -1570,6 +1640,8 @@ namespace detail { DOCTEST_DEFINE_DECORATOR(test_suite, const char*, ""); DOCTEST_DEFINE_DECORATOR(description, const char*, ""); DOCTEST_DEFINE_DECORATOR(skip, bool, true); +DOCTEST_DEFINE_DECORATOR(no_breaks, bool, true); +DOCTEST_DEFINE_DECORATOR(no_output, bool, true); DOCTEST_DEFINE_DECORATOR(timeout, double, 0); DOCTEST_DEFINE_DECORATOR(may_fail, bool, true); DOCTEST_DEFINE_DECORATOR(should_fail, bool, true); @@ -1906,10 +1978,12 @@ int registerReporter(const char* name, int priority, bool isReporter) { static DOCTEST_NOINLINE doctest::detail::TestSuite& getCurrentTestSuite() { \ DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4640) \ DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wexit-time-destructors") \ - static doctest::detail::TestSuite data; \ + DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wmissing-field-initializers") \ + static doctest::detail::TestSuite data{}; \ static bool inited = false; \ DOCTEST_MSVC_SUPPRESS_WARNING_POP \ DOCTEST_CLANG_SUPPRESS_WARNING_POP \ + DOCTEST_GCC_SUPPRESS_WARNING_POP \ if(!inited) { \ data* decorators; \ inited = true; \ @@ -1962,38 +2036,36 @@ int registerReporter(const char* name, int priority, bool isReporter) { DOCTEST_GLOBAL_NO_WARNINGS_END() typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_) // for logging -#define DOCTEST_INFO(expression) \ +#define DOCTEST_INFO(...) \ DOCTEST_INFO_IMPL(DOCTEST_ANONYMOUS(_DOCTEST_CAPTURE_), DOCTEST_ANONYMOUS(_DOCTEST_CAPTURE_), \ - DOCTEST_ANONYMOUS(_DOCTEST_CAPTURE_), expression) + __VA_ARGS__) -#define DOCTEST_INFO_IMPL(lambda_name, mb_name, s_name, expression) \ - DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4626) \ - auto lambda_name = [&](std::ostream* s_name) { \ +#define DOCTEST_INFO_IMPL(mb_name, s_name, ...) \ + auto DOCTEST_ANONYMOUS(_DOCTEST_CAPTURE_) = doctest::detail::MakeContextScope( \ + [&](std::ostream* s_name) { \ doctest::detail::MessageBuilder mb_name(__FILE__, __LINE__, doctest::assertType::is_warn); \ mb_name.m_stream = s_name; \ - mb_name << expression; \ - }; \ - DOCTEST_MSVC_SUPPRESS_WARNING_POP \ - auto DOCTEST_ANONYMOUS(_DOCTEST_CAPTURE_) = doctest::detail::MakeContextScope(lambda_name) + mb_name * __VA_ARGS__; \ + }) -#define DOCTEST_CAPTURE(x) DOCTEST_INFO(#x " := " << x) +#define DOCTEST_CAPTURE(x) DOCTEST_INFO(#x " := ", x) -#define DOCTEST_ADD_AT_IMPL(type, file, line, mb, x) \ +#define DOCTEST_ADD_AT_IMPL(type, file, line, mb, ...) \ do { \ doctest::detail::MessageBuilder mb(file, line, doctest::assertType::type); \ - mb << x; \ + mb * __VA_ARGS__; \ DOCTEST_ASSERT_LOG_AND_REACT(mb); \ } while(false) // clang-format off -#define DOCTEST_ADD_MESSAGE_AT(file, line, x) DOCTEST_ADD_AT_IMPL(is_warn, file, line, DOCTEST_ANONYMOUS(_DOCTEST_MESSAGE_), x) -#define DOCTEST_ADD_FAIL_CHECK_AT(file, line, x) DOCTEST_ADD_AT_IMPL(is_check, file, line, DOCTEST_ANONYMOUS(_DOCTEST_MESSAGE_), x) -#define DOCTEST_ADD_FAIL_AT(file, line, x) DOCTEST_ADD_AT_IMPL(is_require, file, line, DOCTEST_ANONYMOUS(_DOCTEST_MESSAGE_), x) +#define DOCTEST_ADD_MESSAGE_AT(file, line, ...) DOCTEST_ADD_AT_IMPL(is_warn, file, line, DOCTEST_ANONYMOUS(_DOCTEST_MESSAGE_), __VA_ARGS__) +#define DOCTEST_ADD_FAIL_CHECK_AT(file, line, ...) DOCTEST_ADD_AT_IMPL(is_check, file, line, DOCTEST_ANONYMOUS(_DOCTEST_MESSAGE_), __VA_ARGS__) +#define DOCTEST_ADD_FAIL_AT(file, line, ...) DOCTEST_ADD_AT_IMPL(is_require, file, line, DOCTEST_ANONYMOUS(_DOCTEST_MESSAGE_), __VA_ARGS__) // clang-format on -#define DOCTEST_MESSAGE(x) DOCTEST_ADD_MESSAGE_AT(__FILE__, __LINE__, x) -#define DOCTEST_FAIL_CHECK(x) DOCTEST_ADD_FAIL_CHECK_AT(__FILE__, __LINE__, x) -#define DOCTEST_FAIL(x) DOCTEST_ADD_FAIL_AT(__FILE__, __LINE__, x) +#define DOCTEST_MESSAGE(...) DOCTEST_ADD_MESSAGE_AT(__FILE__, __LINE__, __VA_ARGS__) +#define DOCTEST_FAIL_CHECK(...) DOCTEST_ADD_FAIL_CHECK_AT(__FILE__, __LINE__, __VA_ARGS__) +#define DOCTEST_FAIL(...) DOCTEST_ADD_FAIL_AT(__FILE__, __LINE__, __VA_ARGS__) #define DOCTEST_TO_LVALUE(...) __VA_ARGS__ // Not removed to keep backwards compatibility. @@ -2036,12 +2108,12 @@ int registerReporter(const char* name, int priority, bool isReporter) { #define DOCTEST_REQUIRE_FALSE(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_REQUIRE_FALSE, __VA_ARGS__) // clang-format off -#define DOCTEST_WARN_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2(DT_WARN, cond); } while(false) -#define DOCTEST_CHECK_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2(DT_CHECK, cond); } while(false) -#define DOCTEST_REQUIRE_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2(DT_REQUIRE, cond); } while(false) -#define DOCTEST_WARN_FALSE_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2(DT_WARN_FALSE, cond); } while(false) -#define DOCTEST_CHECK_FALSE_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2(DT_CHECK_FALSE, cond); } while(false) -#define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2(DT_REQUIRE_FALSE, cond); } while(false) +#define DOCTEST_WARN_MESSAGE(cond, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_WARN, cond); } while(false) +#define DOCTEST_CHECK_MESSAGE(cond, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_CHECK, cond); } while(false) +#define DOCTEST_REQUIRE_MESSAGE(cond, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_REQUIRE, cond); } while(false) +#define DOCTEST_WARN_FALSE_MESSAGE(cond, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_WARN_FALSE, cond); } while(false) +#define DOCTEST_CHECK_FALSE_MESSAGE(cond, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_CHECK_FALSE, cond); } while(false) +#define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_REQUIRE_FALSE, cond); } while(false) // clang-format on #define DOCTEST_ASSERT_THROWS_AS(expr, assert_type, message, ...) \ @@ -2051,8 +2123,8 @@ int registerReporter(const char* name, int priority, bool isReporter) { __LINE__, #expr, #__VA_ARGS__, message); \ try { \ DOCTEST_CAST_TO_VOID(expr) \ - } catch(const doctest::detail::remove_const< \ - doctest::detail::remove_reference<__VA_ARGS__>::type>::type&) { \ + } catch(const typename doctest::detail::remove_const< \ + typename doctest::detail::remove_reference<__VA_ARGS__>::type>::type&) { \ _DOCTEST_RB.translateException(); \ _DOCTEST_RB.m_threw_as = true; \ } catch(...) { _DOCTEST_RB.translateException(); } \ @@ -2103,21 +2175,21 @@ int registerReporter(const char* name, int priority, bool isReporter) { #define DOCTEST_CHECK_NOTHROW(...) DOCTEST_ASSERT_NOTHROW(DT_CHECK_NOTHROW, __VA_ARGS__) #define DOCTEST_REQUIRE_NOTHROW(...) DOCTEST_ASSERT_NOTHROW(DT_REQUIRE_NOTHROW, __VA_ARGS__) -#define DOCTEST_WARN_THROWS_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_WARN_THROWS(expr); } while(false) -#define DOCTEST_CHECK_THROWS_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_CHECK_THROWS(expr); } while(false) -#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_REQUIRE_THROWS(expr); } while(false) -#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, msg) do { DOCTEST_INFO(msg); DOCTEST_WARN_THROWS_AS(expr, ex); } while(false) -#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, msg) do { DOCTEST_INFO(msg); DOCTEST_CHECK_THROWS_AS(expr, ex); } while(false) -#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, msg) do { DOCTEST_INFO(msg); DOCTEST_REQUIRE_THROWS_AS(expr, ex); } while(false) -#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, msg) do { DOCTEST_INFO(msg); DOCTEST_WARN_THROWS_WITH(expr, with); } while(false) -#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, msg) do { DOCTEST_INFO(msg); DOCTEST_CHECK_THROWS_WITH(expr, with); } while(false) -#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, msg) do { DOCTEST_INFO(msg); DOCTEST_REQUIRE_THROWS_WITH(expr, with); } while(false) -#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) do { DOCTEST_INFO(msg); DOCTEST_WARN_THROWS_WITH_AS(expr, with, ex); } while(false) -#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) do { DOCTEST_INFO(msg); DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ex); } while(false) -#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) do { DOCTEST_INFO(msg); DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ex); } while(false) -#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_WARN_NOTHROW(expr); } while(false) -#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_CHECK_NOTHROW(expr); } while(false) -#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_REQUIRE_NOTHROW(expr); } while(false) +#define DOCTEST_WARN_THROWS_MESSAGE(expr, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS(expr); } while(false) +#define DOCTEST_CHECK_THROWS_MESSAGE(expr, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS(expr); } while(false) +#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS(expr); } while(false) +#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS_AS(expr, ex); } while(false) +#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS_AS(expr, ex); } while(false) +#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS_AS(expr, ex); } while(false) +#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS_WITH(expr, with); } while(false) +#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS_WITH(expr, with); } while(false) +#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS_WITH(expr, with); } while(false) +#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS_WITH_AS(expr, with, ex); } while(false) +#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ex); } while(false) +#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ex); } while(false) +#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_NOTHROW(expr); } while(false) +#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_NOTHROW(expr); } while(false) +#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_NOTHROW(expr); } while(false) // clang-format on #ifndef DOCTEST_CONFIG_SUPER_FAST_ASSERTS @@ -2230,21 +2302,21 @@ int registerReporter(const char* name, int priority, bool isReporter) { #define DOCTEST_CHECK_NOTHROW(...) (static_cast(0)) #define DOCTEST_REQUIRE_NOTHROW(...) (static_cast(0)) -#define DOCTEST_WARN_THROWS_MESSAGE(expr, msg) (static_cast(0)) -#define DOCTEST_CHECK_THROWS_MESSAGE(expr, msg) (static_cast(0)) -#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, msg) (static_cast(0)) -#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, msg) (static_cast(0)) -#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, msg) (static_cast(0)) -#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, msg) (static_cast(0)) -#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, msg) (static_cast(0)) -#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, msg) (static_cast(0)) -#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, msg) (static_cast(0)) -#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) (static_cast(0)) -#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) (static_cast(0)) -#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) (static_cast(0)) -#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, msg) (static_cast(0)) -#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, msg) (static_cast(0)) -#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, msg) (static_cast(0)) +#define DOCTEST_WARN_THROWS_MESSAGE(expr, ...) (static_cast(0)) +#define DOCTEST_CHECK_THROWS_MESSAGE(expr, ...) (static_cast(0)) +#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, ...) (static_cast(0)) +#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, ...) (static_cast(0)) +#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, ...) (static_cast(0)) +#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) (static_cast(0)) +#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, ...) (static_cast(0)) +#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, ...) (static_cast(0)) +#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) (static_cast(0)) +#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) (static_cast(0)) +#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) (static_cast(0)) +#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) (static_cast(0)) +#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, ...) (static_cast(0)) +#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, ...) (static_cast(0)) +#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, ...) (static_cast(0)) #else // DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS @@ -2335,14 +2407,14 @@ int registerReporter(const char* name, int priority, bool isReporter) { #define DOCTEST_REGISTER_REPORTER(name, priority, reporter) #define DOCTEST_REGISTER_LISTENER(name, priority, reporter) -#define DOCTEST_INFO(x) (static_cast(0)) +#define DOCTEST_INFO(...) (static_cast(0)) #define DOCTEST_CAPTURE(x) (static_cast(0)) -#define DOCTEST_ADD_MESSAGE_AT(file, line, x) (static_cast(0)) -#define DOCTEST_ADD_FAIL_CHECK_AT(file, line, x) (static_cast(0)) -#define DOCTEST_ADD_FAIL_AT(file, line, x) (static_cast(0)) -#define DOCTEST_MESSAGE(x) (static_cast(0)) -#define DOCTEST_FAIL_CHECK(x) (static_cast(0)) -#define DOCTEST_FAIL(x) (static_cast(0)) +#define DOCTEST_ADD_MESSAGE_AT(file, line, ...) (static_cast(0)) +#define DOCTEST_ADD_FAIL_CHECK_AT(file, line, ...) (static_cast(0)) +#define DOCTEST_ADD_FAIL_AT(file, line, ...) (static_cast(0)) +#define DOCTEST_MESSAGE(...) (static_cast(0)) +#define DOCTEST_FAIL_CHECK(...) (static_cast(0)) +#define DOCTEST_FAIL(...) (static_cast(0)) #define DOCTEST_WARN(...) (static_cast(0)) #define DOCTEST_CHECK(...) (static_cast(0)) @@ -2351,12 +2423,12 @@ int registerReporter(const char* name, int priority, bool isReporter) { #define DOCTEST_CHECK_FALSE(...) (static_cast(0)) #define DOCTEST_REQUIRE_FALSE(...) (static_cast(0)) -#define DOCTEST_WARN_MESSAGE(cond, msg) (static_cast(0)) -#define DOCTEST_CHECK_MESSAGE(cond, msg) (static_cast(0)) -#define DOCTEST_REQUIRE_MESSAGE(cond, msg) (static_cast(0)) -#define DOCTEST_WARN_FALSE_MESSAGE(cond, msg) (static_cast(0)) -#define DOCTEST_CHECK_FALSE_MESSAGE(cond, msg) (static_cast(0)) -#define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, msg) (static_cast(0)) +#define DOCTEST_WARN_MESSAGE(cond, ...) (static_cast(0)) +#define DOCTEST_CHECK_MESSAGE(cond, ...) (static_cast(0)) +#define DOCTEST_REQUIRE_MESSAGE(cond, ...) (static_cast(0)) +#define DOCTEST_WARN_FALSE_MESSAGE(cond, ...) (static_cast(0)) +#define DOCTEST_CHECK_FALSE_MESSAGE(cond, ...) (static_cast(0)) +#define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, ...) (static_cast(0)) #define DOCTEST_WARN_THROWS(...) (static_cast(0)) #define DOCTEST_CHECK_THROWS(...) (static_cast(0)) @@ -2374,21 +2446,21 @@ int registerReporter(const char* name, int priority, bool isReporter) { #define DOCTEST_CHECK_NOTHROW(...) (static_cast(0)) #define DOCTEST_REQUIRE_NOTHROW(...) (static_cast(0)) -#define DOCTEST_WARN_THROWS_MESSAGE(expr, msg) (static_cast(0)) -#define DOCTEST_CHECK_THROWS_MESSAGE(expr, msg) (static_cast(0)) -#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, msg) (static_cast(0)) -#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, msg) (static_cast(0)) -#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, msg) (static_cast(0)) -#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, msg) (static_cast(0)) -#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, msg) (static_cast(0)) -#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, msg) (static_cast(0)) -#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, msg) (static_cast(0)) -#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) (static_cast(0)) -#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) (static_cast(0)) -#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) (static_cast(0)) -#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, msg) (static_cast(0)) -#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, msg) (static_cast(0)) -#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, msg) (static_cast(0)) +#define DOCTEST_WARN_THROWS_MESSAGE(expr, ...) (static_cast(0)) +#define DOCTEST_CHECK_THROWS_MESSAGE(expr, ...) (static_cast(0)) +#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, ...) (static_cast(0)) +#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, ...) (static_cast(0)) +#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, ...) (static_cast(0)) +#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) (static_cast(0)) +#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, ...) (static_cast(0)) +#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, ...) (static_cast(0)) +#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) (static_cast(0)) +#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) (static_cast(0)) +#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) (static_cast(0)) +#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) (static_cast(0)) +#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, ...) (static_cast(0)) +#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, ...) (static_cast(0)) +#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, ...) (static_cast(0)) #define DOCTEST_WARN_EQ(...) (static_cast(0)) #define DOCTEST_CHECK_EQ(...) (static_cast(0)) @@ -2446,7 +2518,7 @@ int registerReporter(const char* name, int priority, bool isReporter) { #define DOCTEST_FAST_CHECK_UNARY_FALSE DOCTEST_CHECK_UNARY_FALSE #define DOCTEST_FAST_REQUIRE_UNARY_FALSE DOCTEST_REQUIRE_UNARY_FALSE -#define DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE DOCTEST_TEST_CASE_TEMPLATE_INVOKE +#define DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE(id, ...) DOCTEST_TEST_CASE_TEMPLATE_INVOKE(id,__VA_ARGS__) // clang-format on // BDD style macros @@ -2466,138 +2538,138 @@ int registerReporter(const char* name, int priority, bool isReporter) { // == SHORT VERSIONS OF THE MACROS #if !defined(DOCTEST_CONFIG_NO_SHORT_MACRO_NAMES) -#define TEST_CASE DOCTEST_TEST_CASE -#define TEST_CASE_CLASS DOCTEST_TEST_CASE_CLASS -#define TEST_CASE_FIXTURE DOCTEST_TEST_CASE_FIXTURE -#define TYPE_TO_STRING DOCTEST_TYPE_TO_STRING -#define TEST_CASE_TEMPLATE DOCTEST_TEST_CASE_TEMPLATE -#define TEST_CASE_TEMPLATE_DEFINE DOCTEST_TEST_CASE_TEMPLATE_DEFINE -#define TEST_CASE_TEMPLATE_INVOKE DOCTEST_TEST_CASE_TEMPLATE_INVOKE -#define TEST_CASE_TEMPLATE_APPLY DOCTEST_TEST_CASE_TEMPLATE_APPLY -#define SUBCASE DOCTEST_SUBCASE -#define TEST_SUITE DOCTEST_TEST_SUITE -#define TEST_SUITE_BEGIN DOCTEST_TEST_SUITE_BEGIN +#define TEST_CASE(name) DOCTEST_TEST_CASE(name) +#define TEST_CASE_CLASS(name) DOCTEST_TEST_CASE_CLASS(name) +#define TEST_CASE_FIXTURE(x, name) DOCTEST_TEST_CASE_FIXTURE(x, name) +#define TYPE_TO_STRING(...) DOCTEST_TYPE_TO_STRING(__VA_ARGS__) +#define TEST_CASE_TEMPLATE(name, T, ...) DOCTEST_TEST_CASE_TEMPLATE(name, T, __VA_ARGS__) +#define TEST_CASE_TEMPLATE_DEFINE(name, T, id) DOCTEST_TEST_CASE_TEMPLATE_DEFINE(name, T, id) +#define TEST_CASE_TEMPLATE_INVOKE(id, ...) DOCTEST_TEST_CASE_TEMPLATE_INVOKE(id, __VA_ARGS__) +#define TEST_CASE_TEMPLATE_APPLY(id, ...) DOCTEST_TEST_CASE_TEMPLATE_APPLY(id, __VA_ARGS__) +#define SUBCASE(name) DOCTEST_SUBCASE(name) +#define TEST_SUITE(decorators) DOCTEST_TEST_SUITE(decorators) +#define TEST_SUITE_BEGIN(name) DOCTEST_TEST_SUITE_BEGIN(name) #define TEST_SUITE_END DOCTEST_TEST_SUITE_END -#define REGISTER_EXCEPTION_TRANSLATOR DOCTEST_REGISTER_EXCEPTION_TRANSLATOR -#define REGISTER_REPORTER DOCTEST_REGISTER_REPORTER -#define REGISTER_LISTENER DOCTEST_REGISTER_LISTENER -#define INFO DOCTEST_INFO -#define CAPTURE DOCTEST_CAPTURE -#define ADD_MESSAGE_AT DOCTEST_ADD_MESSAGE_AT -#define ADD_FAIL_CHECK_AT DOCTEST_ADD_FAIL_CHECK_AT -#define ADD_FAIL_AT DOCTEST_ADD_FAIL_AT -#define MESSAGE DOCTEST_MESSAGE -#define FAIL_CHECK DOCTEST_FAIL_CHECK -#define FAIL DOCTEST_FAIL -#define TO_LVALUE DOCTEST_TO_LVALUE +#define REGISTER_EXCEPTION_TRANSLATOR(signature) DOCTEST_REGISTER_EXCEPTION_TRANSLATOR(signature) +#define REGISTER_REPORTER(name, priority, reporter) DOCTEST_REGISTER_REPORTER(name, priority, reporter) +#define REGISTER_LISTENER(name, priority, reporter) DOCTEST_REGISTER_LISTENER(name, priority, reporter) +#define INFO(...) DOCTEST_INFO(__VA_ARGS__) +#define CAPTURE(x) DOCTEST_CAPTURE(x) +#define ADD_MESSAGE_AT(file, line, ...) DOCTEST_ADD_MESSAGE_AT(file, line, __VA_ARGS__) +#define ADD_FAIL_CHECK_AT(file, line, ...) DOCTEST_ADD_FAIL_CHECK_AT(file, line, __VA_ARGS__) +#define ADD_FAIL_AT(file, line, ...) DOCTEST_ADD_FAIL_AT(file, line, __VA_ARGS__) +#define MESSAGE(...) DOCTEST_MESSAGE(__VA_ARGS__) +#define FAIL_CHECK(...) DOCTEST_FAIL_CHECK(__VA_ARGS__) +#define FAIL(...) DOCTEST_FAIL(__VA_ARGS__) +#define TO_LVALUE(...) DOCTEST_TO_LVALUE(__VA_ARGS__) -#define WARN DOCTEST_WARN -#define WARN_FALSE DOCTEST_WARN_FALSE -#define WARN_THROWS DOCTEST_WARN_THROWS -#define WARN_THROWS_AS DOCTEST_WARN_THROWS_AS -#define WARN_THROWS_WITH DOCTEST_WARN_THROWS_WITH -#define WARN_THROWS_WITH_AS DOCTEST_WARN_THROWS_WITH_AS -#define WARN_NOTHROW DOCTEST_WARN_NOTHROW -#define CHECK DOCTEST_CHECK -#define CHECK_FALSE DOCTEST_CHECK_FALSE -#define CHECK_THROWS DOCTEST_CHECK_THROWS -#define CHECK_THROWS_AS DOCTEST_CHECK_THROWS_AS -#define CHECK_THROWS_WITH DOCTEST_CHECK_THROWS_WITH -#define CHECK_THROWS_WITH_AS DOCTEST_CHECK_THROWS_WITH_AS -#define CHECK_NOTHROW DOCTEST_CHECK_NOTHROW -#define REQUIRE DOCTEST_REQUIRE -#define REQUIRE_FALSE DOCTEST_REQUIRE_FALSE -#define REQUIRE_THROWS DOCTEST_REQUIRE_THROWS -#define REQUIRE_THROWS_AS DOCTEST_REQUIRE_THROWS_AS -#define REQUIRE_THROWS_WITH DOCTEST_REQUIRE_THROWS_WITH -#define REQUIRE_THROWS_WITH_AS DOCTEST_REQUIRE_THROWS_WITH_AS -#define REQUIRE_NOTHROW DOCTEST_REQUIRE_NOTHROW +#define WARN(...) DOCTEST_WARN(__VA_ARGS__) +#define WARN_FALSE(...) DOCTEST_WARN_FALSE(__VA_ARGS__) +#define WARN_THROWS(...) DOCTEST_WARN_THROWS(__VA_ARGS__) +#define WARN_THROWS_AS(expr, ...) DOCTEST_WARN_THROWS_AS(expr, __VA_ARGS__) +#define WARN_THROWS_WITH(expr, ...) DOCTEST_WARN_THROWS_WITH(expr, __VA_ARGS__) +#define WARN_THROWS_WITH_AS(expr, with, ...) DOCTEST_WARN_THROWS_WITH_AS(expr, with, __VA_ARGS__) +#define WARN_NOTHROW(...) DOCTEST_WARN_NOTHROW(__VA_ARGS__) +#define CHECK(...) DOCTEST_CHECK(__VA_ARGS__) +#define CHECK_FALSE(...) DOCTEST_CHECK_FALSE(__VA_ARGS__) +#define CHECK_THROWS(...) DOCTEST_CHECK_THROWS(__VA_ARGS__) +#define CHECK_THROWS_AS(expr, ...) DOCTEST_CHECK_THROWS_AS(expr, __VA_ARGS__) +#define CHECK_THROWS_WITH(expr, ...) DOCTEST_CHECK_THROWS_WITH(expr, __VA_ARGS__) +#define CHECK_THROWS_WITH_AS(expr, with, ...) DOCTEST_CHECK_THROWS_WITH_AS(expr, with, __VA_ARGS__) +#define CHECK_NOTHROW(...) DOCTEST_CHECK_NOTHROW(__VA_ARGS__) +#define REQUIRE(...) DOCTEST_REQUIRE(__VA_ARGS__) +#define REQUIRE_FALSE(...) DOCTEST_REQUIRE_FALSE(__VA_ARGS__) +#define REQUIRE_THROWS(...) DOCTEST_REQUIRE_THROWS(__VA_ARGS__) +#define REQUIRE_THROWS_AS(expr, ...) DOCTEST_REQUIRE_THROWS_AS(expr, __VA_ARGS__) +#define REQUIRE_THROWS_WITH(expr, ...) DOCTEST_REQUIRE_THROWS_WITH(expr, __VA_ARGS__) +#define REQUIRE_THROWS_WITH_AS(expr, with, ...) DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, __VA_ARGS__) +#define REQUIRE_NOTHROW(...) DOCTEST_REQUIRE_NOTHROW(__VA_ARGS__) -#define WARN_MESSAGE DOCTEST_WARN_MESSAGE -#define WARN_FALSE_MESSAGE DOCTEST_WARN_FALSE_MESSAGE -#define WARN_THROWS_MESSAGE DOCTEST_WARN_THROWS_MESSAGE -#define WARN_THROWS_AS_MESSAGE DOCTEST_WARN_THROWS_AS_MESSAGE -#define WARN_THROWS_WITH_MESSAGE DOCTEST_WARN_THROWS_WITH_MESSAGE -#define WARN_THROWS_WITH_AS_MESSAGE DOCTEST_WARN_THROWS_WITH_AS_MESSAGE -#define WARN_NOTHROW_MESSAGE DOCTEST_WARN_NOTHROW_MESSAGE -#define CHECK_MESSAGE DOCTEST_CHECK_MESSAGE -#define CHECK_FALSE_MESSAGE DOCTEST_CHECK_FALSE_MESSAGE -#define CHECK_THROWS_MESSAGE DOCTEST_CHECK_THROWS_MESSAGE -#define CHECK_THROWS_AS_MESSAGE DOCTEST_CHECK_THROWS_AS_MESSAGE -#define CHECK_THROWS_WITH_MESSAGE DOCTEST_CHECK_THROWS_WITH_MESSAGE -#define CHECK_THROWS_WITH_AS_MESSAGE DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE -#define CHECK_NOTHROW_MESSAGE DOCTEST_CHECK_NOTHROW_MESSAGE -#define REQUIRE_MESSAGE DOCTEST_REQUIRE_MESSAGE -#define REQUIRE_FALSE_MESSAGE DOCTEST_REQUIRE_FALSE_MESSAGE -#define REQUIRE_THROWS_MESSAGE DOCTEST_REQUIRE_THROWS_MESSAGE -#define REQUIRE_THROWS_AS_MESSAGE DOCTEST_REQUIRE_THROWS_AS_MESSAGE -#define REQUIRE_THROWS_WITH_MESSAGE DOCTEST_REQUIRE_THROWS_WITH_MESSAGE -#define REQUIRE_THROWS_WITH_AS_MESSAGE DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE -#define REQUIRE_NOTHROW_MESSAGE DOCTEST_REQUIRE_NOTHROW_MESSAGE +#define WARN_MESSAGE(cond, ...) DOCTEST_WARN_MESSAGE(cond, __VA_ARGS__) +#define WARN_FALSE_MESSAGE(cond, ...) DOCTEST_WARN_FALSE_MESSAGE(cond, __VA_ARGS__) +#define WARN_THROWS_MESSAGE(expr, ...) DOCTEST_WARN_THROWS_MESSAGE(expr, __VA_ARGS__) +#define WARN_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, __VA_ARGS__) +#define WARN_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, __VA_ARGS__) +#define WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, __VA_ARGS__) +#define WARN_NOTHROW_MESSAGE(expr, ...) DOCTEST_WARN_NOTHROW_MESSAGE(expr, __VA_ARGS__) +#define CHECK_MESSAGE(cond, ...) DOCTEST_CHECK_MESSAGE(cond, __VA_ARGS__) +#define CHECK_FALSE_MESSAGE(cond, ...) DOCTEST_CHECK_FALSE_MESSAGE(cond, __VA_ARGS__) +#define CHECK_THROWS_MESSAGE(expr, ...) DOCTEST_CHECK_THROWS_MESSAGE(expr, __VA_ARGS__) +#define CHECK_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, __VA_ARGS__) +#define CHECK_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, __VA_ARGS__) +#define CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, __VA_ARGS__) +#define CHECK_NOTHROW_MESSAGE(expr, ...) DOCTEST_CHECK_NOTHROW_MESSAGE(expr, __VA_ARGS__) +#define REQUIRE_MESSAGE(cond, ...) DOCTEST_REQUIRE_MESSAGE(cond, __VA_ARGS__) +#define REQUIRE_FALSE_MESSAGE(cond, ...) DOCTEST_REQUIRE_FALSE_MESSAGE(cond, __VA_ARGS__) +#define REQUIRE_THROWS_MESSAGE(expr, ...) DOCTEST_REQUIRE_THROWS_MESSAGE(expr, __VA_ARGS__) +#define REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, __VA_ARGS__) +#define REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, __VA_ARGS__) +#define REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, __VA_ARGS__) +#define REQUIRE_NOTHROW_MESSAGE(expr, ...) DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, __VA_ARGS__) -#define SCENARIO DOCTEST_SCENARIO -#define SCENARIO_CLASS DOCTEST_SCENARIO_CLASS -#define SCENARIO_TEMPLATE DOCTEST_SCENARIO_TEMPLATE -#define SCENARIO_TEMPLATE_DEFINE DOCTEST_SCENARIO_TEMPLATE_DEFINE -#define GIVEN DOCTEST_GIVEN -#define WHEN DOCTEST_WHEN -#define AND_WHEN DOCTEST_AND_WHEN -#define THEN DOCTEST_THEN -#define AND_THEN DOCTEST_AND_THEN +#define SCENARIO(name) DOCTEST_SCENARIO(name) +#define SCENARIO_CLASS(name) DOCTEST_SCENARIO_CLASS(name) +#define SCENARIO_TEMPLATE(name, T, ...) DOCTEST_SCENARIO_TEMPLATE(name, T, __VA_ARGS__) +#define SCENARIO_TEMPLATE_DEFINE(name, T, id) DOCTEST_SCENARIO_TEMPLATE_DEFINE(name, T, id) +#define GIVEN(name) DOCTEST_GIVEN(name) +#define WHEN(name) DOCTEST_WHEN(name) +#define AND_WHEN(name) DOCTEST_AND_WHEN(name) +#define THEN(name) DOCTEST_THEN(name) +#define AND_THEN(name) DOCTEST_AND_THEN(name) -#define WARN_EQ DOCTEST_WARN_EQ -#define CHECK_EQ DOCTEST_CHECK_EQ -#define REQUIRE_EQ DOCTEST_REQUIRE_EQ -#define WARN_NE DOCTEST_WARN_NE -#define CHECK_NE DOCTEST_CHECK_NE -#define REQUIRE_NE DOCTEST_REQUIRE_NE -#define WARN_GT DOCTEST_WARN_GT -#define CHECK_GT DOCTEST_CHECK_GT -#define REQUIRE_GT DOCTEST_REQUIRE_GT -#define WARN_LT DOCTEST_WARN_LT -#define CHECK_LT DOCTEST_CHECK_LT -#define REQUIRE_LT DOCTEST_REQUIRE_LT -#define WARN_GE DOCTEST_WARN_GE -#define CHECK_GE DOCTEST_CHECK_GE -#define REQUIRE_GE DOCTEST_REQUIRE_GE -#define WARN_LE DOCTEST_WARN_LE -#define CHECK_LE DOCTEST_CHECK_LE -#define REQUIRE_LE DOCTEST_REQUIRE_LE -#define WARN_UNARY DOCTEST_WARN_UNARY -#define CHECK_UNARY DOCTEST_CHECK_UNARY -#define REQUIRE_UNARY DOCTEST_REQUIRE_UNARY -#define WARN_UNARY_FALSE DOCTEST_WARN_UNARY_FALSE -#define CHECK_UNARY_FALSE DOCTEST_CHECK_UNARY_FALSE -#define REQUIRE_UNARY_FALSE DOCTEST_REQUIRE_UNARY_FALSE +#define WARN_EQ(...) DOCTEST_WARN_EQ(__VA_ARGS__) +#define CHECK_EQ(...) DOCTEST_CHECK_EQ(__VA_ARGS__) +#define REQUIRE_EQ(...) DOCTEST_REQUIRE_EQ(__VA_ARGS__) +#define WARN_NE(...) DOCTEST_WARN_NE(__VA_ARGS__) +#define CHECK_NE(...) DOCTEST_CHECK_NE(__VA_ARGS__) +#define REQUIRE_NE(...) DOCTEST_REQUIRE_NE(__VA_ARGS__) +#define WARN_GT(...) DOCTEST_WARN_GT(__VA_ARGS__) +#define CHECK_GT(...) DOCTEST_CHECK_GT(__VA_ARGS__) +#define REQUIRE_GT(...) DOCTEST_REQUIRE_GT(__VA_ARGS__) +#define WARN_LT(...) DOCTEST_WARN_LT(__VA_ARGS__) +#define CHECK_LT(...) DOCTEST_CHECK_LT(__VA_ARGS__) +#define REQUIRE_LT(...) DOCTEST_REQUIRE_LT(__VA_ARGS__) +#define WARN_GE(...) DOCTEST_WARN_GE(__VA_ARGS__) +#define CHECK_GE(...) DOCTEST_CHECK_GE(__VA_ARGS__) +#define REQUIRE_GE(...) DOCTEST_REQUIRE_GE(__VA_ARGS__) +#define WARN_LE(...) DOCTEST_WARN_LE(__VA_ARGS__) +#define CHECK_LE(...) DOCTEST_CHECK_LE(__VA_ARGS__) +#define REQUIRE_LE(...) DOCTEST_REQUIRE_LE(__VA_ARGS__) +#define WARN_UNARY(...) DOCTEST_WARN_UNARY(__VA_ARGS__) +#define CHECK_UNARY(...) DOCTEST_CHECK_UNARY(__VA_ARGS__) +#define REQUIRE_UNARY(...) DOCTEST_REQUIRE_UNARY(__VA_ARGS__) +#define WARN_UNARY_FALSE(...) DOCTEST_WARN_UNARY_FALSE(__VA_ARGS__) +#define CHECK_UNARY_FALSE(...) DOCTEST_CHECK_UNARY_FALSE(__VA_ARGS__) +#define REQUIRE_UNARY_FALSE(...) DOCTEST_REQUIRE_UNARY_FALSE(__VA_ARGS__) // KEPT FOR BACKWARDS COMPATIBILITY -#define FAST_WARN_EQ DOCTEST_FAST_WARN_EQ -#define FAST_CHECK_EQ DOCTEST_FAST_CHECK_EQ -#define FAST_REQUIRE_EQ DOCTEST_FAST_REQUIRE_EQ -#define FAST_WARN_NE DOCTEST_FAST_WARN_NE -#define FAST_CHECK_NE DOCTEST_FAST_CHECK_NE -#define FAST_REQUIRE_NE DOCTEST_FAST_REQUIRE_NE -#define FAST_WARN_GT DOCTEST_FAST_WARN_GT -#define FAST_CHECK_GT DOCTEST_FAST_CHECK_GT -#define FAST_REQUIRE_GT DOCTEST_FAST_REQUIRE_GT -#define FAST_WARN_LT DOCTEST_FAST_WARN_LT -#define FAST_CHECK_LT DOCTEST_FAST_CHECK_LT -#define FAST_REQUIRE_LT DOCTEST_FAST_REQUIRE_LT -#define FAST_WARN_GE DOCTEST_FAST_WARN_GE -#define FAST_CHECK_GE DOCTEST_FAST_CHECK_GE -#define FAST_REQUIRE_GE DOCTEST_FAST_REQUIRE_GE -#define FAST_WARN_LE DOCTEST_FAST_WARN_LE -#define FAST_CHECK_LE DOCTEST_FAST_CHECK_LE -#define FAST_REQUIRE_LE DOCTEST_FAST_REQUIRE_LE +#define FAST_WARN_EQ(...) DOCTEST_FAST_WARN_EQ(__VA_ARGS__) +#define FAST_CHECK_EQ(...) DOCTEST_FAST_CHECK_EQ(__VA_ARGS__) +#define FAST_REQUIRE_EQ(...) DOCTEST_FAST_REQUIRE_EQ(__VA_ARGS__) +#define FAST_WARN_NE(...) DOCTEST_FAST_WARN_NE(__VA_ARGS__) +#define FAST_CHECK_NE(...) DOCTEST_FAST_CHECK_NE(__VA_ARGS__) +#define FAST_REQUIRE_NE(...) DOCTEST_FAST_REQUIRE_NE(__VA_ARGS__) +#define FAST_WARN_GT(...) DOCTEST_FAST_WARN_GT(__VA_ARGS__) +#define FAST_CHECK_GT(...) DOCTEST_FAST_CHECK_GT(__VA_ARGS__) +#define FAST_REQUIRE_GT(...) DOCTEST_FAST_REQUIRE_GT(__VA_ARGS__) +#define FAST_WARN_LT(...) DOCTEST_FAST_WARN_LT(__VA_ARGS__) +#define FAST_CHECK_LT(...) DOCTEST_FAST_CHECK_LT(__VA_ARGS__) +#define FAST_REQUIRE_LT(...) DOCTEST_FAST_REQUIRE_LT(__VA_ARGS__) +#define FAST_WARN_GE(...) DOCTEST_FAST_WARN_GE(__VA_ARGS__) +#define FAST_CHECK_GE(...) DOCTEST_FAST_CHECK_GE(__VA_ARGS__) +#define FAST_REQUIRE_GE(...) DOCTEST_FAST_REQUIRE_GE(__VA_ARGS__) +#define FAST_WARN_LE(...) DOCTEST_FAST_WARN_LE(__VA_ARGS__) +#define FAST_CHECK_LE(...) DOCTEST_FAST_CHECK_LE(__VA_ARGS__) +#define FAST_REQUIRE_LE(...) DOCTEST_FAST_REQUIRE_LE(__VA_ARGS__) -#define FAST_WARN_UNARY DOCTEST_FAST_WARN_UNARY -#define FAST_CHECK_UNARY DOCTEST_FAST_CHECK_UNARY -#define FAST_REQUIRE_UNARY DOCTEST_FAST_REQUIRE_UNARY -#define FAST_WARN_UNARY_FALSE DOCTEST_FAST_WARN_UNARY_FALSE -#define FAST_CHECK_UNARY_FALSE DOCTEST_FAST_CHECK_UNARY_FALSE -#define FAST_REQUIRE_UNARY_FALSE DOCTEST_FAST_REQUIRE_UNARY_FALSE +#define FAST_WARN_UNARY(...) DOCTEST_FAST_WARN_UNARY(__VA_ARGS__) +#define FAST_CHECK_UNARY(...) DOCTEST_FAST_CHECK_UNARY(__VA_ARGS__) +#define FAST_REQUIRE_UNARY(...) DOCTEST_FAST_REQUIRE_UNARY(__VA_ARGS__) +#define FAST_WARN_UNARY_FALSE(...) DOCTEST_FAST_WARN_UNARY_FALSE(__VA_ARGS__) +#define FAST_CHECK_UNARY_FALSE(...) DOCTEST_FAST_CHECK_UNARY_FALSE(__VA_ARGS__) +#define FAST_REQUIRE_UNARY_FALSE(...) DOCTEST_FAST_REQUIRE_UNARY_FALSE(__VA_ARGS__) -#define TEST_CASE_TEMPLATE_INSTANTIATE DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE +#define TEST_CASE_TEMPLATE_INSTANTIATE(id, ...) DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE(id, __VA_ARGS__) #endif // DOCTEST_CONFIG_NO_SHORT_MACRO_NAMES @@ -2674,6 +2746,7 @@ DOCTEST_CLANG_SUPPRESS_WARNING("-Wmissing-field-initializers") DOCTEST_CLANG_SUPPRESS_WARNING("-Wc++98-compat") DOCTEST_CLANG_SUPPRESS_WARNING("-Wc++98-compat-pedantic") DOCTEST_CLANG_SUPPRESS_WARNING("-Wunused-member-function") +DOCTEST_CLANG_SUPPRESS_WARNING("-Wnonportable-system-include-path") DOCTEST_GCC_SUPPRESS_WARNING_PUSH DOCTEST_GCC_SUPPRESS_WARNING("-Wunknown-pragmas") @@ -2754,9 +2827,7 @@ DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_BEGIN #include #include #include -#ifdef DOCTEST_CONFIG_POSIX_SIGNALS #include -#endif // DOCTEST_CONFIG_POSIX_SIGNALS #include #include #include @@ -2781,11 +2852,7 @@ DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_BEGIN #ifdef __AFXDLL #include #else -#if defined(__MINGW32__) || defined(__MINGW64__) #include -#else // MINGW -#include -#endif // MINGW #endif #include @@ -2821,12 +2888,24 @@ DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_END #define DOCTEST_THREAD_LOCAL thread_local #endif +#ifndef DOCTEST_MULTI_LANE_ATOMICS_THREAD_LANES +#define DOCTEST_MULTI_LANE_ATOMICS_THREAD_LANES 32 +#endif + +#ifndef DOCTEST_MULTI_LANE_ATOMICS_CACHE_LINE_SIZE +#define DOCTEST_MULTI_LANE_ATOMICS_CACHE_LINE_SIZE 64 +#endif + #ifdef DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS #define DOCTEST_OPTIONS_PREFIX_DISPLAY DOCTEST_CONFIG_OPTIONS_PREFIX #else #define DOCTEST_OPTIONS_PREFIX_DISPLAY "" #endif +#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) +#define DOCTEST_CONFIG_NO_MULTI_LANE_ATOMICS +#endif + namespace doctest { bool is_running_in_test = false; @@ -2959,18 +3038,105 @@ typedef timer_large_integer::type ticks_t; ticks_t m_ticks = 0; }; +#ifdef DOCTEST_CONFIG_NO_MULTI_LANE_ATOMICS + template + using AtomicOrMultiLaneAtomic = std::atomic; +#else // DOCTEST_CONFIG_NO_MULTI_LANE_ATOMICS + // Provides a multilane implementation of an atomic variable that supports add, sub, load, + // store. Instead of using a single atomic variable, this splits up into multiple ones, + // each sitting on a separate cache line. The goal is to provide a speedup when most + // operations are modifying. It achieves this with two properties: + // + // * Multiple atomics are used, so chance of congestion from the same atomic is reduced. + // * Each atomic sits on a separate cache line, so false sharing is reduced. + // + // The disadvantage is that there is a small overhead due to the use of TLS, and load/store + // is slower because all atomics have to be accessed. + template + class MultiLaneAtomic + { + struct CacheLineAlignedAtomic + { + std::atomic atomic{}; + char padding[DOCTEST_MULTI_LANE_ATOMICS_CACHE_LINE_SIZE - sizeof(std::atomic)]; + }; + CacheLineAlignedAtomic m_atomics[DOCTEST_MULTI_LANE_ATOMICS_THREAD_LANES]; + + static_assert(sizeof(CacheLineAlignedAtomic) == DOCTEST_MULTI_LANE_ATOMICS_CACHE_LINE_SIZE, + "guarantee one atomic takes exactly one cache line"); + + public: + T operator++() DOCTEST_NOEXCEPT { return fetch_add(1) + 1; } + + T operator++(int) DOCTEST_NOEXCEPT { return fetch_add(1); } + + T fetch_add(T arg, std::memory_order order = std::memory_order_seq_cst) DOCTEST_NOEXCEPT { + return myAtomic().fetch_add(arg, order); + } + + T fetch_sub(T arg, std::memory_order order = std::memory_order_seq_cst) DOCTEST_NOEXCEPT { + return myAtomic().fetch_sub(arg, order); + } + + operator T() const DOCTEST_NOEXCEPT { return load(); } + + T load(std::memory_order order = std::memory_order_seq_cst) const DOCTEST_NOEXCEPT { + auto result = T(); + for(auto const& c : m_atomics) { + result += c.atomic.load(order); + } + return result; + } + + T operator=(T desired) DOCTEST_NOEXCEPT { + store(desired); + return desired; + } + + void store(T desired, std::memory_order order = std::memory_order_seq_cst) DOCTEST_NOEXCEPT { + // first value becomes desired", all others become 0. + for(auto& c : m_atomics) { + c.atomic.store(desired, order); + desired = {}; + } + } + + private: + // Each thread has a different atomic that it operates on. If more than NumLanes threads + // use this, some will use the same atomic. So performance will degrate a bit, but still + // everything will work. + // + // The logic here is a bit tricky. The call should be as fast as possible, so that there + // is minimal to no overhead in determining the correct atomic for the current thread. + // + // 1. A global static counter laneCounter counts continuously up. + // 2. Each successive thread will use modulo operation of that counter so it gets an atomic + // assigned in a round-robin fashion. + // 3. This tlsLaneIdx is stored in the thread local data, so it is directly available with + // little overhead. + std::atomic& myAtomic() DOCTEST_NOEXCEPT { + static std::atomic laneCounter; + DOCTEST_THREAD_LOCAL size_t tlsLaneIdx = + laneCounter++ % DOCTEST_MULTI_LANE_ATOMICS_THREAD_LANES; + + return m_atomics[tlsLaneIdx].atomic; + } + }; + + template + using AtomicOrMultiLaneAtomic = MultiLaneAtomic; +#endif // DOCTEST_CONFIG_NO_MULTI_LANE_ATOMICS + // this holds both parameters from the command line and runtime data for tests struct ContextState : ContextOptions, TestRunStats, CurrentTestCaseStats { - std::atomic numAssertsCurrentTest_atomic; - std::atomic numAssertsFailedCurrentTest_atomic; + AtomicOrMultiLaneAtomic numAssertsCurrentTest_atomic; + AtomicOrMultiLaneAtomic numAssertsFailedCurrentTest_atomic; std::vector> filters = decltype(filters)(9); // 9 different filters std::vector reporters_currently_used; - const TestCase* currentTest = nullptr; - assert_handler ah = nullptr; Timer timer; @@ -3071,6 +3237,7 @@ String::String() { String::~String() { if(!isOnStack()) delete[] data.ptr; + // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) } String::String(const char* in) @@ -3079,14 +3246,16 @@ String::String(const char* in) String::String(const char* in, unsigned in_size) { using namespace std; if(in_size <= last) { - memcpy(buf, in, in_size + 1); + memcpy(buf, in, in_size); + buf[in_size] = '\0'; setLast(last - in_size); } else { setOnHeap(); data.size = in_size; data.capacity = data.size + 1; data.ptr = new char[data.capacity]; - memcpy(data.ptr, in, in_size + 1); + memcpy(data.ptr, in, in_size); + data.ptr[in_size] = '\0'; } } @@ -3112,6 +3281,7 @@ String& String::operator+=(const String& other) { if(total_size < len) { // append to the current stack space memcpy(buf + my_old_size, other.c_str(), other_size + 1); + // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) setLast(last - total_size); } else { // alloc new chunk @@ -3153,6 +3323,7 @@ String& String::operator+=(const String& other) { return *this; } +// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) String String::operator+(const String& other) const { return String(*this) += other; } String::String(String&& other) { @@ -3307,6 +3478,7 @@ DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wnull-dereference") DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wnull-dereference") // depending on the current options this will remove the path of filenames const char* skipPathFromFilename(const char* file) { +#ifndef DOCTEST_CONFIG_DISABLE if(getContextOptions()->no_path_in_filenames) { auto back = std::strrchr(file, '\\'); auto forward = std::strrchr(file, '/'); @@ -3316,6 +3488,7 @@ const char* skipPathFromFilename(const char* file) { return forward + 1; } } +#endif // DOCTEST_CONFIG_DISABLE return file; } DOCTEST_CLANG_SUPPRESS_WARNING_POP @@ -3334,6 +3507,7 @@ IContextScope::~IContextScope() = default; #ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING String toString(char* in) { return toString(static_cast(in)); } +// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) String toString(const char* in) { return String("\"") + (in ? in : "{null string}") + "\""; } #endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING String toString(bool in) { return in ? "true" : "false"; } @@ -3406,6 +3580,7 @@ bool operator>(double lhs, const Approx& rhs) { return lhs > rhs.m_value && lhs bool operator>(const Approx& lhs, double rhs) { return lhs.m_value > rhs && lhs != rhs; } String toString(const Approx& in) { + // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) return String("Approx( ") + doctest::toString(in.m_value) + " )"; } const ContextOptions* getContextOptions() { return DOCTEST_BRANCH_ON_DISABLED(nullptr, g_cs); } @@ -3451,7 +3626,7 @@ int registerReporter(const char*, int, IReporter*) { return 0; } namespace doctest_detail_test_suite_ns { // holds the current test suite doctest::detail::TestSuite& getCurrentTestSuite() { - static doctest::detail::TestSuite data; + static doctest::detail::TestSuite data{}; return data; } } // namespace doctest_detail_test_suite_ns @@ -3563,7 +3738,7 @@ namespace detail { Subcase::Subcase(const String& name, const char* file, int line) : m_signature({name, file, line}) { - ContextState* s = g_cs; + auto* s = g_cs; // check subcase filters if(s->subcasesStack.size() < size_t(s->subcase_filter_levels)) { @@ -3605,7 +3780,7 @@ namespace detail { g_cs->subcasesPassed.insert(g_cs->subcasesStack); g_cs->subcasesStack.pop_back(); -#if defined(__cpp_lib_uncaught_exceptions) && __cpp_lib_uncaught_exceptions >= 201411L +#if defined(__cpp_lib_uncaught_exceptions) && __cpp_lib_uncaught_exceptions >= 201411L && (!defined(__MAC_OS_X_VERSION_MIN_REQUIRED) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200) if(std::uncaught_exceptions() > 0 #else if(std::uncaught_exception() @@ -3640,6 +3815,8 @@ namespace detail { // clear state m_description = nullptr; m_skip = false; + m_no_breaks = false; + m_no_output = false; m_may_fail = false; m_should_fail = false; m_expected_failures = 0; @@ -3655,6 +3832,8 @@ namespace detail { m_test_suite = test_suite.m_test_suite; m_description = test_suite.m_description; m_skip = test_suite.m_skip; + m_no_breaks = test_suite.m_no_breaks; + m_no_output = test_suite.m_no_output; m_may_fail = test_suite.m_may_fail; m_should_fail = test_suite.m_should_fail; m_expected_failures = test_suite.m_expected_failures; @@ -3698,13 +3877,23 @@ namespace detail { } bool TestCase::operator<(const TestCase& other) const { + // this will be used only to differentiate between test cases - not relevant for sorting if(m_line != other.m_line) return m_line < other.m_line; + const int name_cmp = strcmp(m_name, other.m_name); + if(name_cmp != 0) + return name_cmp < 0; const int file_cmp = m_file.compare(other.m_file); if(file_cmp != 0) return file_cmp < 0; return m_template_id < other.m_template_id; } + + // all the registered tests + std::set& getRegisteredTests() { + static std::set data; + return data; + } } // namespace detail namespace { using namespace detail; @@ -3736,12 +3925,6 @@ namespace { return suiteOrderComparator(lhs, rhs); } - // all the registered tests - std::set& getRegisteredTests() { - static std::set data; - return data; - } - #ifdef DOCTEST_CONFIG_COLORS_WINDOWS HANDLE g_stdoutHandle; WORD g_origFgAttrs; @@ -3970,7 +4153,7 @@ namespace detail { // ContextScope has been destroyed (base class destructors run after derived class destructors). // Instead, ContextScope calls this method directly from its destructor. void ContextScopeBase::destroy() { -#if defined(__cpp_lib_uncaught_exceptions) && __cpp_lib_uncaught_exceptions >= 201411L +#if defined(__cpp_lib_uncaught_exceptions) && __cpp_lib_uncaught_exceptions >= 201411L && (!defined(__MAC_OS_X_VERSION_MIN_REQUIRED) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200) if(std::uncaught_exceptions() > 0) { #else if(std::uncaught_exception()) { @@ -3992,7 +4175,9 @@ namespace { #if !defined(DOCTEST_CONFIG_POSIX_SIGNALS) && !defined(DOCTEST_CONFIG_WINDOWS_SEH) struct FatalConditionHandler { - void reset() {} + static void reset() {} + static void allocateAltStackMem() {} + static void freeAltStackMem() {} }; #else // DOCTEST_CONFIG_POSIX_SIGNALS || DOCTEST_CONFIG_WINDOWS_SEH @@ -4009,26 +4194,45 @@ namespace { // Windows can easily distinguish between SO and SigSegV, // but SigInt, SigTerm, etc are handled differently. SignalDefs signalDefs[] = { - {EXCEPTION_ILLEGAL_INSTRUCTION, "SIGILL - Illegal instruction signal"}, - {EXCEPTION_STACK_OVERFLOW, "SIGSEGV - Stack overflow"}, - {EXCEPTION_ACCESS_VIOLATION, "SIGSEGV - Segmentation violation signal"}, - {EXCEPTION_INT_DIVIDE_BY_ZERO, "Divide by zero error"}, + {static_cast(EXCEPTION_ILLEGAL_INSTRUCTION), + "SIGILL - Illegal instruction signal"}, + {static_cast(EXCEPTION_STACK_OVERFLOW), "SIGSEGV - Stack overflow"}, + {static_cast(EXCEPTION_ACCESS_VIOLATION), + "SIGSEGV - Segmentation violation signal"}, + {static_cast(EXCEPTION_INT_DIVIDE_BY_ZERO), "Divide by zero error"}, }; struct FatalConditionHandler { static LONG CALLBACK handleException(PEXCEPTION_POINTERS ExceptionInfo) { - for(size_t i = 0; i < DOCTEST_COUNTOF(signalDefs); ++i) { - if(ExceptionInfo->ExceptionRecord->ExceptionCode == signalDefs[i].id) { - reportFatal(signalDefs[i].name); - break; + // Multiple threads may enter this filter/handler at once. We want the error message to be printed on the + // console just once no matter how many threads have crashed. + static std::mutex mutex; + static bool execute = true; + { + std::lock_guard lock(mutex); + if(execute) { + bool reported = false; + for(size_t i = 0; i < DOCTEST_COUNTOF(signalDefs); ++i) { + if(ExceptionInfo->ExceptionRecord->ExceptionCode == signalDefs[i].id) { + reportFatal(signalDefs[i].name); + reported = true; + break; + } + } + if(reported == false) + reportFatal("Unhandled SEH exception caught"); + if(isDebuggerActive() && !g_cs->no_breaks) + DOCTEST_BREAK_INTO_DEBUGGER(); } + execute = false; } - // If its not an exception we care about, pass it along. - // This stops us from eating debugger breaks etc. - return EXCEPTION_CONTINUE_SEARCH; + std::exit(EXIT_FAILURE); } + static void allocateAltStackMem() {} + static void freeAltStackMem() {} + FatalConditionHandler() { isSet = true; // 32k seems enough for doctest to handle stack overflow, @@ -4038,6 +4242,51 @@ namespace { previousTop = SetUnhandledExceptionFilter(handleException); // Pass in guarantee size to be filled SetThreadStackGuarantee(&guaranteeSize); + + // On Windows uncaught exceptions from another thread, exceptions from + // destructors, or calls to std::terminate are not a SEH exception + + // The terminal handler gets called when: + // - std::terminate is called FROM THE TEST RUNNER THREAD + // - an exception is thrown from a destructor FROM THE TEST RUNNER THREAD + original_terminate_handler = std::get_terminate(); + std::set_terminate([]() DOCTEST_NOEXCEPT { + reportFatal("Terminate handler called"); + if(isDebuggerActive() && !g_cs->no_breaks) + DOCTEST_BREAK_INTO_DEBUGGER(); + std::exit(EXIT_FAILURE); // explicitly exit - otherwise the SIGABRT handler may be called as well + }); + + // SIGABRT is raised when: + // - std::terminate is called FROM A DIFFERENT THREAD + // - an exception is thrown from a destructor FROM A DIFFERENT THREAD + // - an uncaught exception is thrown FROM A DIFFERENT THREAD + prev_sigabrt_handler = std::signal(SIGABRT, [](int signal) DOCTEST_NOEXCEPT { + if(signal == SIGABRT) { + reportFatal("SIGABRT - Abort (abnormal termination) signal"); + if(isDebuggerActive() && !g_cs->no_breaks) + DOCTEST_BREAK_INTO_DEBUGGER(); + std::exit(EXIT_FAILURE); + } + }); + + // The following settings are taken from google test, and more + // specifically from UnitTest::Run() inside of gtest.cc + + // the user does not want to see pop-up dialogs about crashes + prev_error_mode_1 = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT | + SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); + // This forces the abort message to go to stderr in all circumstances. + prev_error_mode_2 = _set_error_mode(_OUT_TO_STDERR); + // In the debug version, Visual Studio pops up a separate dialog + // offering a choice to debug the aborted program - we want to disable that. + prev_abort_behavior = _set_abort_behavior(0x0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); + // In debug mode, the Windows CRT can crash with an assertion over invalid + // input (e.g. passing an invalid file descriptor). The default handling + // for these assertions is to pop up a dialog and wait for user input. + // Instead ask the CRT to dump such assertions to stderr non-interactively. + prev_report_mode = _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG); + prev_report_file = _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR); } static void reset() { @@ -4045,7 +4294,13 @@ namespace { // Unregister handler and restore the old guarantee SetUnhandledExceptionFilter(previousTop); SetThreadStackGuarantee(&guaranteeSize); - previousTop = nullptr; + std::set_terminate(original_terminate_handler); + std::signal(SIGABRT, prev_sigabrt_handler); + SetErrorMode(prev_error_mode_1); + _set_error_mode(prev_error_mode_2); + _set_abort_behavior(prev_abort_behavior, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); + static_cast(_CrtSetReportMode(_CRT_ASSERT, prev_report_mode)); + static_cast(_CrtSetReportFile(_CRT_ASSERT, prev_report_file)); isSet = false; } } @@ -4053,11 +4308,25 @@ namespace { ~FatalConditionHandler() { reset(); } private: + static UINT prev_error_mode_1; + static int prev_error_mode_2; + static unsigned int prev_abort_behavior; + static int prev_report_mode; + static _HFILE prev_report_file; + static void (*prev_sigabrt_handler)(int); + static std::terminate_handler original_terminate_handler; static bool isSet; static ULONG guaranteeSize; static LPTOP_LEVEL_EXCEPTION_FILTER previousTop; }; + UINT FatalConditionHandler::prev_error_mode_1; + int FatalConditionHandler::prev_error_mode_2; + unsigned int FatalConditionHandler::prev_abort_behavior; + int FatalConditionHandler::prev_report_mode; + _HFILE FatalConditionHandler::prev_report_file; + void (*FatalConditionHandler::prev_sigabrt_handler)(int); + std::terminate_handler FatalConditionHandler::original_terminate_handler; bool FatalConditionHandler::isSet = false; ULONG FatalConditionHandler::guaranteeSize = 0; LPTOP_LEVEL_EXCEPTION_FILTER FatalConditionHandler::previousTop = nullptr; @@ -4081,7 +4350,8 @@ namespace { static bool isSet; static struct sigaction oldSigActions[DOCTEST_COUNTOF(signalDefs)]; static stack_t oldSigStack; - static char altStackMem[4 * SIGSTKSZ]; + static size_t altStackSize; + static char* altStackMem; static void handleSignal(int sig) { const char* name = ""; @@ -4097,11 +4367,19 @@ namespace { raise(sig); } + static void allocateAltStackMem() { + altStackMem = new char[altStackSize]; + } + + static void freeAltStackMem() { + delete[] altStackMem; + } + FatalConditionHandler() { isSet = true; stack_t sigStack; sigStack.ss_sp = altStackMem; - sigStack.ss_size = sizeof(altStackMem); + sigStack.ss_size = altStackSize; sigStack.ss_flags = 0; sigaltstack(&sigStack, &oldSigStack); struct sigaction sa = {}; @@ -4126,10 +4404,11 @@ namespace { } }; - bool FatalConditionHandler::isSet = false; + bool FatalConditionHandler::isSet = false; struct sigaction FatalConditionHandler::oldSigActions[DOCTEST_COUNTOF(signalDefs)] = {}; - stack_t FatalConditionHandler::oldSigStack = {}; - char FatalConditionHandler::altStackMem[] = {}; + stack_t FatalConditionHandler::oldSigStack = {}; + size_t FatalConditionHandler::altStackSize = 4 * SIGSTKSZ; + char* FatalConditionHandler::altStackMem = nullptr; #endif // DOCTEST_PLATFORM_WINDOWS #endif // DOCTEST_CONFIG_POSIX_SIGNALS || DOCTEST_CONFIG_WINDOWS_SEH @@ -4231,8 +4510,8 @@ namespace detail { failed_out_of_a_testing_context(*this); } - return m_failed && isDebuggerActive() && - !getContextOptions()->no_breaks; // break into debugger + return m_failed && isDebuggerActive() && !getContextOptions()->no_breaks && + (g_cs->currentTest == nullptr || !g_cs->currentTest->m_no_breaks); // break into debugger } void ResultBuilder::react() const { @@ -4257,6 +4536,7 @@ namespace detail { // ################################################################################### DOCTEST_ASSERT_OUT_OF_TESTS(result.m_decomp); DOCTEST_ASSERT_IN_TESTS(result.m_decomp); + // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) } MessageBuilder::MessageBuilder(const char* file, int line, assertType::Enum severity) { @@ -4281,7 +4561,8 @@ namespace detail { addFailedAssert(m_severity); } - return isDebuggerActive() && !getContextOptions()->no_breaks && !isWarn; // break + return isDebuggerActive() && !getContextOptions()->no_breaks && !isWarn && + (g_cs->currentTest == nullptr || !g_cs->currentTest->m_no_breaks); // break into debugger } void MessageBuilder::react() { @@ -4979,7 +5260,6 @@ namespace { } // TODO: - // - log_contexts() // - log_message() // - respond to queries // - honor remaining options @@ -4993,7 +5273,6 @@ namespace { struct JUnitTestCaseData { -DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations") // gmtime static std::string getCurrentTimestamp() { // Beware, this is not reentrant because of backward compatibility issues // Also, UTC only, again because of backward compatibility (%z is C++11) @@ -5001,16 +5280,19 @@ DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations") // gmtime std::time(&rawtime); auto const timeStampSize = sizeof("2017-01-16T17:06:45Z"); - std::tm* timeInfo; - timeInfo = std::gmtime(&rawtime); + std::tm timeInfo; +#ifdef DOCTEST_PLATFORM_WINDOWS + gmtime_s(&timeInfo, &rawtime); +#else // DOCTEST_PLATFORM_WINDOWS + gmtime_r(&rawtime, &timeInfo); +#endif // DOCTEST_PLATFORM_WINDOWS char timeStamp[timeStampSize]; const char* const fmt = "%Y-%m-%dT%H:%M:%SZ"; - std::strftime(timeStamp, timeStampSize, fmt, timeInfo); + std::strftime(timeStamp, timeStampSize, fmt, &timeInfo); return std::string(timeStamp); } -DOCTEST_CLANG_SUPPRESS_WARNING_POP struct JUnitTestMessage { @@ -5175,12 +5457,27 @@ DOCTEST_CLANG_SUPPRESS_WARNING_POP << line(rb.m_line) << (opt.gnu_file_line ? ":" : "):") << std::endl; fulltext_log_assert_to_stream(os, rb); + log_contexts(os); testCaseData.addFailure(rb.m_decomp.c_str(), assertString(rb.m_at), os.str()); } void log_message(const MessageData&) override {} void test_case_skipped(const TestCaseData&) override {} + + void log_contexts(std::ostringstream& s) { + int num_contexts = get_num_active_contexts(); + if(num_contexts) { + auto contexts = get_active_contexts(); + + s << " logged: "; + for(int i = 0; i < num_contexts; ++i) { + s << (i == 0 ? "" : " "); + contexts[i]->stringify(&s); + s << std::endl; + } + } + } }; DOCTEST_REGISTER_REPORTER("junit", 0, JUnitReporter); @@ -5373,7 +5670,7 @@ DOCTEST_CLANG_SUPPRESS_WARNING_POP << Whitespace(sizePrefixDisplay*1) << "output filename\n"; s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "ob, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "order-by= " << Whitespace(sizePrefixDisplay*1) << "how the tests should be ordered\n"; - s << Whitespace(sizePrefixDisplay*3) << " - by [file/suite/name/rand]\n"; + s << Whitespace(sizePrefixDisplay*3) << " - [file/suite/name/rand/none]\n"; s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "rs, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "rand-seed= " << Whitespace(sizePrefixDisplay*1) << "seed for random ordering\n"; s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "f, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "first= " @@ -5546,6 +5843,9 @@ DOCTEST_CLANG_SUPPRESS_WARNING_POP } void test_case_end(const CurrentTestCaseStats& st) override { + if(tc->m_no_output) + return; + // log the preamble of the test case only if there is something // else to print - something other than that an assert has failed if(opt.duration || @@ -5580,6 +5880,9 @@ DOCTEST_CLANG_SUPPRESS_WARNING_POP } void test_case_exception(const TestCaseException& e) override { + if(tc->m_no_output) + return; + logTestStart(); file_line_to_stream(tc->m_file.c_str(), tc->m_line, " "); @@ -5614,7 +5917,7 @@ DOCTEST_CLANG_SUPPRESS_WARNING_POP } void log_assert(const AssertData& rb) override { - if(!rb.m_failed && !opt.success) + if((!rb.m_failed && !opt.success) || tc->m_no_output) return; std::lock_guard lock(mutex); @@ -5630,6 +5933,9 @@ DOCTEST_CLANG_SUPPRESS_WARNING_POP } void log_message(const MessageData& mb) override { + if(tc->m_no_output) + return; + std::lock_guard lock(mutex); logTestStart(); @@ -5660,8 +5966,10 @@ DOCTEST_CLANG_SUPPRESS_WARNING_POP bool with_col = g_no_colors; \ g_no_colors = false; \ ConsoleReporter::func(arg); \ - DOCTEST_OUTPUT_DEBUG_STRING(oss.str().c_str()); \ - oss.str(""); \ + if(oss.tellp() != std::streampos{}) { \ + DOCTEST_OUTPUT_DEBUG_STRING(oss.str().c_str()); \ + oss.str(""); \ + } \ g_no_colors = with_col; \ } @@ -5848,7 +6156,7 @@ void Context::parseArgs(int argc, const char* const* argv, bool withDefaults) { #define DOCTEST_PARSE_AS_BOOL_OR_FLAG(name, sname, var, default) \ if(parseIntOption(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX name "=", option_bool, intRes) || \ parseIntOption(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX sname "=", option_bool, intRes)) \ - p->var = !!intRes; \ + p->var = static_cast(intRes); \ else if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX name) || \ parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX sname)) \ p->var = true; \ @@ -5894,6 +6202,7 @@ void Context::parseArgs(int argc, const char* const* argv, bool withDefaults) { DOCTEST_PARSE_AS_BOOL_OR_FLAG("gnu-file-line", "gfl", gnu_file_line, !bool(DOCTEST_MSVC)); DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-path-filenames", "npf", no_path_in_filenames, false); DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-line-numbers", "nln", no_line_numbers, false); + DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-debug-output", "ndo", no_debug_output, false); DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-skipped-summary", "nss", no_skipped_summary, false); DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-time-in-output", "ntio", no_time_in_output, false); // clang-format on @@ -5951,6 +6260,7 @@ void Context::clearFilters() { // allows the user to override procedurally the int/bool options from the command line void Context::setOption(const char* option, int value) { setOption(option, toString(value).c_str()); + // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) } // allows the user to override procedurally the string options from the command line @@ -5991,7 +6301,11 @@ int Context::run() { p->cout = &fstr; } + FatalConditionHandler::allocateAltStackMem(); + auto cleanup_and_return = [&]() { + FatalConditionHandler::freeAltStackMem(); + if(fstr.is_open()) fstr.close(); @@ -6026,7 +6340,7 @@ int Context::run() { p->reporters_currently_used.insert(p->reporters_currently_used.begin(), curr.second(*g_cs)); #ifdef DOCTEST_PLATFORM_WINDOWS - if(isDebuggerActive()) + if(isDebuggerActive() && p->no_debug_output == false) p->reporters_currently_used.push_back(new DebugOutputWindowReporter(*g_cs)); #endif // DOCTEST_PLATFORM_WINDOWS @@ -6063,6 +6377,9 @@ int Context::run() { first[i] = first[idxToSwap]; first[idxToSwap] = temp; } + } else if(p->order_by.compare("none", true) == 0) { + // means no sorting - beneficial for death tests which call into the executable + // with a specific test case in mind - we don't want to slow down the startup times } } @@ -6162,10 +6479,13 @@ int Context::run() { #ifndef DOCTEST_CONFIG_NO_EXCEPTIONS try { #endif // DOCTEST_CONFIG_NO_EXCEPTIONS +// MSVC 2015 diagnoses fatalConditionHandler as unused (because reset() is a static method) +DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4101) // unreferenced local variable FatalConditionHandler fatalConditionHandler; // Handle signals // execute the test tc.m_test(); fatalConditionHandler.reset(); +DOCTEST_MSVC_SUPPRESS_WARNING_POP #ifndef DOCTEST_CONFIG_NO_EXCEPTIONS } catch(const TestFailureException&) { p->failure_flags |= TestCaseFailureReason::AssertFailure; From d1c9bc40d88d8cb9c5e17a6e114d05e0f2a264a4 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Wed, 30 Jun 2021 01:02:11 +0700 Subject: [PATCH 004/233] fix doctest building --- untests/doctest/doctest.hpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/untests/doctest/doctest.hpp b/untests/doctest/doctest.hpp index 2c0032e..139d4b6 100644 --- a/untests/doctest/doctest.hpp +++ b/untests/doctest/doctest.hpp @@ -2,6 +2,9 @@ #include "doctest.h" +// https://github.com/onqtam/doctest/issues/126 +#include + #define STATIC_CHECK(...)\ static_assert(__VA_ARGS__, #__VA_ARGS__);\ CHECK(__VA_ARGS__) From bcd0c3ec77005772c756138508b14159f67c3848 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Wed, 30 Jun 2021 02:37:45 +0700 Subject: [PATCH 005/233] separate info and registry classes --- headers/meta.hpp/meta.hpp | 12 +- headers/meta.hpp/meta_class.hpp | 65 +-------- headers/meta.hpp/meta_class_info.hpp | 74 ++++++++++ headers/meta.hpp/meta_field.hpp | 89 +----------- headers/meta.hpp/meta_field_info.hpp | 98 ++++++++++++++ headers/meta.hpp/meta_function.hpp | 96 +------------ headers/meta.hpp/meta_function_info.hpp | 105 +++++++++++++++ headers/meta.hpp/meta_fwd.hpp | 1 - headers/meta.hpp/meta_method.hpp | 156 +-------------------- headers/meta.hpp/meta_method_info.hpp | 165 +++++++++++++++++++++++ headers/meta.hpp/meta_namespace.hpp | 56 +------- headers/meta.hpp/meta_namespace_info.hpp | 65 +++++++++ headers/meta.hpp/meta_registry.hpp | 46 ------- headers/meta.hpp/meta_variable.hpp | 86 +----------- headers/meta.hpp/meta_variable_info.hpp | 95 +++++++++++++ untests/meta_class_tests.cpp | 5 + untests/meta_examples.cpp | 38 +++--- untests/meta_namespace_tests.cpp | 4 + untests/meta_registry_tests.cpp | 67 --------- 19 files changed, 645 insertions(+), 678 deletions(-) create mode 100644 headers/meta.hpp/meta_class_info.hpp create mode 100644 headers/meta.hpp/meta_field_info.hpp create mode 100644 headers/meta.hpp/meta_function_info.hpp create mode 100644 headers/meta.hpp/meta_method_info.hpp create mode 100644 headers/meta.hpp/meta_namespace_info.hpp delete mode 100644 headers/meta.hpp/meta_registry.hpp create mode 100644 headers/meta.hpp/meta_variable_info.hpp delete mode 100644 untests/meta_registry_tests.cpp diff --git a/headers/meta.hpp/meta.hpp b/headers/meta.hpp/meta.hpp index 5a55fac..04605e9 100644 --- a/headers/meta.hpp/meta.hpp +++ b/headers/meta.hpp/meta.hpp @@ -9,11 +9,21 @@ #include "meta_fwd.hpp" #include "meta_value.hpp" -#include "meta_registry.hpp" #include "meta_class.hpp" +#include "meta_class_info.hpp" + #include "meta_field.hpp" +#include "meta_field_info.hpp" + #include "meta_function.hpp" +#include "meta_function_info.hpp" + #include "meta_method.hpp" +#include "meta_method_info.hpp" + #include "meta_namespace.hpp" +#include "meta_namespace_info.hpp" + #include "meta_variable.hpp" +#include "meta_variable_info.hpp" diff --git a/headers/meta.hpp/meta_class.hpp b/headers/meta.hpp/meta_class.hpp index 134431f..b7362ae 100644 --- a/headers/meta.hpp/meta_class.hpp +++ b/headers/meta.hpp/meta_class.hpp @@ -8,70 +8,7 @@ #include "meta_fwd.hpp" -#include "meta_field.hpp" -#include "meta_function.hpp" -#include "meta_method.hpp" -#include "meta_variable.hpp" - -namespace meta_hpp -{ - class class_info { - public: - class_info() = delete; - - class_info(class_info&&) = default; - class_info(const class_info&) = default; - - class_info& operator=(class_info&&) = default; - class_info& operator=(const class_info&) = default; - - class_info(std::string id) - : id_(std::move(id)) {} - - const std::string& id() const noexcept { - return id_; - } - - std::optional get_class(std::string_view id) const { - return detail::find_opt(classes_, id); - } - - std::optional get_field(std::string_view id) const { - return detail::find_opt(fields_, id); - } - - std::optional get_function(std::string_view id) const { - return detail::find_opt(functions_, id); - } - - std::optional get_method(std::string_view id) const { - return detail::find_opt(methods_, id); - } - - std::optional get_variable(std::string_view id) const { - return detail::find_opt(variables_, id); - } - private: - friend class namespace_info; - template < typename Class > friend class class_; - friend class namespace_; - private: - void merge_with_(const class_info& other) { - detail::merge_with(classes_, other.classes_, &class_info::merge_with_); - detail::merge_with(fields_, other.fields_, &field_info::merge_with_); - detail::merge_with(functions_, other.functions_, &function_info::merge_with_); - detail::merge_with(methods_, other.methods_, &method_info::merge_with_); - detail::merge_with(variables_, other.variables_, &variable_info::merge_with_); - } - private: - std::string id_; - std::map> classes_; - std::map> fields_; - std::map> functions_; - std::map> methods_; - std::map> variables_; - }; -} +#include "meta_class_info.hpp" namespace meta_hpp { diff --git a/headers/meta.hpp/meta_class_info.hpp b/headers/meta.hpp/meta_class_info.hpp new file mode 100644 index 0000000..8964d70 --- /dev/null +++ b/headers/meta.hpp/meta_class_info.hpp @@ -0,0 +1,74 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "meta_fwd.hpp" + +#include "meta_field_info.hpp" +#include "meta_function_info.hpp" +#include "meta_method_info.hpp" +#include "meta_variable_info.hpp" + +namespace meta_hpp +{ + class class_info { + public: + class_info() = delete; + + class_info(class_info&&) = default; + class_info(const class_info&) = default; + + class_info& operator=(class_info&&) = default; + class_info& operator=(const class_info&) = default; + + class_info(std::string id) + : id_(std::move(id)) {} + + const std::string& id() const noexcept { + return id_; + } + + std::optional get_class(std::string_view id) const { + return detail::find_opt(classes_, id); + } + + std::optional get_field(std::string_view id) const { + return detail::find_opt(fields_, id); + } + + std::optional get_function(std::string_view id) const { + return detail::find_opt(functions_, id); + } + + std::optional get_method(std::string_view id) const { + return detail::find_opt(methods_, id); + } + + std::optional get_variable(std::string_view id) const { + return detail::find_opt(variables_, id); + } + private: + friend class namespace_info; + template < typename Class > friend class class_; + friend class namespace_; + private: + void merge_with_(const class_info& other) { + detail::merge_with(classes_, other.classes_, &class_info::merge_with_); + detail::merge_with(fields_, other.fields_, &field_info::merge_with_); + detail::merge_with(functions_, other.functions_, &function_info::merge_with_); + detail::merge_with(methods_, other.methods_, &method_info::merge_with_); + detail::merge_with(variables_, other.variables_, &variable_info::merge_with_); + } + private: + std::string id_; + std::map> classes_; + std::map> fields_; + std::map> functions_; + std::map> methods_; + std::map> variables_; + }; +} diff --git a/headers/meta.hpp/meta_field.hpp b/headers/meta.hpp/meta_field.hpp index 1cba987..228fc0f 100644 --- a/headers/meta.hpp/meta_field.hpp +++ b/headers/meta.hpp/meta_field.hpp @@ -8,94 +8,7 @@ #include "meta_fwd.hpp" -#include "meta_value.hpp" - -namespace meta_hpp::field_detail -{ - template < typename Field > - struct field_traits; - - template < typename T, typename Base > - struct field_traits { - static constexpr bool is_const = false; - using value_type = T; - using instance_type = Base; - }; - - template < typename T, typename Base > - struct field_traits - : field_traits { - static constexpr bool is_const = true; - }; - - template < auto Field > - value getter(const void* instance) { - using ft = field_traits; - using value_type = typename ft::value_type; - using instance_type = typename ft::instance_type; - - auto instance_ptr = static_cast(instance); - value_type typed_value = std::invoke(Field, *instance_ptr); - - return value{std::move(typed_value)}; - } - - template < auto Field > - void setter([[maybe_unused]] void* instance, value value) { - using ft = field_traits; - using value_type = typename ft::value_type; - using instance_type = typename ft::instance_type; - - if constexpr ( !ft::is_const ) { - auto instance_ptr = static_cast(instance); - std::invoke(Field, *instance_ptr) = value.cast(); - } else { - throw std::logic_error("an attempt to change a constant field"); - } - } -} - -namespace meta_hpp -{ - class field_info { - public: - field_info() = delete; - - field_info(field_info&&) = default; - field_info(const field_info&) = default; - - field_info& operator=(field_info&&) = default; - field_info& operator=(const field_info&) = default; - - field_info(std::string id) - : id_(std::move(id)) {} - - const std::string& id() const noexcept { - return id_; - } - public: - value get(const void* instance) const { - return getter_(instance); - } - - template < typename Value > - void set(void* instance, Value&& value) const { - return setter_(instance, std::forward(value)); - } - private: - friend class class_info; - template < typename Class > friend class class_; - template < auto Field > friend class field_; - private: - void merge_with_(const field_info& other) { - (void)other; - } - private: - std::string id_; - value(*getter_)(const void*); - void(*setter_)(void*, value); - }; -} +#include "meta_field_info.hpp" namespace meta_hpp { diff --git a/headers/meta.hpp/meta_field_info.hpp b/headers/meta.hpp/meta_field_info.hpp new file mode 100644 index 0000000..0bfc86e --- /dev/null +++ b/headers/meta.hpp/meta_field_info.hpp @@ -0,0 +1,98 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "meta_fwd.hpp" + +#include "meta_value.hpp" + +namespace meta_hpp::field_detail +{ + template < typename Field > + struct field_traits; + + template < typename T, typename Base > + struct field_traits { + static constexpr bool is_const = false; + using value_type = T; + using instance_type = Base; + }; + + template < typename T, typename Base > + struct field_traits + : field_traits { + static constexpr bool is_const = true; + }; + + template < auto Field > + value getter(const void* instance) { + using ft = field_traits; + using value_type = typename ft::value_type; + using instance_type = typename ft::instance_type; + + auto instance_ptr = static_cast(instance); + value_type typed_value = std::invoke(Field, *instance_ptr); + + return value{std::move(typed_value)}; + } + + template < auto Field > + void setter([[maybe_unused]] void* instance, value value) { + using ft = field_traits; + using value_type = typename ft::value_type; + using instance_type = typename ft::instance_type; + + if constexpr ( !ft::is_const ) { + auto instance_ptr = static_cast(instance); + std::invoke(Field, *instance_ptr) = value.cast(); + } else { + throw std::logic_error("an attempt to change a constant field"); + } + } +} + +namespace meta_hpp +{ + class field_info { + public: + field_info() = delete; + + field_info(field_info&&) = default; + field_info(const field_info&) = default; + + field_info& operator=(field_info&&) = default; + field_info& operator=(const field_info&) = default; + + field_info(std::string id) + : id_(std::move(id)) {} + + const std::string& id() const noexcept { + return id_; + } + public: + value get(const void* instance) const { + return getter_(instance); + } + + template < typename Value > + void set(void* instance, Value&& value) const { + return setter_(instance, std::forward(value)); + } + private: + friend class class_info; + template < typename Class > friend class class_; + template < auto Field > friend class field_; + private: + void merge_with_(const field_info& other) { + (void)other; + } + private: + std::string id_; + value(*getter_)(const void*); + void(*setter_)(void*, value); + }; +} diff --git a/headers/meta.hpp/meta_function.hpp b/headers/meta.hpp/meta_function.hpp index e11b333..c87be3f 100644 --- a/headers/meta.hpp/meta_function.hpp +++ b/headers/meta.hpp/meta_function.hpp @@ -8,101 +8,7 @@ #include "meta_fwd.hpp" -#include "meta_value.hpp" - -namespace meta_hpp::function_detail -{ - template < typename Function > - struct function_traits; - - template < typename R, typename... Args > - struct function_traits { - static constexpr std::size_t arity = sizeof...(Args); - using return_type = R; - using argument_types = std::tuple; - }; - - template < typename R, typename... Args > - struct function_traits - : function_traits {}; - - template < auto Function, std::size_t... Is > - value invoke(value* args, std::index_sequence) { - using ft = function_traits; - using return_type = typename ft::return_type; - using argument_types = typename ft::argument_types; - - [[maybe_unused]] auto typed_arguments = std::make_tuple( - (args + Is)->try_cast>()...); - - if ( !(std::get(typed_arguments) && ...) ) { - throw std::logic_error("an attempt to call a function with incorrect argument types"); - } - - if constexpr ( std::is_void_v ) { - std::invoke(Function, - *std::get(typed_arguments)...); - return value{}; - } else { - return_type return_value = std::invoke(Function, - *std::get(typed_arguments)...); - return value{std::move(return_value)}; - } - } - - template < auto Function > - value invoke(value* args, std::size_t arg_count) { - using ft = function_traits; - - if ( arg_count != ft::arity ) { - throw std::logic_error("an attempt to call a function with an incorrect arity"); - } - - return invoke(args, std::make_index_sequence()); - } -} - -namespace meta_hpp -{ - class function_info { - public: - function_info() = delete; - - function_info(function_info&&) = default; - function_info(const function_info&) = default; - - function_info& operator=(function_info&&) = default; - function_info& operator=(const function_info&) = default; - - function_info(std::string id) - : id_(std::move(id)) {} - - const std::string& id() const noexcept { - return id_; - } - public: - template < typename... Args > - value invoke(Args&&... args) const { - std::array vargs{{std::forward(args)...}}; - return invoke_(vargs.data(), vargs.size()); - } - private: - friend class class_info; - friend class namespace_info; - - template < typename Class > friend class class_; - friend class namespace_; - - template < auto Function > friend class function_; - private: - void merge_with_(const function_info& other) { - (void)other; - } - private: - std::string id_; - value(*invoke_)(value*, std::size_t); - }; -} +#include "meta_function_info.hpp" namespace meta_hpp { diff --git a/headers/meta.hpp/meta_function_info.hpp b/headers/meta.hpp/meta_function_info.hpp new file mode 100644 index 0000000..5e95977 --- /dev/null +++ b/headers/meta.hpp/meta_function_info.hpp @@ -0,0 +1,105 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "meta_fwd.hpp" + +#include "meta_value.hpp" + +namespace meta_hpp::function_detail +{ + template < typename Function > + struct function_traits; + + template < typename R, typename... Args > + struct function_traits { + static constexpr std::size_t arity = sizeof...(Args); + using return_type = R; + using argument_types = std::tuple; + }; + + template < typename R, typename... Args > + struct function_traits + : function_traits {}; + + template < auto Function, std::size_t... Is > + value invoke(value* args, std::index_sequence) { + using ft = function_traits; + using return_type = typename ft::return_type; + using argument_types = typename ft::argument_types; + + [[maybe_unused]] auto typed_arguments = std::make_tuple( + (args + Is)->try_cast>()...); + + if ( !(std::get(typed_arguments) && ...) ) { + throw std::logic_error("an attempt to call a function with incorrect argument types"); + } + + if constexpr ( std::is_void_v ) { + std::invoke(Function, + *std::get(typed_arguments)...); + return value{}; + } else { + return_type return_value = std::invoke(Function, + *std::get(typed_arguments)...); + return value{std::move(return_value)}; + } + } + + template < auto Function > + value invoke(value* args, std::size_t arg_count) { + using ft = function_traits; + + if ( arg_count != ft::arity ) { + throw std::logic_error("an attempt to call a function with an incorrect arity"); + } + + return invoke(args, std::make_index_sequence()); + } +} + +namespace meta_hpp +{ + class function_info { + public: + function_info() = delete; + + function_info(function_info&&) = default; + function_info(const function_info&) = default; + + function_info& operator=(function_info&&) = default; + function_info& operator=(const function_info&) = default; + + function_info(std::string id) + : id_(std::move(id)) {} + + const std::string& id() const noexcept { + return id_; + } + public: + template < typename... Args > + value invoke(Args&&... args) const { + std::array vargs{{std::forward(args)...}}; + return invoke_(vargs.data(), vargs.size()); + } + private: + friend class class_info; + friend class namespace_info; + + template < typename Class > friend class class_; + friend class namespace_; + + template < auto Function > friend class function_; + private: + void merge_with_(const function_info& other) { + (void)other; + } + private: + std::string id_; + value(*invoke_)(value*, std::size_t); + }; +} diff --git a/headers/meta.hpp/meta_fwd.hpp b/headers/meta.hpp/meta_fwd.hpp index cc304c8..7ba6e3d 100644 --- a/headers/meta.hpp/meta_fwd.hpp +++ b/headers/meta.hpp/meta_fwd.hpp @@ -21,7 +21,6 @@ namespace meta_hpp { class value; - class registry; class class_info; class field_info; diff --git a/headers/meta.hpp/meta_method.hpp b/headers/meta.hpp/meta_method.hpp index 8ce683a..1447385 100644 --- a/headers/meta.hpp/meta_method.hpp +++ b/headers/meta.hpp/meta_method.hpp @@ -8,161 +8,7 @@ #include "meta_fwd.hpp" -#include "meta_value.hpp" - -namespace meta_hpp::method_detail -{ - template < typename Method > - struct method_traits; - - template < typename R, typename Base, typename... Args > - struct method_traits { - static constexpr bool is_const = false; - static constexpr std::size_t arity = sizeof...(Args); - using return_type = R; - using instance_type = Base; - using argument_types = std::tuple; - }; - - template < typename R, typename Base, typename... Args > - struct method_traits - : method_traits { - static constexpr bool is_const = true; - }; - - template < typename R, typename Base, typename... Args > - struct method_traits - : method_traits {}; - - template < typename R, typename Base, typename... Args > - struct method_traits - : method_traits {}; - - template < auto Method, std::size_t... Is > - value 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; - using argument_types = typename mt::argument_types; - - [[maybe_unused]] auto typed_arguments = std::make_tuple( - (args + Is)->try_cast>()...); - - if ( !(std::get(typed_arguments) && ...) ) { - throw std::logic_error("an attempt to call a method with incorrect argument types"); - } - - if constexpr ( std::is_void_v ) { - std::invoke(Method, - std::ref(*static_cast(instance)), - *std::get(typed_arguments)...); - return value{}; - } else { - return_type return_value = std::invoke(Method, - std::ref(*static_cast(instance)), - *std::get(typed_arguments)...); - return value{std::move(return_value)}; - } - } - - template < auto Method > - value invoke(void* instance, value* args, std::size_t arg_count) { - using mt = method_traits; - - if ( arg_count != mt::arity ) { - throw std::logic_error("an attempt to call a method with an incorrect arity"); - } - - return invoke(instance, args, std::make_index_sequence()); - } - - template < auto Method, std::size_t... Is > - value 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; - using argument_types = typename mt::argument_types; - - [[maybe_unused]] auto typed_arguments = std::make_tuple( - (args + Is)->try_cast>()...); - - if ( !(std::get(typed_arguments) && ...) ) { - throw std::logic_error("an attempt to call a method with incorrect argument types"); - } - - if constexpr ( mt::is_const ) { - if constexpr ( std::is_void_v ) { - std::invoke(Method, - std::ref(*static_cast(instance)), - *std::get(typed_arguments)...); - return value{}; - } else { - return_type return_value = std::invoke(Method, - std::ref(*static_cast(instance)), - *std::get(typed_arguments)...); - return value{std::move(return_value)}; - } - } else { - throw std::logic_error("an attempt to call a non-constant method by constant instance"); - } - } - - template < auto Method > - value cinvoke(const void* instance, value* args, std::size_t arg_count) { - using mt = method_traits; - - if ( arg_count != mt::arity ) { - throw std::logic_error("an attempt to call a method with a different arity"); - } - - return cinvoke(instance, args, std::make_index_sequence()); - } -} - -namespace meta_hpp -{ - class method_info { - public: - method_info() = delete; - - method_info(method_info&&) = default; - method_info(const method_info&) = default; - - method_info& operator=(method_info&&) = default; - method_info& operator=(const method_info&) = default; - - method_info(std::string id) - : id_(std::move(id)) {} - - const std::string& id() const noexcept { - return id_; - } - public: - template < typename... Args > - value 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::array vargs{{std::forward(args)...}}; - return cinvoke_(instance, vargs.data(), vargs.size()); - } - private: - friend class class_info; - template < typename Class > friend class class_; - template < auto Method > friend class method_; - private: - void merge_with_(const method_info& other) { - (void)other; - } - private: - std::string id_; - value(*invoke_)(void*, value*, std::size_t); - value(*cinvoke_)(const void*, value*, std::size_t); - }; -} +#include "meta_method_info.hpp" namespace meta_hpp { diff --git a/headers/meta.hpp/meta_method_info.hpp b/headers/meta.hpp/meta_method_info.hpp new file mode 100644 index 0000000..3fca6c2 --- /dev/null +++ b/headers/meta.hpp/meta_method_info.hpp @@ -0,0 +1,165 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "meta_fwd.hpp" + +#include "meta_value.hpp" + +namespace meta_hpp::method_detail +{ + template < typename Method > + struct method_traits; + + template < typename R, typename Base, typename... Args > + struct method_traits { + static constexpr bool is_const = false; + static constexpr std::size_t arity = sizeof...(Args); + using return_type = R; + using instance_type = Base; + using argument_types = std::tuple; + }; + + template < typename R, typename Base, typename... Args > + struct method_traits + : method_traits { + static constexpr bool is_const = true; + }; + + template < typename R, typename Base, typename... Args > + struct method_traits + : method_traits {}; + + template < typename R, typename Base, typename... Args > + struct method_traits + : method_traits {}; + + template < auto Method, std::size_t... Is > + value 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; + using argument_types = typename mt::argument_types; + + [[maybe_unused]] auto typed_arguments = std::make_tuple( + (args + Is)->try_cast>()...); + + if ( !(std::get(typed_arguments) && ...) ) { + throw std::logic_error("an attempt to call a method with incorrect argument types"); + } + + if constexpr ( std::is_void_v ) { + std::invoke(Method, + std::ref(*static_cast(instance)), + *std::get(typed_arguments)...); + return value{}; + } else { + return_type return_value = std::invoke(Method, + std::ref(*static_cast(instance)), + *std::get(typed_arguments)...); + return value{std::move(return_value)}; + } + } + + template < auto Method > + value invoke(void* instance, value* args, std::size_t arg_count) { + using mt = method_traits; + + if ( arg_count != mt::arity ) { + throw std::logic_error("an attempt to call a method with an incorrect arity"); + } + + return invoke(instance, args, std::make_index_sequence()); + } + + template < auto Method, std::size_t... Is > + value 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; + using argument_types = typename mt::argument_types; + + [[maybe_unused]] auto typed_arguments = std::make_tuple( + (args + Is)->try_cast>()...); + + if ( !(std::get(typed_arguments) && ...) ) { + throw std::logic_error("an attempt to call a method with incorrect argument types"); + } + + if constexpr ( mt::is_const ) { + if constexpr ( std::is_void_v ) { + std::invoke(Method, + std::ref(*static_cast(instance)), + *std::get(typed_arguments)...); + return value{}; + } else { + return_type return_value = std::invoke(Method, + std::ref(*static_cast(instance)), + *std::get(typed_arguments)...); + return value{std::move(return_value)}; + } + } else { + throw std::logic_error("an attempt to call a non-constant method by constant instance"); + } + } + + template < auto Method > + value cinvoke(const void* instance, value* args, std::size_t arg_count) { + using mt = method_traits; + + if ( arg_count != mt::arity ) { + throw std::logic_error("an attempt to call a method with a different arity"); + } + + return cinvoke(instance, args, std::make_index_sequence()); + } +} + +namespace meta_hpp +{ + class method_info { + public: + method_info() = delete; + + method_info(method_info&&) = default; + method_info(const method_info&) = default; + + method_info& operator=(method_info&&) = default; + method_info& operator=(const method_info&) = default; + + method_info(std::string id) + : id_(std::move(id)) {} + + const std::string& id() const noexcept { + return id_; + } + public: + template < typename... Args > + value 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::array vargs{{std::forward(args)...}}; + return cinvoke_(instance, vargs.data(), vargs.size()); + } + private: + friend class class_info; + template < typename Class > friend class class_; + template < auto Method > friend class method_; + private: + void merge_with_(const method_info& other) { + (void)other; + } + private: + std::string id_; + value(*invoke_)(void*, value*, std::size_t); + value(*cinvoke_)(const void*, value*, std::size_t); + }; +} diff --git a/headers/meta.hpp/meta_namespace.hpp b/headers/meta.hpp/meta_namespace.hpp index 895e1e4..e3280a9 100644 --- a/headers/meta.hpp/meta_namespace.hpp +++ b/headers/meta.hpp/meta_namespace.hpp @@ -8,61 +8,7 @@ #include "meta_fwd.hpp" -#include "meta_class.hpp" -#include "meta_function.hpp" -#include "meta_variable.hpp" - -namespace meta_hpp -{ - class namespace_info { - public: - namespace_info() = delete; - - namespace_info(namespace_info&&) = default; - namespace_info(const namespace_info&) = default; - - namespace_info& operator=(namespace_info&&) = default; - namespace_info& operator=(const namespace_info&) = default; - - namespace_info(std::string id) - : id_(std::move(id)) {} - - const std::string& id() const noexcept { - return id_; - } - - std::optional get_class(std::string_view id) const { - return detail::find_opt(classes_, id); - } - - std::optional get_function(std::string_view id) const { - return detail::find_opt(functions_, id); - } - - std::optional get_namespace(std::string_view id) const { - return detail::find_opt(namespaces_, id); - } - - std::optional get_variable(std::string_view id) const { - return detail::find_opt(variables_, id); - } - private: - friend class namespace_; - private: - void merge_with_(const namespace_info& other) { - detail::merge_with(classes_, other.classes_, &class_info::merge_with_); - detail::merge_with(functions_, other.functions_, &function_info::merge_with_); - detail::merge_with(namespaces_, other.namespaces_, &namespace_info::merge_with_); - detail::merge_with(variables_, other.variables_, &variable_info::merge_with_); - } - private: - std::string id_; - std::map> classes_; - std::map> functions_; - std::map> namespaces_; - std::map> variables_; - }; -} +#include "meta_namespace_info.hpp" namespace meta_hpp { diff --git a/headers/meta.hpp/meta_namespace_info.hpp b/headers/meta.hpp/meta_namespace_info.hpp new file mode 100644 index 0000000..4ad5bb2 --- /dev/null +++ b/headers/meta.hpp/meta_namespace_info.hpp @@ -0,0 +1,65 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "meta_fwd.hpp" + +#include "meta_class_info.hpp" +#include "meta_function_info.hpp" +#include "meta_variable_info.hpp" + +namespace meta_hpp +{ + class namespace_info { + public: + namespace_info() = delete; + + namespace_info(namespace_info&&) = default; + namespace_info(const namespace_info&) = default; + + namespace_info& operator=(namespace_info&&) = default; + namespace_info& operator=(const namespace_info&) = default; + + namespace_info(std::string id) + : id_(std::move(id)) {} + + const std::string& id() const noexcept { + return id_; + } + + std::optional get_class(std::string_view id) const { + return detail::find_opt(classes_, id); + } + + std::optional get_function(std::string_view id) const { + return detail::find_opt(functions_, id); + } + + std::optional get_namespace(std::string_view id) const { + return detail::find_opt(namespaces_, id); + } + + std::optional get_variable(std::string_view id) const { + return detail::find_opt(variables_, id); + } + private: + friend class namespace_; + private: + void merge_with_(const namespace_info& other) { + detail::merge_with(classes_, other.classes_, &class_info::merge_with_); + detail::merge_with(functions_, other.functions_, &function_info::merge_with_); + detail::merge_with(namespaces_, other.namespaces_, &namespace_info::merge_with_); + detail::merge_with(variables_, other.variables_, &variable_info::merge_with_); + } + private: + std::string id_; + std::map> classes_; + std::map> functions_; + std::map> namespaces_; + std::map> variables_; + }; +} diff --git a/headers/meta.hpp/meta_registry.hpp b/headers/meta.hpp/meta_registry.hpp deleted file mode 100644 index b2f43ce..0000000 --- a/headers/meta.hpp/meta_registry.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "meta_fwd.hpp" - -#include "meta_class.hpp" -#include "meta_function.hpp" -#include "meta_namespace.hpp" -#include "meta_variable.hpp" - -namespace meta_hpp -{ - class registry { - public: - registry() = default; - - template < typename... Internals > - registry& operator()(Internals&&...internals) { - default_namespace_(std::forward(internals)...); - return *this; - } - - std::optional get_class(std::string_view id) const { - return default_namespace_.info().get_class(id); - } - - std::optional get_function(std::string_view id) const { - return default_namespace_.info().get_function(id); - } - - std::optional get_namespace(std::string_view id) const { - return default_namespace_.info().get_namespace(id); - } - - std::optional get_variable(std::string_view id) const { - return default_namespace_.info().get_variable(id); - } - private: - namespace_ default_namespace_{""}; - }; -} diff --git a/headers/meta.hpp/meta_variable.hpp b/headers/meta.hpp/meta_variable.hpp index 0b840a6..78fe289 100644 --- a/headers/meta.hpp/meta_variable.hpp +++ b/headers/meta.hpp/meta_variable.hpp @@ -8,91 +8,7 @@ #include "meta_fwd.hpp" -#include "meta_value.hpp" - -namespace meta_hpp::variable_detail -{ - template < typename Variable > - struct variable_traits; - - template < typename T > - struct variable_traits { - static constexpr bool is_const = false; - using value_type = T; - }; - - template < typename T > - struct variable_traits { - static constexpr bool is_const = true; - using value_type = T; - }; - - template < auto Variable > - value getter() { - using vt = variable_traits; - using value_type = typename vt::value_type; - - value_type typed_value = *Variable; - - return value{std::move(typed_value)}; - } - - template < auto Variable > - void setter(value value) { - using vt = variable_traits; - using value_type = typename vt::value_type; - - if constexpr ( !vt::is_const ) { - *Variable = value.cast(); - } else { - throw std::logic_error("an attempt to change a constant variable"); - } - } -} - -namespace meta_hpp -{ - class variable_info { - public: - variable_info() = delete; - - variable_info(variable_info&&) = default; - variable_info(const variable_info&) = default; - - variable_info& operator=(variable_info&&) = default; - variable_info& operator=(const variable_info&) = default; - - variable_info(std::string id) - : id_(std::move(id)) {} - - const std::string& id() const noexcept { - return id_; - } - public: - value get() const { - return getter_(); - } - - template < typename Value > - void set(Value&& value) const { - return setter_(std::forward(value)); - } - private: - friend class class_info; - friend class namespace_info; - template < typename Class > friend class class_; - friend class namespace_; - template < auto Variable > friend class variable_; - private: - void merge_with_(const variable_info& other) { - (void)other; - } - private: - std::string id_; - value(*getter_)(); - void(*setter_)(value); - }; -} +#include "meta_variable_info.hpp" namespace meta_hpp { diff --git a/headers/meta.hpp/meta_variable_info.hpp b/headers/meta.hpp/meta_variable_info.hpp new file mode 100644 index 0000000..f9c6767 --- /dev/null +++ b/headers/meta.hpp/meta_variable_info.hpp @@ -0,0 +1,95 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "meta_fwd.hpp" + +#include "meta_value.hpp" + +namespace meta_hpp::variable_detail +{ + template < typename Variable > + struct variable_traits; + + template < typename T > + struct variable_traits { + static constexpr bool is_const = false; + using value_type = T; + }; + + template < typename T > + struct variable_traits { + static constexpr bool is_const = true; + using value_type = T; + }; + + template < auto Variable > + value getter() { + using vt = variable_traits; + using value_type = typename vt::value_type; + + value_type typed_value = *Variable; + + return value{std::move(typed_value)}; + } + + template < auto Variable > + void setter(value value) { + using vt = variable_traits; + using value_type = typename vt::value_type; + + if constexpr ( !vt::is_const ) { + *Variable = value.cast(); + } else { + throw std::logic_error("an attempt to change a constant variable"); + } + } +} + +namespace meta_hpp +{ + class variable_info { + public: + variable_info() = delete; + + variable_info(variable_info&&) = default; + variable_info(const variable_info&) = default; + + variable_info& operator=(variable_info&&) = default; + variable_info& operator=(const variable_info&) = default; + + variable_info(std::string id) + : id_(std::move(id)) {} + + const std::string& id() const noexcept { + return id_; + } + public: + value get() const { + return getter_(); + } + + template < typename Value > + void set(Value&& value) const { + return setter_(std::forward(value)); + } + private: + friend class class_info; + friend class namespace_info; + template < typename Class > friend class class_; + friend class namespace_; + template < auto Variable > friend class variable_; + private: + void merge_with_(const variable_info& other) { + (void)other; + } + private: + std::string id_; + value(*getter_)(); + void(*setter_)(value); + }; +} diff --git a/untests/meta_class_tests.cpp b/untests/meta_class_tests.cpp index d399e53..4cdc650 100644 --- a/untests/meta_class_tests.cpp +++ b/untests/meta_class_tests.cpp @@ -5,6 +5,11 @@ ******************************************************************************/ #include +#include +#include +#include +#include + #include "doctest/doctest.hpp" namespace diff --git a/untests/meta_examples.cpp b/untests/meta_examples.cpp index 4df1896..e8332e7 100644 --- a/untests/meta_examples.cpp +++ b/untests/meta_examples.cpp @@ -87,27 +87,23 @@ TEST_CASE("meta/examples/ivec3") { TEST_CASE("meta/examples/simple") { namespace meta = meta_hpp; - auto registry = meta::registry{}( - meta::namespace_("vmath")( - meta::class_("ivec2")( - meta::field_<&ivec2::x>("x"), - meta::field_<&ivec2::y>("y"), - meta::method_<&ivec2::dot>("dot"), - meta::method_<&ivec2::length2>("length2") - ), - meta::class_("ivec3")( - meta::field_<&ivec3::x>("x"), - meta::field_<&ivec3::y>("y"), - meta::field_<&ivec3::z>("z"), - meta::method_<&ivec3::dot>("dot"), - meta::method_<&ivec3::length2>("length2") - ), - meta::function_(&add)>("iadd2"), - meta::function_(&add)>("iadd3") - ) - ); - - meta::namespace_info vmath_info = registry.get_namespace("vmath").value(); + meta::namespace_info vmath_info = meta::namespace_("vmath")( + meta::class_("ivec2")( + meta::field_<&ivec2::x>("x"), + meta::field_<&ivec2::y>("y"), + meta::method_<&ivec2::dot>("dot"), + meta::method_<&ivec2::length2>("length2") + ), + meta::class_("ivec3")( + meta::field_<&ivec3::x>("x"), + meta::field_<&ivec3::y>("y"), + meta::field_<&ivec3::z>("z"), + meta::method_<&ivec3::dot>("dot"), + meta::method_<&ivec3::length2>("length2") + ), + meta::function_(&add)>("iadd2"), + meta::function_(&add)>("iadd3") + ).info(); meta::class_info ivec2_info = vmath_info.get_class("ivec2").value(); meta::field_info ivec2_x_info = ivec2_info.get_field("x").value(); diff --git a/untests/meta_namespace_tests.cpp b/untests/meta_namespace_tests.cpp index 146d71c..e5aca71 100644 --- a/untests/meta_namespace_tests.cpp +++ b/untests/meta_namespace_tests.cpp @@ -4,7 +4,11 @@ * Copyright (C) 2021, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ +#include +#include #include +#include + #include "doctest/doctest.hpp" namespace diff --git a/untests/meta_registry_tests.cpp b/untests/meta_registry_tests.cpp deleted file mode 100644 index e62fc43..0000000 --- a/untests/meta_registry_tests.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/******************************************************************************* - * 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 -#include "doctest/doctest.hpp" - -namespace -{ - class clazz {}; - int func(int a) { return a; } - int variable{1}; - const int cvariable{2}; -} - -TEST_CASE("meta/registry") { - namespace meta = meta_hpp; - - meta::registry registry; - const meta::registry& cregistry = registry; - - CHECK_FALSE(cregistry.get_class("clazz")); - CHECK_FALSE(cregistry.get_function("func")); - CHECK_FALSE(cregistry.get_namespace("ns")); - CHECK_FALSE(cregistry.get_variable("variable")); - CHECK_FALSE(cregistry.get_variable("cvariable")); - - registry( - meta::class_("clazz"), - meta::function_<&func>("func"), - meta::namespace_("ns"), - meta::variable_<&variable>("variable"), - meta::variable_<&cvariable>("cvariable")); - - CHECK(cregistry.get_class("clazz")); - CHECK(cregistry.get_function("func")); - CHECK(cregistry.get_namespace("ns")); - CHECK(cregistry.get_variable("variable")); - CHECK(cregistry.get_variable("cvariable")); - - { - meta::class_info clazz_info = cregistry.get_class("clazz").value(); - CHECK(clazz_info.id() == "clazz"); - } - - { - meta::function_info clazz_info = cregistry.get_function("func").value(); - CHECK(clazz_info.id() == "func"); - } - - { - meta::namespace_info namespace_info = cregistry.get_namespace("ns").value(); - CHECK(namespace_info.id() == "ns"); - } - - { - meta::variable_info variable_info = cregistry.get_variable("variable").value(); - CHECK(variable_info.id() == "variable"); - } - - { - meta::variable_info cvariable_info = cregistry.get_variable("cvariable").value(); - CHECK(cvariable_info.id() == "cvariable"); - } -} From 416ed1962737056f34c22a27dda3434e02377782 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Wed, 30 Jun 2021 18:45:27 +0700 Subject: [PATCH 006/233] namespace merge test --- untests/meta_namespace_tests.cpp | 39 ++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/untests/meta_namespace_tests.cpp b/untests/meta_namespace_tests.cpp index e5aca71..c4438cb 100644 --- a/untests/meta_namespace_tests.cpp +++ b/untests/meta_namespace_tests.cpp @@ -70,3 +70,42 @@ TEST_CASE("meta/namespace") { CHECK(cvariable_info.id() == "cvariable"); } } + +TEST_CASE("meta/namespace/merge") { + namespace meta = meta_hpp; + + meta::namespace_ namespace_{"ns"}; + + namespace_( + meta::namespace_{"ns2"}( + meta::class_{"clazz"}, + meta::function_<&func>("func"), + meta::namespace_{"ns3"}, + meta::variable_<&variable>("variable") + ) + ); + + namespace_( + meta::namespace_{"ns2"}( + meta::class_{"clazz"}, + meta::function_<&func>("func2"), + meta::namespace_{"ns3"}( + meta::namespace_{"ns4"}, + meta::variable_<&variable>("variable2") + ) + ) + ); + + const meta::namespace_info ns2_info = namespace_.info().get_namespace("ns2").value(); + const meta::namespace_info ns3_info = ns2_info.get_namespace("ns3").value(); + + CHECK(ns2_info.get_class("clazz")); + CHECK(ns2_info.get_function("func")); + CHECK(ns2_info.get_function("func2")); + + CHECK(ns2_info.get_namespace("ns3")); + CHECK(ns2_info.get_variable("variable")); + + CHECK(ns3_info.get_namespace("ns4")); + CHECK(ns3_info.get_variable("variable2")); +} From 4616ae46d5099177475a0b6f30c484b442597f24 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Wed, 30 Jun 2021 21:44:51 +0700 Subject: [PATCH 007/233] metadata for infos --- headers/meta.hpp/meta.hpp | 3 ++ headers/meta.hpp/meta_class.hpp | 14 +++++ headers/meta.hpp/meta_class_info.hpp | 11 +++- headers/meta.hpp/meta_data.hpp | 40 +++++++++++++++ headers/meta.hpp/meta_data_info.hpp | 65 ++++++++++++++++++++++++ headers/meta.hpp/meta_field.hpp | 16 ++++++ headers/meta.hpp/meta_field_info.hpp | 16 ++++-- headers/meta.hpp/meta_function.hpp | 16 ++++++ headers/meta.hpp/meta_function_info.hpp | 15 ++++-- headers/meta.hpp/meta_fwd.hpp | 22 +++----- headers/meta.hpp/meta_method.hpp | 16 ++++++ headers/meta.hpp/meta_method_info.hpp | 15 ++++-- headers/meta.hpp/meta_namespace.hpp | 17 ++++++- headers/meta.hpp/meta_namespace_info.hpp | 11 +++- headers/meta.hpp/meta_variable.hpp | 16 ++++++ headers/meta.hpp/meta_variable_info.hpp | 17 +++++-- untests/meta_examples.cpp | 58 +++++++++++++-------- 17 files changed, 310 insertions(+), 58 deletions(-) create mode 100644 headers/meta.hpp/meta_data.hpp create mode 100644 headers/meta.hpp/meta_data_info.hpp diff --git a/headers/meta.hpp/meta.hpp b/headers/meta.hpp/meta.hpp index 04605e9..420cd6b 100644 --- a/headers/meta.hpp/meta.hpp +++ b/headers/meta.hpp/meta.hpp @@ -13,6 +13,9 @@ #include "meta_class.hpp" #include "meta_class_info.hpp" +#include "meta_data.hpp" +#include "meta_data_info.hpp" + #include "meta_field.hpp" #include "meta_field_info.hpp" diff --git a/headers/meta.hpp/meta_class.hpp b/headers/meta.hpp/meta_class.hpp index b7362ae..3d2c155 100644 --- a/headers/meta.hpp/meta_class.hpp +++ b/headers/meta.hpp/meta_class.hpp @@ -8,6 +8,12 @@ #include "meta_fwd.hpp" +#include "meta_data.hpp" +#include "meta_field.hpp" +#include "meta_function.hpp" +#include "meta_method.hpp" +#include "meta_variable.hpp" + #include "meta_class_info.hpp" namespace meta_hpp @@ -37,6 +43,14 @@ namespace meta_hpp &class_info::merge_with_); } + void add_(const data_& internal) { + detail::merge_with( + info_.datas_, + internal.info().id(), + internal.info(), + &data_info::merge_with_); + } + template < auto InternalField > void add_(const field_& internal) { detail::merge_with( diff --git a/headers/meta.hpp/meta_class_info.hpp b/headers/meta.hpp/meta_class_info.hpp index 8964d70..46cc4c5 100644 --- a/headers/meta.hpp/meta_class_info.hpp +++ b/headers/meta.hpp/meta_class_info.hpp @@ -7,7 +7,9 @@ #pragma once #include "meta_fwd.hpp" +#include "meta_value.hpp" +#include "meta_data_info.hpp" #include "meta_field_info.hpp" #include "meta_function_info.hpp" #include "meta_method_info.hpp" @@ -27,7 +29,7 @@ namespace meta_hpp class_info(std::string id) : id_(std::move(id)) {} - + public: const std::string& id() const noexcept { return id_; } @@ -36,6 +38,10 @@ namespace meta_hpp return detail::find_opt(classes_, id); } + std::optional get_data(std::string_view id) const { + return detail::find_opt(datas_, id); + } + std::optional get_field(std::string_view id) const { return detail::find_opt(fields_, id); } @@ -53,11 +59,13 @@ namespace meta_hpp } private: friend class namespace_info; + template < typename Class > friend class class_; friend class namespace_; private: void merge_with_(const class_info& other) { detail::merge_with(classes_, other.classes_, &class_info::merge_with_); + detail::merge_with(datas_, other.datas_, &data_info::merge_with_); detail::merge_with(fields_, other.fields_, &field_info::merge_with_); detail::merge_with(functions_, other.functions_, &function_info::merge_with_); detail::merge_with(methods_, other.methods_, &method_info::merge_with_); @@ -66,6 +74,7 @@ namespace meta_hpp private: std::string id_; std::map> classes_; + std::map> datas_; std::map> fields_; std::map> functions_; std::map> methods_; diff --git a/headers/meta.hpp/meta_data.hpp b/headers/meta.hpp/meta_data.hpp new file mode 100644 index 0000000..5a172b1 --- /dev/null +++ b/headers/meta.hpp/meta_data.hpp @@ -0,0 +1,40 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "meta_fwd.hpp" + +#include "meta_data_info.hpp" + +namespace meta_hpp +{ + class data_ { + public: + explicit data_(std::string id, value value) + : info_(std::move(id), std::move(value)) {} + + const data_info& info() const noexcept { + return info_; + } + + template < typename... Internals > + data_& operator()(Internals&&...internals) { + (add_(std::forward(internals)), ...); + return *this; + } + private: + void add_(const data_& internal) { + detail::merge_with( + info_.datas_, + internal.info().id(), + internal.info(), + &data_info::merge_with_); + } + private: + data_info info_; + }; +} diff --git a/headers/meta.hpp/meta_data_info.hpp b/headers/meta.hpp/meta_data_info.hpp new file mode 100644 index 0000000..0c26133 --- /dev/null +++ b/headers/meta.hpp/meta_data_info.hpp @@ -0,0 +1,65 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "meta_fwd.hpp" +#include "meta_value.hpp" + +namespace meta_hpp +{ + class data_info { + public: + data_info() = delete; + + data_info(data_info&&) = default; + data_info(const data_info&) = default; + + data_info& operator=(data_info&&) = default; + data_info& operator=(const data_info&) = default; + + data_info(std::string id, value value) + : id_(std::move(id)) + , value_(std::move(value)) {} + public: + const std::string& id() const noexcept { + return id_; + } + + const value& get() const noexcept { + return value_; + } + + std::optional get_data(std::string_view id) const { + return detail::find_opt(datas_, id); + } + private: + friend class class_info; + friend class field_info; + friend class function_info; + friend class method_info; + friend class namespace_info; + friend class variable_info; + + template < typename Class > friend class class_; + template < auto Field > friend class field_; + template < auto Function > friend class function_; + template < auto Method > friend class method_; + friend class namespace_; + template < auto Variable > friend class variable_; + + friend class data_; + private: + void merge_with_(const data_info& other) { + value_ = other.value_; + detail::merge_with(datas_, other.datas_, &data_info::merge_with_); + } + private: + std::string id_; + value value_; + std::map> datas_; + }; +} diff --git a/headers/meta.hpp/meta_field.hpp b/headers/meta.hpp/meta_field.hpp index 228fc0f..07c9417 100644 --- a/headers/meta.hpp/meta_field.hpp +++ b/headers/meta.hpp/meta_field.hpp @@ -8,6 +8,8 @@ #include "meta_fwd.hpp" +#include "meta_data.hpp" + #include "meta_field_info.hpp" namespace meta_hpp @@ -26,6 +28,20 @@ namespace meta_hpp const field_info& info() const noexcept { return info_; } + + template < typename... Internals > + field_& operator()(Internals&&...internals) { + (add_(std::forward(internals)), ...); + return *this; + } + private: + void add_(const data_& internal) { + detail::merge_with( + info_.datas_, + internal.info().id(), + internal.info(), + &data_info::merge_with_); + } private: field_info info_; }; diff --git a/headers/meta.hpp/meta_field_info.hpp b/headers/meta.hpp/meta_field_info.hpp index 0bfc86e..8a0a57e 100644 --- a/headers/meta.hpp/meta_field_info.hpp +++ b/headers/meta.hpp/meta_field_info.hpp @@ -7,9 +7,10 @@ #pragma once #include "meta_fwd.hpp" - #include "meta_value.hpp" +#include "meta_data_info.hpp" + namespace meta_hpp::field_detail { template < typename Field > @@ -69,11 +70,10 @@ namespace meta_hpp field_info(std::string id) : id_(std::move(id)) {} - + public: const std::string& id() const noexcept { return id_; } - public: value get(const void* instance) const { return getter_(instance); } @@ -82,17 +82,25 @@ namespace meta_hpp void set(void* instance, Value&& value) const { return setter_(instance, std::forward(value)); } + + std::optional get_data(std::string_view id) const { + return detail::find_opt(datas_, id); + } private: friend class class_info; + template < typename Class > friend class class_; template < auto Field > friend class field_; private: void merge_with_(const field_info& other) { - (void)other; + getter_ = other.getter_; + setter_ = other.setter_; + detail::merge_with(datas_, other.datas_, &data_info::merge_with_); } private: std::string id_; value(*getter_)(const void*); void(*setter_)(void*, value); + std::map> datas_; }; } diff --git a/headers/meta.hpp/meta_function.hpp b/headers/meta.hpp/meta_function.hpp index c87be3f..35d3fe1 100644 --- a/headers/meta.hpp/meta_function.hpp +++ b/headers/meta.hpp/meta_function.hpp @@ -8,6 +8,8 @@ #include "meta_fwd.hpp" +#include "meta_data.hpp" + #include "meta_function_info.hpp" namespace meta_hpp @@ -25,6 +27,20 @@ namespace meta_hpp const function_info& info() const noexcept { return info_; } + + template < typename... Internals > + function_& operator()(Internals&&...internals) { + (add_(std::forward(internals)), ...); + return *this; + } + private: + void add_(const data_& internal) { + detail::merge_with( + info_.datas_, + internal.info().id(), + internal.info(), + &data_info::merge_with_); + } private: function_info info_; }; diff --git a/headers/meta.hpp/meta_function_info.hpp b/headers/meta.hpp/meta_function_info.hpp index 5e95977..c208022 100644 --- a/headers/meta.hpp/meta_function_info.hpp +++ b/headers/meta.hpp/meta_function_info.hpp @@ -7,9 +7,10 @@ #pragma once #include "meta_fwd.hpp" - #include "meta_value.hpp" +#include "meta_data_info.hpp" + namespace meta_hpp::function_detail { template < typename Function > @@ -76,16 +77,20 @@ namespace meta_hpp function_info(std::string id) : id_(std::move(id)) {} - + public: const std::string& id() const noexcept { return id_; } - public: + template < typename... Args > value invoke(Args&&... args) const { std::array vargs{{std::forward(args)...}}; return invoke_(vargs.data(), vargs.size()); } + + std::optional get_data(std::string_view id) const { + return detail::find_opt(datas_, id); + } private: friend class class_info; friend class namespace_info; @@ -96,10 +101,12 @@ namespace meta_hpp template < auto Function > friend class function_; private: void merge_with_(const function_info& other) { - (void)other; + invoke_ = other.invoke_; + detail::merge_with(datas_, other.datas_, &data_info::merge_with_); } private: std::string id_; value(*invoke_)(value*, std::size_t); + std::map> datas_; }; } diff --git a/headers/meta.hpp/meta_fwd.hpp b/headers/meta.hpp/meta_fwd.hpp index 7ba6e3d..ab9ac34 100644 --- a/headers/meta.hpp/meta_fwd.hpp +++ b/headers/meta.hpp/meta_fwd.hpp @@ -23,28 +23,20 @@ namespace meta_hpp class value; class class_info; + class data_info; class field_info; class function_info; class method_info; class namespace_info; class variable_info; - template < typename Class > - class class_; - - template < auto Field > - class field_; - - template < auto Function > - class function_; - - template < auto Method > - class method_; - + template < typename Class > class class_; + class data_; + template < auto Field > class field_; + template < auto Function > class function_; + template < auto Method > class method_; class namespace_; - - template < auto Variable > - class variable_; + template < auto Variable > class variable_; } namespace meta_hpp diff --git a/headers/meta.hpp/meta_method.hpp b/headers/meta.hpp/meta_method.hpp index 1447385..740c7a4 100644 --- a/headers/meta.hpp/meta_method.hpp +++ b/headers/meta.hpp/meta_method.hpp @@ -8,6 +8,8 @@ #include "meta_fwd.hpp" +#include "meta_data.hpp" + #include "meta_method_info.hpp" namespace meta_hpp @@ -26,6 +28,20 @@ namespace meta_hpp const method_info& info() const noexcept { return info_; } + + template < typename... Internals > + method_& operator()(Internals&&...internals) { + (add_(std::forward(internals)), ...); + return *this; + } + private: + void add_(const data_& internal) { + detail::merge_with( + info_.datas_, + internal.info().id(), + internal.info(), + &data_info::merge_with_); + } private: method_info info_; }; diff --git a/headers/meta.hpp/meta_method_info.hpp b/headers/meta.hpp/meta_method_info.hpp index 3fca6c2..9d3758c 100644 --- a/headers/meta.hpp/meta_method_info.hpp +++ b/headers/meta.hpp/meta_method_info.hpp @@ -7,9 +7,10 @@ #pragma once #include "meta_fwd.hpp" - #include "meta_value.hpp" +#include "meta_data_info.hpp" + namespace meta_hpp::method_detail { template < typename Method > @@ -133,11 +134,10 @@ namespace meta_hpp method_info(std::string id) : id_(std::move(id)) {} - + public: const std::string& id() const noexcept { return id_; } - public: template < typename... Args > value invoke(void* instance, Args&&... args) const { std::array vargs{{std::forward(args)...}}; @@ -149,17 +149,24 @@ namespace meta_hpp std::array vargs{{std::forward(args)...}}; return cinvoke_(instance, vargs.data(), vargs.size()); } + + std::optional get_data(std::string_view id) const { + return detail::find_opt(datas_, id); + } private: friend class class_info; template < typename Class > friend class class_; template < auto Method > friend class method_; private: void merge_with_(const method_info& other) { - (void)other; + invoke_ = other.invoke_; + cinvoke_ = other.cinvoke_; + detail::merge_with(datas_, other.datas_, &data_info::merge_with_); } private: std::string id_; value(*invoke_)(void*, value*, std::size_t); value(*cinvoke_)(const void*, value*, std::size_t); + std::map> datas_; }; } diff --git a/headers/meta.hpp/meta_namespace.hpp b/headers/meta.hpp/meta_namespace.hpp index e3280a9..1fd5cb9 100644 --- a/headers/meta.hpp/meta_namespace.hpp +++ b/headers/meta.hpp/meta_namespace.hpp @@ -8,6 +8,11 @@ #include "meta_fwd.hpp" +#include "meta_class.hpp" +#include "meta_data.hpp" +#include "meta_function.hpp" +#include "meta_variable.hpp" + #include "meta_namespace_info.hpp" namespace meta_hpp @@ -36,6 +41,14 @@ namespace meta_hpp &class_info::merge_with_); } + void add_(const data_& internal) { + detail::merge_with( + info_.datas_, + internal.info().id(), + internal.info(), + &data_info::merge_with_); + } + template < auto InternalFunction > void add_(const function_& internal) { detail::merge_with( @@ -53,8 +66,8 @@ namespace meta_hpp &namespace_info::merge_with_); } - template < auto Internalvariable > - void add_(const variable_& internal) { + template < auto InternalVariable > + void add_(const variable_& internal) { detail::merge_with( info_.variables_, internal.info().id(), diff --git a/headers/meta.hpp/meta_namespace_info.hpp b/headers/meta.hpp/meta_namespace_info.hpp index 4ad5bb2..cec5528 100644 --- a/headers/meta.hpp/meta_namespace_info.hpp +++ b/headers/meta.hpp/meta_namespace_info.hpp @@ -7,8 +7,10 @@ #pragma once #include "meta_fwd.hpp" +#include "meta_value.hpp" #include "meta_class_info.hpp" +#include "meta_data_info.hpp" #include "meta_function_info.hpp" #include "meta_variable_info.hpp" @@ -26,15 +28,18 @@ namespace meta_hpp namespace_info(std::string id) : id_(std::move(id)) {} - + public: const std::string& id() const noexcept { return id_; } - std::optional get_class(std::string_view id) const { return detail::find_opt(classes_, id); } + std::optional get_data(std::string_view id) const { + return detail::find_opt(datas_, id); + } + std::optional get_function(std::string_view id) const { return detail::find_opt(functions_, id); } @@ -51,6 +56,7 @@ namespace meta_hpp private: void merge_with_(const namespace_info& other) { detail::merge_with(classes_, other.classes_, &class_info::merge_with_); + detail::merge_with(datas_, other.datas_, &data_info::merge_with_); detail::merge_with(functions_, other.functions_, &function_info::merge_with_); detail::merge_with(namespaces_, other.namespaces_, &namespace_info::merge_with_); detail::merge_with(variables_, other.variables_, &variable_info::merge_with_); @@ -58,6 +64,7 @@ namespace meta_hpp private: std::string id_; std::map> classes_; + std::map> datas_; std::map> functions_; std::map> namespaces_; std::map> variables_; diff --git a/headers/meta.hpp/meta_variable.hpp b/headers/meta.hpp/meta_variable.hpp index 78fe289..7ba050a 100644 --- a/headers/meta.hpp/meta_variable.hpp +++ b/headers/meta.hpp/meta_variable.hpp @@ -8,6 +8,8 @@ #include "meta_fwd.hpp" +#include "meta_data.hpp" + #include "meta_variable_info.hpp" namespace meta_hpp @@ -24,6 +26,20 @@ namespace meta_hpp const variable_info& info() const noexcept { return info_; } + + template < typename... Internals > + variable_& operator()(Internals&&...internals) { + (add_(std::forward(internals)), ...); + return *this; + } + private: + void add_(const data_& internal) { + detail::merge_with( + info_.datas_, + internal.info().id(), + internal.info(), + &data_info::merge_with_); + } private: variable_info info_; }; diff --git a/headers/meta.hpp/meta_variable_info.hpp b/headers/meta.hpp/meta_variable_info.hpp index f9c6767..96e0486 100644 --- a/headers/meta.hpp/meta_variable_info.hpp +++ b/headers/meta.hpp/meta_variable_info.hpp @@ -7,9 +7,10 @@ #pragma once #include "meta_fwd.hpp" - #include "meta_value.hpp" +#include "meta_data_info.hpp" + namespace meta_hpp::variable_detail { template < typename Variable > @@ -64,11 +65,10 @@ namespace meta_hpp variable_info(std::string id) : id_(std::move(id)) {} - + public: const std::string& id() const noexcept { return id_; } - public: value get() const { return getter_(); } @@ -77,19 +77,28 @@ namespace meta_hpp void set(Value&& value) const { return setter_(std::forward(value)); } + + std::optional get_data(std::string_view id) const { + return detail::find_opt(datas_, id); + } private: friend class class_info; friend class namespace_info; + template < typename Class > friend class class_; friend class namespace_; + template < auto Variable > friend class variable_; private: void merge_with_(const variable_info& other) { - (void)other; + getter_ = other.getter_; + setter_ = other.setter_; + detail::merge_with(datas_, other.datas_, &data_info::merge_with_); } private: std::string id_; value(*getter_)(); void(*setter_)(value); + std::map> datas_; }; } diff --git a/untests/meta_examples.cpp b/untests/meta_examples.cpp index e8332e7..e72e439 100644 --- a/untests/meta_examples.cpp +++ b/untests/meta_examples.cpp @@ -85,35 +85,49 @@ TEST_CASE("meta/examples/ivec3") { } TEST_CASE("meta/examples/simple") { - namespace meta = meta_hpp; + using namespace meta_hpp; - meta::namespace_info vmath_info = meta::namespace_("vmath")( - meta::class_("ivec2")( - meta::field_<&ivec2::x>("x"), - meta::field_<&ivec2::y>("y"), - meta::method_<&ivec2::dot>("dot"), - meta::method_<&ivec2::length2>("length2") + namespace_info vmath_info = namespace_("vmath")( + class_("ivec2")( + field_<&ivec2::x>("x")( + data_("tooltip", "x-coordinate field") + ), + field_<&ivec2::y>("y")( + data_("tooltip", "y-coordinate field") + ), + method_<&ivec2::dot>("dot"), + method_<&ivec2::length2>("length2") ), - meta::class_("ivec3")( - meta::field_<&ivec3::x>("x"), - meta::field_<&ivec3::y>("y"), - meta::field_<&ivec3::z>("z"), - meta::method_<&ivec3::dot>("dot"), - meta::method_<&ivec3::length2>("length2") + class_("ivec3")( + field_<&ivec3::x>("x")( + data_("tooltip", "x-coordinate field") + ), + field_<&ivec3::y>("y")( + data_("tooltip", "y-coordinate field") + ), + field_<&ivec3::z>("z")( + data_("tooltip", "z-coordinate field") + ), + method_<&ivec3::dot>("dot"), + method_<&ivec3::length2>("length2") ), - meta::function_(&add)>("iadd2"), - meta::function_(&add)>("iadd3") + function_(&add)>("iadd2"), + function_(&add)>("iadd3") ).info(); - meta::class_info ivec2_info = vmath_info.get_class("ivec2").value(); - meta::field_info ivec2_x_info = ivec2_info.get_field("x").value(); - meta::field_info ivec2_y_info = ivec2_info.get_field("y").value(); + class_info ivec2_info = vmath_info.get_class("ivec2").value(); - meta::method_info ivec2_dot_info = ivec2_info.get_method("dot").value(); - meta::method_info ivec2_length2_info = ivec2_info.get_method("length2").value(); + field_info ivec2_x_info = ivec2_info.get_field("x").value(); + field_info ivec2_y_info = ivec2_info.get_field("y").value(); - meta::function_info iadd2_info = vmath_info.get_function("iadd2").value(); - meta::function_info iadd3_info = vmath_info.get_function("iadd3").value(); + data_info ivec2_x_tooltip_info = ivec2_x_info.get_data("tooltip").value(); + data_info ivec2_y_tooltip_info = ivec2_y_info.get_data("tooltip").value(); + + method_info ivec2_dot_info = ivec2_info.get_method("dot").value(); + method_info ivec2_length2_info = ivec2_info.get_method("length2").value(); + + function_info iadd2_info = vmath_info.get_function("iadd2").value(); + function_info iadd3_info = vmath_info.get_function("iadd3").value(); { ivec2 v2{1,2}; From 0d3243f4f2911b4b6cd6cd6c1244ce2cd75c67eb Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Wed, 30 Jun 2021 23:28:26 +0700 Subject: [PATCH 008/233] add value helper-functions --- headers/meta.hpp/meta_fwd.hpp | 2 ++ headers/meta.hpp/meta_value.hpp | 23 +++++++++++++++++++++++ untests/meta_value_tests.cpp | 20 ++++++++++++++++++++ 3 files changed, 45 insertions(+) diff --git a/headers/meta.hpp/meta_fwd.hpp b/headers/meta.hpp/meta_fwd.hpp index ab9ac34..f27f9c1 100644 --- a/headers/meta.hpp/meta_fwd.hpp +++ b/headers/meta.hpp/meta_fwd.hpp @@ -8,6 +8,8 @@ #include #include +#include +#include #include #include #include diff --git a/headers/meta.hpp/meta_value.hpp b/headers/meta.hpp/meta_value.hpp index b059626..aa6a910 100644 --- a/headers/meta.hpp/meta_value.hpp +++ b/headers/meta.hpp/meta_value.hpp @@ -18,6 +18,10 @@ namespace meta_hpp value(T&& value) : raw_{std::forward(value)} {} + template < typename T, typename... Args > + value(std::in_place_type_t, Args&&... args) + : raw_{std::in_place_type, std::forward(args)...} {} + template < typename T > auto cast() const { return std::any_cast(raw_); @@ -32,6 +36,25 @@ namespace meta_hpp auto try_cast() const noexcept { return std::any_cast(&raw_); } + public: + bool to_bool() const { return cast(); } + int to_int() const { return cast(); } + float to_float() const { return cast(); } + double to_double() const { return cast(); } + std::string to_string() const { return cast(); } + + std::int8_t to_int8() const { return cast(); } + std::int16_t to_int16() const { return cast(); } + std::int32_t to_int32() const { return cast(); } + std::int64_t to_int64() const { return cast(); } + + std::uint8_t to_uint8() const { return cast(); } + std::uint16_t to_uint16() const { return cast(); } + std::uint32_t to_uint32() const { return cast(); } + std::uint64_t to_uint64() const { return cast(); } + + std::size_t to_size_t() const { return cast(); } + std::ptrdiff_t to_ptrdiff_t() const { return cast(); } private: std::any raw_; }; diff --git a/untests/meta_value_tests.cpp b/untests/meta_value_tests.cpp index f01d424..6e4a5aa 100644 --- a/untests/meta_value_tests.cpp +++ b/untests/meta_value_tests.cpp @@ -13,4 +13,24 @@ namespace TEST_CASE("meta/value") { namespace meta = meta_hpp; + using namespace std::string_literals; + + CHECK(meta::value{true}.to_bool() == true); + CHECK(meta::value{1}.to_int() == 1); + CHECK(meta::value{1.f}.to_float() == 1.f); + CHECK(meta::value{1.0}.to_double() == 1.0); + CHECK(meta::value{"meta"s}.to_string() == "meta"); + + CHECK(meta::value{std::in_place_type, 1}.to_int8() == 1); + CHECK(meta::value{std::in_place_type, 1}.to_int16() == 1); + CHECK(meta::value{std::in_place_type, 1}.to_int32() == 1); + CHECK(meta::value{std::in_place_type, 1}.to_int64() == 1); + + CHECK(meta::value{std::in_place_type, 1}.to_uint8() == 1u); + CHECK(meta::value{std::in_place_type, 1}.to_uint16() == 1u); + CHECK(meta::value{std::in_place_type, 1}.to_uint32() == 1u); + CHECK(meta::value{std::in_place_type, 1}.to_uint64() == 1u); + + CHECK(meta::value{std::in_place_type, 1}.to_size_t() == 1u); + CHECK(meta::value{std::in_place_type, 1}.to_ptrdiff_t() == 1u); } From 4782c328befe405b67bbe180ab01d20b9773efca Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Wed, 30 Jun 2021 23:29:40 +0700 Subject: [PATCH 009/233] add data tests --- untests/meta_data_tests.cpp | 168 ++++++++++++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 untests/meta_data_tests.cpp diff --git a/untests/meta_data_tests.cpp b/untests/meta_data_tests.cpp new file mode 100644 index 0000000..80e9483 --- /dev/null +++ b/untests/meta_data_tests.cpp @@ -0,0 +1,168 @@ +/******************************************************************************* + * 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 +#include +#include +#include +#include +#include +#include + +#include "doctest/doctest.hpp" + +namespace +{ + struct clazz { + int field{42}; + static int variable; + int method() const { return 42; } + static int function() { return 42; } + }; + + int clazz::variable{42}; +} + +TEST_CASE("meta/data") { + namespace meta = meta_hpp; + using namespace std::string_literals; + + meta::data_ data_("key"s, "value"s); + const meta::data_info& data_info = data_.info(); + + CHECK(data_info.id() == "key"); + CHECK(data_info.get().to_string() == "value"); + + { + data_( + meta::data_("key2"s, "value2"s)( + meta::data_("key3"s, "value3"s) + ) + ); + + CHECK(data_info.get_data("key2")); + CHECK(data_info.get_data("key2")->get().to_string() == "value2"); + + CHECK(data_info.get_data("key2")->get_data("key3")); + CHECK(data_info.get_data("key2")->get_data("key3")->get().to_string() == "value3"); + } + + { + data_( + meta::data_("key2"s, "value2"s)( + meta::data_("key4"s, "value4"s) + ) + ); + + CHECK(data_info.get_data("key2")); + CHECK(data_info.get_data("key2")->get().to_string() == "value2"); + + CHECK(data_info.get_data("key2")->get_data("key3")); + CHECK(data_info.get_data("key2")->get_data("key3")->get().to_string() == "value3"); + + CHECK(data_info.get_data("key2")->get_data("key4")); + CHECK(data_info.get_data("key2")->get_data("key4")->get().to_string() == "value4"); + } +} + +TEST_CASE("meta/data/class") { + namespace meta = meta_hpp; + using namespace std::string_literals; + + const meta::class_info clazz_info = meta::class_("clazz")( + meta::data_("hello"s, "world"s) + ).info(); + + CHECK(clazz_info.get_data("hello")); + CHECK(clazz_info.get_data("hello")->get().to_string() == "world"); +} + +TEST_CASE("meta/data/data") { + namespace meta = meta_hpp; + using namespace std::string_literals; + + const meta::class_info clazz_info = meta::class_("clazz")( + meta::data_("hello"s, "world"s)( + meta::data_("hello2"s, "world2"s) + ) + ).info(); + + CHECK(clazz_info.get_data("hello")); + CHECK(clazz_info.get_data("hello")->get_data("hello2")); + CHECK(clazz_info.get_data("hello")->get_data("hello2")->get().to_string() == "world2"); +} + +TEST_CASE("meta/data/field") { + namespace meta = meta_hpp; + using namespace std::string_literals; + + const meta::class_info clazz_info = meta::class_("clazz")( + meta::field_<&clazz::field>("field")( + meta::data_("hello"s, "world"s) + ) + ).info(); + + CHECK(clazz_info.get_field("field")); + CHECK(clazz_info.get_field("field")->get_data("hello")); + CHECK(clazz_info.get_field("field")->get_data("hello")->get().to_string() == "world"); +} + +TEST_CASE("meta/data/function") { + namespace meta = meta_hpp; + using namespace std::string_literals; + + const meta::class_info clazz_info = meta::class_("clazz")( + meta::function_<&clazz::function>("function")( + meta::data_("hello"s, "world"s) + ) + ).info(); + + CHECK(clazz_info.get_function("function")); + CHECK(clazz_info.get_function("function")->get_data("hello")); + CHECK(clazz_info.get_function("function")->get_data("hello")->get().to_string() == "world"); +} + +TEST_CASE("meta/data/method") { + namespace meta = meta_hpp; + using namespace std::string_literals; + + const meta::class_info clazz_info = meta::class_("clazz")( + meta::method_<&clazz::method>("method")( + meta::data_("hello"s, "world"s) + ) + ).info(); + + CHECK(clazz_info.get_method("method")); + CHECK(clazz_info.get_method("method")->get_data("hello")); + CHECK(clazz_info.get_method("method")->get_data("hello")->get().to_string() == "world"); +} + +TEST_CASE("meta/data/namespace") { + namespace meta = meta_hpp; + using namespace std::string_literals; + + const meta::namespace_info ns_info = meta::namespace_("ns")( + meta::data_("hello"s, "world"s) + ).info(); + + CHECK(ns_info.get_data("hello")); + CHECK(ns_info.get_data("hello")->get().to_string() == "world"); +} + +TEST_CASE("meta/data/variable") { + namespace meta = meta_hpp; + using namespace std::string_literals; + + const meta::class_info clazz_info = meta::class_("clazz")( + meta::variable_<&clazz::variable>("variable")( + meta::data_("hello"s, "world"s) + ) + ).info(); + + CHECK(clazz_info.get_variable("variable")); + CHECK(clazz_info.get_variable("variable")->get_data("hello")); + CHECK(clazz_info.get_variable("variable")->get_data("hello")->get().to_string() == "world"); +} From 0d17759942583f7570e81dea40066d848fbfd1f0 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Thu, 1 Jul 2021 01:44:41 +0700 Subject: [PATCH 010/233] foreach by info internals --- headers/meta.hpp/meta_class_info.hpp | 42 ++++++++++++++++++++++++ headers/meta.hpp/meta_data_info.hpp | 7 ++++ headers/meta.hpp/meta_field_info.hpp | 7 ++++ headers/meta.hpp/meta_function_info.hpp | 7 ++++ headers/meta.hpp/meta_method_info.hpp | 7 ++++ headers/meta.hpp/meta_namespace_info.hpp | 36 ++++++++++++++++++++ headers/meta.hpp/meta_variable_info.hpp | 7 ++++ 7 files changed, 113 insertions(+) diff --git a/headers/meta.hpp/meta_class_info.hpp b/headers/meta.hpp/meta_class_info.hpp index 46cc4c5..6f3ea3b 100644 --- a/headers/meta.hpp/meta_class_info.hpp +++ b/headers/meta.hpp/meta_class_info.hpp @@ -34,6 +34,48 @@ namespace meta_hpp return id_; } + template < typename F > + void each_class(F&& f) const { + for ( auto [_, info] : classes_ ) { + std::invoke(f, info); + } + } + + template < typename F > + void each_data(F&& f) const { + for ( auto [_, info] : datas_ ) { + std::invoke(f, info); + } + } + + template < typename F > + void each_field(F&& f) const { + for ( auto [_, info] : fields_ ) { + std::invoke(f, info); + } + } + + template < typename F > + void each_function(F&& f) const { + for ( auto [_, info] : functions_ ) { + std::invoke(f, info); + } + } + + template < typename F > + void each_method(F&& f) const { + for ( auto [_, info] : methods_ ) { + std::invoke(f, info); + } + } + + template < typename F > + void each_variable(F&& f) const { + for ( auto [_, info] : variables_ ) { + std::invoke(f, info); + } + } + std::optional get_class(std::string_view id) const { return detail::find_opt(classes_, id); } diff --git a/headers/meta.hpp/meta_data_info.hpp b/headers/meta.hpp/meta_data_info.hpp index 0c26133..e86aa82 100644 --- a/headers/meta.hpp/meta_data_info.hpp +++ b/headers/meta.hpp/meta_data_info.hpp @@ -33,6 +33,13 @@ namespace meta_hpp return value_; } + template < typename F > + void each_data(F&& f) const { + for ( auto [_, info] : datas_ ) { + std::invoke(f, info); + } + } + std::optional get_data(std::string_view id) const { return detail::find_opt(datas_, id); } diff --git a/headers/meta.hpp/meta_field_info.hpp b/headers/meta.hpp/meta_field_info.hpp index 8a0a57e..3099767 100644 --- a/headers/meta.hpp/meta_field_info.hpp +++ b/headers/meta.hpp/meta_field_info.hpp @@ -83,6 +83,13 @@ namespace meta_hpp return setter_(instance, std::forward(value)); } + template < typename F > + void each_data(F&& f) const { + for ( auto [_, info] : datas_ ) { + std::invoke(f, info); + } + } + std::optional get_data(std::string_view id) const { return detail::find_opt(datas_, id); } diff --git a/headers/meta.hpp/meta_function_info.hpp b/headers/meta.hpp/meta_function_info.hpp index c208022..b1b66e8 100644 --- a/headers/meta.hpp/meta_function_info.hpp +++ b/headers/meta.hpp/meta_function_info.hpp @@ -88,6 +88,13 @@ namespace meta_hpp return invoke_(vargs.data(), vargs.size()); } + template < typename F > + void each_data(F&& f) const { + for ( auto [_, info] : datas_ ) { + std::invoke(f, info); + } + } + std::optional get_data(std::string_view id) const { return detail::find_opt(datas_, id); } diff --git a/headers/meta.hpp/meta_method_info.hpp b/headers/meta.hpp/meta_method_info.hpp index 9d3758c..106ca97 100644 --- a/headers/meta.hpp/meta_method_info.hpp +++ b/headers/meta.hpp/meta_method_info.hpp @@ -150,6 +150,13 @@ namespace meta_hpp return cinvoke_(instance, vargs.data(), vargs.size()); } + template < typename F > + void each_data(F&& f) const { + for ( auto [_, info] : datas_ ) { + std::invoke(f, info); + } + } + std::optional get_data(std::string_view id) const { return detail::find_opt(datas_, id); } diff --git a/headers/meta.hpp/meta_namespace_info.hpp b/headers/meta.hpp/meta_namespace_info.hpp index cec5528..c8a11f5 100644 --- a/headers/meta.hpp/meta_namespace_info.hpp +++ b/headers/meta.hpp/meta_namespace_info.hpp @@ -32,6 +32,42 @@ namespace meta_hpp const std::string& id() const noexcept { return id_; } + + template < typename F > + void each_class(F&& f) const { + for ( auto [_, info] : classes_ ) { + std::invoke(f, info); + } + } + + template < typename F > + void each_data(F&& f) const { + for ( auto [_, info] : datas_ ) { + std::invoke(f, info); + } + } + + template < typename F > + void each_function(F&& f) const { + for ( auto [_, info] : functions_ ) { + std::invoke(f, info); + } + } + + template < typename F > + void each_namespace(F&& f) const { + for ( auto [_, info] : namespaces_ ) { + std::invoke(f, info); + } + } + + template < typename F > + void each_variable(F&& f) const { + for ( auto [_, info] : variables_ ) { + std::invoke(f, info); + } + } + std::optional get_class(std::string_view id) const { return detail::find_opt(classes_, id); } diff --git a/headers/meta.hpp/meta_variable_info.hpp b/headers/meta.hpp/meta_variable_info.hpp index 96e0486..c385e89 100644 --- a/headers/meta.hpp/meta_variable_info.hpp +++ b/headers/meta.hpp/meta_variable_info.hpp @@ -78,6 +78,13 @@ namespace meta_hpp return setter_(std::forward(value)); } + template < typename F > + void each_data(F&& f) const { + for ( auto [_, info] : datas_ ) { + std::invoke(f, info); + } + } + std::optional get_data(std::string_view id) const { return detail::find_opt(datas_, id); } From 1c8b962f5ad7996302d8144e2765246fc7f911b7 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Thu, 1 Jul 2021 02:01:47 +0700 Subject: [PATCH 011/233] common type info class --- headers/meta.hpp/meta.hpp | 2 ++ headers/meta.hpp/meta_fwd.hpp | 3 ++ headers/meta.hpp/meta_type.hpp | 56 +++++++++++++++++++++++++++++++++ untests/meta_type_tests.cpp | 57 ++++++++++++++++++++++++++++++++++ 4 files changed, 118 insertions(+) create mode 100644 headers/meta.hpp/meta_type.hpp create mode 100644 untests/meta_type_tests.cpp diff --git a/headers/meta.hpp/meta.hpp b/headers/meta.hpp/meta.hpp index 420cd6b..c4d3df7 100644 --- a/headers/meta.hpp/meta.hpp +++ b/headers/meta.hpp/meta.hpp @@ -10,6 +10,8 @@ #include "meta_value.hpp" +#include "meta_type.hpp" + #include "meta_class.hpp" #include "meta_class_info.hpp" diff --git a/headers/meta.hpp/meta_fwd.hpp b/headers/meta.hpp/meta_fwd.hpp index f27f9c1..173d887 100644 --- a/headers/meta.hpp/meta_fwd.hpp +++ b/headers/meta.hpp/meta_fwd.hpp @@ -19,11 +19,14 @@ #include #include #include +#include namespace meta_hpp { class value; + class type; + class class_info; class data_info; class field_info; diff --git a/headers/meta.hpp/meta_type.hpp b/headers/meta.hpp/meta_type.hpp new file mode 100644 index 0000000..8f86765 --- /dev/null +++ b/headers/meta.hpp/meta_type.hpp @@ -0,0 +1,56 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "meta_fwd.hpp" + +#include "meta_class_info.hpp" +#include "meta_field_info.hpp" +#include "meta_function_info.hpp" +#include "meta_method_info.hpp" +#include "meta_namespace_info.hpp" +#include "meta_variable_info.hpp" + +namespace meta_hpp +{ + class type { + public: + type() = delete; + + type(type&&) = default; + type(const type&) = default; + + type& operator=(type&&) = default; + type& operator=(const type&) = default; + + template < typename Info > + type(Info&& info) + : info_(std::forward(info)) {} + + bool is_class() const noexcept { return std::holds_alternative(info_); } + bool is_field() const noexcept { return std::holds_alternative(info_); } + bool is_function() const noexcept { return std::holds_alternative(info_); } + bool is_method() const noexcept { return std::holds_alternative(info_); } + bool is_namespace() const noexcept { return std::holds_alternative(info_); } + bool is_variable() const noexcept { return std::holds_alternative(info_); } + + const class_info& get_class_info() const { return std::get(info_); } + const field_info& get_field_info() const { return std::get(info_); } + const function_info& get_function_info() const { return std::get(info_); } + const method_info& get_method_info() const { return std::get(info_); } + const namespace_info& get_namespace_info() const { return std::get(info_); } + const variable_info& get_variable_info() const { return std::get(info_); } + private: + std::variant< + class_info, + field_info, + function_info, + method_info, + namespace_info, + variable_info> info_; + }; +} diff --git a/untests/meta_type_tests.cpp b/untests/meta_type_tests.cpp new file mode 100644 index 0000000..f7e8585 --- /dev/null +++ b/untests/meta_type_tests.cpp @@ -0,0 +1,57 @@ +/******************************************************************************* + * 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 + +#include +#include +#include +#include +#include +#include + +#include "doctest/doctest.hpp" + +namespace +{ + struct clazz { + int field{42}; + static int variable; + int method() const { return 42; } + static int function() { return 42; } + }; + + int clazz::variable{42}; +} + +TEST_CASE("meta/type") { + namespace meta = meta_hpp; + using namespace std::string_literals; + + meta::type class_type = meta::class_("clazz").info(); + CHECK(class_type.is_class()); + CHECK(class_type.get_class_info().id() == "clazz"); + + meta::type field_type = meta::field_<&clazz::field>("field").info(); + CHECK(field_type.is_field()); + CHECK(field_type.get_field_info().id() == "field"); + + meta::type function_type = meta::function_<&clazz::function>("function").info(); + CHECK(function_type.is_function()); + CHECK(function_type.get_function_info().id() == "function"); + + meta::type method_type = meta::method_<&clazz::method>("method").info(); + CHECK(method_type.is_method()); + CHECK(method_type.get_method_info().id() == "method"); + + meta::type namespace_type = meta::namespace_("ns").info(); + CHECK(namespace_type.is_namespace()); + CHECK(namespace_type.get_namespace_info().id() == "ns"); + + meta::type variable_type = meta::variable_<&clazz::variable>("variable").info(); + CHECK(variable_type.is_variable()); + CHECK(variable_type.get_variable_info().id() == "variable"); +} From 0e65288a9c0153d81a58c59b26818309013f3989 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Thu, 1 Jul 2021 05:20:31 +0700 Subject: [PATCH 012/233] family id for infos --- headers/meta.hpp/meta_class.hpp | 2 +- headers/meta.hpp/meta_class_info.hpp | 10 ++++-- headers/meta.hpp/meta_field.hpp | 2 +- headers/meta.hpp/meta_field_info.hpp | 10 ++++-- headers/meta.hpp/meta_function.hpp | 2 +- headers/meta.hpp/meta_function_info.hpp | 10 ++++-- headers/meta.hpp/meta_fwd.hpp | 43 +++++++++++++++++++++++++ headers/meta.hpp/meta_method.hpp | 2 +- headers/meta.hpp/meta_method_info.hpp | 10 ++++-- headers/meta.hpp/meta_variable.hpp | 2 +- headers/meta.hpp/meta_variable_info.hpp | 10 ++++-- 11 files changed, 88 insertions(+), 15 deletions(-) diff --git a/headers/meta.hpp/meta_class.hpp b/headers/meta.hpp/meta_class.hpp index 3d2c155..8a965ad 100644 --- a/headers/meta.hpp/meta_class.hpp +++ b/headers/meta.hpp/meta_class.hpp @@ -22,7 +22,7 @@ namespace meta_hpp class class_ { public: explicit class_(std::string id) - : info_(std::move(id)) {} + : info_{get_family_id(), std::move(id)} {} const class_info& info() const noexcept { return info_; diff --git a/headers/meta.hpp/meta_class_info.hpp b/headers/meta.hpp/meta_class_info.hpp index 6f3ea3b..92752b5 100644 --- a/headers/meta.hpp/meta_class_info.hpp +++ b/headers/meta.hpp/meta_class_info.hpp @@ -27,9 +27,14 @@ namespace meta_hpp class_info& operator=(class_info&&) = default; class_info& operator=(const class_info&) = default; - class_info(std::string id) - : id_(std::move(id)) {} + class_info(family_id fid, std::string id) + : fid_(std::move(fid)) + , id_(std::move(id)) {} public: + const family_id& fid() const noexcept { + return fid_; + } + const std::string& id() const noexcept { return id_; } @@ -114,6 +119,7 @@ namespace meta_hpp detail::merge_with(variables_, other.variables_, &variable_info::merge_with_); } private: + family_id fid_; std::string id_; std::map> classes_; std::map> datas_; diff --git a/headers/meta.hpp/meta_field.hpp b/headers/meta.hpp/meta_field.hpp index 07c9417..e4b3934 100644 --- a/headers/meta.hpp/meta_field.hpp +++ b/headers/meta.hpp/meta_field.hpp @@ -20,7 +20,7 @@ namespace meta_hpp static_assert(std::is_member_object_pointer_v); explicit field_(std::string id) - : info_(std::move(id)) { + : info_{get_family_id(), std::move(id)} { info_.getter_ = &field_detail::getter; info_.setter_ = &field_detail::setter; } diff --git a/headers/meta.hpp/meta_field_info.hpp b/headers/meta.hpp/meta_field_info.hpp index 3099767..08056ff 100644 --- a/headers/meta.hpp/meta_field_info.hpp +++ b/headers/meta.hpp/meta_field_info.hpp @@ -68,9 +68,14 @@ namespace meta_hpp field_info& operator=(field_info&&) = default; field_info& operator=(const field_info&) = default; - field_info(std::string id) - : id_(std::move(id)) {} + field_info(family_id fid, std::string id) + : fid_(std::move(fid)) + , id_(std::move(id)) {} public: + const family_id& fid() const noexcept { + return fid_; + } + const std::string& id() const noexcept { return id_; } @@ -105,6 +110,7 @@ namespace meta_hpp detail::merge_with(datas_, other.datas_, &data_info::merge_with_); } private: + family_id fid_; std::string id_; value(*getter_)(const void*); void(*setter_)(void*, value); diff --git a/headers/meta.hpp/meta_function.hpp b/headers/meta.hpp/meta_function.hpp index 35d3fe1..eb77afc 100644 --- a/headers/meta.hpp/meta_function.hpp +++ b/headers/meta.hpp/meta_function.hpp @@ -20,7 +20,7 @@ namespace meta_hpp static_assert(std::is_function_v>); explicit function_(std::string id) - : info_(std::move(id)) { + : info_{get_family_id(), std::move(id)} { info_.invoke_ = &function_detail::invoke; } diff --git a/headers/meta.hpp/meta_function_info.hpp b/headers/meta.hpp/meta_function_info.hpp index b1b66e8..2de241b 100644 --- a/headers/meta.hpp/meta_function_info.hpp +++ b/headers/meta.hpp/meta_function_info.hpp @@ -75,9 +75,14 @@ namespace meta_hpp function_info& operator=(function_info&&) = default; function_info& operator=(const function_info&) = default; - function_info(std::string id) - : id_(std::move(id)) {} + function_info(family_id fid, std::string id) + : fid_(std::move(fid)) + , id_(std::move(id)) {} public: + const family_id& fid() const noexcept { + return fid_; + } + const std::string& id() const noexcept { return id_; } @@ -112,6 +117,7 @@ namespace meta_hpp detail::merge_with(datas_, other.datas_, &data_info::merge_with_); } private: + family_id fid_; std::string id_; value(*invoke_)(value*, std::size_t); std::map> datas_; diff --git a/headers/meta.hpp/meta_fwd.hpp b/headers/meta.hpp/meta_fwd.hpp index 173d887..09be441 100644 --- a/headers/meta.hpp/meta_fwd.hpp +++ b/headers/meta.hpp/meta_fwd.hpp @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -44,6 +45,48 @@ namespace meta_hpp template < auto Variable > class variable_; } +namespace meta_hpp +{ + struct family_id { + using underlying_type = std::size_t; + underlying_type id{}; + + friend bool operator<(family_id l, family_id r) noexcept { + return l.id < r.id; + } + }; + + namespace family_id_detail + { + template < typename Void = void > + class type_family_base { + static_assert( + std::is_void_v, + "unexpected internal error"); + protected: + static family_id::underlying_type last_id_; + }; + + template < typename T > + class type_family final : public type_family_base<> { + public: + static family_id id() noexcept { + static family_id self_id{++last_id_}; + assert(self_id.id > 0u && "family_id overflow"); + return self_id; + } + }; + + template < typename Void > + family_id::underlying_type type_family_base::last_id_{}; + } + + template < typename T > + family_id get_family_id() noexcept { + return family_id_detail::type_family::id(); + } +} + namespace meta_hpp { template < typename Signature > diff --git a/headers/meta.hpp/meta_method.hpp b/headers/meta.hpp/meta_method.hpp index 740c7a4..6b1c419 100644 --- a/headers/meta.hpp/meta_method.hpp +++ b/headers/meta.hpp/meta_method.hpp @@ -20,7 +20,7 @@ namespace meta_hpp static_assert(std::is_member_function_pointer_v); explicit method_(std::string id) - : info_(std::move(id)) { + : info_{get_family_id(), std::move(id)} { info_.invoke_ = &method_detail::invoke; info_.cinvoke_ = &method_detail::cinvoke; } diff --git a/headers/meta.hpp/meta_method_info.hpp b/headers/meta.hpp/meta_method_info.hpp index 106ca97..14ad0e9 100644 --- a/headers/meta.hpp/meta_method_info.hpp +++ b/headers/meta.hpp/meta_method_info.hpp @@ -132,9 +132,14 @@ namespace meta_hpp method_info& operator=(method_info&&) = default; method_info& operator=(const method_info&) = default; - method_info(std::string id) - : id_(std::move(id)) {} + method_info(family_id fid, std::string id) + : fid_(std::move(fid)) + , id_(std::move(id)) {} public: + const family_id& fid() const noexcept { + return fid_; + } + const std::string& id() const noexcept { return id_; } @@ -171,6 +176,7 @@ namespace meta_hpp detail::merge_with(datas_, other.datas_, &data_info::merge_with_); } private: + family_id fid_; std::string id_; value(*invoke_)(void*, value*, std::size_t); value(*cinvoke_)(const void*, value*, std::size_t); diff --git a/headers/meta.hpp/meta_variable.hpp b/headers/meta.hpp/meta_variable.hpp index 7ba050a..656219f 100644 --- a/headers/meta.hpp/meta_variable.hpp +++ b/headers/meta.hpp/meta_variable.hpp @@ -18,7 +18,7 @@ namespace meta_hpp class variable_ { public: explicit variable_(std::string id) - : info_(std::move(id)) { + : info_{get_family_id(), std::move(id)} { info_.getter_ = &variable_detail::getter; info_.setter_ = &variable_detail::setter; } diff --git a/headers/meta.hpp/meta_variable_info.hpp b/headers/meta.hpp/meta_variable_info.hpp index c385e89..5162f28 100644 --- a/headers/meta.hpp/meta_variable_info.hpp +++ b/headers/meta.hpp/meta_variable_info.hpp @@ -63,9 +63,14 @@ namespace meta_hpp variable_info& operator=(variable_info&&) = default; variable_info& operator=(const variable_info&) = default; - variable_info(std::string id) - : id_(std::move(id)) {} + variable_info(family_id fid, std::string id) + : fid_(std::move(fid)) + , id_(std::move(id)) {} public: + const family_id& fid() const noexcept { + return fid_; + } + const std::string& id() const noexcept { return id_; } @@ -103,6 +108,7 @@ namespace meta_hpp detail::merge_with(datas_, other.datas_, &data_info::merge_with_); } private: + family_id fid_; std::string id_; value(*getter_)(); void(*setter_)(value); From 8d5d57992b14283ff68437ee38713380769bf229 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Thu, 1 Jul 2021 05:47:53 +0700 Subject: [PATCH 013/233] implicit get info from registry classes --- headers/meta.hpp/meta_class.hpp | 57 ++++++++--------------------- headers/meta.hpp/meta_data.hpp | 12 +++--- headers/meta.hpp/meta_field.hpp | 12 +++--- headers/meta.hpp/meta_function.hpp | 12 +++--- headers/meta.hpp/meta_method.hpp | 12 +++--- headers/meta.hpp/meta_namespace.hpp | 47 +++++++----------------- headers/meta.hpp/meta_variable.hpp | 12 +++--- untests/meta_class_tests.cpp | 2 +- untests/meta_data_tests.cpp | 16 ++++---- untests/meta_examples.cpp | 2 +- untests/meta_field_tests.cpp | 4 +- untests/meta_function_tests.cpp | 12 +++--- untests/meta_method_tests.cpp | 24 ++++++------ untests/meta_namespace_tests.cpp | 5 ++- untests/meta_type_tests.cpp | 12 +++--- untests/meta_variable_tests.cpp | 8 ++-- 16 files changed, 103 insertions(+), 146 deletions(-) diff --git a/headers/meta.hpp/meta_class.hpp b/headers/meta.hpp/meta_class.hpp index 8a965ad..aff8dfb 100644 --- a/headers/meta.hpp/meta_class.hpp +++ b/headers/meta.hpp/meta_class.hpp @@ -28,63 +28,38 @@ namespace meta_hpp return info_; } + operator const class_info&() const noexcept { + return info_; + } + template < typename... Internals > class_& operator()(Internals&&...internals) { (add_(std::forward(internals)), ...); return *this; } private: - template < typename InternalClass > - void add_(const class_& internal) { - detail::merge_with( - info_.classes_, - internal.info().id(), - internal.info(), - &class_info::merge_with_); + void add_(const class_info& info) { + detail::merge_with(info_.classes_, info.id(), info, &class_info::merge_with_); } - void add_(const data_& internal) { - detail::merge_with( - info_.datas_, - internal.info().id(), - internal.info(), - &data_info::merge_with_); + void add_(const data_info& info) { + detail::merge_with(info_.datas_, info.id(), info, &data_info::merge_with_); } - template < auto InternalField > - void add_(const field_& internal) { - detail::merge_with( - info_.fields_, - internal.info().id(), - internal.info(), - &field_info::merge_with_); + void add_(const field_info& info) { + detail::merge_with(info_.fields_, info.id(), info, &field_info::merge_with_); } - template < auto InternalFunction > - void add_(const function_& internal) { - detail::merge_with( - info_.functions_, - internal.info().id(), - internal.info(), - &function_info::merge_with_); + void add_(const function_info& info) { + detail::merge_with(info_.functions_, info.id(), info, &function_info::merge_with_); } - template < auto InternalMethod > - void add_(const method_& internal) { - detail::merge_with( - info_.methods_, - internal.info().id(), - internal.info(), - &method_info::merge_with_); + void add_(const method_info& info) { + detail::merge_with(info_.methods_, info.id(), info, &method_info::merge_with_); } - template < auto InternalVariable > - void add_(const variable_& internal) { - detail::merge_with( - info_.variables_, - internal.info().id(), - internal.info(), - &variable_info::merge_with_); + void add_(const variable_info& info) { + detail::merge_with(info_.variables_, info.id(), info, &variable_info::merge_with_); } private: class_info info_; diff --git a/headers/meta.hpp/meta_data.hpp b/headers/meta.hpp/meta_data.hpp index 5a172b1..14392cf 100644 --- a/headers/meta.hpp/meta_data.hpp +++ b/headers/meta.hpp/meta_data.hpp @@ -21,18 +21,18 @@ namespace meta_hpp return info_; } + operator const data_info&() const noexcept { + return info_; + } + template < typename... Internals > data_& operator()(Internals&&...internals) { (add_(std::forward(internals)), ...); return *this; } private: - void add_(const data_& internal) { - detail::merge_with( - info_.datas_, - internal.info().id(), - internal.info(), - &data_info::merge_with_); + void add_(const data_info& info) { + detail::merge_with(info_.datas_, info.id(), info, &data_info::merge_with_); } private: data_info info_; diff --git a/headers/meta.hpp/meta_field.hpp b/headers/meta.hpp/meta_field.hpp index e4b3934..6d3dbdf 100644 --- a/headers/meta.hpp/meta_field.hpp +++ b/headers/meta.hpp/meta_field.hpp @@ -29,18 +29,18 @@ namespace meta_hpp return info_; } + operator const field_info&() const noexcept { + return info_; + } + template < typename... Internals > field_& operator()(Internals&&...internals) { (add_(std::forward(internals)), ...); return *this; } private: - void add_(const data_& internal) { - detail::merge_with( - info_.datas_, - internal.info().id(), - internal.info(), - &data_info::merge_with_); + void add_(const data_info& info) { + detail::merge_with(info_.datas_, info.id(), info, &data_info::merge_with_); } private: field_info info_; diff --git a/headers/meta.hpp/meta_function.hpp b/headers/meta.hpp/meta_function.hpp index eb77afc..7400ca5 100644 --- a/headers/meta.hpp/meta_function.hpp +++ b/headers/meta.hpp/meta_function.hpp @@ -28,18 +28,18 @@ namespace meta_hpp return info_; } + operator const function_info&() const noexcept { + return info_; + } + template < typename... Internals > function_& operator()(Internals&&...internals) { (add_(std::forward(internals)), ...); return *this; } private: - void add_(const data_& internal) { - detail::merge_with( - info_.datas_, - internal.info().id(), - internal.info(), - &data_info::merge_with_); + void add_(const data_info& info) { + detail::merge_with(info_.datas_, info.id(), info, &data_info::merge_with_); } private: function_info info_; diff --git a/headers/meta.hpp/meta_method.hpp b/headers/meta.hpp/meta_method.hpp index 6b1c419..9a6223f 100644 --- a/headers/meta.hpp/meta_method.hpp +++ b/headers/meta.hpp/meta_method.hpp @@ -29,18 +29,18 @@ namespace meta_hpp return info_; } + operator const method_info&() const { + return info_; + } + template < typename... Internals > method_& operator()(Internals&&...internals) { (add_(std::forward(internals)), ...); return *this; } private: - void add_(const data_& internal) { - detail::merge_with( - info_.datas_, - internal.info().id(), - internal.info(), - &data_info::merge_with_); + void add_(const data_info& info) { + detail::merge_with(info_.datas_, info.id(), info, &data_info::merge_with_); } private: method_info info_; diff --git a/headers/meta.hpp/meta_namespace.hpp b/headers/meta.hpp/meta_namespace.hpp index 1fd5cb9..c3fd0ce 100644 --- a/headers/meta.hpp/meta_namespace.hpp +++ b/headers/meta.hpp/meta_namespace.hpp @@ -26,53 +26,34 @@ namespace meta_hpp return info_; } + operator const namespace_info&() const noexcept { + return info_; + } + template < typename... Internals > namespace_& operator()(Internals&&...internals) { (add_(std::forward(internals)), ...); return *this; } private: - template < typename InternalClass > - void add_(const class_& internal) { - detail::merge_with( - info_.classes_, - internal.info().id(), - internal.info(), - &class_info::merge_with_); + void add_(const class_info& info) { + detail::merge_with(info_.classes_, info.id(), info, &class_info::merge_with_); } - void add_(const data_& internal) { - detail::merge_with( - info_.datas_, - internal.info().id(), - internal.info(), - &data_info::merge_with_); + void add_(const data_info& info) { + detail::merge_with(info_.datas_, info.id(), info, &data_info::merge_with_); } - template < auto InternalFunction > - void add_(const function_& internal) { - detail::merge_with( - info_.functions_, - internal.info().id(), - internal.info(), - &function_info::merge_with_); + void add_(const function_info& info) { + detail::merge_with(info_.functions_, info.id(), info, &function_info::merge_with_); } - void add_(const namespace_& internal) { - detail::merge_with( - info_.namespaces_, - internal.info().id(), - internal.info(), - &namespace_info::merge_with_); + void add_(const namespace_info& info) { + detail::merge_with(info_.namespaces_, info.id(), info, &namespace_info::merge_with_); } - template < auto InternalVariable > - void add_(const variable_& internal) { - detail::merge_with( - info_.variables_, - internal.info().id(), - internal.info(), - &variable_info::merge_with_); + void add_(const variable_info& info) { + detail::merge_with(info_.variables_, info.id(), info, &variable_info::merge_with_); } private: namespace_info info_; diff --git a/headers/meta.hpp/meta_variable.hpp b/headers/meta.hpp/meta_variable.hpp index 656219f..6718a0e 100644 --- a/headers/meta.hpp/meta_variable.hpp +++ b/headers/meta.hpp/meta_variable.hpp @@ -27,18 +27,18 @@ namespace meta_hpp return info_; } + operator const variable_info&() const noexcept { + return info_; + } + template < typename... Internals > variable_& operator()(Internals&&...internals) { (add_(std::forward(internals)), ...); return *this; } private: - void add_(const data_& internal) { - detail::merge_with( - info_.datas_, - internal.info().id(), - internal.info(), - &data_info::merge_with_); + void add_(const data_info& info) { + detail::merge_with(info_.datas_, info.id(), info, &data_info::merge_with_); } private: variable_info info_; diff --git a/untests/meta_class_tests.cpp b/untests/meta_class_tests.cpp index 4cdc650..4596024 100644 --- a/untests/meta_class_tests.cpp +++ b/untests/meta_class_tests.cpp @@ -40,7 +40,7 @@ TEST_CASE("meta/class") { meta::class_ class_{"clazz"}; const meta::class_& cclass_ = class_; - const meta::class_info& clazz_info = cclass_.info(); + const meta::class_info& clazz_info = cclass_; CHECK_FALSE(clazz_info.get_class("clazz2")); CHECK_FALSE(clazz_info.get_field("field")); diff --git a/untests/meta_data_tests.cpp b/untests/meta_data_tests.cpp index 80e9483..c66c520 100644 --- a/untests/meta_data_tests.cpp +++ b/untests/meta_data_tests.cpp @@ -31,7 +31,7 @@ TEST_CASE("meta/data") { using namespace std::string_literals; meta::data_ data_("key"s, "value"s); - const meta::data_info& data_info = data_.info(); + const meta::data_info& data_info = data_; CHECK(data_info.id() == "key"); CHECK(data_info.get().to_string() == "value"); @@ -74,7 +74,7 @@ TEST_CASE("meta/data/class") { const meta::class_info clazz_info = meta::class_("clazz")( meta::data_("hello"s, "world"s) - ).info(); + ); CHECK(clazz_info.get_data("hello")); CHECK(clazz_info.get_data("hello")->get().to_string() == "world"); @@ -88,7 +88,7 @@ TEST_CASE("meta/data/data") { meta::data_("hello"s, "world"s)( meta::data_("hello2"s, "world2"s) ) - ).info(); + ); CHECK(clazz_info.get_data("hello")); CHECK(clazz_info.get_data("hello")->get_data("hello2")); @@ -103,7 +103,7 @@ TEST_CASE("meta/data/field") { meta::field_<&clazz::field>("field")( meta::data_("hello"s, "world"s) ) - ).info(); + ); CHECK(clazz_info.get_field("field")); CHECK(clazz_info.get_field("field")->get_data("hello")); @@ -118,7 +118,7 @@ TEST_CASE("meta/data/function") { meta::function_<&clazz::function>("function")( meta::data_("hello"s, "world"s) ) - ).info(); + ); CHECK(clazz_info.get_function("function")); CHECK(clazz_info.get_function("function")->get_data("hello")); @@ -133,7 +133,7 @@ TEST_CASE("meta/data/method") { meta::method_<&clazz::method>("method")( meta::data_("hello"s, "world"s) ) - ).info(); + ); CHECK(clazz_info.get_method("method")); CHECK(clazz_info.get_method("method")->get_data("hello")); @@ -146,7 +146,7 @@ TEST_CASE("meta/data/namespace") { const meta::namespace_info ns_info = meta::namespace_("ns")( meta::data_("hello"s, "world"s) - ).info(); + ); CHECK(ns_info.get_data("hello")); CHECK(ns_info.get_data("hello")->get().to_string() == "world"); @@ -160,7 +160,7 @@ TEST_CASE("meta/data/variable") { meta::variable_<&clazz::variable>("variable")( meta::data_("hello"s, "world"s) ) - ).info(); + ); CHECK(clazz_info.get_variable("variable")); CHECK(clazz_info.get_variable("variable")->get_data("hello")); diff --git a/untests/meta_examples.cpp b/untests/meta_examples.cpp index e72e439..a3283cf 100644 --- a/untests/meta_examples.cpp +++ b/untests/meta_examples.cpp @@ -113,7 +113,7 @@ TEST_CASE("meta/examples/simple") { ), function_(&add)>("iadd2"), function_(&add)>("iadd3") - ).info(); + ); class_info ivec2_info = vmath_info.get_class("ivec2").value(); diff --git a/untests/meta_field_tests.cpp b/untests/meta_field_tests.cpp index 05adcf6..990f6cb 100644 --- a/untests/meta_field_tests.cpp +++ b/untests/meta_field_tests.cpp @@ -22,8 +22,8 @@ TEST_CASE("meta/field") { meta::field_<&clazz::field> field_{"field"}; meta::field_<&clazz::cfield> cfield_{"cfield"}; - const meta::field_info& field_info = field_.info(); - const meta::field_info& cfield_info = cfield_.info(); + const meta::field_info& field_info = field_; + const meta::field_info& cfield_info = cfield_; { clazz instance; diff --git a/untests/meta_function_tests.cpp b/untests/meta_function_tests.cpp index d599fa1..5884233 100644 --- a/untests/meta_function_tests.cpp +++ b/untests/meta_function_tests.cpp @@ -29,13 +29,13 @@ TEST_CASE("meta/function") { meta::function_<&int_f_int> int_f_int_function_("int_f_int"); meta::function_<&int_f_int2> int_f_int2_function_("int_f_int2"); - const meta::function_info& void_f_void_info = void_f_void_function_.info(); - const meta::function_info& void_f_int_info = void_f_int_function_.info(); - const meta::function_info& void_f_int2_info = void_f_int2_function_.info(); + const meta::function_info& void_f_void_info = void_f_void_function_; + const meta::function_info& void_f_int_info = void_f_int_function_; + const meta::function_info& void_f_int2_info = void_f_int2_function_; - const meta::function_info& int_f_void_info = int_f_void_function_.info(); - const meta::function_info& int_f_int_info = int_f_int_function_.info(); - const meta::function_info& int_f_int2_info = int_f_int2_function_.info(); + const meta::function_info& int_f_void_info = int_f_void_function_; + const meta::function_info& int_f_int_info = int_f_int_function_; + const meta::function_info& int_f_int2_info = int_f_int2_function_; SUBCASE("void_return") { CHECK_NOTHROW(void_f_void_info.invoke()); diff --git a/untests/meta_method_tests.cpp b/untests/meta_method_tests.cpp index 19011e2..2192b6e 100644 --- a/untests/meta_method_tests.cpp +++ b/untests/meta_method_tests.cpp @@ -40,13 +40,13 @@ TEST_CASE("meta/non_const_method") { meta::method_<&clazz::int_f_int> int_f_int_method_("int_f_int"); meta::method_<&clazz::int_f_int2> int_f_int2_method_("int_f_int2"); - const meta::method_info& void_f_void_info = void_f_void_method_.info(); - const meta::method_info& void_f_int_info = void_f_int_method_.info(); - const meta::method_info& void_f_int2_info = void_f_int2_method_.info(); + const meta::method_info& void_f_void_info = void_f_void_method_; + const meta::method_info& void_f_int_info = void_f_int_method_; + const meta::method_info& void_f_int2_info = void_f_int2_method_; - const meta::method_info& int_f_void_info = int_f_void_method_.info(); - const meta::method_info& int_f_int_info = int_f_int_method_.info(); - const meta::method_info& int_f_int2_info = int_f_int2_method_.info(); + const meta::method_info& int_f_void_info = int_f_void_method_; + const meta::method_info& int_f_int_info = int_f_int_method_; + const meta::method_info& int_f_int2_info = int_f_int2_method_; SUBCASE("void_return") { clazz instance; @@ -108,13 +108,13 @@ TEST_CASE("meta/const_method") { meta::method_<&clazz::const_int_f_int> int_f_int_method_("int_f_int"); meta::method_<&clazz::const_int_f_int2> int_f_int2_method_("int_f_int2"); - const meta::method_info& void_f_void_info = void_f_void_method_.info(); - const meta::method_info& void_f_int_info = void_f_int_method_.info(); - const meta::method_info& void_f_int2_info = void_f_int2_method_.info(); + const meta::method_info& void_f_void_info = void_f_void_method_; + const meta::method_info& void_f_int_info = void_f_int_method_; + const meta::method_info& void_f_int2_info = void_f_int2_method_; - const meta::method_info& int_f_void_info = int_f_void_method_.info(); - const meta::method_info& int_f_int_info = int_f_int_method_.info(); - const meta::method_info& int_f_int2_info = int_f_int2_method_.info(); + const meta::method_info& int_f_void_info = int_f_void_method_; + const meta::method_info& int_f_int_info = int_f_int_method_; + const meta::method_info& int_f_int2_info = int_f_int2_method_; SUBCASE("void_return") { clazz instance; diff --git a/untests/meta_namespace_tests.cpp b/untests/meta_namespace_tests.cpp index c4438cb..5613b87 100644 --- a/untests/meta_namespace_tests.cpp +++ b/untests/meta_namespace_tests.cpp @@ -24,7 +24,7 @@ TEST_CASE("meta/namespace") { meta::namespace_ namespace_{"ns"}; const meta::namespace_& cnamespace_ = namespace_; - const meta::namespace_info& ns_info = cnamespace_.info(); + const meta::namespace_info& ns_info = cnamespace_; CHECK_FALSE(ns_info.get_class("clazz")); CHECK_FALSE(ns_info.get_function("func")); @@ -75,6 +75,7 @@ TEST_CASE("meta/namespace/merge") { namespace meta = meta_hpp; meta::namespace_ namespace_{"ns"}; + const meta::namespace_info& ns_info = namespace_; namespace_( meta::namespace_{"ns2"}( @@ -96,7 +97,7 @@ TEST_CASE("meta/namespace/merge") { ) ); - const meta::namespace_info ns2_info = namespace_.info().get_namespace("ns2").value(); + const meta::namespace_info ns2_info = ns_info.get_namespace("ns2").value(); const meta::namespace_info ns3_info = ns2_info.get_namespace("ns3").value(); CHECK(ns2_info.get_class("clazz")); diff --git a/untests/meta_type_tests.cpp b/untests/meta_type_tests.cpp index f7e8585..919c577 100644 --- a/untests/meta_type_tests.cpp +++ b/untests/meta_type_tests.cpp @@ -31,27 +31,27 @@ TEST_CASE("meta/type") { namespace meta = meta_hpp; using namespace std::string_literals; - meta::type class_type = meta::class_("clazz").info(); + meta::type class_type = meta::class_("clazz"); CHECK(class_type.is_class()); CHECK(class_type.get_class_info().id() == "clazz"); - meta::type field_type = meta::field_<&clazz::field>("field").info(); + meta::type field_type = meta::field_<&clazz::field>("field"); CHECK(field_type.is_field()); CHECK(field_type.get_field_info().id() == "field"); - meta::type function_type = meta::function_<&clazz::function>("function").info(); + meta::type function_type = meta::function_<&clazz::function>("function"); CHECK(function_type.is_function()); CHECK(function_type.get_function_info().id() == "function"); - meta::type method_type = meta::method_<&clazz::method>("method").info(); + meta::type method_type = meta::method_<&clazz::method>("method"); CHECK(method_type.is_method()); CHECK(method_type.get_method_info().id() == "method"); - meta::type namespace_type = meta::namespace_("ns").info(); + meta::type namespace_type = meta::namespace_("ns"); CHECK(namespace_type.is_namespace()); CHECK(namespace_type.get_namespace_info().id() == "ns"); - meta::type variable_type = meta::variable_<&clazz::variable>("variable").info(); + meta::type variable_type = meta::variable_<&clazz::variable>("variable"); CHECK(variable_type.is_variable()); CHECK(variable_type.get_variable_info().id() == "variable"); } diff --git a/untests/meta_variable_tests.cpp b/untests/meta_variable_tests.cpp index e70a55b..0ec0f59 100644 --- a/untests/meta_variable_tests.cpp +++ b/untests/meta_variable_tests.cpp @@ -29,8 +29,8 @@ TEST_CASE("meta/variable") { meta::variable_<&variable> variable_{"variable"}; meta::variable_<&cvariable> cvariable_{"cvariable"}; - const meta::variable_info& variable_info = variable_.info(); - const meta::variable_info& cvariable_info = cvariable_.info(); + const meta::variable_info& variable_info = variable_; + const meta::variable_info& cvariable_info = cvariable_; { CHECK(variable == 1); @@ -62,8 +62,8 @@ TEST_CASE("meta/variable") { meta::variable_<&clazz::variable> variable_{"variable"}; meta::variable_<&clazz::cvariable> cvariable_{"cvariable"}; - const meta::variable_info& variable_info = variable_.info(); - const meta::variable_info& cvariable_info = cvariable_.info(); + const meta::variable_info& variable_info = variable_; + const meta::variable_info& cvariable_info = cvariable_; { CHECK(clazz::variable == 1); From 0a5c7d87d874a790b790dd7ea4af75d6c429539b Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Thu, 1 Jul 2021 05:51:11 +0700 Subject: [PATCH 014/233] registry type holder --- headers/meta.hpp/meta.hpp | 1 + headers/meta.hpp/meta_fwd.hpp | 1 + headers/meta.hpp/meta_registry.hpp | 108 ++++++++++++++++++ untests/meta_registry_tests.cpp | 171 +++++++++++++++++++++++++++++ 4 files changed, 281 insertions(+) create mode 100644 headers/meta.hpp/meta_registry.hpp create mode 100644 untests/meta_registry_tests.cpp diff --git a/headers/meta.hpp/meta.hpp b/headers/meta.hpp/meta.hpp index c4d3df7..5a4b00a 100644 --- a/headers/meta.hpp/meta.hpp +++ b/headers/meta.hpp/meta.hpp @@ -10,6 +10,7 @@ #include "meta_value.hpp" +#include "meta_registry.hpp" #include "meta_type.hpp" #include "meta_class.hpp" diff --git a/headers/meta.hpp/meta_fwd.hpp b/headers/meta.hpp/meta_fwd.hpp index 09be441..7e3a219 100644 --- a/headers/meta.hpp/meta_fwd.hpp +++ b/headers/meta.hpp/meta_fwd.hpp @@ -26,6 +26,7 @@ namespace meta_hpp { class value; + class registry; class type; class class_info; diff --git a/headers/meta.hpp/meta_registry.hpp b/headers/meta.hpp/meta_registry.hpp new file mode 100644 index 0000000..feb24ae --- /dev/null +++ b/headers/meta.hpp/meta_registry.hpp @@ -0,0 +1,108 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "meta_fwd.hpp" + +#include "meta_type.hpp" + +#include "meta_class.hpp" +#include "meta_field.hpp" +#include "meta_function.hpp" +#include "meta_method.hpp" +#include "meta_namespace.hpp" +#include "meta_variable.hpp" + +namespace meta_hpp +{ + class registry { + public: + template < auto T > + std::optional resolve() const { + const family_id fid = get_family_id(); + return detail::find_opt(family_to_types_, fid); + } + + template < typename T > + std::optional resolve() const { + const family_id fid = get_family_id(); + return detail::find_opt(family_to_types_, fid); + } + + template < typename T > + std::optional resolve(const T&) const { + const family_id fid = get_family_id(); + return detail::find_opt(family_to_types_, fid); + } + + template < typename... Internals > + registry& operator()(Internals&&...internals) { + (add_(std::forward(internals)), ...); + return *this; + } + private: + void add_(const class_info& info) { + family_to_types_.emplace(info.fid(), info); + + info.each_class([this](const class_info& internal){ + add_(internal); + }); + + info.each_field([this](const field_info& internal){ + add_(internal); + }); + + info.each_function([this](const function_info& internal){ + add_(internal); + }); + + info.each_method([this](const method_info& internal){ + add_(internal); + }); + + info.each_variable([this](const variable_info& internal){ + add_(internal); + }); + } + + void add_(const field_info& info) { + family_to_types_.emplace(info.fid(), info); + } + + void add_(const function_info& info) { + family_to_types_.emplace(info.fid(), info); + } + + void add_(const method_info& info) { + family_to_types_.emplace(info.fid(), info); + } + + void add_(const namespace_info& info) { + info.each_class([this](const class_info& internal){ + add_(internal); + }); + + info.each_function([this](const function_info& internal){ + add_(internal); + }); + + info.each_namespace([this](const namespace_info& internal){ + add_(internal); + }); + + info.each_variable([this](const variable_info& internal){ + add_(internal); + }); + } + + void add_(const variable_info& info) { + family_to_types_.emplace(info.fid(), info); + } + private: + std::map> family_to_types_; + }; +} diff --git a/untests/meta_registry_tests.cpp b/untests/meta_registry_tests.cpp new file mode 100644 index 0000000..7dce6b8 --- /dev/null +++ b/untests/meta_registry_tests.cpp @@ -0,0 +1,171 @@ +/******************************************************************************* + * 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 +#include "doctest/doctest.hpp" + +namespace +{ + struct ivec2 { + int x{}; + int y{}; + + static ivec2 zero; + + int dot(ivec2 other) const { + return x * other.x + y * other.y; + } + }; + + struct ivec3 { + int x{}; + int y{}; + int z{}; + + static ivec3 zero; + + int dot(ivec3 other) const { + return x * other.x + y * other.y + z * other.z; + } + }; + + ivec2 ivec2::zero{}; + ivec3 ivec3::zero{}; + + ivec2 iadd2(ivec2 l, ivec2 r) { + return {l.x + r.x, l.y + r.y}; + } + + ivec3 iadd3(ivec3 l, ivec3 r) { + return {l.x + r.x, l.y + r.y, l.z + r.z}; + } +} + +TEST_CASE("meta/registry") { + namespace meta = meta_hpp; + using namespace std::string_literals; + + auto registry = meta::registry{}( + meta::namespace_("vmath")( + meta::class_("ivec2")( + meta::field_<&ivec2::x>("x"), + meta::field_<&ivec2::y>("y"), + meta::method_<&ivec2::dot>("dot"), + meta::variable_<&ivec2::zero>("zero") + ), + meta::class_("ivec3")( + meta::field_<&ivec3::x>("x"), + meta::field_<&ivec3::y>("y"), + meta::field_<&ivec3::z>("z"), + meta::method_<&ivec3::dot>("dot"), + meta::variable_<&ivec3::zero>("zero") + ), + meta::function_<&iadd2>("iadd2"), + meta::function_<&iadd3>("iadd3") + ) + ); + + SUBCASE("class_template") { + CHECK(registry.resolve()); + + const meta::type ivec2_type = registry.resolve().value(); + CHECK(ivec2_type.is_class()); + + const meta::class_info& ivec2_info = ivec2_type.get_class_info(); + CHECK(ivec2_info.id() == "ivec2"); + } + + SUBCASE("class_instance") { + ivec3 v3; + CHECK(registry.resolve(v3)); + + const meta::type ivec3_type = registry.resolve(v3).value(); + CHECK(ivec3_type.is_class()); + + const meta::class_info& ivec3_info = ivec3_type.get_class_info(); + CHECK(ivec3_info.id() == "ivec3"); + } + + SUBCASE("field_template") { + CHECK(registry.resolve<&ivec2::x>()); + + const meta::type ivec2_x_type = registry.resolve<&ivec2::x>().value(); + CHECK(ivec2_x_type.is_field()); + + const meta::field_info& ivec2_x_info = ivec2_x_type.get_field_info(); + CHECK(ivec2_x_info.id() == "x"); + } + + SUBCASE("field_instance") { + CHECK(registry.resolve(&ivec3::x)); + + const meta::type ivec3_x_type = registry.resolve<&ivec3::x>().value(); + CHECK(ivec3_x_type.is_field()); + + const meta::field_info& ivec3_x_info = ivec3_x_type.get_field_info(); + CHECK(ivec3_x_info.id() == "x"); + } + + SUBCASE("function_template") { + CHECK(registry.resolve<&iadd2>()); + + const meta::type iadd2_type = registry.resolve<&iadd2>().value(); + CHECK(iadd2_type.is_function()); + + const meta::function_info& iadd2_info = iadd2_type.get_function_info(); + CHECK(iadd2_info.id() == "iadd2"); + } + + SUBCASE("function_instance") { + CHECK(registry.resolve(&iadd3)); + + const meta::type iadd3_type = registry.resolve<&iadd3>().value(); + CHECK(iadd3_type.is_function()); + + const meta::function_info& iadd3_info = iadd3_type.get_function_info(); + CHECK(iadd3_info.id() == "iadd3"); + } + + SUBCASE("method_template") { + CHECK(registry.resolve<&ivec2::dot>()); + + const meta::type ivec2_dot_type = registry.resolve<&ivec2::dot>().value(); + CHECK(ivec2_dot_type.is_method()); + + const meta::method_info& ivec2_dot_info = ivec2_dot_type.get_method_info(); + CHECK(ivec2_dot_info.id() == "dot"); + } + + SUBCASE("method_instance") { + CHECK(registry.resolve(&ivec3::dot)); + + const meta::type ivec3_dot_type = registry.resolve<&ivec3::dot>().value(); + CHECK(ivec3_dot_type.is_method()); + + const meta::method_info& ivec3_dot_info = ivec3_dot_type.get_method_info(); + CHECK(ivec3_dot_info.id() == "dot"); + } + + SUBCASE("variable_template") { + CHECK(registry.resolve<&ivec2::zero>()); + + const meta::type ivec2_zero_type = registry.resolve<&ivec2::zero>().value(); + CHECK(ivec2_zero_type.is_variable()); + + const meta::variable_info& ivec2_x_info = ivec2_zero_type.get_variable_info(); + CHECK(ivec2_x_info.id() == "zero"); + } + + SUBCASE("variable_instance") { + CHECK(registry.resolve(&ivec3::zero)); + + const meta::type ivec3_zero_type = registry.resolve<&ivec3::zero>().value(); + CHECK(ivec3_zero_type.is_variable()); + + const meta::variable_info& ivec3_x_info = ivec3_zero_type.get_variable_info(); + CHECK(ivec3_x_info.id() == "zero"); + } +} From ebfc3ddfc7166e4532e2a36ebc55ec271571ebb3 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Thu, 1 Jul 2021 05:55:34 +0700 Subject: [PATCH 015/233] add resolve example --- untests/meta_examples.cpp | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/untests/meta_examples.cpp b/untests/meta_examples.cpp index a3283cf..d12d5fd 100644 --- a/untests/meta_examples.cpp +++ b/untests/meta_examples.cpp @@ -150,3 +150,41 @@ TEST_CASE("meta/examples/simple") { CHECK(v.z == 8); } } + +TEST_CASE("meta/examples/advanced") { + using namespace meta_hpp; + + auto db = registry{}( + class_("ivec2")( + field_<&ivec2::x>("x"), + field_<&ivec2::y>("y"), + method_<&ivec2::dot>("dot"), + method_<&ivec2::length2>("length2") + ), + class_("ivec3")( + field_<&ivec3::x>("x"), + field_<&ivec3::y>("y"), + field_<&ivec3::z>("z"), + method_<&ivec3::dot>("dot"), + method_<&ivec3::length2>("length2") + ) + ); + + ivec3 v3{1,2,3}; + + type v3_type = db.resolve(v3).value(); + class_info v3_info = v3_type.get_class_info(); + + std::cout << "class " << v3_info.id() << std::endl; + + v3_info.each_field([&v3](const field_info& info){ + std::cout + << " - " << info.id() + << ": " << info.get(&v3).to_int() << std::endl; + }); + + v3_info.each_method([](const method_info& info){ + std::cout + << " + " << info.id() << "()" << std::endl; + }); +} From 9495c2a69d5455570d23bed6001ed8056e5dc272 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 2 Jul 2021 00:55:11 +0700 Subject: [PATCH 016/233] throw in incorrect merge --- headers/meta.hpp/meta_class_info.hpp | 3 ++ headers/meta.hpp/meta_field_info.hpp | 5 ++- headers/meta.hpp/meta_function_info.hpp | 4 +- headers/meta.hpp/meta_fwd.hpp | 8 ++++ headers/meta.hpp/meta_method_info.hpp | 5 ++- headers/meta.hpp/meta_variable_info.hpp | 5 ++- untests/meta_class_tests.cpp | 49 ++++++++++++++++++++++++- 7 files changed, 70 insertions(+), 9 deletions(-) diff --git a/headers/meta.hpp/meta_class_info.hpp b/headers/meta.hpp/meta_class_info.hpp index 92752b5..bc74084 100644 --- a/headers/meta.hpp/meta_class_info.hpp +++ b/headers/meta.hpp/meta_class_info.hpp @@ -111,6 +111,9 @@ namespace meta_hpp friend class namespace_; private: void merge_with_(const class_info& other) { + if ( fid() != other.fid() ) { + throw std::logic_error("class_info::merge failed"); + } detail::merge_with(classes_, other.classes_, &class_info::merge_with_); detail::merge_with(datas_, other.datas_, &data_info::merge_with_); detail::merge_with(fields_, other.fields_, &field_info::merge_with_); diff --git a/headers/meta.hpp/meta_field_info.hpp b/headers/meta.hpp/meta_field_info.hpp index 08056ff..71e8c24 100644 --- a/headers/meta.hpp/meta_field_info.hpp +++ b/headers/meta.hpp/meta_field_info.hpp @@ -105,8 +105,9 @@ namespace meta_hpp template < auto Field > friend class field_; private: void merge_with_(const field_info& other) { - getter_ = other.getter_; - setter_ = other.setter_; + if ( fid() != other.fid() ) { + throw std::logic_error("field_info::merge failed"); + } detail::merge_with(datas_, other.datas_, &data_info::merge_with_); } private: diff --git a/headers/meta.hpp/meta_function_info.hpp b/headers/meta.hpp/meta_function_info.hpp index 2de241b..7b9dd23 100644 --- a/headers/meta.hpp/meta_function_info.hpp +++ b/headers/meta.hpp/meta_function_info.hpp @@ -113,7 +113,9 @@ namespace meta_hpp template < auto Function > friend class function_; private: void merge_with_(const function_info& other) { - invoke_ = other.invoke_; + if ( fid() != other.fid() ) { + throw std::logic_error("function_info::merge failed"); + } detail::merge_with(datas_, other.datas_, &data_info::merge_with_); } private: diff --git a/headers/meta.hpp/meta_fwd.hpp b/headers/meta.hpp/meta_fwd.hpp index 7e3a219..f736c5a 100644 --- a/headers/meta.hpp/meta_fwd.hpp +++ b/headers/meta.hpp/meta_fwd.hpp @@ -55,6 +55,14 @@ namespace meta_hpp friend bool operator<(family_id l, family_id r) noexcept { return l.id < r.id; } + + friend bool operator==(family_id l, family_id r) noexcept { + return l.id == r.id; + } + + friend bool operator!=(family_id l, family_id r) noexcept { + return l.id != r.id; + } }; namespace family_id_detail diff --git a/headers/meta.hpp/meta_method_info.hpp b/headers/meta.hpp/meta_method_info.hpp index 14ad0e9..f59324b 100644 --- a/headers/meta.hpp/meta_method_info.hpp +++ b/headers/meta.hpp/meta_method_info.hpp @@ -171,8 +171,9 @@ namespace meta_hpp template < auto Method > friend class method_; private: void merge_with_(const method_info& other) { - invoke_ = other.invoke_; - cinvoke_ = other.cinvoke_; + if ( fid() != other.fid() ) { + throw std::logic_error("method_info::merge failed"); + } detail::merge_with(datas_, other.datas_, &data_info::merge_with_); } private: diff --git a/headers/meta.hpp/meta_variable_info.hpp b/headers/meta.hpp/meta_variable_info.hpp index 5162f28..0cc2574 100644 --- a/headers/meta.hpp/meta_variable_info.hpp +++ b/headers/meta.hpp/meta_variable_info.hpp @@ -103,8 +103,9 @@ namespace meta_hpp template < auto Variable > friend class variable_; private: void merge_with_(const variable_info& other) { - getter_ = other.getter_; - setter_ = other.setter_; + if ( fid() != other.fid() ) { + throw std::logic_error("variable_info::merge failed"); + } detail::merge_with(datas_, other.datas_, &data_info::merge_with_); } private: diff --git a/untests/meta_class_tests.cpp b/untests/meta_class_tests.cpp index 4596024..cd2105e 100644 --- a/untests/meta_class_tests.cpp +++ b/untests/meta_class_tests.cpp @@ -17,6 +17,15 @@ namespace class clazz { public: class clazz2 { + public: + int field{21}; + const int cfield{22}; + }; + + class clazz3 { + public: + int field{31}; + const int cfield{32}; }; int field{1}; @@ -39,8 +48,7 @@ TEST_CASE("meta/class") { namespace meta = meta_hpp; meta::class_ class_{"clazz"}; - const meta::class_& cclass_ = class_; - const meta::class_info& clazz_info = cclass_; + const meta::class_info& clazz_info = class_; CHECK_FALSE(clazz_info.get_class("clazz2")); CHECK_FALSE(clazz_info.get_field("field")); @@ -110,3 +118,40 @@ TEST_CASE("meta/class") { CHECK(cvariable_info.id() == "cvariable"); } } + +TEST_CASE("meta/class/merge") { + namespace meta = meta_hpp; + + meta::class_ clazz_{"clazz"}; + const meta::class_info& clazz_info = clazz_; + + SUBCASE("merge") { + CHECK_NOTHROW(clazz_( + meta::class_("child")( + meta::field_<&clazz::clazz2::field>("field") + ) + )); + + CHECK_NOTHROW(clazz_( + meta::class_("child")( + meta::field_<&clazz::clazz2::cfield>("cfield") + ) + )); + + CHECK_THROWS_AS(clazz_( + meta::class_("child")( + meta::field_<&clazz::clazz3::field>("field") + ) + ), std::logic_error); + + CHECK(clazz_info.get_class("child")); + CHECK(clazz_info.get_class("child")->get_field("field")); + CHECK(clazz_info.get_class("child")->get_field("cfield")); + + { + clazz::clazz2 instance{}; + CHECK(clazz_info.get_class("child")->get_field("field")->get(&instance).to_int() == 21); + CHECK(clazz_info.get_class("child")->get_field("cfield")->get(&instance).to_int() == 22); + } + } +} From e738782c69a1d65badc135bd886d5d5de9bb7987 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 2 Jul 2021 05:18:57 +0700 Subject: [PATCH 017/233] public info merge functions --- headers/meta.hpp/meta_class.hpp | 12 ++++++------ headers/meta.hpp/meta_class_info.hpp | 22 ++++++++++------------ headers/meta.hpp/meta_data.hpp | 2 +- headers/meta.hpp/meta_data_info.hpp | 22 ++++------------------ headers/meta.hpp/meta_field.hpp | 2 +- headers/meta.hpp/meta_field_info.hpp | 12 +++++------- headers/meta.hpp/meta_function.hpp | 2 +- headers/meta.hpp/meta_function_info.hpp | 15 +++++---------- headers/meta.hpp/meta_method.hpp | 2 +- headers/meta.hpp/meta_method_info.hpp | 13 ++++++------- headers/meta.hpp/meta_namespace.hpp | 10 +++++----- headers/meta.hpp/meta_namespace_info.hpp | 16 ++++++++-------- headers/meta.hpp/meta_variable.hpp | 2 +- headers/meta.hpp/meta_variable_info.hpp | 15 +++++---------- 14 files changed, 59 insertions(+), 88 deletions(-) diff --git a/headers/meta.hpp/meta_class.hpp b/headers/meta.hpp/meta_class.hpp index aff8dfb..0e2c4f6 100644 --- a/headers/meta.hpp/meta_class.hpp +++ b/headers/meta.hpp/meta_class.hpp @@ -39,27 +39,27 @@ namespace meta_hpp } private: void add_(const class_info& info) { - detail::merge_with(info_.classes_, info.id(), info, &class_info::merge_with_); + detail::merge_with(info_.classes_, info.id(), info, &class_info::merge); } void add_(const data_info& info) { - detail::merge_with(info_.datas_, info.id(), info, &data_info::merge_with_); + detail::merge_with(info_.datas_, info.id(), info, &data_info::merge); } void add_(const field_info& info) { - detail::merge_with(info_.fields_, info.id(), info, &field_info::merge_with_); + detail::merge_with(info_.fields_, info.id(), info, &field_info::merge); } void add_(const function_info& info) { - detail::merge_with(info_.functions_, info.id(), info, &function_info::merge_with_); + detail::merge_with(info_.functions_, info.id(), info, &function_info::merge); } void add_(const method_info& info) { - detail::merge_with(info_.methods_, info.id(), info, &method_info::merge_with_); + detail::merge_with(info_.methods_, info.id(), info, &method_info::merge); } void add_(const variable_info& info) { - detail::merge_with(info_.variables_, info.id(), info, &variable_info::merge_with_); + detail::merge_with(info_.variables_, info.id(), info, &variable_info::merge); } private: class_info info_; diff --git a/headers/meta.hpp/meta_class_info.hpp b/headers/meta.hpp/meta_class_info.hpp index bc74084..4c2757c 100644 --- a/headers/meta.hpp/meta_class_info.hpp +++ b/headers/meta.hpp/meta_class_info.hpp @@ -104,23 +104,21 @@ namespace meta_hpp std::optional get_variable(std::string_view id) const { return detail::find_opt(variables_, id); } - private: - friend class namespace_info; - template < typename Class > friend class class_; - friend class namespace_; - private: - void merge_with_(const class_info& other) { + void merge(const class_info& other) { if ( fid() != other.fid() ) { throw std::logic_error("class_info::merge failed"); } - detail::merge_with(classes_, other.classes_, &class_info::merge_with_); - detail::merge_with(datas_, other.datas_, &data_info::merge_with_); - detail::merge_with(fields_, other.fields_, &field_info::merge_with_); - detail::merge_with(functions_, other.functions_, &function_info::merge_with_); - detail::merge_with(methods_, other.methods_, &method_info::merge_with_); - detail::merge_with(variables_, other.variables_, &variable_info::merge_with_); + detail::merge_with(classes_, other.classes_, &class_info::merge); + detail::merge_with(datas_, other.datas_, &data_info::merge); + detail::merge_with(fields_, other.fields_, &field_info::merge); + detail::merge_with(functions_, other.functions_, &function_info::merge); + detail::merge_with(methods_, other.methods_, &method_info::merge); + detail::merge_with(variables_, other.variables_, &variable_info::merge); } + private: + template < typename Class > + friend class class_; private: family_id fid_; std::string id_; diff --git a/headers/meta.hpp/meta_data.hpp b/headers/meta.hpp/meta_data.hpp index 14392cf..5dbebec 100644 --- a/headers/meta.hpp/meta_data.hpp +++ b/headers/meta.hpp/meta_data.hpp @@ -32,7 +32,7 @@ namespace meta_hpp } private: void add_(const data_info& info) { - detail::merge_with(info_.datas_, info.id(), info, &data_info::merge_with_); + detail::merge_with(info_.datas_, info.id(), info, &data_info::merge); } private: data_info info_; diff --git a/headers/meta.hpp/meta_data_info.hpp b/headers/meta.hpp/meta_data_info.hpp index e86aa82..c83a0d9 100644 --- a/headers/meta.hpp/meta_data_info.hpp +++ b/headers/meta.hpp/meta_data_info.hpp @@ -43,27 +43,13 @@ namespace meta_hpp std::optional get_data(std::string_view id) const { return detail::find_opt(datas_, id); } - private: - friend class class_info; - friend class field_info; - friend class function_info; - friend class method_info; - friend class namespace_info; - friend class variable_info; - template < typename Class > friend class class_; - template < auto Field > friend class field_; - template < auto Function > friend class function_; - template < auto Method > friend class method_; - friend class namespace_; - template < auto Variable > friend class variable_; - - friend class data_; - private: - void merge_with_(const data_info& other) { + void merge(const data_info& other) { value_ = other.value_; - detail::merge_with(datas_, other.datas_, &data_info::merge_with_); + detail::merge_with(datas_, other.datas_, &data_info::merge); } + private: + friend class data_; private: std::string id_; value value_; diff --git a/headers/meta.hpp/meta_field.hpp b/headers/meta.hpp/meta_field.hpp index 6d3dbdf..61aab5d 100644 --- a/headers/meta.hpp/meta_field.hpp +++ b/headers/meta.hpp/meta_field.hpp @@ -40,7 +40,7 @@ namespace meta_hpp } private: void add_(const data_info& info) { - detail::merge_with(info_.datas_, info.id(), info, &data_info::merge_with_); + detail::merge_with(info_.datas_, info.id(), info, &data_info::merge); } private: field_info info_; diff --git a/headers/meta.hpp/meta_field_info.hpp b/headers/meta.hpp/meta_field_info.hpp index 71e8c24..ed8e534 100644 --- a/headers/meta.hpp/meta_field_info.hpp +++ b/headers/meta.hpp/meta_field_info.hpp @@ -98,18 +98,16 @@ namespace meta_hpp std::optional get_data(std::string_view id) const { return detail::find_opt(datas_, id); } - private: - friend class class_info; - template < typename Class > friend class class_; - template < auto Field > friend class field_; - private: - void merge_with_(const field_info& other) { + void merge(const field_info& other) { if ( fid() != other.fid() ) { throw std::logic_error("field_info::merge failed"); } - detail::merge_with(datas_, other.datas_, &data_info::merge_with_); + detail::merge_with(datas_, other.datas_, &data_info::merge); } + private: + template < auto Field > + friend class field_; private: family_id fid_; std::string id_; diff --git a/headers/meta.hpp/meta_function.hpp b/headers/meta.hpp/meta_function.hpp index 7400ca5..be7ccea 100644 --- a/headers/meta.hpp/meta_function.hpp +++ b/headers/meta.hpp/meta_function.hpp @@ -39,7 +39,7 @@ namespace meta_hpp } private: void add_(const data_info& info) { - detail::merge_with(info_.datas_, info.id(), info, &data_info::merge_with_); + detail::merge_with(info_.datas_, info.id(), info, &data_info::merge); } private: function_info info_; diff --git a/headers/meta.hpp/meta_function_info.hpp b/headers/meta.hpp/meta_function_info.hpp index 7b9dd23..8a4c291 100644 --- a/headers/meta.hpp/meta_function_info.hpp +++ b/headers/meta.hpp/meta_function_info.hpp @@ -103,21 +103,16 @@ namespace meta_hpp std::optional get_data(std::string_view id) const { return detail::find_opt(datas_, id); } - private: - friend class class_info; - friend class namespace_info; - template < typename Class > friend class class_; - friend class namespace_; - - template < auto Function > friend class function_; - private: - void merge_with_(const function_info& other) { + void merge(const function_info& other) { if ( fid() != other.fid() ) { throw std::logic_error("function_info::merge failed"); } - detail::merge_with(datas_, other.datas_, &data_info::merge_with_); + detail::merge_with(datas_, other.datas_, &data_info::merge); } + private: + template < auto Function > + friend class function_; private: family_id fid_; std::string id_; diff --git a/headers/meta.hpp/meta_method.hpp b/headers/meta.hpp/meta_method.hpp index 9a6223f..a509ab9 100644 --- a/headers/meta.hpp/meta_method.hpp +++ b/headers/meta.hpp/meta_method.hpp @@ -40,7 +40,7 @@ namespace meta_hpp } private: void add_(const data_info& info) { - detail::merge_with(info_.datas_, info.id(), info, &data_info::merge_with_); + detail::merge_with(info_.datas_, info.id(), info, &data_info::merge); } private: method_info info_; diff --git a/headers/meta.hpp/meta_method_info.hpp b/headers/meta.hpp/meta_method_info.hpp index f59324b..f36ee9a 100644 --- a/headers/meta.hpp/meta_method_info.hpp +++ b/headers/meta.hpp/meta_method_info.hpp @@ -165,17 +165,16 @@ namespace meta_hpp std::optional get_data(std::string_view id) const { return detail::find_opt(datas_, id); } - private: - friend class class_info; - template < typename Class > friend class class_; - template < auto Method > friend class method_; - private: - void merge_with_(const method_info& other) { + + void merge(const method_info& other) { if ( fid() != other.fid() ) { throw std::logic_error("method_info::merge failed"); } - detail::merge_with(datas_, other.datas_, &data_info::merge_with_); + detail::merge_with(datas_, other.datas_, &data_info::merge); } + private: + template < auto Method > + friend class method_; private: family_id fid_; std::string id_; diff --git a/headers/meta.hpp/meta_namespace.hpp b/headers/meta.hpp/meta_namespace.hpp index c3fd0ce..5ea6740 100644 --- a/headers/meta.hpp/meta_namespace.hpp +++ b/headers/meta.hpp/meta_namespace.hpp @@ -37,23 +37,23 @@ namespace meta_hpp } private: void add_(const class_info& info) { - detail::merge_with(info_.classes_, info.id(), info, &class_info::merge_with_); + detail::merge_with(info_.classes_, info.id(), info, &class_info::merge); } void add_(const data_info& info) { - detail::merge_with(info_.datas_, info.id(), info, &data_info::merge_with_); + detail::merge_with(info_.datas_, info.id(), info, &data_info::merge); } void add_(const function_info& info) { - detail::merge_with(info_.functions_, info.id(), info, &function_info::merge_with_); + detail::merge_with(info_.functions_, info.id(), info, &function_info::merge); } void add_(const namespace_info& info) { - detail::merge_with(info_.namespaces_, info.id(), info, &namespace_info::merge_with_); + detail::merge_with(info_.namespaces_, info.id(), info, &namespace_info::merge); } void add_(const variable_info& info) { - detail::merge_with(info_.variables_, info.id(), info, &variable_info::merge_with_); + detail::merge_with(info_.variables_, info.id(), info, &variable_info::merge); } private: namespace_info info_; diff --git a/headers/meta.hpp/meta_namespace_info.hpp b/headers/meta.hpp/meta_namespace_info.hpp index c8a11f5..07d0985 100644 --- a/headers/meta.hpp/meta_namespace_info.hpp +++ b/headers/meta.hpp/meta_namespace_info.hpp @@ -87,16 +87,16 @@ namespace meta_hpp std::optional get_variable(std::string_view id) const { return detail::find_opt(variables_, id); } + + void merge(const namespace_info& other) { + detail::merge_with(classes_, other.classes_, &class_info::merge); + detail::merge_with(datas_, other.datas_, &data_info::merge); + detail::merge_with(functions_, other.functions_, &function_info::merge); + detail::merge_with(namespaces_, other.namespaces_, &namespace_info::merge); + detail::merge_with(variables_, other.variables_, &variable_info::merge); + } private: friend class namespace_; - private: - void merge_with_(const namespace_info& other) { - detail::merge_with(classes_, other.classes_, &class_info::merge_with_); - detail::merge_with(datas_, other.datas_, &data_info::merge_with_); - detail::merge_with(functions_, other.functions_, &function_info::merge_with_); - detail::merge_with(namespaces_, other.namespaces_, &namespace_info::merge_with_); - detail::merge_with(variables_, other.variables_, &variable_info::merge_with_); - } private: std::string id_; std::map> classes_; diff --git a/headers/meta.hpp/meta_variable.hpp b/headers/meta.hpp/meta_variable.hpp index 6718a0e..ce133ea 100644 --- a/headers/meta.hpp/meta_variable.hpp +++ b/headers/meta.hpp/meta_variable.hpp @@ -38,7 +38,7 @@ namespace meta_hpp } private: void add_(const data_info& info) { - detail::merge_with(info_.datas_, info.id(), info, &data_info::merge_with_); + detail::merge_with(info_.datas_, info.id(), info, &data_info::merge); } private: variable_info info_; diff --git a/headers/meta.hpp/meta_variable_info.hpp b/headers/meta.hpp/meta_variable_info.hpp index 0cc2574..8c0a8b6 100644 --- a/headers/meta.hpp/meta_variable_info.hpp +++ b/headers/meta.hpp/meta_variable_info.hpp @@ -93,21 +93,16 @@ namespace meta_hpp std::optional get_data(std::string_view id) const { return detail::find_opt(datas_, id); } - private: - friend class class_info; - friend class namespace_info; - template < typename Class > friend class class_; - friend class namespace_; - - template < auto Variable > friend class variable_; - private: - void merge_with_(const variable_info& other) { + void merge(const variable_info& other) { if ( fid() != other.fid() ) { throw std::logic_error("variable_info::merge failed"); } - detail::merge_with(datas_, other.datas_, &data_info::merge_with_); + detail::merge_with(datas_, other.datas_, &data_info::merge); } + private: + template < auto Variable > + friend class variable_; private: family_id fid_; std::string id_; From e2b5a721bfd39aabf07d661a7aab0002aa8b23bd Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 2 Jul 2021 06:07:14 +0700 Subject: [PATCH 018/233] private info ctors --- headers/meta.hpp/meta_class_info.hpp | 8 ++++---- headers/meta.hpp/meta_data_info.hpp | 8 ++++---- headers/meta.hpp/meta_field_info.hpp | 8 ++++---- headers/meta.hpp/meta_function_info.hpp | 8 ++++---- headers/meta.hpp/meta_method_info.hpp | 8 ++++---- headers/meta.hpp/meta_namespace_info.hpp | 6 +++--- headers/meta.hpp/meta_variable_info.hpp | 8 ++++---- 7 files changed, 27 insertions(+), 27 deletions(-) diff --git a/headers/meta.hpp/meta_class_info.hpp b/headers/meta.hpp/meta_class_info.hpp index 4c2757c..20ddc2b 100644 --- a/headers/meta.hpp/meta_class_info.hpp +++ b/headers/meta.hpp/meta_class_info.hpp @@ -26,10 +26,6 @@ namespace meta_hpp class_info& operator=(class_info&&) = default; class_info& operator=(const class_info&) = default; - - class_info(family_id fid, std::string id) - : fid_(std::move(fid)) - , id_(std::move(id)) {} public: const family_id& fid() const noexcept { return fid_; @@ -119,6 +115,10 @@ namespace meta_hpp private: template < typename Class > friend class class_; + + class_info(family_id fid, std::string id) + : fid_{std::move(fid)} + , id_{std::move(id)} {} private: family_id fid_; std::string id_; diff --git a/headers/meta.hpp/meta_data_info.hpp b/headers/meta.hpp/meta_data_info.hpp index c83a0d9..773208d 100644 --- a/headers/meta.hpp/meta_data_info.hpp +++ b/headers/meta.hpp/meta_data_info.hpp @@ -20,10 +20,6 @@ namespace meta_hpp data_info& operator=(data_info&&) = default; data_info& operator=(const data_info&) = default; - - data_info(std::string id, value value) - : id_(std::move(id)) - , value_(std::move(value)) {} public: const std::string& id() const noexcept { return id_; @@ -50,6 +46,10 @@ namespace meta_hpp } private: friend class data_; + + data_info(std::string id, value value) + : id_{std::move(id)} + , value_{std::move(value)} {} private: std::string id_; value value_; diff --git a/headers/meta.hpp/meta_field_info.hpp b/headers/meta.hpp/meta_field_info.hpp index ed8e534..ad3e386 100644 --- a/headers/meta.hpp/meta_field_info.hpp +++ b/headers/meta.hpp/meta_field_info.hpp @@ -67,10 +67,6 @@ namespace meta_hpp field_info& operator=(field_info&&) = default; field_info& operator=(const field_info&) = default; - - field_info(family_id fid, std::string id) - : fid_(std::move(fid)) - , id_(std::move(id)) {} public: const family_id& fid() const noexcept { return fid_; @@ -108,6 +104,10 @@ namespace meta_hpp private: template < auto Field > friend class field_; + + field_info(family_id fid, std::string id) + : fid_{std::move(fid)} + , id_{std::move(id)} {} private: family_id fid_; std::string id_; diff --git a/headers/meta.hpp/meta_function_info.hpp b/headers/meta.hpp/meta_function_info.hpp index 8a4c291..22ec424 100644 --- a/headers/meta.hpp/meta_function_info.hpp +++ b/headers/meta.hpp/meta_function_info.hpp @@ -74,10 +74,6 @@ namespace meta_hpp function_info& operator=(function_info&&) = default; function_info& operator=(const function_info&) = default; - - function_info(family_id fid, std::string id) - : fid_(std::move(fid)) - , id_(std::move(id)) {} public: const family_id& fid() const noexcept { return fid_; @@ -113,6 +109,10 @@ namespace meta_hpp private: template < auto Function > friend class function_; + + function_info(family_id fid, std::string id) + : fid_{std::move(fid)} + , id_{std::move(id)} {} private: family_id fid_; std::string id_; diff --git a/headers/meta.hpp/meta_method_info.hpp b/headers/meta.hpp/meta_method_info.hpp index f36ee9a..3198225 100644 --- a/headers/meta.hpp/meta_method_info.hpp +++ b/headers/meta.hpp/meta_method_info.hpp @@ -131,10 +131,6 @@ namespace meta_hpp method_info& operator=(method_info&&) = default; method_info& operator=(const method_info&) = default; - - method_info(family_id fid, std::string id) - : fid_(std::move(fid)) - , id_(std::move(id)) {} public: const family_id& fid() const noexcept { return fid_; @@ -175,6 +171,10 @@ namespace meta_hpp private: template < auto Method > friend class method_; + + method_info(family_id fid, std::string id) + : fid_{std::move(fid)} + , id_{std::move(id)} {} private: family_id fid_; std::string id_; diff --git a/headers/meta.hpp/meta_namespace_info.hpp b/headers/meta.hpp/meta_namespace_info.hpp index 07d0985..66a3f69 100644 --- a/headers/meta.hpp/meta_namespace_info.hpp +++ b/headers/meta.hpp/meta_namespace_info.hpp @@ -25,9 +25,6 @@ namespace meta_hpp namespace_info& operator=(namespace_info&&) = default; namespace_info& operator=(const namespace_info&) = default; - - namespace_info(std::string id) - : id_(std::move(id)) {} public: const std::string& id() const noexcept { return id_; @@ -97,6 +94,9 @@ namespace meta_hpp } private: friend class namespace_; + + namespace_info(std::string id) + : id_{std::move(id)} {} private: std::string id_; std::map> classes_; diff --git a/headers/meta.hpp/meta_variable_info.hpp b/headers/meta.hpp/meta_variable_info.hpp index 8c0a8b6..0438779 100644 --- a/headers/meta.hpp/meta_variable_info.hpp +++ b/headers/meta.hpp/meta_variable_info.hpp @@ -62,10 +62,6 @@ namespace meta_hpp variable_info& operator=(variable_info&&) = default; variable_info& operator=(const variable_info&) = default; - - variable_info(family_id fid, std::string id) - : fid_(std::move(fid)) - , id_(std::move(id)) {} public: const family_id& fid() const noexcept { return fid_; @@ -103,6 +99,10 @@ namespace meta_hpp private: template < auto Variable > friend class variable_; + + variable_info(family_id fid, std::string id) + : fid_{std::move(fid)} + , id_{std::move(id)} {} private: family_id fid_; std::string id_; From ce7f7d0bebc7b40ac4b98869d275e65305b4bcfd Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 2 Jul 2021 07:21:58 +0700 Subject: [PATCH 019/233] less work in registry classes --- headers/meta.hpp/meta_class.hpp | 6 +--- headers/meta.hpp/meta_class_info.hpp | 5 +-- headers/meta.hpp/meta_data.hpp | 6 +--- headers/meta.hpp/meta_field.hpp | 9 +----- headers/meta.hpp/meta_field_info.hpp | 9 ++++-- headers/meta.hpp/meta_function.hpp | 8 +---- headers/meta.hpp/meta_function_info.hpp | 8 +++-- headers/meta.hpp/meta_fwd.hpp | 41 ++++++++++--------------- headers/meta.hpp/meta_method.hpp | 9 +----- headers/meta.hpp/meta_method_info.hpp | 10 ++++-- headers/meta.hpp/meta_namespace.hpp | 6 +--- headers/meta.hpp/meta_type.hpp | 2 +- headers/meta.hpp/meta_variable.hpp | 9 +----- headers/meta.hpp/meta_variable_info.hpp | 10 ++++-- 14 files changed, 53 insertions(+), 85 deletions(-) diff --git a/headers/meta.hpp/meta_class.hpp b/headers/meta.hpp/meta_class.hpp index 0e2c4f6..31a510a 100644 --- a/headers/meta.hpp/meta_class.hpp +++ b/headers/meta.hpp/meta_class.hpp @@ -22,11 +22,7 @@ namespace meta_hpp class class_ { public: explicit class_(std::string id) - : info_{get_family_id(), std::move(id)} {} - - const class_info& info() const noexcept { - return info_; - } + : info_{detail::typename_arg, std::move(id)} {} operator const class_info&() const noexcept { return info_; diff --git a/headers/meta.hpp/meta_class_info.hpp b/headers/meta.hpp/meta_class_info.hpp index 20ddc2b..706fcce 100644 --- a/headers/meta.hpp/meta_class_info.hpp +++ b/headers/meta.hpp/meta_class_info.hpp @@ -116,8 +116,9 @@ namespace meta_hpp template < typename Class > friend class class_; - class_info(family_id fid, std::string id) - : fid_{std::move(fid)} + template < typename Class > + class_info(detail::typename_arg_t, std::string id) + : fid_{get_family_id()} , id_{std::move(id)} {} private: family_id fid_; diff --git a/headers/meta.hpp/meta_data.hpp b/headers/meta.hpp/meta_data.hpp index 5dbebec..f68a9b3 100644 --- a/headers/meta.hpp/meta_data.hpp +++ b/headers/meta.hpp/meta_data.hpp @@ -15,11 +15,7 @@ namespace meta_hpp class data_ { public: explicit data_(std::string id, value value) - : info_(std::move(id), std::move(value)) {} - - const data_info& info() const noexcept { - return info_; - } + : info_{std::move(id), std::move(value)} {} operator const data_info&() const noexcept { return info_; diff --git a/headers/meta.hpp/meta_field.hpp b/headers/meta.hpp/meta_field.hpp index 61aab5d..de7f1bc 100644 --- a/headers/meta.hpp/meta_field.hpp +++ b/headers/meta.hpp/meta_field.hpp @@ -20,14 +20,7 @@ namespace meta_hpp static_assert(std::is_member_object_pointer_v); explicit field_(std::string id) - : info_{get_family_id(), std::move(id)} { - info_.getter_ = &field_detail::getter; - info_.setter_ = &field_detail::setter; - } - - const field_info& info() const noexcept { - return info_; - } + : info_{detail::auto_arg, std::move(id)} {} operator const field_info&() const noexcept { return info_; diff --git a/headers/meta.hpp/meta_field_info.hpp b/headers/meta.hpp/meta_field_info.hpp index ad3e386..2690461 100644 --- a/headers/meta.hpp/meta_field_info.hpp +++ b/headers/meta.hpp/meta_field_info.hpp @@ -105,9 +105,12 @@ namespace meta_hpp template < auto Field > friend class field_; - field_info(family_id fid, std::string id) - : fid_{std::move(fid)} - , id_{std::move(id)} {} + template < typename FieldType, FieldType Field > + field_info(detail::auto_arg_t, std::string id) + : fid_{get_family_id()} + , id_{std::move(id)} + , getter_{&field_detail::getter} + , setter_{&field_detail::setter} {} private: family_id fid_; std::string id_; diff --git a/headers/meta.hpp/meta_function.hpp b/headers/meta.hpp/meta_function.hpp index be7ccea..5dc110a 100644 --- a/headers/meta.hpp/meta_function.hpp +++ b/headers/meta.hpp/meta_function.hpp @@ -20,13 +20,7 @@ namespace meta_hpp static_assert(std::is_function_v>); explicit function_(std::string id) - : info_{get_family_id(), std::move(id)} { - info_.invoke_ = &function_detail::invoke; - } - - const function_info& info() const noexcept { - return info_; - } + : info_{detail::auto_arg, std::move(id)} {} operator const function_info&() const noexcept { return info_; diff --git a/headers/meta.hpp/meta_function_info.hpp b/headers/meta.hpp/meta_function_info.hpp index 22ec424..6d8d355 100644 --- a/headers/meta.hpp/meta_function_info.hpp +++ b/headers/meta.hpp/meta_function_info.hpp @@ -110,9 +110,11 @@ namespace meta_hpp template < auto Function > friend class function_; - function_info(family_id fid, std::string id) - : fid_{std::move(fid)} - , id_{std::move(id)} {} + template < typename FunctionType, FunctionType Function > + function_info(detail::auto_arg_t, std::string id) + : fid_{get_family_id()} + , id_{std::move(id)} + , invoke_{&function_detail::invoke} {} private: family_id fid_; std::string id_; diff --git a/headers/meta.hpp/meta_fwd.hpp b/headers/meta.hpp/meta_fwd.hpp index f736c5a..f5b4bbd 100644 --- a/headers/meta.hpp/meta_fwd.hpp +++ b/headers/meta.hpp/meta_fwd.hpp @@ -22,30 +22,6 @@ #include #include -namespace meta_hpp -{ - class value; - - class registry; - class type; - - class class_info; - class data_info; - class field_info; - class function_info; - class method_info; - class namespace_info; - class variable_info; - - template < typename Class > class class_; - class data_; - template < auto Field > class field_; - template < auto Function > class function_; - template < auto Method > class method_; - class namespace_; - template < auto Variable > class variable_; -} - namespace meta_hpp { struct family_id { @@ -119,6 +95,23 @@ namespace meta_hpp } } +namespace meta_hpp::detail +{ + template < auto Arg > + struct auto_arg_t { + }; + + template < typename Arg > + struct typename_arg_t { + }; + + template < auto Arg > + inline auto_arg_t auto_arg; + + template < typename Arg > + inline typename_arg_t typename_arg; +} + namespace meta_hpp::detail { template < typename K, typename V, typename C, typename K2 > diff --git a/headers/meta.hpp/meta_method.hpp b/headers/meta.hpp/meta_method.hpp index a509ab9..a179cdf 100644 --- a/headers/meta.hpp/meta_method.hpp +++ b/headers/meta.hpp/meta_method.hpp @@ -20,14 +20,7 @@ namespace meta_hpp static_assert(std::is_member_function_pointer_v); explicit method_(std::string id) - : info_{get_family_id(), std::move(id)} { - info_.invoke_ = &method_detail::invoke; - info_.cinvoke_ = &method_detail::cinvoke; - } - - const method_info& info() const noexcept { - return info_; - } + : info_{detail::auto_arg, std::move(id)} {} operator const method_info&() const { return info_; diff --git a/headers/meta.hpp/meta_method_info.hpp b/headers/meta.hpp/meta_method_info.hpp index 3198225..4fcd699 100644 --- a/headers/meta.hpp/meta_method_info.hpp +++ b/headers/meta.hpp/meta_method_info.hpp @@ -139,6 +139,7 @@ namespace meta_hpp const std::string& id() const noexcept { return id_; } + template < typename... Args > value invoke(void* instance, Args&&... args) const { std::array vargs{{std::forward(args)...}}; @@ -172,9 +173,12 @@ namespace meta_hpp template < auto Method > friend class method_; - method_info(family_id fid, std::string id) - : fid_{std::move(fid)} - , id_{std::move(id)} {} + template < typename MethodType, MethodType Method > + method_info(detail::auto_arg_t, std::string id) + : fid_{get_family_id()} + , id_{std::move(id)} + , invoke_{&method_detail::invoke} + , cinvoke_{&method_detail::cinvoke} {} private: family_id fid_; std::string id_; diff --git a/headers/meta.hpp/meta_namespace.hpp b/headers/meta.hpp/meta_namespace.hpp index 5ea6740..9a05806 100644 --- a/headers/meta.hpp/meta_namespace.hpp +++ b/headers/meta.hpp/meta_namespace.hpp @@ -20,11 +20,7 @@ namespace meta_hpp class namespace_ { public: explicit namespace_(std::string id) - : info_(std::move(id)) {} - - const namespace_info& info() const noexcept { - return info_; - } + : info_{std::move(id)} {} operator const namespace_info&() const noexcept { return info_; diff --git a/headers/meta.hpp/meta_type.hpp b/headers/meta.hpp/meta_type.hpp index 8f86765..c2a5ab1 100644 --- a/headers/meta.hpp/meta_type.hpp +++ b/headers/meta.hpp/meta_type.hpp @@ -29,7 +29,7 @@ namespace meta_hpp template < typename Info > type(Info&& info) - : info_(std::forward(info)) {} + : info_{std::forward(info)} {} bool is_class() const noexcept { return std::holds_alternative(info_); } bool is_field() const noexcept { return std::holds_alternative(info_); } diff --git a/headers/meta.hpp/meta_variable.hpp b/headers/meta.hpp/meta_variable.hpp index ce133ea..eabd19f 100644 --- a/headers/meta.hpp/meta_variable.hpp +++ b/headers/meta.hpp/meta_variable.hpp @@ -18,14 +18,7 @@ namespace meta_hpp class variable_ { public: explicit variable_(std::string id) - : info_{get_family_id(), std::move(id)} { - info_.getter_ = &variable_detail::getter; - info_.setter_ = &variable_detail::setter; - } - - const variable_info& info() const noexcept { - return info_; - } + : info_{detail::auto_arg, std::move(id)} {} operator const variable_info&() const noexcept { return info_; diff --git a/headers/meta.hpp/meta_variable_info.hpp b/headers/meta.hpp/meta_variable_info.hpp index 0438779..c407b3f 100644 --- a/headers/meta.hpp/meta_variable_info.hpp +++ b/headers/meta.hpp/meta_variable_info.hpp @@ -70,6 +70,7 @@ namespace meta_hpp const std::string& id() const noexcept { return id_; } + value get() const { return getter_(); } @@ -100,9 +101,12 @@ namespace meta_hpp template < auto Variable > friend class variable_; - variable_info(family_id fid, std::string id) - : fid_{std::move(fid)} - , id_{std::move(id)} {} + template < typename VariableType, VariableType Variable > + variable_info(detail::auto_arg_t, std::string id) + : fid_{get_family_id()} + , id_{std::move(id)} + , getter_{&variable_detail::getter} + , setter_{&variable_detail::setter} {} private: family_id fid_; std::string id_; From 7c4f6e00353e435c74ef6c325fc4c7510484dbed Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 2 Jul 2021 08:16:25 +0700 Subject: [PATCH 020/233] fix msvc compilation --- headers/meta.hpp/meta_value.hpp | 6 ++++-- headers/meta.hpp/meta_variable_info.hpp | 8 ++++---- untests/meta_value_tests.cpp | 24 +++++++++++++----------- 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/headers/meta.hpp/meta_value.hpp b/headers/meta.hpp/meta_value.hpp index aa6a910..f4f7552 100644 --- a/headers/meta.hpp/meta_value.hpp +++ b/headers/meta.hpp/meta_value.hpp @@ -39,6 +39,7 @@ namespace meta_hpp public: bool to_bool() const { return cast(); } int to_int() const { return cast(); } + unsigned to_uint() const { return cast(); } float to_float() const { return cast(); } double to_double() const { return cast(); } std::string to_string() const { return cast(); } @@ -47,14 +48,15 @@ namespace meta_hpp std::int16_t to_int16() const { return cast(); } std::int32_t to_int32() const { return cast(); } std::int64_t to_int64() const { return cast(); } + std::ptrdiff_t to_ptrdiff_t() const { return cast(); } + std::intptr_t to_intptr_t() const { return cast(); } std::uint8_t to_uint8() const { return cast(); } std::uint16_t to_uint16() const { return cast(); } std::uint32_t to_uint32() const { return cast(); } std::uint64_t to_uint64() const { return cast(); } - std::size_t to_size_t() const { return cast(); } - std::ptrdiff_t to_ptrdiff_t() const { return cast(); } + std::uintptr_t to_uintptr_t() const { return cast(); } private: std::any raw_; }; diff --git a/headers/meta.hpp/meta_variable_info.hpp b/headers/meta.hpp/meta_variable_info.hpp index c407b3f..9e6b27b 100644 --- a/headers/meta.hpp/meta_variable_info.hpp +++ b/headers/meta.hpp/meta_variable_info.hpp @@ -23,14 +23,14 @@ namespace meta_hpp::variable_detail }; template < typename T > - struct variable_traits { + struct variable_traits + : variable_traits { static constexpr bool is_const = true; - using value_type = T; }; template < auto Variable > value getter() { - using vt = variable_traits; + using vt = variable_traits>; using value_type = typename vt::value_type; value_type typed_value = *Variable; @@ -40,7 +40,7 @@ namespace meta_hpp::variable_detail template < auto Variable > void setter(value value) { - using vt = variable_traits; + using vt = variable_traits>; using value_type = typename vt::value_type; if constexpr ( !vt::is_const ) { diff --git a/untests/meta_value_tests.cpp b/untests/meta_value_tests.cpp index 6e4a5aa..7de31cd 100644 --- a/untests/meta_value_tests.cpp +++ b/untests/meta_value_tests.cpp @@ -17,20 +17,22 @@ TEST_CASE("meta/value") { CHECK(meta::value{true}.to_bool() == true); CHECK(meta::value{1}.to_int() == 1); + CHECK(meta::value{1u}.to_uint() == 1u); CHECK(meta::value{1.f}.to_float() == 1.f); CHECK(meta::value{1.0}.to_double() == 1.0); CHECK(meta::value{"meta"s}.to_string() == "meta"); - CHECK(meta::value{std::in_place_type, 1}.to_int8() == 1); - CHECK(meta::value{std::in_place_type, 1}.to_int16() == 1); - CHECK(meta::value{std::in_place_type, 1}.to_int32() == 1); - CHECK(meta::value{std::in_place_type, 1}.to_int64() == 1); + CHECK(meta::value{std::in_place_type, std::int8_t{1}}.to_int8() == 1); + CHECK(meta::value{std::in_place_type, std::int16_t{1}}.to_int16() == 1); + CHECK(meta::value{std::in_place_type, std::int32_t{1}}.to_int32() == 1); + CHECK(meta::value{std::in_place_type, std::int64_t{1}}.to_int64() == 1); + CHECK(meta::value{std::in_place_type, std::ptrdiff_t{1}}.to_ptrdiff_t() == 1); + CHECK(meta::value{std::in_place_type, std::intptr_t{1}}.to_intptr_t() == 1); - CHECK(meta::value{std::in_place_type, 1}.to_uint8() == 1u); - CHECK(meta::value{std::in_place_type, 1}.to_uint16() == 1u); - CHECK(meta::value{std::in_place_type, 1}.to_uint32() == 1u); - CHECK(meta::value{std::in_place_type, 1}.to_uint64() == 1u); - - CHECK(meta::value{std::in_place_type, 1}.to_size_t() == 1u); - CHECK(meta::value{std::in_place_type, 1}.to_ptrdiff_t() == 1u); + CHECK(meta::value{std::in_place_type, std::uint8_t{1}}.to_uint8() == 1u); + CHECK(meta::value{std::in_place_type, std::uint16_t{1}}.to_uint16() == 1u); + CHECK(meta::value{std::in_place_type, std::uint32_t{1}}.to_uint32() == 1u); + CHECK(meta::value{std::in_place_type, std::uint64_t{1}}.to_uint64() == 1u); + CHECK(meta::value{std::in_place_type, std::size_t{1}}.to_size_t() == 1u); + CHECK(meta::value{std::in_place_type, std::uintptr_t{1}}.to_uintptr_t() == 1u); } From 4a5b60eb65f34530961344fab4a36f3a93b2cb15 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 2 Jul 2021 08:32:56 +0700 Subject: [PATCH 021/233] temporary remove msvc 2017 --- .github/workflows/windows.yml | 2 -- README.md | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 1c48908..985cf43 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -10,8 +10,6 @@ jobs: matrix: config: # https://github.com/actions/virtual-environments/tree/main/images/win - - { os: "windows-2016", vs: "Visual Studio 2017", arch: "x86" } - - { os: "windows-2016", vs: "Visual Studio 2017", arch: "x64" } - { os: "windows-2019", vs: "Visual Studio 2019", arch: "x86" } - { os: "windows-2019", vs: "Visual Studio 2019", arch: "x64" } name: "${{matrix.config.vs}} ${{matrix.config.arch}}" diff --git a/README.md b/README.md index cad2743..c9051a5 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ - [gcc](https://www.gnu.org/software/gcc/) **>= 7** - [clang](https://clang.llvm.org/) **>= 5.0** -- [msvc](https://visualstudio.microsoft.com/) **>= 2017** +- [msvc](https://visualstudio.microsoft.com/) **>= 2019** ## Installation From e0cd11370ddc5c05bb336cc6e222eb750a38f93c Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 2 Jul 2021 08:48:48 +0700 Subject: [PATCH 022/233] more compilers --- .github/workflows/linux.yml | 1 + README.md | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 3f508ac..8d7085b 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -14,6 +14,7 @@ jobs: - { os: "ubuntu-20.04", cc: "gcc-8", cxx: "g++-8" } - { os: "ubuntu-20.04", cc: "gcc-9", cxx: "g++-9" } - { os: "ubuntu-20.04", cc: "gcc-10", cxx: "g++-10" } + - { os: "ubuntu-20.04", cc: "clang-7", cxx: "clang++-7" } - { os: "ubuntu-20.04", cc: "clang-8", cxx: "clang++-8" } - { os: "ubuntu-20.04", cc: "clang-9", cxx: "clang++-9" } - { os: "ubuntu-20.04", cc: "clang-10", cxx: "clang++-10" } diff --git a/README.md b/README.md index c9051a5..c02fbbe 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ ## Requirements - [gcc](https://www.gnu.org/software/gcc/) **>= 7** -- [clang](https://clang.llvm.org/) **>= 5.0** +- [clang](https://clang.llvm.org/) **>= 7** - [msvc](https://visualstudio.microsoft.com/) **>= 2019** ## Installation From a7fe249964f14ab84abf265c794cb6731367128f Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 2 Jul 2021 09:00:51 +0700 Subject: [PATCH 023/233] fix gcc-7 warnings --- headers/meta.hpp/meta_class_info.hpp | 24 ++++++++++++------------ headers/meta.hpp/meta_data_info.hpp | 4 ++-- headers/meta.hpp/meta_field_info.hpp | 4 ++-- headers/meta.hpp/meta_function_info.hpp | 4 ++-- headers/meta.hpp/meta_method_info.hpp | 4 ++-- headers/meta.hpp/meta_namespace_info.hpp | 20 ++++++++++---------- headers/meta.hpp/meta_variable_info.hpp | 4 ++-- 7 files changed, 32 insertions(+), 32 deletions(-) diff --git a/headers/meta.hpp/meta_class_info.hpp b/headers/meta.hpp/meta_class_info.hpp index 706fcce..c2241c0 100644 --- a/headers/meta.hpp/meta_class_info.hpp +++ b/headers/meta.hpp/meta_class_info.hpp @@ -37,43 +37,43 @@ namespace meta_hpp template < typename F > void each_class(F&& f) const { - for ( auto [_, info] : classes_ ) { - std::invoke(f, info); + for ( auto&& id_info : classes_ ) { + std::invoke(f, id_info.second); } } template < typename F > void each_data(F&& f) const { - for ( auto [_, info] : datas_ ) { - std::invoke(f, info); + for ( auto&& id_info : datas_ ) { + std::invoke(f, id_info.second); } } template < typename F > void each_field(F&& f) const { - for ( auto [_, info] : fields_ ) { - std::invoke(f, info); + for ( auto&& id_info : fields_ ) { + std::invoke(f, id_info.second); } } template < typename F > void each_function(F&& f) const { - for ( auto [_, info] : functions_ ) { - std::invoke(f, info); + for ( auto&& id_info : functions_ ) { + std::invoke(f, id_info.second); } } template < typename F > void each_method(F&& f) const { - for ( auto [_, info] : methods_ ) { - std::invoke(f, info); + for ( auto&& id_info : methods_ ) { + std::invoke(f, id_info.second); } } template < typename F > void each_variable(F&& f) const { - for ( auto [_, info] : variables_ ) { - std::invoke(f, info); + for ( auto&& id_info : variables_ ) { + std::invoke(f, id_info.second); } } diff --git a/headers/meta.hpp/meta_data_info.hpp b/headers/meta.hpp/meta_data_info.hpp index 773208d..b9cbbae 100644 --- a/headers/meta.hpp/meta_data_info.hpp +++ b/headers/meta.hpp/meta_data_info.hpp @@ -31,8 +31,8 @@ namespace meta_hpp template < typename F > void each_data(F&& f) const { - for ( auto [_, info] : datas_ ) { - std::invoke(f, info); + for ( auto&& id_info : datas_ ) { + std::invoke(f, id_info.second); } } diff --git a/headers/meta.hpp/meta_field_info.hpp b/headers/meta.hpp/meta_field_info.hpp index 2690461..e4b9f00 100644 --- a/headers/meta.hpp/meta_field_info.hpp +++ b/headers/meta.hpp/meta_field_info.hpp @@ -86,8 +86,8 @@ namespace meta_hpp template < typename F > void each_data(F&& f) const { - for ( auto [_, info] : datas_ ) { - std::invoke(f, info); + for ( auto&& id_info : datas_ ) { + std::invoke(f, id_info.second); } } diff --git a/headers/meta.hpp/meta_function_info.hpp b/headers/meta.hpp/meta_function_info.hpp index 6d8d355..443b3bb 100644 --- a/headers/meta.hpp/meta_function_info.hpp +++ b/headers/meta.hpp/meta_function_info.hpp @@ -91,8 +91,8 @@ namespace meta_hpp template < typename F > void each_data(F&& f) const { - for ( auto [_, info] : datas_ ) { - std::invoke(f, info); + for ( auto&& id_info : datas_ ) { + std::invoke(f, id_info.second); } } diff --git a/headers/meta.hpp/meta_method_info.hpp b/headers/meta.hpp/meta_method_info.hpp index 4fcd699..8025b44 100644 --- a/headers/meta.hpp/meta_method_info.hpp +++ b/headers/meta.hpp/meta_method_info.hpp @@ -154,8 +154,8 @@ namespace meta_hpp template < typename F > void each_data(F&& f) const { - for ( auto [_, info] : datas_ ) { - std::invoke(f, info); + for ( auto&& id_info : datas_ ) { + std::invoke(f, id_info.second); } } diff --git a/headers/meta.hpp/meta_namespace_info.hpp b/headers/meta.hpp/meta_namespace_info.hpp index 66a3f69..a27584c 100644 --- a/headers/meta.hpp/meta_namespace_info.hpp +++ b/headers/meta.hpp/meta_namespace_info.hpp @@ -32,36 +32,36 @@ namespace meta_hpp template < typename F > void each_class(F&& f) const { - for ( auto [_, info] : classes_ ) { - std::invoke(f, info); + for ( auto&& id_info : classes_ ) { + std::invoke(f, id_info.second); } } template < typename F > void each_data(F&& f) const { - for ( auto [_, info] : datas_ ) { - std::invoke(f, info); + for ( auto&& id_info : datas_ ) { + std::invoke(f, id_info.second); } } template < typename F > void each_function(F&& f) const { - for ( auto [_, info] : functions_ ) { - std::invoke(f, info); + for ( auto&& id_info : functions_ ) { + std::invoke(f, id_info.second); } } template < typename F > void each_namespace(F&& f) const { - for ( auto [_, info] : namespaces_ ) { - std::invoke(f, info); + for ( auto&& id_info : namespaces_ ) { + std::invoke(f, id_info.second); } } template < typename F > void each_variable(F&& f) const { - for ( auto [_, info] : variables_ ) { - std::invoke(f, info); + for ( auto&& id_info : variables_ ) { + std::invoke(f, id_info.second); } } diff --git a/headers/meta.hpp/meta_variable_info.hpp b/headers/meta.hpp/meta_variable_info.hpp index 9e6b27b..f4e2f7b 100644 --- a/headers/meta.hpp/meta_variable_info.hpp +++ b/headers/meta.hpp/meta_variable_info.hpp @@ -82,8 +82,8 @@ namespace meta_hpp template < typename F > void each_data(F&& f) const { - for ( auto [_, info] : datas_ ) { - std::invoke(f, info); + for ( auto&& id_info : datas_ ) { + std::invoke(f, id_info.second); } } From bc621df5c818b06e0ce4ec91f816df6b05729c22 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 2 Jul 2021 09:09:30 +0700 Subject: [PATCH 024/233] warning as error for tests --- untests/CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/untests/CMakeLists.txt b/untests/CMakeLists.txt index 3bb8c0c..2748725 100644 --- a/untests/CMakeLists.txt +++ b/untests/CMakeLists.txt @@ -23,13 +23,13 @@ target_link_libraries(${PROJECT_NAME} meta.hpp) target_compile_options(${PROJECT_NAME} PRIVATE $<$: - /W4> + /WX /W4> PRIVATE $<$: - -Wall -Wextra -Wpedantic> + -Werror -Wall -Wextra -Wpedantic> PRIVATE $<$,$>: - -Weverything -Wno-unknown-warning-option + -Werror -Weverything -Wno-unknown-warning-option -Wconversion -Wimplicit-int-float-conversion -Wno-c++98-compat-pedantic -Wno-ctad-maybe-unsupported -Wno-float-equal -Wno-double-promotion -Wno-shadow-field-in-constructor>) From 89e47e538861fe799725861f6821dfd1a9075f0e Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sun, 4 Jul 2021 01:34:18 +0700 Subject: [PATCH 025/233] 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); } } From 699f6beb76080095ee86e5cd4b5796c18170bb58 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sun, 4 Jul 2021 22:35:01 +0700 Subject: [PATCH 026/233] visit info function --- headers/meta.hpp/meta_class_info.hpp | 10 ++++++++++ headers/meta.hpp/meta_data_info.hpp | 5 +++++ headers/meta.hpp/meta_field_info.hpp | 5 +++++ headers/meta.hpp/meta_function_info.hpp | 5 +++++ headers/meta.hpp/meta_fwd.hpp | 11 +++++++++++ headers/meta.hpp/meta_method_info.hpp | 5 +++++ headers/meta.hpp/meta_namespace_info.hpp | 9 +++++++++ headers/meta.hpp/meta_variable_info.hpp | 5 +++++ 8 files changed, 55 insertions(+) diff --git a/headers/meta.hpp/meta_class_info.hpp b/headers/meta.hpp/meta_class_info.hpp index c2241c0..488346d 100644 --- a/headers/meta.hpp/meta_class_info.hpp +++ b/headers/meta.hpp/meta_class_info.hpp @@ -77,6 +77,16 @@ namespace meta_hpp } } + template < typename F > + void visit(F&& f) const { + each_class(f); + each_data(f); + each_field(f); + each_function(f); + each_method(f); + each_variable(f); + } + std::optional get_class(std::string_view id) const { return detail::find_opt(classes_, id); } diff --git a/headers/meta.hpp/meta_data_info.hpp b/headers/meta.hpp/meta_data_info.hpp index b9cbbae..fc32ab4 100644 --- a/headers/meta.hpp/meta_data_info.hpp +++ b/headers/meta.hpp/meta_data_info.hpp @@ -36,6 +36,11 @@ namespace meta_hpp } } + template < typename F > + void visit(F&& f) const { + each_data(f); + } + std::optional get_data(std::string_view id) const { return detail::find_opt(datas_, id); } diff --git a/headers/meta.hpp/meta_field_info.hpp b/headers/meta.hpp/meta_field_info.hpp index e4b9f00..6e4f9bb 100644 --- a/headers/meta.hpp/meta_field_info.hpp +++ b/headers/meta.hpp/meta_field_info.hpp @@ -91,6 +91,11 @@ namespace meta_hpp } } + template < typename F > + void visit(F&& f) const { + each_data(f); + } + std::optional get_data(std::string_view id) const { return detail::find_opt(datas_, id); } diff --git a/headers/meta.hpp/meta_function_info.hpp b/headers/meta.hpp/meta_function_info.hpp index 06dbaf2..0d9c0e9 100644 --- a/headers/meta.hpp/meta_function_info.hpp +++ b/headers/meta.hpp/meta_function_info.hpp @@ -96,6 +96,11 @@ namespace meta_hpp } } + template < typename F > + void visit(F&& f) const { + each_data(f); + } + std::optional get_data(std::string_view id) const { return detail::find_opt(datas_, id); } diff --git a/headers/meta.hpp/meta_fwd.hpp b/headers/meta.hpp/meta_fwd.hpp index f5b4bbd..2a607b4 100644 --- a/headers/meta.hpp/meta_fwd.hpp +++ b/headers/meta.hpp/meta_fwd.hpp @@ -22,6 +22,17 @@ #include #include +namespace meta_hpp +{ + template < typename... Ts > + struct overloaded : Ts... { + using Ts::operator()...; + }; + + template < typename... Ts > + overloaded(Ts...) -> overloaded; +} + namespace meta_hpp { struct family_id { diff --git a/headers/meta.hpp/meta_method_info.hpp b/headers/meta.hpp/meta_method_info.hpp index 6f31031..894ca8b 100644 --- a/headers/meta.hpp/meta_method_info.hpp +++ b/headers/meta.hpp/meta_method_info.hpp @@ -159,6 +159,11 @@ namespace meta_hpp } } + template < typename F > + void visit(F&& f) const { + each_data(f); + } + std::optional get_data(std::string_view id) const { return detail::find_opt(datas_, id); } diff --git a/headers/meta.hpp/meta_namespace_info.hpp b/headers/meta.hpp/meta_namespace_info.hpp index a27584c..4df3cc3 100644 --- a/headers/meta.hpp/meta_namespace_info.hpp +++ b/headers/meta.hpp/meta_namespace_info.hpp @@ -65,6 +65,15 @@ namespace meta_hpp } } + template < typename F > + void visit(F&& f) const { + each_class(f); + each_data(f); + each_function(f); + each_namespace(f); + each_variable(f); + } + std::optional get_class(std::string_view id) const { return detail::find_opt(classes_, id); } diff --git a/headers/meta.hpp/meta_variable_info.hpp b/headers/meta.hpp/meta_variable_info.hpp index f4e2f7b..1d0a20e 100644 --- a/headers/meta.hpp/meta_variable_info.hpp +++ b/headers/meta.hpp/meta_variable_info.hpp @@ -87,6 +87,11 @@ namespace meta_hpp } } + template < typename F > + void visit(F&& f) const { + each_data(f); + } + std::optional get_data(std::string_view id) const { return detail::find_opt(datas_, id); } From 7df45ed270bc8bcdbea28e739019dc0027dcb698 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sun, 4 Jul 2021 22:59:58 +0700 Subject: [PATCH 027/233] merge types in registry --- headers/meta.hpp/meta_registry.hpp | 176 ++++++++++++++++++++--------- headers/meta.hpp/meta_type.hpp | 88 +++++++++++++-- untests/meta_examples.cpp | 2 +- untests/meta_registry_tests.cpp | 76 +++++++++++-- untests/meta_type_tests.cpp | 31 ++++- 5 files changed, 288 insertions(+), 85 deletions(-) diff --git a/headers/meta.hpp/meta_registry.hpp b/headers/meta.hpp/meta_registry.hpp index feb24ae..149189a 100644 --- a/headers/meta.hpp/meta_registry.hpp +++ b/headers/meta.hpp/meta_registry.hpp @@ -21,88 +21,152 @@ namespace meta_hpp { class registry { public: + template < typename T > + std::optional resolve() const { + return detail::find_opt(family_to_types_, get_family_id()); + } + template < auto T > std::optional resolve() const { - const family_id fid = get_family_id(); - return detail::find_opt(family_to_types_, fid); + return resolve(); } template < typename T > - std::optional resolve() const { - const family_id fid = get_family_id(); - return detail::find_opt(family_to_types_, fid); + std::optional resolve(T&&) const { + return resolve>(); } - template < typename T > - std::optional resolve(const T&) const { - const family_id fid = get_family_id(); - return detail::find_opt(family_to_types_, fid); + std::optional get_class_by_name(std::string_view name) const { + return detail::find_opt(name_to_classes_, name); + } + + std::optional get_field_by_name(std::string_view name) const { + return detail::find_opt(name_to_fields_, name); + } + + std::optional get_function_by_name(std::string_view name) const { + return detail::find_opt(name_to_functions_, name); + } + + std::optional get_method_by_name(std::string_view name) const { + return detail::find_opt(name_to_methods_, name); + } + + std::optional get_namespace_by_name(std::string_view name) const { + return detail::find_opt(name_to_namespaces_, name); + } + + std::optional get_variable_by_name(std::string_view name) const { + return detail::find_opt(name_to_variables_, name); } template < typename... Internals > registry& operator()(Internals&&...internals) { - (add_(std::forward(internals)), ...); + (add_(std::string{}, std::forward(internals)), ...); return *this; } private: - void add_(const class_info& info) { - family_to_types_.emplace(info.fid(), info); + void add_(const std::string& prefix, const class_info& info) { + const std::string name = prefix.empty() + ? info.id() + : prefix + "::" + info.id(); - info.each_class([this](const class_info& internal){ - add_(internal); - }); + detail::merge_with(name_to_classes_, name, info, &class_info::merge); + detail::merge_with(family_to_types_, info.fid(), info, &type::merge); - info.each_field([this](const field_info& internal){ - add_(internal); - }); - - info.each_function([this](const function_info& internal){ - add_(internal); - }); - - info.each_method([this](const method_info& internal){ - add_(internal); - }); - - info.each_variable([this](const variable_info& internal){ - add_(internal); + info.visit(overloaded { + [](const data_info&) {}, + [this, &name](const auto& internal){ + add_(name, internal); + } }); } - void add_(const field_info& info) { - family_to_types_.emplace(info.fid(), info); - } + void add_(const std::string& prefix, const field_info& info) { + const std::string name = prefix.empty() + ? info.id() + : prefix + "::" + info.id(); - void add_(const function_info& info) { - family_to_types_.emplace(info.fid(), info); - } + detail::merge_with(name_to_fields_, name, info, &field_info::merge); + detail::merge_with(family_to_types_, info.fid(), info, &type::merge); - void add_(const method_info& info) { - family_to_types_.emplace(info.fid(), info); - } - - void add_(const namespace_info& info) { - info.each_class([this](const class_info& internal){ - add_(internal); - }); - - info.each_function([this](const function_info& internal){ - add_(internal); - }); - - info.each_namespace([this](const namespace_info& internal){ - add_(internal); - }); - - info.each_variable([this](const variable_info& internal){ - add_(internal); + info.visit(overloaded { + [](const data_info&) {}, + [this, &name](const auto& internal){ + add_(name, internal); + } }); } - void add_(const variable_info& info) { - family_to_types_.emplace(info.fid(), info); + void add_(const std::string& prefix, const function_info& info) { + const std::string name = prefix.empty() + ? info.id() + : prefix + "::" + info.id(); + + detail::merge_with(name_to_functions_, name, info, &function_info::merge); + detail::merge_with(family_to_types_, info.fid(), info, &type::merge); + + info.visit(overloaded { + [](const data_info&) {}, + [this, &name](const auto& internal){ + add_(name, internal); + } + }); + } + + void add_(const std::string& prefix, const method_info& info) { + const std::string name = prefix.empty() + ? info.id() + : prefix + "::" + info.id(); + + detail::merge_with(name_to_methods_, name, info, &method_info::merge); + detail::merge_with(family_to_types_, info.fid(), info, &type::merge); + + info.visit(overloaded { + [](const data_info&) {}, + [this, &name](const auto& internal){ + add_(name, internal); + } + }); + } + + void add_(const std::string& prefix, const namespace_info& info) { + const std::string name = prefix.empty() + ? info.id() + : prefix + "::" + info.id(); + + detail::merge_with(name_to_namespaces_, name, info, &namespace_info::merge); + + info.visit(overloaded { + [](const data_info&) {}, + [this, &name](const auto& internal){ + add_(name, internal); + } + }); + } + + void add_(const std::string& prefix, const variable_info& info) { + const std::string name = prefix.empty() + ? info.id() + : prefix + "::" + info.id(); + + detail::merge_with(name_to_variables_, name, info, &variable_info::merge); + detail::merge_with(family_to_types_, info.fid(), info, &type::merge); + + info.visit(overloaded { + [](const data_info&) {}, + [this, &name](const auto& internal){ + add_(name, internal); + } + }); } private: std::map> family_to_types_; + std::map> name_to_classes_; + std::map> name_to_fields_; + std::map> name_to_functions_; + std::map> name_to_methods_; + std::map> name_to_namespaces_; + std::map> name_to_variables_; }; } diff --git a/headers/meta.hpp/meta_type.hpp b/headers/meta.hpp/meta_type.hpp index c2a5ab1..01033e9 100644 --- a/headers/meta.hpp/meta_type.hpp +++ b/headers/meta.hpp/meta_type.hpp @@ -31,19 +31,83 @@ namespace meta_hpp type(Info&& info) : info_{std::forward(info)} {} - bool is_class() const noexcept { return std::holds_alternative(info_); } - bool is_field() const noexcept { return std::holds_alternative(info_); } - bool is_function() const noexcept { return std::holds_alternative(info_); } - bool is_method() const noexcept { return std::holds_alternative(info_); } - bool is_namespace() const noexcept { return std::holds_alternative(info_); } - bool is_variable() const noexcept { return std::holds_alternative(info_); } + bool is_class() const noexcept { + return std::holds_alternative(info_); + } - const class_info& get_class_info() const { return std::get(info_); } - const field_info& get_field_info() const { return std::get(info_); } - const function_info& get_function_info() const { return std::get(info_); } - const method_info& get_method_info() const { return std::get(info_); } - const namespace_info& get_namespace_info() const { return std::get(info_); } - const variable_info& get_variable_info() const { return std::get(info_); } + bool is_field() const noexcept { + return std::holds_alternative(info_); + } + + bool is_function() const noexcept { + return std::holds_alternative(info_); + } + + bool is_method() const noexcept { + return std::holds_alternative(info_); + } + + bool is_namespace() const noexcept { + return std::holds_alternative(info_); + } + + bool is_variable() const noexcept { + return std::holds_alternative(info_); + } + + std::optional get_class() const { + if ( const class_info* info = std::get_if(&info_); info ) { + return *info; + } + return std::nullopt; + } + + std::optional get_field() const { + if ( const field_info* info = std::get_if(&info_); info ) { + return *info; + } + return std::nullopt; + } + + std::optional get_function() const { + if ( const function_info* info = std::get_if(&info_); info ) { + return *info; + } + return std::nullopt; + } + + std::optional get_method() const { + if ( const method_info* info = std::get_if(&info_); info ) { + return *info; + } + return std::nullopt; + } + + std::optional get_namespace() const { + if ( const namespace_info* info = std::get_if(&info_); info ) { + return *info; + } + return std::nullopt; + } + + std::optional get_variable() const { + if ( const variable_info* info = std::get_if(&info_); info ) { + return *info; + } + return std::nullopt; + } + + void merge(const type& other) { + if ( info_.index() != other.info_.index() ) { + throw std::logic_error("type::merge failed"); + } + std::visit(overloaded { + [&other](auto& info){ + using info_type = std::remove_reference_t; + info.merge(std::get(other.info_)); + } + }, info_); + } private: std::variant< class_info, diff --git a/untests/meta_examples.cpp b/untests/meta_examples.cpp index 8c97308..1c377ef 100644 --- a/untests/meta_examples.cpp +++ b/untests/meta_examples.cpp @@ -173,7 +173,7 @@ TEST_CASE("meta/examples/advanced") { ivec3 v3{1,2,3}; type v3_type = db.resolve(v3).value(); - class_info v3_info = v3_type.get_class_info(); + class_info v3_info = v3_type.get_class().value(); std::cout << "class " << v3_info.id() << std::endl; diff --git a/untests/meta_registry_tests.cpp b/untests/meta_registry_tests.cpp index 7dce6b8..1ab1574 100644 --- a/untests/meta_registry_tests.cpp +++ b/untests/meta_registry_tests.cpp @@ -68,13 +68,22 @@ TEST_CASE("meta/registry") { ) ); + SUBCASE("get_xxx_by_name") { + CHECK(registry.get_class_by_name("vmath::ivec2")); + CHECK(registry.get_field_by_name("vmath::ivec2::x")); + CHECK(registry.get_function_by_name("vmath::iadd2")); + CHECK(registry.get_method_by_name("vmath::ivec2::dot")); + CHECK(registry.get_namespace_by_name("vmath")); + CHECK(registry.get_variable_by_name("vmath::ivec2::zero")); + } + SUBCASE("class_template") { CHECK(registry.resolve()); const meta::type ivec2_type = registry.resolve().value(); CHECK(ivec2_type.is_class()); - const meta::class_info& ivec2_info = ivec2_type.get_class_info(); + const meta::class_info ivec2_info = ivec2_type.get_class().value(); CHECK(ivec2_info.id() == "ivec2"); } @@ -85,7 +94,7 @@ TEST_CASE("meta/registry") { const meta::type ivec3_type = registry.resolve(v3).value(); CHECK(ivec3_type.is_class()); - const meta::class_info& ivec3_info = ivec3_type.get_class_info(); + const meta::class_info ivec3_info = ivec3_type.get_class().value(); CHECK(ivec3_info.id() == "ivec3"); } @@ -95,7 +104,7 @@ TEST_CASE("meta/registry") { const meta::type ivec2_x_type = registry.resolve<&ivec2::x>().value(); CHECK(ivec2_x_type.is_field()); - const meta::field_info& ivec2_x_info = ivec2_x_type.get_field_info(); + const meta::field_info ivec2_x_info = ivec2_x_type.get_field().value(); CHECK(ivec2_x_info.id() == "x"); } @@ -105,7 +114,7 @@ TEST_CASE("meta/registry") { const meta::type ivec3_x_type = registry.resolve<&ivec3::x>().value(); CHECK(ivec3_x_type.is_field()); - const meta::field_info& ivec3_x_info = ivec3_x_type.get_field_info(); + const meta::field_info ivec3_x_info = ivec3_x_type.get_field().value(); CHECK(ivec3_x_info.id() == "x"); } @@ -115,7 +124,7 @@ TEST_CASE("meta/registry") { const meta::type iadd2_type = registry.resolve<&iadd2>().value(); CHECK(iadd2_type.is_function()); - const meta::function_info& iadd2_info = iadd2_type.get_function_info(); + const meta::function_info iadd2_info = iadd2_type.get_function().value(); CHECK(iadd2_info.id() == "iadd2"); } @@ -125,7 +134,7 @@ TEST_CASE("meta/registry") { const meta::type iadd3_type = registry.resolve<&iadd3>().value(); CHECK(iadd3_type.is_function()); - const meta::function_info& iadd3_info = iadd3_type.get_function_info(); + const meta::function_info iadd3_info = iadd3_type.get_function().value(); CHECK(iadd3_info.id() == "iadd3"); } @@ -135,7 +144,7 @@ TEST_CASE("meta/registry") { const meta::type ivec2_dot_type = registry.resolve<&ivec2::dot>().value(); CHECK(ivec2_dot_type.is_method()); - const meta::method_info& ivec2_dot_info = ivec2_dot_type.get_method_info(); + const meta::method_info ivec2_dot_info = ivec2_dot_type.get_method().value(); CHECK(ivec2_dot_info.id() == "dot"); } @@ -145,7 +154,7 @@ TEST_CASE("meta/registry") { const meta::type ivec3_dot_type = registry.resolve<&ivec3::dot>().value(); CHECK(ivec3_dot_type.is_method()); - const meta::method_info& ivec3_dot_info = ivec3_dot_type.get_method_info(); + const meta::method_info ivec3_dot_info = ivec3_dot_type.get_method().value(); CHECK(ivec3_dot_info.id() == "dot"); } @@ -155,7 +164,7 @@ TEST_CASE("meta/registry") { const meta::type ivec2_zero_type = registry.resolve<&ivec2::zero>().value(); CHECK(ivec2_zero_type.is_variable()); - const meta::variable_info& ivec2_x_info = ivec2_zero_type.get_variable_info(); + const meta::variable_info ivec2_x_info = ivec2_zero_type.get_variable().value(); CHECK(ivec2_x_info.id() == "zero"); } @@ -165,7 +174,54 @@ TEST_CASE("meta/registry") { const meta::type ivec3_zero_type = registry.resolve<&ivec3::zero>().value(); CHECK(ivec3_zero_type.is_variable()); - const meta::variable_info& ivec3_x_info = ivec3_zero_type.get_variable_info(); + const meta::variable_info ivec3_x_info = ivec3_zero_type.get_variable().value(); CHECK(ivec3_x_info.id() == "zero"); } } + +TEST_CASE("meta/registry/merge") { + namespace meta = meta_hpp; + using namespace std::string_literals; + + auto registry = meta::registry{}; + + SUBCASE("class") { + registry( + meta::class_("ivec2")( + meta::field_<&ivec2::x>("x") + )); + + registry( + meta::class_("ivec2")( + meta::field_<&ivec2::y>("y") + )); + + CHECK(registry.resolve()); + CHECK(registry.resolve()->get_class()); + CHECK(registry.resolve()->get_class()->get_field("x")); + CHECK(registry.resolve()->get_class()->get_field("y")); + + CHECK(registry.resolve(ivec2{})); + CHECK(registry.resolve(ivec2{})->get_class()); + CHECK(registry.resolve(ivec2{})->get_class()->get_field("x")); + CHECK(registry.resolve(ivec2{})->get_class()->get_field("y")); + + CHECK(registry.get_class_by_name("ivec2")); + CHECK(registry.get_class_by_name("ivec2")->get_field("x")); + CHECK(registry.get_class_by_name("ivec2")->get_field("y")); + } + + SUBCASE("namespace") { + registry( + meta::namespace_("vmath")( + meta::class_("ivec2"))); + + registry( + meta::namespace_("vmath")( + meta::class_("ivec3"))); + + CHECK(registry.get_namespace_by_name("vmath")); + CHECK(registry.get_namespace_by_name("vmath")->get_class("ivec2")); + CHECK(registry.get_namespace_by_name("vmath")->get_class("ivec3")); + } +} diff --git a/untests/meta_type_tests.cpp b/untests/meta_type_tests.cpp index 919c577..4e94218 100644 --- a/untests/meta_type_tests.cpp +++ b/untests/meta_type_tests.cpp @@ -33,25 +33,44 @@ TEST_CASE("meta/type") { meta::type class_type = meta::class_("clazz"); CHECK(class_type.is_class()); - CHECK(class_type.get_class_info().id() == "clazz"); + CHECK(class_type.get_class()->id() == "clazz"); meta::type field_type = meta::field_<&clazz::field>("field"); CHECK(field_type.is_field()); - CHECK(field_type.get_field_info().id() == "field"); + CHECK(field_type.get_field()->id() == "field"); meta::type function_type = meta::function_<&clazz::function>("function"); CHECK(function_type.is_function()); - CHECK(function_type.get_function_info().id() == "function"); + CHECK(function_type.get_function()->id() == "function"); meta::type method_type = meta::method_<&clazz::method>("method"); CHECK(method_type.is_method()); - CHECK(method_type.get_method_info().id() == "method"); + CHECK(method_type.get_method()->id() == "method"); meta::type namespace_type = meta::namespace_("ns"); CHECK(namespace_type.is_namespace()); - CHECK(namespace_type.get_namespace_info().id() == "ns"); + CHECK(namespace_type.get_namespace()->id() == "ns"); meta::type variable_type = meta::variable_<&clazz::variable>("variable"); CHECK(variable_type.is_variable()); - CHECK(variable_type.get_variable_info().id() == "variable"); + CHECK(variable_type.get_variable()->id() == "variable"); +} + +TEST_CASE("meta/type/merge") { + namespace meta = meta_hpp; + using namespace std::string_literals; + + { + meta::type clazz_type = meta::class_("clazz")( + meta::field_<&clazz::field>("field") + ); + + clazz_type.merge(meta::class_("clazz")( + meta::function_<&clazz::function>("function") + )); + + REQUIRE(clazz_type.is_class()); + CHECK(clazz_type.get_class()->get_field("field")); + CHECK(clazz_type.get_class()->get_function("function")); + } } From ac98bc1e8bf37441d75c7dbd6b889586cce9c05e Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Mon, 5 Jul 2021 00:10:46 +0700 Subject: [PATCH 028/233] fix msvc compilation --- headers/meta.hpp/meta_function_info.hpp | 8 ++++++-- headers/meta.hpp/meta_method_info.hpp | 16 ++++++++++++---- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/headers/meta.hpp/meta_function_info.hpp b/headers/meta.hpp/meta_function_info.hpp index 0d9c0e9..30be2f5 100644 --- a/headers/meta.hpp/meta_function_info.hpp +++ b/headers/meta.hpp/meta_function_info.hpp @@ -85,8 +85,12 @@ namespace meta_hpp template < typename... Args > std::optional invoke(Args&&... args) const { - std::array vargs{{std::forward(args)...}}; - return invoke_(vargs.data(), vargs.size()); + if constexpr ( sizeof...(Args) > 0u ) { + std::array vargs{std::forward(args)...}; + return invoke_(vargs.data(), vargs.size()); + } else { + return invoke_(nullptr, 0u); + } } template < typename F > diff --git a/headers/meta.hpp/meta_method_info.hpp b/headers/meta.hpp/meta_method_info.hpp index 894ca8b..74c8c6c 100644 --- a/headers/meta.hpp/meta_method_info.hpp +++ b/headers/meta.hpp/meta_method_info.hpp @@ -142,14 +142,22 @@ namespace meta_hpp template < typename... Args > std::optional invoke(void* instance, Args&&... args) const { - std::array vargs{{std::forward(args)...}}; - return invoke_(instance, vargs.data(), vargs.size()); + if constexpr ( sizeof...(Args) > 0u ) { + std::array vargs{std::forward(args)...}; + return invoke_(instance, vargs.data(), vargs.size()); + } else { + return invoke_(instance, nullptr, 0u); + } } template < typename... Args > std::optional invoke(const void* instance, Args&&... args) const { - std::array vargs{{std::forward(args)...}}; - return cinvoke_(instance, vargs.data(), vargs.size()); + if constexpr ( sizeof...(Args) > 0u ) { + std::array vargs{std::forward(args)...}; + return cinvoke_(instance, vargs.data(), vargs.size()); + } else { + return cinvoke_(instance, nullptr, 0u); + } } template < typename F > From 2d27e822f233af005b7387ef170d3d1d3bd07f7f Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Mon, 5 Jul 2021 01:27:22 +0700 Subject: [PATCH 029/233] fix some family id issues --- headers/meta.hpp/meta_class_info.hpp | 2 +- headers/meta.hpp/meta_field_info.hpp | 4 +- headers/meta.hpp/meta_function_info.hpp | 4 +- headers/meta.hpp/meta_fwd.hpp | 23 +++++-- headers/meta.hpp/meta_method_info.hpp | 4 +- headers/meta.hpp/meta_registry.hpp | 9 ++- headers/meta.hpp/meta_variable_info.hpp | 4 +- untests/meta_family_tests.cpp | 85 +++++++++++++++++++++++++ untests/meta_registry_tests.cpp | 55 ++++++---------- 9 files changed, 138 insertions(+), 52 deletions(-) create mode 100644 untests/meta_family_tests.cpp diff --git a/headers/meta.hpp/meta_class_info.hpp b/headers/meta.hpp/meta_class_info.hpp index 488346d..0ca403a 100644 --- a/headers/meta.hpp/meta_class_info.hpp +++ b/headers/meta.hpp/meta_class_info.hpp @@ -128,7 +128,7 @@ namespace meta_hpp template < typename Class > class_info(detail::typename_arg_t, std::string id) - : fid_{get_family_id()} + : fid_{get_type_family_id()} , id_{std::move(id)} {} private: family_id fid_; diff --git a/headers/meta.hpp/meta_field_info.hpp b/headers/meta.hpp/meta_field_info.hpp index 6e4f9bb..f4c2a38 100644 --- a/headers/meta.hpp/meta_field_info.hpp +++ b/headers/meta.hpp/meta_field_info.hpp @@ -110,9 +110,9 @@ namespace meta_hpp template < auto Field > friend class field_; - template < typename FieldType, FieldType Field > + template < auto Field > field_info(detail::auto_arg_t, std::string id) - : fid_{get_family_id()} + : fid_{get_value_family_id()} , id_{std::move(id)} , getter_{&field_detail::getter} , setter_{&field_detail::setter} {} diff --git a/headers/meta.hpp/meta_function_info.hpp b/headers/meta.hpp/meta_function_info.hpp index 30be2f5..8c1908c 100644 --- a/headers/meta.hpp/meta_function_info.hpp +++ b/headers/meta.hpp/meta_function_info.hpp @@ -119,9 +119,9 @@ namespace meta_hpp template < auto Function > friend class function_; - template < typename FunctionType, FunctionType Function > + template < auto Function > function_info(detail::auto_arg_t, std::string id) - : fid_{get_family_id()} + : fid_{get_value_family_id()} , id_{std::move(id)} , invoke_{&function_detail::invoke} {} private: diff --git a/headers/meta.hpp/meta_fwd.hpp b/headers/meta.hpp/meta_fwd.hpp index 2a607b4..96c6b49 100644 --- a/headers/meta.hpp/meta_fwd.hpp +++ b/headers/meta.hpp/meta_fwd.hpp @@ -55,7 +55,7 @@ namespace meta_hpp namespace family_id_detail { template < typename Void = void > - class type_family_base { + class family_base { static_assert( std::is_void_v, "unexpected internal error"); @@ -64,7 +64,17 @@ namespace meta_hpp }; template < typename T > - class type_family final : public type_family_base<> { + class type_family final : public family_base<> { + public: + static family_id id() noexcept { + static family_id self_id{++last_id_}; + assert(self_id.id > 0u && "family_id overflow"); + return self_id; + } + }; + + template < auto V > + class value_family final : public family_base<> { public: static family_id id() noexcept { static family_id self_id{++last_id_}; @@ -74,13 +84,18 @@ namespace meta_hpp }; template < typename Void > - family_id::underlying_type type_family_base::last_id_{}; + family_id::underlying_type family_base::last_id_{}; } template < typename T > - family_id get_family_id() noexcept { + family_id get_type_family_id() noexcept { return family_id_detail::type_family::id(); } + + template < auto V > + family_id get_value_family_id() noexcept { + return family_id_detail::value_family::id(); + } } namespace meta_hpp diff --git a/headers/meta.hpp/meta_method_info.hpp b/headers/meta.hpp/meta_method_info.hpp index 74c8c6c..81fdedf 100644 --- a/headers/meta.hpp/meta_method_info.hpp +++ b/headers/meta.hpp/meta_method_info.hpp @@ -186,9 +186,9 @@ namespace meta_hpp template < auto Method > friend class method_; - template < typename MethodType, MethodType Method > + template < auto Method > method_info(detail::auto_arg_t, std::string id) - : fid_{get_family_id()} + : fid_{get_value_family_id()} , id_{std::move(id)} , invoke_{&method_detail::invoke} , cinvoke_{&method_detail::cinvoke} {} diff --git a/headers/meta.hpp/meta_registry.hpp b/headers/meta.hpp/meta_registry.hpp index 149189a..c22c76c 100644 --- a/headers/meta.hpp/meta_registry.hpp +++ b/headers/meta.hpp/meta_registry.hpp @@ -23,17 +23,20 @@ namespace meta_hpp public: template < typename T > std::optional resolve() const { - return detail::find_opt(family_to_types_, get_family_id()); + const family_id fid = get_type_family_id(); + return detail::find_opt(family_to_types_, fid); } template < auto T > std::optional resolve() const { - return resolve(); + const family_id fid = get_value_family_id(); + return detail::find_opt(family_to_types_, fid); } template < typename T > std::optional resolve(T&&) const { - return resolve>(); + const family_id fid = get_type_family_id>(); + return detail::find_opt(family_to_types_, fid); } std::optional get_class_by_name(std::string_view name) const { diff --git a/headers/meta.hpp/meta_variable_info.hpp b/headers/meta.hpp/meta_variable_info.hpp index 1d0a20e..513f6ee 100644 --- a/headers/meta.hpp/meta_variable_info.hpp +++ b/headers/meta.hpp/meta_variable_info.hpp @@ -106,9 +106,9 @@ namespace meta_hpp template < auto Variable > friend class variable_; - template < typename VariableType, VariableType Variable > + template < auto Variable > variable_info(detail::auto_arg_t, std::string id) - : fid_{get_family_id()} + : fid_{get_value_family_id()} , id_{std::move(id)} , getter_{&variable_detail::getter} , setter_{&variable_detail::setter} {} diff --git a/untests/meta_family_tests.cpp b/untests/meta_family_tests.cpp new file mode 100644 index 0000000..ef38c47 --- /dev/null +++ b/untests/meta_family_tests.cpp @@ -0,0 +1,85 @@ +/******************************************************************************* + * 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 +#include +#include +#include +#include + +#include "doctest/doctest.hpp" + +namespace +{ + struct ivec2 { + int x{}; + int y{}; + + static ivec2 zero; + + int dot(ivec2 other) const { + return x * other.x + y * other.y; + } + }; + + struct ivec3 { + int x{}; + int y{}; + int z{}; + + static ivec3 zero; + + int dot(ivec3 other) const { + return x * other.x + y * other.y + z * other.z; + } + }; + + ivec2 ivec2::zero{}; + ivec3 ivec3::zero{}; + + ivec2 iadd2(ivec2 l, ivec2 r) { + return {l.x + r.x, l.y + r.y}; + } + + ivec3 iadd3(ivec3 l, ivec3 r) { + return {l.x + r.x, l.y + r.y, l.z + r.z}; + } +} + +TEST_CASE("meta/family") { + namespace meta = meta_hpp; + using namespace std::string_literals; + + SUBCASE("class") { + meta::class_info ivec2_info = meta::class_("ivec2"); + meta::class_info ivec3_info = meta::class_("ivec3"); + CHECK_FALSE(ivec2_info.fid() == ivec3_info.fid()); + } + + SUBCASE("field") { + meta::field_info x_info = meta::field_<&ivec2::x>("x"); + meta::field_info y_info = meta::field_<&ivec2::y>("y"); + CHECK_FALSE(x_info.fid() == y_info.fid()); + } + + SUBCASE("function") { + meta::function_info iadd2_info = meta::function_<&iadd2>("iadd2"); + meta::function_info iadd3_info = meta::function_<&iadd3>("iadd3"); + CHECK_FALSE(iadd2_info.fid() == iadd3_info.fid()); + } + + SUBCASE("method") { + meta::method_info dot2_info = meta::method_<&ivec2::dot>("dot"); + meta::method_info dot3_info = meta::method_<&ivec3::dot>("dot"); + CHECK_FALSE(dot2_info.fid() == dot3_info.fid()); + } + + SUBCASE("variable") { + meta::variable_info zero2_info = meta::variable_<&ivec2::zero>("zero"); + meta::variable_info zero3_info = meta::variable_<&ivec3::zero>("zero"); + CHECK_FALSE(zero2_info.fid() == zero3_info.fid()); + } +} diff --git a/untests/meta_registry_tests.cpp b/untests/meta_registry_tests.cpp index 1ab1574..03befc5 100644 --- a/untests/meta_registry_tests.cpp +++ b/untests/meta_registry_tests.cpp @@ -99,83 +99,66 @@ TEST_CASE("meta/registry") { } SUBCASE("field_template") { - CHECK(registry.resolve<&ivec2::x>()); + REQUIRE(registry.resolve<&ivec2::x>()); + REQUIRE(registry.resolve<&ivec2::y>()); const meta::type ivec2_x_type = registry.resolve<&ivec2::x>().value(); - CHECK(ivec2_x_type.is_field()); + const meta::type ivec2_y_type = registry.resolve<&ivec2::y>().value(); + + REQUIRE(ivec2_x_type.is_field()); + REQUIRE(ivec2_y_type.is_field()); const meta::field_info ivec2_x_info = ivec2_x_type.get_field().value(); + const meta::field_info ivec2_y_info = ivec2_y_type.get_field().value(); + CHECK(ivec2_x_info.id() == "x"); + CHECK(ivec2_y_info.id() == "y"); } SUBCASE("field_instance") { - CHECK(registry.resolve(&ivec3::x)); - - const meta::type ivec3_x_type = registry.resolve<&ivec3::x>().value(); - CHECK(ivec3_x_type.is_field()); - - const meta::field_info ivec3_x_info = ivec3_x_type.get_field().value(); - CHECK(ivec3_x_info.id() == "x"); + CHECK_FALSE(registry.resolve(&ivec2::x)); } SUBCASE("function_template") { - CHECK(registry.resolve<&iadd2>()); + REQUIRE(registry.resolve<&iadd2>()); const meta::type iadd2_type = registry.resolve<&iadd2>().value(); - CHECK(iadd2_type.is_function()); + REQUIRE(iadd2_type.is_function()); const meta::function_info iadd2_info = iadd2_type.get_function().value(); CHECK(iadd2_info.id() == "iadd2"); } SUBCASE("function_instance") { - CHECK(registry.resolve(&iadd3)); - - const meta::type iadd3_type = registry.resolve<&iadd3>().value(); - CHECK(iadd3_type.is_function()); - - const meta::function_info iadd3_info = iadd3_type.get_function().value(); - CHECK(iadd3_info.id() == "iadd3"); + CHECK_FALSE(registry.resolve(&iadd3)); } SUBCASE("method_template") { - CHECK(registry.resolve<&ivec2::dot>()); + REQUIRE(registry.resolve<&ivec2::dot>()); const meta::type ivec2_dot_type = registry.resolve<&ivec2::dot>().value(); - CHECK(ivec2_dot_type.is_method()); + REQUIRE(ivec2_dot_type.is_method()); const meta::method_info ivec2_dot_info = ivec2_dot_type.get_method().value(); CHECK(ivec2_dot_info.id() == "dot"); } SUBCASE("method_instance") { - CHECK(registry.resolve(&ivec3::dot)); - - const meta::type ivec3_dot_type = registry.resolve<&ivec3::dot>().value(); - CHECK(ivec3_dot_type.is_method()); - - const meta::method_info ivec3_dot_info = ivec3_dot_type.get_method().value(); - CHECK(ivec3_dot_info.id() == "dot"); + CHECK_FALSE(registry.resolve(&ivec3::dot)); } SUBCASE("variable_template") { - CHECK(registry.resolve<&ivec2::zero>()); + REQUIRE(registry.resolve<&ivec2::zero>()); const meta::type ivec2_zero_type = registry.resolve<&ivec2::zero>().value(); - CHECK(ivec2_zero_type.is_variable()); + REQUIRE(ivec2_zero_type.is_variable()); const meta::variable_info ivec2_x_info = ivec2_zero_type.get_variable().value(); CHECK(ivec2_x_info.id() == "zero"); } SUBCASE("variable_instance") { - CHECK(registry.resolve(&ivec3::zero)); - - const meta::type ivec3_zero_type = registry.resolve<&ivec3::zero>().value(); - CHECK(ivec3_zero_type.is_variable()); - - const meta::variable_info ivec3_x_info = ivec3_zero_type.get_variable().value(); - CHECK(ivec3_x_info.id() == "zero"); + CHECK_FALSE(registry.resolve(&ivec3::zero)); } } From 61b03b74c4fe2327dd3e6d8c4cab93a9c0ffc54b Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Mon, 5 Jul 2021 02:10:08 +0700 Subject: [PATCH 030/233] more registry resolve tests --- untests/meta_registry_tests.cpp | 153 ++++++++++++++++++++++++++++++-- 1 file changed, 144 insertions(+), 9 deletions(-) diff --git a/untests/meta_registry_tests.cpp b/untests/meta_registry_tests.cpp index 03befc5..532b6b1 100644 --- a/untests/meta_registry_tests.cpp +++ b/untests/meta_registry_tests.cpp @@ -68,15 +68,6 @@ TEST_CASE("meta/registry") { ) ); - SUBCASE("get_xxx_by_name") { - CHECK(registry.get_class_by_name("vmath::ivec2")); - CHECK(registry.get_field_by_name("vmath::ivec2::x")); - CHECK(registry.get_function_by_name("vmath::iadd2")); - CHECK(registry.get_method_by_name("vmath::ivec2::dot")); - CHECK(registry.get_namespace_by_name("vmath")); - CHECK(registry.get_variable_by_name("vmath::ivec2::zero")); - } - SUBCASE("class_template") { CHECK(registry.resolve()); @@ -160,6 +151,150 @@ TEST_CASE("meta/registry") { SUBCASE("variable_instance") { CHECK_FALSE(registry.resolve(&ivec3::zero)); } + + SUBCASE("resolve/class") { + ivec2 v2; + ivec3 v3; + + REQUIRE(registry.resolve()); + REQUIRE(registry.resolve(v2)); + REQUIRE(registry.resolve(std::as_const(v2))); + REQUIRE(registry.resolve(static_cast(v2))); + + REQUIRE(registry.resolve()); + REQUIRE(registry.resolve(v3)); + REQUIRE(registry.resolve(std::as_const(v3))); + REQUIRE(registry.resolve(static_cast(v3))); + + const meta::class_info v2_info = meta::class_("ivec2"); + const meta::class_info v3_info = meta::class_("ivec3"); + CHECK(v2_info.fid() != v3_info.fid()); + + CHECK(v2_info.fid() == registry.resolve()->get_class()->fid()); + CHECK(v2_info.fid() == registry.resolve(v2)->get_class()->fid()); + CHECK(v2_info.fid() == registry.resolve(std::as_const(v2))->get_class()->fid()); + CHECK(v2_info.fid() == registry.resolve(static_cast(v2))->get_class()->fid()); + + CHECK(v3_info.fid() == registry.resolve()->get_class()->fid()); + CHECK(v3_info.fid() == registry.resolve(v3)->get_class()->fid()); + CHECK(v3_info.fid() == registry.resolve(std::as_const(v3))->get_class()->fid()); + CHECK(v3_info.fid() == registry.resolve(static_cast(v3))->get_class()->fid()); + + { + REQUIRE(registry.get_class_by_name("vmath::ivec2")); + REQUIRE(registry.get_class_by_name("vmath::ivec3")); + + CHECK(v2_info.fid() == registry.get_class_by_name("vmath::ivec2")->fid()); + CHECK(v3_info.fid() == registry.get_class_by_name("vmath::ivec3")->fid()); + } + } + + SUBCASE("resolve/field") { + REQUIRE(registry.resolve<&ivec2::x>()); + REQUIRE(registry.resolve<&ivec2::y>()); + CHECK_FALSE(registry.resolve(&ivec2::x)); + CHECK_FALSE(registry.resolve(&ivec2::y)); + + REQUIRE(registry.resolve<&ivec3::x>()); + REQUIRE(registry.resolve<&ivec3::y>()); + CHECK_FALSE(registry.resolve(&ivec3::x)); + CHECK_FALSE(registry.resolve(&ivec3::y)); + + const meta::field_info v2_x_info = meta::field_<&ivec2::x>("x"); + const meta::field_info v2_y_info = meta::field_<&ivec2::y>("y"); + CHECK(v2_x_info.fid() != v2_y_info.fid()); + + const meta::field_info v3_x_info = meta::field_<&ivec3::x>("x"); + const meta::field_info v3_y_info = meta::field_<&ivec3::y>("y"); + CHECK(v3_x_info.fid() != v3_y_info.fid()); + + CHECK(v2_x_info.fid() != v3_x_info.fid()); + CHECK(v2_y_info.fid() != v3_y_info.fid()); + + CHECK(v2_x_info.fid() == registry.resolve<&ivec2::x>()->get_field()->fid()); + CHECK(v2_y_info.fid() == registry.resolve<&ivec2::y>()->get_field()->fid()); + + CHECK(v3_x_info.fid() == registry.resolve<&ivec3::x>()->get_field()->fid()); + CHECK(v3_y_info.fid() == registry.resolve<&ivec3::y>()->get_field()->fid()); + + { + REQUIRE(registry.get_field_by_name("vmath::ivec2::x")); + REQUIRE(registry.get_field_by_name("vmath::ivec2::y")); + REQUIRE(registry.get_field_by_name("vmath::ivec3::x")); + REQUIRE(registry.get_field_by_name("vmath::ivec3::y")); + + CHECK(v2_x_info.fid() == registry.get_field_by_name("vmath::ivec2::x")->fid()); + CHECK(v2_y_info.fid() == registry.get_field_by_name("vmath::ivec2::y")->fid()); + CHECK(v3_x_info.fid() == registry.get_field_by_name("vmath::ivec3::x")->fid()); + CHECK(v3_y_info.fid() == registry.get_field_by_name("vmath::ivec3::y")->fid()); + } + } + + SUBCASE("resolve/function") { + REQUIRE(registry.resolve<&iadd2>()); + REQUIRE(registry.resolve<&iadd3>()); + CHECK_FALSE(registry.resolve(&iadd2)); + CHECK_FALSE(registry.resolve(&iadd3)); + + const meta::function_info iadd2_info = meta::function_<&iadd2>("iadd2"); + const meta::function_info iadd3_info = meta::function_<&iadd3>("iadd3"); + CHECK(iadd2_info.fid() != iadd3_info.fid()); + + CHECK(iadd2_info.fid() == registry.resolve<&iadd2>()->get_function()->fid()); + CHECK(iadd3_info.fid() == registry.resolve<&iadd3>()->get_function()->fid()); + + { + REQUIRE(registry.get_function_by_name("vmath::iadd2")); + REQUIRE(registry.get_function_by_name("vmath::iadd3")); + + CHECK(iadd2_info.fid() == registry.get_function_by_name("vmath::iadd2")->fid()); + CHECK(iadd3_info.fid() == registry.get_function_by_name("vmath::iadd3")->fid()); + } + } + + SUBCASE("resolve/method") { + REQUIRE(registry.resolve<&ivec2::dot>()); + REQUIRE(registry.resolve<&ivec3::dot>()); + CHECK_FALSE(registry.resolve(&ivec2::dot)); + CHECK_FALSE(registry.resolve(&ivec3::dot)); + + const meta::method_info v2_dot_info = meta::method_<&ivec2::dot>("dot"); + const meta::method_info v3_dot_info = meta::method_<&ivec3::dot>("dot"); + CHECK(v2_dot_info.fid() != v3_dot_info.fid()); + + CHECK(v2_dot_info.fid() == registry.resolve<&ivec2::dot>()->get_method()->fid()); + CHECK(v3_dot_info.fid() == registry.resolve<&ivec3::dot>()->get_method()->fid()); + + { + REQUIRE(registry.get_method_by_name("vmath::ivec2::dot")); + REQUIRE(registry.get_method_by_name("vmath::ivec3::dot")); + + CHECK(v2_dot_info.fid() == registry.get_method_by_name("vmath::ivec2::dot")->fid()); + CHECK(v3_dot_info.fid() == registry.get_method_by_name("vmath::ivec3::dot")->fid()); + } + } + + SUBCASE("resolve/variable") { + REQUIRE(registry.resolve<&ivec2::zero>()); + REQUIRE(registry.resolve<&ivec3::zero>()); + CHECK_FALSE(registry.resolve(&ivec2::zero)); + CHECK_FALSE(registry.resolve(&ivec3::zero)); + + const meta::variable_info v2_zero_info = meta::variable_<&ivec2::zero>("zero"); + const meta::variable_info v3_zero_info = meta::variable_<&ivec3::zero>("zero"); + CHECK(v2_zero_info.fid() != v3_zero_info.fid()); + + CHECK(v2_zero_info.fid() == registry.resolve<&ivec2::zero>()->get_variable()->fid()); + CHECK(v3_zero_info.fid() == registry.resolve<&ivec3::zero>()->get_variable()->fid()); + + { + REQUIRE(registry.get_variable_by_name("vmath::ivec2::zero")); + REQUIRE(registry.get_variable_by_name("vmath::ivec3::zero")); + + CHECK(v2_zero_info.fid() == registry.get_variable_by_name("vmath::ivec2::zero")->fid()); + CHECK(v3_zero_info.fid() == registry.get_variable_by_name("vmath::ivec3::zero")->fid()); + } + } } TEST_CASE("meta/registry/merge") { From 548a2c680afd92b070d92d17427decc992ea9c4d Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Mon, 5 Jul 2021 02:24:40 +0700 Subject: [PATCH 031/233] family id atomic generator --- headers/meta.hpp/meta_fwd.hpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/headers/meta.hpp/meta_fwd.hpp b/headers/meta.hpp/meta_fwd.hpp index 96c6b49..f6497d9 100644 --- a/headers/meta.hpp/meta_fwd.hpp +++ b/headers/meta.hpp/meta_fwd.hpp @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -60,9 +61,12 @@ namespace meta_hpp std::is_void_v, "unexpected internal error"); protected: - static family_id::underlying_type last_id_; + static std::atomic last_id_; }; + template < typename Void > + std::atomic family_base::last_id_{}; + template < typename T > class type_family final : public family_base<> { public: @@ -82,9 +86,6 @@ namespace meta_hpp return self_id; } }; - - template < typename Void > - family_id::underlying_type family_base::last_id_{}; } template < typename T > From e9cdbd0c0ac42f7606b3a4119e60cec553925d72 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Mon, 5 Jul 2021 21:17:27 +0700 Subject: [PATCH 032/233] add family id to value --- headers/meta.hpp/meta_value.hpp | 42 ++++++++++++++++++++++----------- untests/meta_value_tests.cpp | 39 ++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 14 deletions(-) diff --git a/headers/meta.hpp/meta_value.hpp b/headers/meta.hpp/meta_value.hpp index 3676cc1..bfef1d3 100644 --- a/headers/meta.hpp/meta_value.hpp +++ b/headers/meta.hpp/meta_value.hpp @@ -20,27 +20,30 @@ namespace meta_hpp value& operator=(value&&) = default; value& operator=(const value&) = default; - template < typename T > - value(T&& value) - : raw_{std::forward(value)} {} + template < typename T + , typename U = std::decay_t + , typename = std::enable_if_t> > + value(T&& val) + : raw_{std::forward(val)} + , fid_{get_type_family_id()} {} - template < typename T > - value& operator=(T&& value) noexcept { - raw_ = std::forward(value); + template < typename T + , typename U = std::decay_t + , typename = std::enable_if_t> > + value& operator=(T&& val) { + value{std::forward(val)}.swap(*this); return *this; } template < typename T, typename... Args > - value(std::in_place_type_t, Args&&... args) - : raw_{std::in_place_type, std::forward(args)...} {} + explicit value(std::in_place_type_t, Args&&... args) + : raw_{std::in_place_type, std::forward(args)...} + , fid_{get_type_family_id()} {} 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_); - } + explicit value(std::in_place_type_t, std::initializer_list ilist, Args&&... args) + : raw_{std::in_place_type, ilist, std::forward(args)...} + , fid_{get_type_family_id()} {} template < typename T > T cast() && { @@ -68,6 +71,16 @@ namespace meta_hpp try_cast() const noexcept { return std::any_cast(&raw_); } + + family_id fid() const noexcept { + return fid_; + } + + void swap(value& other) noexcept { + using std::swap; + swap(raw_, other.raw_); + swap(fid_, other.fid_); + } public: bool to_bool() const { return cast(); } int to_int() const { return cast(); } @@ -91,6 +104,7 @@ namespace meta_hpp std::uintptr_t to_uintptr_t() const { return cast(); } private: std::any raw_; + family_id fid_; }; inline void swap(value& l, value& r) noexcept { diff --git a/untests/meta_value_tests.cpp b/untests/meta_value_tests.cpp index 7de31cd..cd7363e 100644 --- a/untests/meta_value_tests.cpp +++ b/untests/meta_value_tests.cpp @@ -7,8 +7,13 @@ #include #include "doctest/doctest.hpp" +#include +#include + namespace { + class clazz {}; + class clazz2 {}; } TEST_CASE("meta/value") { @@ -36,3 +41,37 @@ TEST_CASE("meta/value") { CHECK(meta::value{std::in_place_type, std::size_t{1}}.to_size_t() == 1u); CHECK(meta::value{std::in_place_type, std::uintptr_t{1}}.to_uintptr_t() == 1u); } + +TEST_CASE("meta/value/fid") { + namespace meta = meta_hpp; + using namespace std::string_literals; + + CHECK(meta::value{clazz{}}.fid() == meta::get_type_family_id()); + CHECK(meta::value{clazz2{}}.fid() == meta::get_type_family_id()); + CHECK(meta::value{clazz{}}.fid() != meta::value{clazz2{}}.fid()); + + { + meta::value v = clazz{}; + CHECK(v.fid() == meta::get_type_family_id()); + v = clazz2{}; + CHECK(v.fid() == meta::get_type_family_id()); + } + + CHECK(meta::value{std::in_place_type, 1}.fid() == meta::get_type_family_id()); + CHECK(meta::value{std::in_place_type>, {1,2,3,4}}.fid() == meta::get_type_family_id>()); +} + +TEST_CASE("meta/value/swap") { + namespace meta = meta_hpp; + using namespace std::string_literals; + + meta::value v1{"hello"s}; + meta::value v2{42}; + meta::swap(v1, v2); + + CHECK(v1.fid() == meta::get_type_family_id()); + CHECK(v1.to_int() == 42); + + CHECK(v2.fid() == meta::get_type_family_id()); + CHECK(v2.to_string() == "hello"); +} From 88c3bf4eb26173e0d883b61fc40b055a685e6b7c Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Mon, 5 Jul 2021 21:17:58 +0700 Subject: [PATCH 033/233] add traits to value --- headers/meta.hpp/meta_value.hpp | 110 +++++++++++++++++++++++++++++++- untests/meta_value_tests.cpp | 106 ++++++++++++++++++++++++++++++ 2 files changed, 213 insertions(+), 3 deletions(-) diff --git a/headers/meta.hpp/meta_value.hpp b/headers/meta.hpp/meta_value.hpp index bfef1d3..a6e6bc8 100644 --- a/headers/meta.hpp/meta_value.hpp +++ b/headers/meta.hpp/meta_value.hpp @@ -8,6 +8,34 @@ #include "meta_fwd.hpp" +namespace meta_hpp +{ + class value; +} + +namespace meta_hpp::value_detail +{ + struct traits { + bool(*equal)(const value&, const value&){}; + bool(*not_equal)(const value&, const value&){}; + }; + + template < typename T > + bool value_equal(const value& l, const value& r); + + template < typename T > + bool value_not_equal(const value& l, const value& r); + + template < typename T > + const traits* get_traits() noexcept { + static traits traits{ + &value_equal, + &value_not_equal, + }; + return &traits; + } +} + namespace meta_hpp { class value { @@ -25,7 +53,8 @@ namespace meta_hpp , typename = std::enable_if_t> > value(T&& val) : raw_{std::forward(val)} - , fid_{get_type_family_id()} {} + , fid_{get_type_family_id()} + , traits_{value_detail::get_traits()} {} template < typename T , typename U = std::decay_t @@ -38,12 +67,14 @@ namespace meta_hpp template < typename T, typename... Args > explicit value(std::in_place_type_t, Args&&... args) : raw_{std::in_place_type, std::forward(args)...} - , fid_{get_type_family_id()} {} + , fid_{get_type_family_id()} + , traits_{value_detail::get_traits()} {} template < typename T, typename U, typename... Args > explicit value(std::in_place_type_t, std::initializer_list ilist, Args&&... args) : raw_{std::in_place_type, ilist, std::forward(args)...} - , fid_{get_type_family_id()} {} + , fid_{get_type_family_id()} + , traits_{value_detail::get_traits()} {} template < typename T > T cast() && { @@ -80,6 +111,51 @@ namespace meta_hpp using std::swap; swap(raw_, other.raw_); swap(fid_, other.fid_); + swap(traits_, other.traits_); + } + + template < typename T + , typename U = std::decay_t + , typename = std::enable_if_t> + , typename = std::enable_if_t, U, U>> > + friend bool operator==(const value& l, T&& r) { + return l.fid() == get_type_family_id() + && std::equal_to<>{}(*l.try_cast(), std::forward(r)); + } + + template < typename T + , typename U = std::decay_t + , typename = std::enable_if_t> + , typename = std::enable_if_t, U, U>> > + friend bool operator==(T&& l, const value& r) { + return get_type_family_id() == r.fid() + && std::equal_to<>{}(std::forward(l), *r.try_cast()); + } + + template < typename T + , typename U = std::decay_t + , typename = std::enable_if_t> + , typename = std::enable_if_t, U, U>> > + friend bool operator!=(const value& l, T&& r) { + return l.fid() != get_type_family_id() + || std::not_equal_to<>{}(*l.try_cast(), std::forward(r)); + } + + template < typename T + , typename U = std::decay_t + , typename = std::enable_if_t> + , typename = std::enable_if_t, U, U>> > + friend bool operator!=(T&& l, const value& r) { + return get_type_family_id() != r.fid() + || std::not_equal_to<>{}(std::forward(l), *r.try_cast()); + } + + friend bool operator==(const value& l, const value& r) { + return l.traits_->equal(l, r); + } + + friend bool operator!=(const value& l, const value& r) { + return l.traits_->not_equal(l, r); } public: bool to_bool() const { return cast(); } @@ -105,9 +181,37 @@ namespace meta_hpp private: std::any raw_; family_id fid_; + const value_detail::traits* traits_{}; }; inline void swap(value& l, value& r) noexcept { l.swap(r); } } + +namespace meta_hpp::value_detail +{ + template < typename T > + bool value_equal(const value& l, const value& r) { + if ( l.fid() != r.fid() ) { + return false; + } + if constexpr ( std::is_invocable_v, T, T> ) { + return std::equal_to<>{}(*l.try_cast(), *(r.try_cast())); + } else { + return std::addressof(l) == std::addressof(r); + } + } + + template < typename T > + bool value_not_equal(const value& l, const value& r) { + if ( l.fid() != r.fid() ) { + return true; + } + if constexpr ( std::is_invocable_v, T, T> ) { + return std::not_equal_to<>{}(*l.try_cast(), *(r.try_cast())); + } else { + return std::addressof(l) != std::addressof(r); + } + } +} diff --git a/untests/meta_value_tests.cpp b/untests/meta_value_tests.cpp index cd7363e..ffaa7b6 100644 --- a/untests/meta_value_tests.cpp +++ b/untests/meta_value_tests.cpp @@ -14,6 +14,8 @@ namespace { class clazz {}; class clazz2 {}; + + void func() {} } TEST_CASE("meta/value") { @@ -61,6 +63,110 @@ TEST_CASE("meta/value/fid") { CHECK(meta::value{std::in_place_type>, {1,2,3,4}}.fid() == meta::get_type_family_id>()); } +TEST_CASE("meta/value/equal") { + namespace meta = meta_hpp; + using namespace std::string_literals; + + { + CHECK(meta::value{1} == 1); + CHECK(meta::value{1} != 0); + CHECK(meta::value{1} != "hello"s); + + CHECK_FALSE(meta::value{1} != 1); + CHECK_FALSE(meta::value{1} == 0); + CHECK_FALSE(meta::value{1} == "hello"s); + } + + { + CHECK(1 == meta::value{1}); + CHECK(0 != meta::value{1}); + CHECK("hello"s != meta::value{1}); + + CHECK_FALSE(1 != meta::value{1}); + CHECK_FALSE(0 == meta::value{1}); + CHECK_FALSE("hello"s == meta::value{1}); + } + + { + int i = 1; + + CHECK(meta::value{1} == i); + CHECK(meta::value{1} == std::as_const(i)); + CHECK_FALSE(meta::value{1} != i); + CHECK_FALSE(meta::value{1} != std::as_const(i)); + + CHECK(i == meta::value{1}); + CHECK(std::as_const(i) == meta::value{1}); + CHECK_FALSE(i != meta::value{1}); + CHECK_FALSE(std::as_const(i) != meta::value{1}); + } + + { + CHECK(meta::value{1} == meta::value{1}); + CHECK(meta::value{1} != meta::value{0}); + CHECK(meta::value{1} != meta::value{"hello"s}); + CHECK_FALSE(meta::value{1} != meta::value{1}); + CHECK_FALSE(meta::value{1} == meta::value{0}); + CHECK_FALSE(meta::value{1} == meta::value{"hello"s}); + + CHECK(meta::value{1} == meta::value{1}); + CHECK(meta::value{0} != meta::value{1}); + CHECK(meta::value{"hello"s} != meta::value{1}); + CHECK_FALSE(meta::value{1} != meta::value{1}); + CHECK_FALSE(meta::value{0} == meta::value{1}); + CHECK_FALSE(meta::value{"hello"s} == meta::value{1}); + } + + { + CHECK(meta::value{std::in_place_type, 1} == meta::value{1}); + CHECK(meta::value{1} == meta::value{std::in_place_type, 1}); + + using vi = std::vector; + CHECK(meta::value{std::in_place_type, {1,2,3}} == meta::value{vi{1,2,3}}); + CHECK(meta::value{vi{1,2,3}} == meta::value{std::in_place_type, {1,2,3}}); + CHECK_FALSE(meta::value{std::in_place_type, {1,2,3}} == meta::value{vi{1,2,4}}); + CHECK_FALSE(meta::value{vi{1,2,4}} == meta::value{std::in_place_type, {1,2,3}}); + } + + { + meta::value v1{&func}; + meta::value v2{&func}; + + CHECK(v1 == v1); + CHECK_FALSE(v1 != v1); + + CHECK(v1 == v2); + CHECK_FALSE(v1 != v2); + } + + { + meta::value v1{clazz{}}; + meta::value v2{clazz{}}; + + CHECK(v1 == v1); + CHECK_FALSE(v1 != v1); + + CHECK(v1 != v2); + CHECK_FALSE(v1 == v2); + } + + { + const int rv = 1; + + meta::value v1{&rv}; + meta::value v2{&rv}; + + CHECK(v1 == v1); + CHECK_FALSE(v1 != v1); + } + + { + meta::value v1{"hello"s}; + meta::value{1}.swap(v1); + CHECK(v1 == meta::value{1}); + } +} + TEST_CASE("meta/value/swap") { namespace meta = meta_hpp; using namespace std::string_literals; From 5e10b46f08fe94fc392c6d94c0de774a0d55a6c0 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Mon, 5 Jul 2021 22:01:08 +0700 Subject: [PATCH 034/233] visit functions for registry --- headers/meta.hpp/meta_registry.hpp | 113 ++++++++++++++++++++++------- 1 file changed, 86 insertions(+), 27 deletions(-) diff --git a/headers/meta.hpp/meta_registry.hpp b/headers/meta.hpp/meta_registry.hpp index c22c76c..2fdda74 100644 --- a/headers/meta.hpp/meta_registry.hpp +++ b/headers/meta.hpp/meta_registry.hpp @@ -24,43 +24,102 @@ namespace meta_hpp template < typename T > std::optional resolve() const { const family_id fid = get_type_family_id(); - return detail::find_opt(family_to_types_, fid); + return detail::find_opt(types_, fid); } template < auto T > std::optional resolve() const { const family_id fid = get_value_family_id(); - return detail::find_opt(family_to_types_, fid); + return detail::find_opt(types_, fid); } template < typename T > std::optional resolve(T&&) const { const family_id fid = get_type_family_id>(); - return detail::find_opt(family_to_types_, fid); + return detail::find_opt(types_, fid); } std::optional get_class_by_name(std::string_view name) const { - return detail::find_opt(name_to_classes_, name); + return detail::find_opt(classes_, name); } std::optional get_field_by_name(std::string_view name) const { - return detail::find_opt(name_to_fields_, name); + return detail::find_opt(fields_, name); } std::optional get_function_by_name(std::string_view name) const { - return detail::find_opt(name_to_functions_, name); + return detail::find_opt(functions_, name); } std::optional get_method_by_name(std::string_view name) const { - return detail::find_opt(name_to_methods_, name); + return detail::find_opt(methods_, name); } std::optional get_namespace_by_name(std::string_view name) const { - return detail::find_opt(name_to_namespaces_, name); + return detail::find_opt(namespaces_, name); } std::optional get_variable_by_name(std::string_view name) const { - return detail::find_opt(name_to_variables_, name); + return detail::find_opt(variables_, name); + } + + template < typename F > + void each_type(F&& f) const { + for ( auto&& id_type : types_ ) { + std::invoke(f, id_type.second); + } + } + + template < typename F > + void each_class(F&& f) const { + for ( auto&& id_info : classes_ ) { + std::invoke(f, id_info.second); + } + } + + template < typename F > + void each_field(F&& f) const { + for ( auto&& id_info : fields_ ) { + std::invoke(f, id_info.second); + } + } + + template < typename F > + void each_function(F&& f) const { + for ( auto&& id_info : functions_ ) { + std::invoke(f, id_info.second); + } + } + + template < typename F > + void each_method(F&& f) const { + for ( auto&& id_info : methods_ ) { + std::invoke(f, id_info.second); + } + } + + template < typename F > + void each_namespace(F&& f) const { + for ( auto&& id_info : namespaces_ ) { + std::invoke(f, id_info.second); + } + } + + template < typename F > + void each_variable(F&& f) const { + for ( auto&& id_info : variables_ ) { + std::invoke(f, id_info.second); + } + } + + template < typename F > + void visit(F&& f) const { + each_class(f); + each_field(f); + each_function(f); + each_method(f); + each_namespace(f); + each_variable(f); } template < typename... Internals > @@ -74,8 +133,8 @@ namespace meta_hpp ? info.id() : prefix + "::" + info.id(); - detail::merge_with(name_to_classes_, name, info, &class_info::merge); - detail::merge_with(family_to_types_, info.fid(), info, &type::merge); + detail::merge_with(types_, info.fid(), info, &type::merge); + detail::merge_with(classes_, name, info, &class_info::merge); info.visit(overloaded { [](const data_info&) {}, @@ -90,8 +149,8 @@ namespace meta_hpp ? info.id() : prefix + "::" + info.id(); - detail::merge_with(name_to_fields_, name, info, &field_info::merge); - detail::merge_with(family_to_types_, info.fid(), info, &type::merge); + detail::merge_with(types_, info.fid(), info, &type::merge); + detail::merge_with(fields_, name, info, &field_info::merge); info.visit(overloaded { [](const data_info&) {}, @@ -106,8 +165,8 @@ namespace meta_hpp ? info.id() : prefix + "::" + info.id(); - detail::merge_with(name_to_functions_, name, info, &function_info::merge); - detail::merge_with(family_to_types_, info.fid(), info, &type::merge); + detail::merge_with(types_, info.fid(), info, &type::merge); + detail::merge_with(functions_, name, info, &function_info::merge); info.visit(overloaded { [](const data_info&) {}, @@ -122,8 +181,8 @@ namespace meta_hpp ? info.id() : prefix + "::" + info.id(); - detail::merge_with(name_to_methods_, name, info, &method_info::merge); - detail::merge_with(family_to_types_, info.fid(), info, &type::merge); + detail::merge_with(types_, info.fid(), info, &type::merge); + detail::merge_with(methods_, name, info, &method_info::merge); info.visit(overloaded { [](const data_info&) {}, @@ -138,7 +197,7 @@ namespace meta_hpp ? info.id() : prefix + "::" + info.id(); - detail::merge_with(name_to_namespaces_, name, info, &namespace_info::merge); + detail::merge_with(namespaces_, name, info, &namespace_info::merge); info.visit(overloaded { [](const data_info&) {}, @@ -153,8 +212,8 @@ namespace meta_hpp ? info.id() : prefix + "::" + info.id(); - detail::merge_with(name_to_variables_, name, info, &variable_info::merge); - detail::merge_with(family_to_types_, info.fid(), info, &type::merge); + detail::merge_with(types_, info.fid(), info, &type::merge); + detail::merge_with(variables_, name, info, &variable_info::merge); info.visit(overloaded { [](const data_info&) {}, @@ -164,12 +223,12 @@ namespace meta_hpp }); } private: - std::map> family_to_types_; - std::map> name_to_classes_; - std::map> name_to_fields_; - std::map> name_to_functions_; - std::map> name_to_methods_; - std::map> name_to_namespaces_; - std::map> name_to_variables_; + std::map> types_; + std::map> classes_; + std::map> fields_; + std::map> functions_; + std::map> methods_; + std::map> namespaces_; + std::map> variables_; }; } From c006d10e33b8839ed18e77c50be4d3bd2b2ae6b7 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Tue, 6 Jul 2021 01:24:25 +0700 Subject: [PATCH 035/233] is_xxx and data functions for value --- headers/meta.hpp/meta_value.hpp | 57 +++++++++++++++++++++++++++++++++ untests/meta_value_tests.cpp | 38 ++++++++++++++++++++++ 2 files changed, 95 insertions(+) diff --git a/headers/meta.hpp/meta_value.hpp b/headers/meta.hpp/meta_value.hpp index a6e6bc8..9bcf737 100644 --- a/headers/meta.hpp/meta_value.hpp +++ b/headers/meta.hpp/meta_value.hpp @@ -16,10 +16,18 @@ namespace meta_hpp namespace meta_hpp::value_detail { struct traits { + void*(*data)(value&); + const void*(*cdata)(const value&); bool(*equal)(const value&, const value&){}; bool(*not_equal)(const value&, const value&){}; }; + template < typename T > + void* value_data(value& v); + + template < typename T > + const void* value_cdata(const value& v); + template < typename T > bool value_equal(const value& l, const value& r); @@ -29,6 +37,8 @@ namespace meta_hpp::value_detail template < typename T > const traits* get_traits() noexcept { static traits traits{ + &value_data, + &value_cdata, &value_equal, &value_not_equal, }; @@ -107,6 +117,14 @@ namespace meta_hpp return fid_; } + void* data() noexcept { + return traits_->data(*this); + } + + const void* data() const noexcept { + return traits_->cdata(*this); + } + void swap(value& other) noexcept { using std::swap; swap(raw_, other.raw_); @@ -178,12 +196,41 @@ namespace meta_hpp std::uint64_t to_uint64() const { return cast(); } std::size_t to_size_t() const { return cast(); } std::uintptr_t to_uintptr_t() const { return cast(); } + public: + bool is_bool() const noexcept { return !!try_cast(); } + bool is_int() const noexcept { return !!try_cast(); } + bool is_uint() const noexcept { return !!try_cast(); } + bool is_float() const noexcept { return !!try_cast(); } + bool is_double() const noexcept { return !!try_cast(); } + bool is_string() const noexcept { return !!try_cast(); } + + bool is_int8() const noexcept { return !!try_cast(); } + bool is_int16() const noexcept { return !!try_cast(); } + bool is_int32() const noexcept { return !!try_cast(); } + bool is_int64() const noexcept { return !!try_cast(); } + bool is_ptrdiff_t() const noexcept { return !!try_cast(); } + bool is_intptr_t() const noexcept { return !!try_cast(); } + + bool is_uint8() const noexcept { return !!try_cast(); } + bool is_uint16() const noexcept { return !!try_cast(); } + bool is_uint32() const noexcept { return !!try_cast(); } + bool is_uint64() const noexcept { return !!try_cast(); } + bool is_size_t() const noexcept { return !!try_cast(); } + bool is_uintptr_t() const noexcept { return !!try_cast(); } private: std::any raw_; family_id fid_; const value_detail::traits* traits_{}; }; + inline void* data(value& v) noexcept { + return v.data(); + } + + inline const void* data(const value& v) noexcept { + return v.data(); + } + inline void swap(value& l, value& r) noexcept { l.swap(r); } @@ -191,6 +238,16 @@ namespace meta_hpp namespace meta_hpp::value_detail { + template < typename T > + void* value_data(value& v) { + return v.try_cast(); + } + + template < typename T > + const void* value_cdata(const value& v) { + return v.try_cast(); + } + template < typename T > bool value_equal(const value& l, const value& r) { if ( l.fid() != r.fid() ) { diff --git a/untests/meta_value_tests.cpp b/untests/meta_value_tests.cpp index ffaa7b6..f54c276 100644 --- a/untests/meta_value_tests.cpp +++ b/untests/meta_value_tests.cpp @@ -29,6 +29,19 @@ TEST_CASE("meta/value") { CHECK(meta::value{1.0}.to_double() == 1.0); CHECK(meta::value{"meta"s}.to_string() == "meta"); + CHECK(meta::value{true}.is_bool()); + CHECK_FALSE(meta::value{true}.is_int()); + CHECK(meta::value{1}.is_int()); + CHECK_FALSE(meta::value{1}.is_uint()); + CHECK(meta::value{1u}.is_uint()); + CHECK_FALSE(meta::value{1u}.is_float()); + CHECK(meta::value{1.f}.is_float()); + CHECK_FALSE(meta::value{1.f}.is_double()); + CHECK(meta::value{1.0}.is_double()); + CHECK_FALSE(meta::value{1.0}.is_string()); + CHECK(meta::value{"meta"s}.is_string()); + CHECK_FALSE(meta::value{"meta"s}.is_bool()); + CHECK(meta::value{std::in_place_type, std::int8_t{1}}.to_int8() == 1); CHECK(meta::value{std::in_place_type, std::int16_t{1}}.to_int16() == 1); CHECK(meta::value{std::in_place_type, std::int32_t{1}}.to_int32() == 1); @@ -42,6 +55,20 @@ TEST_CASE("meta/value") { CHECK(meta::value{std::in_place_type, std::uint64_t{1}}.to_uint64() == 1u); CHECK(meta::value{std::in_place_type, std::size_t{1}}.to_size_t() == 1u); CHECK(meta::value{std::in_place_type, std::uintptr_t{1}}.to_uintptr_t() == 1u); + + CHECK(meta::value{std::in_place_type, std::int8_t{1}}.is_int8()); + CHECK(meta::value{std::in_place_type, std::int16_t{1}}.is_int16()); + CHECK(meta::value{std::in_place_type, std::int32_t{1}}.is_int32()); + CHECK(meta::value{std::in_place_type, std::int64_t{1}}.is_int64()); + CHECK(meta::value{std::in_place_type, std::ptrdiff_t{1}}.is_ptrdiff_t()); + CHECK(meta::value{std::in_place_type, std::intptr_t{1}}.is_intptr_t()); + + CHECK(meta::value{std::in_place_type, std::uint8_t{1}}.is_uint8()); + CHECK(meta::value{std::in_place_type, std::uint16_t{1}}.is_uint16()); + CHECK(meta::value{std::in_place_type, std::uint32_t{1}}.is_uint32()); + CHECK(meta::value{std::in_place_type, std::uint64_t{1}}.is_uint64()); + CHECK(meta::value{std::in_place_type, std::size_t{1}}.is_size_t()); + CHECK(meta::value{std::in_place_type, std::uintptr_t{1}}.is_uintptr_t()); } TEST_CASE("meta/value/fid") { @@ -63,6 +90,17 @@ TEST_CASE("meta/value/fid") { CHECK(meta::value{std::in_place_type>, {1,2,3,4}}.fid() == meta::get_type_family_id>()); } +TEST_CASE("meta/value/data") { + namespace meta = meta_hpp; + using namespace std::string_literals; + + meta::value v{1}; + CHECK(*static_cast(v.data()) == 1); + *static_cast(v.data()) = 2; + CHECK(v.to_int() == 2); + CHECK(*static_cast(std::as_const(v).data()) == 2); +} + TEST_CASE("meta/value/equal") { namespace meta = meta_hpp; using namespace std::string_literals; From 3a49cafe9fcd73fd40e65e260592d9f606dc0148 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Tue, 6 Jul 2021 04:14:21 +0700 Subject: [PATCH 036/233] more complete function, method, and field traits --- headers/meta.hpp/meta_fwd.hpp | 85 +++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/headers/meta.hpp/meta_fwd.hpp b/headers/meta.hpp/meta_fwd.hpp index f6497d9..99ffa0c 100644 --- a/headers/meta.hpp/meta_fwd.hpp +++ b/headers/meta.hpp/meta_fwd.hpp @@ -165,3 +165,88 @@ namespace meta_hpp::detail } } } + +namespace meta_hpp::detail +{ + template < typename Field > + struct field_traits; + + template < typename T, typename I > + struct field_traits { + static constexpr bool is_const = false; + using value_type = T; + using instance_type = I; + }; + + template < typename T, typename I > + struct field_traits + : field_traits { + static constexpr bool is_const = true; + }; +} + +namespace meta_hpp::detail +{ + template < typename Function > + struct function_traits; + + template < typename R, typename... Args > + struct function_traits { + static constexpr bool is_noexcept = false; + static constexpr std::size_t arity = sizeof...(Args); + using return_type = R; + using argument_types = std::tuple; + }; + + template < typename R, typename... Args > + struct function_traits + : function_traits {}; + + template < typename R, typename... Args > + struct function_traits + : function_traits {}; + + template < typename R, typename... Args > + struct function_traits + : function_traits { + static constexpr bool is_noexcept = true; + }; + + template < typename R, typename... Args > + struct function_traits + : function_traits { + static constexpr bool is_noexcept = true; + }; +} + +namespace meta_hpp::detail +{ + template < typename Method > + struct method_traits; + + template < typename R, typename I, typename... Args > + struct method_traits + : function_traits { + static constexpr bool is_const = false; + using instance_type = I; + }; + + template < typename R, typename I, typename... Args > + struct method_traits + : method_traits { + static constexpr bool is_const = true; + }; + + template < typename R, typename I, typename... Args > + struct method_traits + : method_traits { + static constexpr bool is_noexcept = true; + }; + + template < typename R, typename I, typename... Args > + struct method_traits + : method_traits { + static constexpr bool is_const = true; + static constexpr bool is_noexcept = true; + }; +} From 8f2427996e421cd49e663a29a78e954af475b6ec Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Tue, 6 Jul 2021 04:16:15 +0700 Subject: [PATCH 037/233] instance and cinstance classes --- headers/meta.hpp/meta.hpp | 1 + headers/meta.hpp/meta_instance.hpp | 99 ++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+) create mode 100644 headers/meta.hpp/meta_instance.hpp diff --git a/headers/meta.hpp/meta.hpp b/headers/meta.hpp/meta.hpp index 5a4b00a..125d059 100644 --- a/headers/meta.hpp/meta.hpp +++ b/headers/meta.hpp/meta.hpp @@ -8,6 +8,7 @@ #include "meta_fwd.hpp" +#include "meta_instance.hpp" #include "meta_value.hpp" #include "meta_registry.hpp" diff --git a/headers/meta.hpp/meta_instance.hpp b/headers/meta.hpp/meta_instance.hpp new file mode 100644 index 0000000..dd01c77 --- /dev/null +++ b/headers/meta.hpp/meta_instance.hpp @@ -0,0 +1,99 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "meta_fwd.hpp" + +#include "meta_value.hpp" + +namespace meta_hpp +{ + class instance; + class cinstance; +} + +namespace meta_hpp +{ + class instance { + public: + instance() = delete; + + instance(instance&&) = default; + instance(const instance&) = default; + + instance& operator=(instance&&) = default; + instance& operator=(const instance&) = default; + + template < typename T + , typename = std::enable_if_t> + , typename = std::enable_if_t> + , typename = std::enable_if_t> > + instance(T& v) + : data_{std::addressof(v)} + , fid_{get_type_family_id()} {} + + instance(value& v) + : data_{v.data()} + , fid_{v.fid()} {} + + void* data() noexcept { + return data_; + } + + const void* data() const noexcept { + return data_; + } + + family_id fid() const noexcept { + return fid_; + } + private: + void* data_{}; + family_id fid_{}; + }; +} + +namespace meta_hpp +{ + class cinstance { + public: + cinstance() = delete; + + cinstance(cinstance&&) = default; + cinstance(const cinstance&) = default; + + cinstance& operator=(cinstance&&) = default; + cinstance& operator=(const cinstance&) = default; + + template < typename T + , typename = std::enable_if_t> + , typename = std::enable_if_t> + , typename = std::enable_if_t> > + cinstance(const T& data) + : data_{std::addressof(data)} + , fid_{get_type_family_id()} {} + + cinstance(const value& v) + : data_{v.data()} + , fid_{v.fid()} {} + + cinstance(const instance& v) + : data_{v.data()} + , fid_{v.fid()} {} + + const void* data() const noexcept { + return data_; + } + + family_id fid() const noexcept { + return fid_; + } + private: + const void* data_{}; + family_id fid_{}; + }; +} From b6c469ccb325669b1f6f34ded4e6b504fcda7224 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Tue, 6 Jul 2021 05:19:40 +0700 Subject: [PATCH 038/233] invoke info by instance --- headers/meta.hpp/meta_field_info.hpp | 54 ++++----- headers/meta.hpp/meta_function_info.hpp | 27 +---- headers/meta.hpp/meta_fwd.hpp | 18 +++ headers/meta.hpp/meta_instance.hpp | 27 +++++ headers/meta.hpp/meta_method_info.hpp | 106 +++++++---------- headers/meta.hpp/meta_value.hpp | 2 + headers/meta.hpp/meta_variable_info.hpp | 32 ++--- untests/meta_class_tests.cpp | 4 +- untests/meta_examples.cpp | 10 +- untests/meta_field_tests.cpp | 25 ++-- untests/meta_method_tests.cpp | 150 ++++++++++++++---------- untests/meta_variable_tests.cpp | 1 + 12 files changed, 243 insertions(+), 213 deletions(-) diff --git a/headers/meta.hpp/meta_field_info.hpp b/headers/meta.hpp/meta_field_info.hpp index f4c2a38..a521fdc 100644 --- a/headers/meta.hpp/meta_field_info.hpp +++ b/headers/meta.hpp/meta_field_info.hpp @@ -7,49 +7,47 @@ #pragma once #include "meta_fwd.hpp" + +#include "meta_instance.hpp" #include "meta_value.hpp" #include "meta_data_info.hpp" namespace meta_hpp::field_detail { - template < typename Field > - struct field_traits; - - template < typename T, typename Base > - struct field_traits { - static constexpr bool is_const = false; - using value_type = T; - using instance_type = Base; - }; - - template < typename T, typename Base > - struct field_traits - : field_traits { - static constexpr bool is_const = true; - }; - template < auto Field > - value getter(const void* instance) { - using ft = field_traits; + value getter(cinstance instance) { + using ft = detail::field_traits; using value_type = typename ft::value_type; using instance_type = typename ft::instance_type; - auto instance_ptr = static_cast(instance); - value_type typed_value = std::invoke(Field, *instance_ptr); + const instance_type* typed_instance{instance.try_cast()}; + if ( !typed_instance ) { + throw std::logic_error("an attempt to get a field with incorrect instance type"); + } + value_type typed_value{std::invoke(Field, *typed_instance)}; return value{std::move(typed_value)}; } template < auto Field > - void setter([[maybe_unused]] void* instance, value value) { - using ft = field_traits; + void setter([[maybe_unused]] instance instance, value value) { + using ft = detail::field_traits; using value_type = typename ft::value_type; using instance_type = typename ft::instance_type; if constexpr ( !ft::is_const ) { - auto instance_ptr = static_cast(instance); - std::invoke(Field, *instance_ptr) = value.cast(); + instance_type* typed_instance{instance.try_cast()}; + if ( !typed_instance ) { + throw std::logic_error("an attempt to set a field with incorrect instance type"); + } + + value_type* typed_value{value.try_cast()}; + if ( !typed_value ) { + throw std::logic_error("an attempt to set a field with incorrect argument type"); + } + + std::invoke(Field, *typed_instance) = std::move(*typed_value); } else { throw std::logic_error("an attempt to change a constant field"); } @@ -75,12 +73,12 @@ namespace meta_hpp const std::string& id() const noexcept { return id_; } - value get(const void* instance) const { + value get(cinstance instance) const { return getter_(instance); } template < typename Value > - void set(void* instance, Value&& value) const { + void set(instance instance, Value&& value) const { return setter_(instance, std::forward(value)); } @@ -119,8 +117,8 @@ namespace meta_hpp private: family_id fid_; std::string id_; - value(*getter_)(const void*); - void(*setter_)(void*, value); + value(*getter_)(cinstance); + void(*setter_)(instance, value); std::map> datas_; }; } diff --git a/headers/meta.hpp/meta_function_info.hpp b/headers/meta.hpp/meta_function_info.hpp index 8c1908c..3826c11 100644 --- a/headers/meta.hpp/meta_function_info.hpp +++ b/headers/meta.hpp/meta_function_info.hpp @@ -7,33 +7,20 @@ #pragma once #include "meta_fwd.hpp" + #include "meta_value.hpp" #include "meta_data_info.hpp" namespace meta_hpp::function_detail { - template < typename Function > - struct function_traits; - - template < typename R, typename... Args > - struct function_traits { - static constexpr std::size_t arity = sizeof...(Args); - using return_type = R; - using argument_types = std::tuple; - }; - - template < typename R, typename... Args > - struct function_traits - : function_traits {}; - template < auto Function, std::size_t... Is > std::optional invoke(value* args, std::index_sequence) { - using ft = function_traits; + using ft = detail::function_traits; using return_type = typename ft::return_type; using argument_types = typename ft::argument_types; - [[maybe_unused]] auto typed_arguments = std::make_tuple( + auto typed_arguments = std::make_tuple( (args + Is)->try_cast>()...); if ( !(std::get(typed_arguments) && ...) ) { @@ -41,19 +28,17 @@ namespace meta_hpp::function_detail } if constexpr ( std::is_void_v ) { - std::invoke(Function, - *std::get(typed_arguments)...); + std::invoke(Function, std::move(*std::get(typed_arguments))...); return std::nullopt; } else { - return_type return_value = std::invoke(Function, - *std::get(typed_arguments)...); + return_type return_value{std::invoke(Function, std::move(*std::get(typed_arguments))...)}; return value{std::move(return_value)}; } } template < auto Function > std::optional invoke(value* args, std::size_t arg_count) { - using ft = function_traits; + using ft = detail::function_traits; if ( arg_count != ft::arity ) { throw std::logic_error("an attempt to call a function with an incorrect arity"); diff --git a/headers/meta.hpp/meta_fwd.hpp b/headers/meta.hpp/meta_fwd.hpp index 99ffa0c..cdd2a8e 100644 --- a/headers/meta.hpp/meta_fwd.hpp +++ b/headers/meta.hpp/meta_fwd.hpp @@ -250,3 +250,21 @@ namespace meta_hpp::detail static constexpr bool is_noexcept = true; }; } + +namespace meta_hpp::detail +{ + template < typename Variable > + struct variable_traits; + + template < typename T > + struct variable_traits { + static constexpr bool is_const = false; + using value_type = T; + }; + + template < typename T > + struct variable_traits + : variable_traits { + static constexpr bool is_const = true; + }; +} diff --git a/headers/meta.hpp/meta_instance.hpp b/headers/meta.hpp/meta_instance.hpp index dd01c77..05ce486 100644 --- a/headers/meta.hpp/meta_instance.hpp +++ b/headers/meta.hpp/meta_instance.hpp @@ -51,6 +51,24 @@ namespace meta_hpp family_id fid() const noexcept { return fid_; } + + template < typename T > + std::add_pointer_t + try_cast() noexcept { + static_assert(!std::is_reference_v); + return fid() == get_type_family_id() + ? static_cast>(data_) + : nullptr; + } + + template < typename T > + std::add_pointer_t> + try_cast() const noexcept { + static_assert(!std::is_reference_v); + return fid() == get_type_family_id() + ? static_cast>>(data_) + : nullptr; + } private: void* data_{}; family_id fid_{}; @@ -92,6 +110,15 @@ namespace meta_hpp family_id fid() const noexcept { return fid_; } + + template < typename T > + std::add_pointer_t> + try_cast() const noexcept { + static_assert(!std::is_reference_v); + return fid() == get_type_family_id() + ? static_cast>>(data_) + : nullptr; + } private: const void* data_{}; family_id fid_{}; diff --git a/headers/meta.hpp/meta_method_info.hpp b/headers/meta.hpp/meta_method_info.hpp index 81fdedf..e3974aa 100644 --- a/headers/meta.hpp/meta_method_info.hpp +++ b/headers/meta.hpp/meta_method_info.hpp @@ -7,46 +7,27 @@ #pragma once #include "meta_fwd.hpp" + +#include "meta_instance.hpp" #include "meta_value.hpp" #include "meta_data_info.hpp" namespace meta_hpp::method_detail { - template < typename Method > - struct method_traits; - - template < typename R, typename Base, typename... Args > - struct method_traits { - static constexpr bool is_const = false; - static constexpr std::size_t arity = sizeof...(Args); - using return_type = R; - using instance_type = Base; - using argument_types = std::tuple; - }; - - template < typename R, typename Base, typename... Args > - struct method_traits - : method_traits { - static constexpr bool is_const = true; - }; - - template < typename R, typename Base, typename... Args > - struct method_traits - : method_traits {}; - - template < typename R, typename Base, typename... Args > - struct method_traits - : method_traits {}; - template < auto Method, std::size_t... Is > - std::optional invoke([[maybe_unused]] void* instance, value* args, std::index_sequence) { - using mt = method_traits; + std::optional invoke(instance instance, value* args, std::index_sequence) { + using mt = detail::method_traits; using return_type = typename mt::return_type; using instance_type = typename mt::instance_type; using argument_types = typename mt::argument_types; - [[maybe_unused]] auto typed_arguments = std::make_tuple( + instance_type* typed_instance{instance.try_cast()}; + if ( !typed_instance ) { + throw std::logic_error("an attempt to call a method with incorrect instance type"); + } + + auto typed_arguments = std::make_tuple( (args + Is)->try_cast>()...); if ( !(std::get(typed_arguments) && ...) ) { @@ -54,21 +35,17 @@ namespace meta_hpp::method_detail } if constexpr ( std::is_void_v ) { - std::invoke(Method, - std::ref(*static_cast(instance)), - *std::get(typed_arguments)...); + std::invoke(Method, *typed_instance, std::move(*std::get(typed_arguments))...); return std::nullopt; } else { - return_type return_value = std::invoke(Method, - std::ref(*static_cast(instance)), - *std::get(typed_arguments)...); + return_type return_value{std::invoke(Method, *typed_instance, std::move(*std::get(typed_arguments))...)}; return value{std::move(return_value)}; } } template < auto Method > - std::optional invoke(void* instance, value* args, std::size_t arg_count) { - using mt = method_traits; + std::optional invoke(instance instance, value* args, std::size_t arg_count) { + using mt = detail::method_traits; if ( arg_count != mt::arity ) { throw std::logic_error("an attempt to call a method with an incorrect arity"); @@ -78,29 +55,30 @@ namespace meta_hpp::method_detail } template < auto Method, std::size_t... Is > - std::optional cinvoke([[maybe_unused]] const void* instance, value* args, std::index_sequence) { - using mt = method_traits; + std::optional cinvoke([[maybe_unused]] cinstance instance, value* args, std::index_sequence) { + using mt = detail::method_traits; using return_type = typename mt::return_type; using instance_type = typename mt::instance_type; using argument_types = typename mt::argument_types; - [[maybe_unused]] auto typed_arguments = std::make_tuple( - (args + Is)->try_cast>()...); - - if ( !(std::get(typed_arguments) && ...) ) { - throw std::logic_error("an attempt to call a method with incorrect argument types"); - } - if constexpr ( mt::is_const ) { + const instance_type* typed_instance{instance.try_cast()}; + if ( !typed_instance ) { + throw std::logic_error("an attempt to call a method with incorrect instance type"); + } + + auto typed_arguments = std::make_tuple( + (args + Is)->try_cast>()...); + + if ( !(std::get(typed_arguments) && ...) ) { + throw std::logic_error("an attempt to call a method with incorrect argument types"); + } + if constexpr ( std::is_void_v ) { - std::invoke(Method, - std::ref(*static_cast(instance)), - *std::get(typed_arguments)...); + std::invoke(Method, *typed_instance, std::move(*std::get(typed_arguments))...); return std::nullopt; } else { - return_type return_value = std::invoke(Method, - std::ref(*static_cast(instance)), - *std::get(typed_arguments)...); + return_type return_value{std::invoke(Method, *typed_instance, std::move(*std::get(typed_arguments))...)}; return value{std::move(return_value)}; } } else { @@ -109,8 +87,8 @@ namespace meta_hpp::method_detail } template < auto Method > - std::optional cinvoke(const void* instance, value* args, std::size_t arg_count) { - using mt = method_traits; + std::optional cinvoke(cinstance instance, value* args, std::size_t arg_count) { + using mt = detail::method_traits; if ( arg_count != mt::arity ) { throw std::logic_error("an attempt to call a method with a different arity"); @@ -140,23 +118,23 @@ namespace meta_hpp return id_; } - template < typename... Args > - std::optional invoke(void* instance, Args&&... args) const { + template < typename T, typename... Args > + std::optional invoke(T& inst, Args&&... args) const { if constexpr ( sizeof...(Args) > 0u ) { std::array vargs{std::forward(args)...}; - return invoke_(instance, vargs.data(), vargs.size()); + return invoke_(inst, vargs.data(), vargs.size()); } else { - return invoke_(instance, nullptr, 0u); + return invoke_(inst, nullptr, 0u); } } - template < typename... Args > - std::optional invoke(const void* instance, Args&&... args) const { + template < typename T, typename... Args > + std::optional invoke(const T& inst, Args&&... args) const { if constexpr ( sizeof...(Args) > 0u ) { std::array vargs{std::forward(args)...}; - return cinvoke_(instance, vargs.data(), vargs.size()); + return cinvoke_(inst, vargs.data(), vargs.size()); } else { - return cinvoke_(instance, nullptr, 0u); + return cinvoke_(inst, nullptr, 0u); } } @@ -195,8 +173,8 @@ namespace meta_hpp private: family_id fid_; std::string id_; - std::optional(*invoke_)(void*, value*, std::size_t); - std::optional(*cinvoke_)(const void*, value*, std::size_t); + std::optional(*invoke_)(instance, value*, std::size_t); + std::optional(*cinvoke_)(cinstance, value*, std::size_t); std::map> datas_; }; } diff --git a/headers/meta.hpp/meta_value.hpp b/headers/meta.hpp/meta_value.hpp index 9bcf737..a2a8a7f 100644 --- a/headers/meta.hpp/meta_value.hpp +++ b/headers/meta.hpp/meta_value.hpp @@ -104,12 +104,14 @@ namespace meta_hpp template < typename T > std::add_pointer_t try_cast() noexcept { + static_assert(!std::is_reference_v); return std::any_cast(&raw_); } template < typename T > std::add_pointer_t> try_cast() const noexcept { + static_assert(!std::is_reference_v); return std::any_cast(&raw_); } diff --git a/headers/meta.hpp/meta_variable_info.hpp b/headers/meta.hpp/meta_variable_info.hpp index 513f6ee..a460254 100644 --- a/headers/meta.hpp/meta_variable_info.hpp +++ b/headers/meta.hpp/meta_variable_info.hpp @@ -7,46 +7,36 @@ #pragma once #include "meta_fwd.hpp" + #include "meta_value.hpp" #include "meta_data_info.hpp" namespace meta_hpp::variable_detail { - template < typename Variable > - struct variable_traits; - - template < typename T > - struct variable_traits { - static constexpr bool is_const = false; - using value_type = T; - }; - - template < typename T > - struct variable_traits - : variable_traits { - static constexpr bool is_const = true; - }; - template < auto Variable > value getter() { - using vt = variable_traits>; + using vt = detail::variable_traits>; using value_type = typename vt::value_type; - value_type typed_value = *Variable; - + value_type typed_value{*Variable}; return value{std::move(typed_value)}; } template < auto Variable > void setter(value value) { - using vt = variable_traits>; + using vt = detail::variable_traits>; using value_type = typename vt::value_type; if constexpr ( !vt::is_const ) { - *Variable = value.cast(); + value_type* typed_value{value.try_cast()}; + if ( !typed_value ) { + throw std::logic_error("an attempt to set a variable with incorrect argument type"); + } + + *Variable = std::move(*typed_value); } else { - throw std::logic_error("an attempt to change a constant variable"); + throw std::logic_error("an attempt to set a constant variable"); } } } diff --git a/untests/meta_class_tests.cpp b/untests/meta_class_tests.cpp index cd2105e..0df71d1 100644 --- a/untests/meta_class_tests.cpp +++ b/untests/meta_class_tests.cpp @@ -150,8 +150,8 @@ TEST_CASE("meta/class/merge") { { clazz::clazz2 instance{}; - CHECK(clazz_info.get_class("child")->get_field("field")->get(&instance).to_int() == 21); - CHECK(clazz_info.get_class("child")->get_field("cfield")->get(&instance).to_int() == 22); + CHECK(clazz_info.get_class("child")->get_field("field")->get(instance).to_int() == 21); + CHECK(clazz_info.get_class("child")->get_field("cfield")->get(instance).to_int() == 22); } } } diff --git a/untests/meta_examples.cpp b/untests/meta_examples.cpp index 1c377ef..ba0959b 100644 --- a/untests/meta_examples.cpp +++ b/untests/meta_examples.cpp @@ -131,10 +131,10 @@ 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_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); } { @@ -180,7 +180,7 @@ TEST_CASE("meta/examples/advanced") { v3_info.each_field([&v3](const field_info& info){ std::cout << " - " << info.id() - << ": " << info.get(&v3).to_int() << std::endl; + << ": " << info.get(v3).to_int() << std::endl; }); v3_info.each_method([](const method_info& info){ diff --git a/untests/meta_field_tests.cpp b/untests/meta_field_tests.cpp index 990f6cb..3b0ce40 100644 --- a/untests/meta_field_tests.cpp +++ b/untests/meta_field_tests.cpp @@ -29,35 +29,36 @@ TEST_CASE("meta/field") { clazz instance; CHECK(instance.field == 1); - CHECK(field_info.get(&instance).cast() == 1); - CHECK(field_info.get(&std::as_const(instance)).cast() == 1); + CHECK(field_info.get(instance).cast() == 1); + CHECK(field_info.get(std::as_const(instance)).cast() == 1); - CHECK_NOTHROW(field_info.set(&instance, 3)); + CHECK_NOTHROW(field_info.set(instance, 3)); + CHECK_THROWS_AS(field_info.set(instance, 4.f), std::logic_error); CHECK(instance.field == 3); - CHECK(field_info.get(&instance).cast() == 3); - CHECK(field_info.get(&std::as_const(instance)).cast() == 3); + CHECK(field_info.get(instance).cast() == 3); + CHECK(field_info.get(std::as_const(instance)).cast() == 3); } { clazz instance; CHECK(instance.cfield == 2); - CHECK(cfield_info.get(&instance).cast() == 2); - CHECK(cfield_info.get(&std::as_const(instance)).cast() == 2); + CHECK(cfield_info.get(instance).cast() == 2); + CHECK(cfield_info.get(std::as_const(instance)).cast() == 2); - CHECK_THROWS_AS(cfield_info.set(&instance, 4), std::logic_error); + CHECK_THROWS_AS(cfield_info.set(instance, 4), std::logic_error); CHECK(instance.cfield == 2); - CHECK(cfield_info.get(&instance).cast() == 2); - CHECK(cfield_info.get(&std::as_const(instance)).cast() == 2); + CHECK(cfield_info.get(instance).cast() == 2); + CHECK(cfield_info.get(std::as_const(instance)).cast() == 2); } { clazz instance; instance.field = 5; - CHECK(field_info.get(&instance).cast() == 5); - CHECK(field_info.get(&std::as_const(instance)).cast() == 5); + CHECK(field_info.get(instance).cast() == 5); + CHECK(field_info.get(std::as_const(instance)).cast() == 5); } } diff --git a/untests/meta_method_tests.cpp b/untests/meta_method_tests.cpp index 62b069d..d8000a1 100644 --- a/untests/meta_method_tests.cpp +++ b/untests/meta_method_tests.cpp @@ -27,6 +27,8 @@ namespace int const_int_f_int(int a) const { return a; } int const_int_f_int2(int a, int b) const { return a + b; } }; + + class clazz2 {}; } TEST_CASE("meta/non_const_method") { @@ -48,52 +50,66 @@ TEST_CASE("meta/non_const_method") { const meta::method_info& int_f_int_info = int_f_int_method_; const meta::method_info& int_f_int2_info = int_f_int2_method_; + SUBCASE("another_instance") { + clazz2 instance; + CHECK_THROWS_AS(void_f_void_info.invoke(instance), std::logic_error); + CHECK_THROWS_AS(void_f_int_info.invoke(instance, 1), std::logic_error); + CHECK_THROWS_AS(void_f_int2_info.invoke(instance, 1, 2), std::logic_error); + } + SUBCASE("void_return") { clazz instance; - CHECK_NOTHROW(void_f_void_info.invoke(&instance)); - CHECK_THROWS_AS(void_f_void_info.invoke(&instance, 1), std::logic_error); + CHECK_NOTHROW(void_f_void_info.invoke(instance)); + CHECK_THROWS_AS(void_f_void_info.invoke(instance, 1), std::logic_error); - CHECK_THROWS_AS(void_f_int_info.invoke(&instance), std::logic_error); - CHECK_NOTHROW(void_f_int_info.invoke(&instance, 1)); - CHECK_THROWS_AS(void_f_int_info.invoke(&instance, 1.f), std::logic_error); - CHECK_THROWS_AS(void_f_int_info.invoke(&instance, 1, 2), std::logic_error); + CHECK_THROWS_AS(void_f_int_info.invoke(instance), std::logic_error); + CHECK_NOTHROW(void_f_int_info.invoke(instance, 1)); + CHECK_THROWS_AS(void_f_int_info.invoke(instance, 1.f), std::logic_error); + CHECK_THROWS_AS(void_f_int_info.invoke(instance, 1, 2), std::logic_error); - CHECK_THROWS_AS(void_f_int2_info.invoke(&instance), std::logic_error); - CHECK_THROWS_AS(void_f_int2_info.invoke(&instance, 1), std::logic_error); - CHECK_NOTHROW(void_f_int2_info.invoke(&instance, 1, 2)); - CHECK_THROWS_AS(void_f_int2_info.invoke(&instance, 1.f, 2), std::logic_error); - CHECK_THROWS_AS(void_f_int2_info.invoke(&instance, 1, 2.f), std::logic_error); - CHECK_THROWS_AS(void_f_int2_info.invoke(&instance, 1, 2, 3), std::logic_error); + CHECK_THROWS_AS(void_f_int2_info.invoke(instance), std::logic_error); + CHECK_THROWS_AS(void_f_int2_info.invoke(instance, 1), std::logic_error); + CHECK_NOTHROW(void_f_int2_info.invoke(instance, 1, 2)); + CHECK_THROWS_AS(void_f_int2_info.invoke(instance, 1.f, 2), std::logic_error); + CHECK_THROWS_AS(void_f_int2_info.invoke(instance, 1, 2.f), std::logic_error); + CHECK_THROWS_AS(void_f_int2_info.invoke(instance, 1, 2, 3), std::logic_error); const clazz& cinstance = instance; - CHECK_THROWS_AS(void_f_void_info.invoke(&cinstance), std::logic_error); - CHECK_THROWS_AS(void_f_int_info.invoke(&cinstance, 1), std::logic_error); - CHECK_THROWS_AS(void_f_int2_info.invoke(&cinstance, 1, 2), std::logic_error); + CHECK_THROWS_AS(void_f_void_info.invoke(cinstance), std::logic_error); + CHECK_THROWS_AS(void_f_int_info.invoke(cinstance, 1), std::logic_error); + CHECK_THROWS_AS(void_f_int2_info.invoke(cinstance, 1, 2), std::logic_error); } SUBCASE("int_return") { clazz instance; - CHECK(int_f_void_info.invoke(&instance)->cast() == 1); - CHECK_THROWS_AS(int_f_void_info.invoke(&instance, 1), std::logic_error); + 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_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_int_info.invoke(instance), std::logic_error); + 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_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); + 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_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_THROWS_AS(int_f_void_info.invoke(&cinstance), std::logic_error); - CHECK_THROWS_AS(int_f_int_info.invoke(&cinstance, 1), std::logic_error); - CHECK_THROWS_AS(int_f_int2_info.invoke(&cinstance, 1, 2), std::logic_error); + CHECK_THROWS_AS(int_f_void_info.invoke(cinstance), std::logic_error); + CHECK_THROWS_AS(int_f_int_info.invoke(cinstance, 1), std::logic_error); + CHECK_THROWS_AS(int_f_int2_info.invoke(cinstance, 1, 2), std::logic_error); + } + + SUBCASE("int_return_by_value") { + meta::value instance{clazz{}}; + CHECK(int_f_void_info.invoke(instance)->cast() == 1); + CHECK(int_f_int_info.invoke(instance, 1)->cast() == 1); + CHECK(int_f_int2_info.invoke(instance, 1, 2)->cast() == 3); } } @@ -116,51 +132,65 @@ TEST_CASE("meta/const_method") { const meta::method_info& int_f_int_info = int_f_int_method_; const meta::method_info& int_f_int2_info = int_f_int2_method_; + SUBCASE("another_instance") { + const clazz2 instance; + CHECK_THROWS_AS(void_f_void_info.invoke(instance), std::logic_error); + CHECK_THROWS_AS(void_f_int_info.invoke(instance, 1), std::logic_error); + CHECK_THROWS_AS(void_f_int2_info.invoke(instance, 1, 2), std::logic_error); + } + SUBCASE("void_return") { clazz instance; - CHECK_NOTHROW(void_f_void_info.invoke(&instance)); - CHECK_THROWS_AS(void_f_void_info.invoke(&instance, 1), std::logic_error); + CHECK_NOTHROW(void_f_void_info.invoke(instance)); + CHECK_THROWS_AS(void_f_void_info.invoke(instance, 1), std::logic_error); - CHECK_THROWS_AS(void_f_int_info.invoke(&instance), std::logic_error); - CHECK_NOTHROW(void_f_int_info.invoke(&instance, 1)); - CHECK_THROWS_AS(void_f_int_info.invoke(&instance, 1.f), std::logic_error); - CHECK_THROWS_AS(void_f_int_info.invoke(&instance, 1, 2), std::logic_error); + CHECK_THROWS_AS(void_f_int_info.invoke(instance), std::logic_error); + CHECK_NOTHROW(void_f_int_info.invoke(instance, 1)); + CHECK_THROWS_AS(void_f_int_info.invoke(instance, 1.f), std::logic_error); + CHECK_THROWS_AS(void_f_int_info.invoke(instance, 1, 2), std::logic_error); - CHECK_THROWS_AS(void_f_int2_info.invoke(&instance), std::logic_error); - CHECK_THROWS_AS(void_f_int2_info.invoke(&instance, 1), std::logic_error); - CHECK_NOTHROW(void_f_int2_info.invoke(&instance, 1, 2)); - CHECK_THROWS_AS(void_f_int2_info.invoke(&instance, 1.f, 2), std::logic_error); - CHECK_THROWS_AS(void_f_int2_info.invoke(&instance, 1, 2.f), std::logic_error); - CHECK_THROWS_AS(void_f_int2_info.invoke(&instance, 1, 2, 3), std::logic_error); + CHECK_THROWS_AS(void_f_int2_info.invoke(instance), std::logic_error); + CHECK_THROWS_AS(void_f_int2_info.invoke(instance, 1), std::logic_error); + CHECK_NOTHROW(void_f_int2_info.invoke(instance, 1, 2)); + CHECK_THROWS_AS(void_f_int2_info.invoke(instance, 1.f, 2), std::logic_error); + CHECK_THROWS_AS(void_f_int2_info.invoke(instance, 1, 2.f), std::logic_error); + CHECK_THROWS_AS(void_f_int2_info.invoke(instance, 1, 2, 3), std::logic_error); const clazz& cinstance = instance; - CHECK_NOTHROW(void_f_void_info.invoke(&cinstance)); - CHECK_NOTHROW(void_f_int_info.invoke(&cinstance, 1)); - CHECK_NOTHROW(void_f_int2_info.invoke(&cinstance, 1, 2)); + CHECK_NOTHROW(void_f_void_info.invoke(cinstance)); + CHECK_NOTHROW(void_f_int_info.invoke(cinstance, 1)); + CHECK_NOTHROW(void_f_int2_info.invoke(cinstance, 1, 2)); } SUBCASE("int_return") { clazz instance; - CHECK(int_f_void_info.invoke(&instance)->cast() == 1); - CHECK_THROWS_AS(int_f_void_info.invoke(&instance, 1), std::logic_error); + 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_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_int_info.invoke(instance), std::logic_error); + 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_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); + 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_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); + } + + SUBCASE("int_return_by_value") { + meta::value instance{clazz{}}; + CHECK(int_f_void_info.invoke(instance)->cast() == 1); + CHECK(int_f_int_info.invoke(instance, 1)->cast() == 1); + CHECK(int_f_int2_info.invoke(instance, 1, 2)->cast() == 3); } } diff --git a/untests/meta_variable_tests.cpp b/untests/meta_variable_tests.cpp index 0ec0f59..868abfd 100644 --- a/untests/meta_variable_tests.cpp +++ b/untests/meta_variable_tests.cpp @@ -37,6 +37,7 @@ TEST_CASE("meta/variable") { CHECK(variable_info.get().cast() == 1); CHECK_NOTHROW(variable_info.set(3)); + CHECK_THROWS_AS(variable_info.set(4.f), std::logic_error); CHECK(variable == 3); CHECK(variable_info.get().cast() == 3); From 6c64df3bce2769b5c714e4312e88e853492552c5 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Tue, 6 Jul 2021 06:37:12 +0700 Subject: [PATCH 039/233] fix gcc warnings --- headers/meta.hpp/meta_function_info.hpp | 2 +- headers/meta.hpp/meta_method_info.hpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/headers/meta.hpp/meta_function_info.hpp b/headers/meta.hpp/meta_function_info.hpp index 3826c11..b879529 100644 --- a/headers/meta.hpp/meta_function_info.hpp +++ b/headers/meta.hpp/meta_function_info.hpp @@ -20,7 +20,7 @@ namespace meta_hpp::function_detail using return_type = typename ft::return_type; using argument_types = typename ft::argument_types; - auto typed_arguments = std::make_tuple( + [[maybe_unused]] auto typed_arguments = std::make_tuple( (args + Is)->try_cast>()...); if ( !(std::get(typed_arguments) && ...) ) { diff --git a/headers/meta.hpp/meta_method_info.hpp b/headers/meta.hpp/meta_method_info.hpp index e3974aa..91ea929 100644 --- a/headers/meta.hpp/meta_method_info.hpp +++ b/headers/meta.hpp/meta_method_info.hpp @@ -27,7 +27,7 @@ namespace meta_hpp::method_detail throw std::logic_error("an attempt to call a method with incorrect instance type"); } - auto typed_arguments = std::make_tuple( + [[maybe_unused]] auto typed_arguments = std::make_tuple( (args + Is)->try_cast>()...); if ( !(std::get(typed_arguments) && ...) ) { @@ -67,7 +67,7 @@ namespace meta_hpp::method_detail throw std::logic_error("an attempt to call a method with incorrect instance type"); } - auto typed_arguments = std::make_tuple( + [[maybe_unused]] auto typed_arguments = std::make_tuple( (args + Is)->try_cast>()...); if ( !(std::get(typed_arguments) && ...) ) { From e471b3b70ab9cb8e7fbd6ff62a4a6320e455c6cf Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Tue, 6 Jul 2021 22:20:23 +0700 Subject: [PATCH 040/233] remove auto templates usage --- headers/meta.hpp/meta_field.hpp | 2 +- headers/meta.hpp/meta_field_info.hpp | 18 ++++---- headers/meta.hpp/meta_function.hpp | 2 +- headers/meta.hpp/meta_function_info.hpp | 18 ++++---- headers/meta.hpp/meta_fwd.hpp | 14 +++--- headers/meta.hpp/meta_method.hpp | 2 +- headers/meta.hpp/meta_method_info.hpp | 30 ++++++------- headers/meta.hpp/meta_registry.hpp | 4 +- headers/meta.hpp/meta_variable.hpp | 2 +- headers/meta.hpp/meta_variable_info.hpp | 18 ++++---- untests/meta_registry_tests.cpp | 60 ++++++++++++------------- 11 files changed, 86 insertions(+), 84 deletions(-) diff --git a/headers/meta.hpp/meta_field.hpp b/headers/meta.hpp/meta_field.hpp index de7f1bc..2ba7475 100644 --- a/headers/meta.hpp/meta_field.hpp +++ b/headers/meta.hpp/meta_field.hpp @@ -20,7 +20,7 @@ namespace meta_hpp static_assert(std::is_member_object_pointer_v); explicit field_(std::string id) - : info_{detail::auto_arg, std::move(id)} {} + : info_{detail::auto_arg, std::move(id)} {} operator const field_info&() const noexcept { return info_; diff --git a/headers/meta.hpp/meta_field_info.hpp b/headers/meta.hpp/meta_field_info.hpp index a521fdc..ce1c488 100644 --- a/headers/meta.hpp/meta_field_info.hpp +++ b/headers/meta.hpp/meta_field_info.hpp @@ -15,9 +15,9 @@ namespace meta_hpp::field_detail { - template < auto Field > + template < typename FieldType, FieldType Field > value getter(cinstance instance) { - using ft = detail::field_traits; + using ft = detail::field_traits; using value_type = typename ft::value_type; using instance_type = typename ft::instance_type; @@ -30,9 +30,9 @@ namespace meta_hpp::field_detail return value{std::move(typed_value)}; } - template < auto Field > + template < typename FieldType, FieldType Field > void setter([[maybe_unused]] instance instance, value value) { - using ft = detail::field_traits; + using ft = detail::field_traits; using value_type = typename ft::value_type; using instance_type = typename ft::instance_type; @@ -108,12 +108,12 @@ namespace meta_hpp template < auto Field > friend class field_; - template < auto Field > - field_info(detail::auto_arg_t, std::string id) - : fid_{get_value_family_id()} + template < typename FieldType, FieldType Field > + field_info(detail::auto_arg_t, std::string id) + : fid_{get_value_family_id()} , id_{std::move(id)} - , getter_{&field_detail::getter} - , setter_{&field_detail::setter} {} + , getter_{&field_detail::getter} + , setter_{&field_detail::setter} {} private: family_id fid_; std::string id_; diff --git a/headers/meta.hpp/meta_function.hpp b/headers/meta.hpp/meta_function.hpp index 5dc110a..94a85d1 100644 --- a/headers/meta.hpp/meta_function.hpp +++ b/headers/meta.hpp/meta_function.hpp @@ -20,7 +20,7 @@ namespace meta_hpp static_assert(std::is_function_v>); explicit function_(std::string id) - : info_{detail::auto_arg, std::move(id)} {} + : info_{detail::auto_arg, std::move(id)} {} operator const function_info&() const noexcept { return info_; diff --git a/headers/meta.hpp/meta_function_info.hpp b/headers/meta.hpp/meta_function_info.hpp index b879529..b169858 100644 --- a/headers/meta.hpp/meta_function_info.hpp +++ b/headers/meta.hpp/meta_function_info.hpp @@ -14,9 +14,9 @@ namespace meta_hpp::function_detail { - template < auto Function, std::size_t... Is > + template < typename FunctionType, FunctionType Function, std::size_t... Is > std::optional invoke(value* args, std::index_sequence) { - using ft = detail::function_traits; + using ft = detail::function_traits; using return_type = typename ft::return_type; using argument_types = typename ft::argument_types; @@ -36,15 +36,15 @@ namespace meta_hpp::function_detail } } - template < auto Function > + template < typename FunctionType, FunctionType Function > std::optional invoke(value* args, std::size_t arg_count) { - using ft = detail::function_traits; + using ft = detail::function_traits; if ( arg_count != ft::arity ) { throw std::logic_error("an attempt to call a function with an incorrect arity"); } - return invoke(args, std::make_index_sequence()); + return invoke(args, std::make_index_sequence()); } } @@ -104,11 +104,11 @@ namespace meta_hpp template < auto Function > friend class function_; - template < auto Function > - function_info(detail::auto_arg_t, std::string id) - : fid_{get_value_family_id()} + template < typename FunctionType, FunctionType Function > + function_info(detail::auto_arg_t, std::string id) + : fid_{get_value_family_id()} , id_{std::move(id)} - , invoke_{&function_detail::invoke} {} + , invoke_{&function_detail::invoke} {} private: family_id fid_; std::string id_; diff --git a/headers/meta.hpp/meta_fwd.hpp b/headers/meta.hpp/meta_fwd.hpp index cdd2a8e..68513c1 100644 --- a/headers/meta.hpp/meta_fwd.hpp +++ b/headers/meta.hpp/meta_fwd.hpp @@ -23,6 +23,8 @@ #include #include +#define META_HPP_AUTO_T(V) decltype(V), V + namespace meta_hpp { template < typename... Ts > @@ -77,7 +79,7 @@ namespace meta_hpp } }; - template < auto V > + template < typename T, T V > class value_family final : public family_base<> { public: static family_id id() noexcept { @@ -93,9 +95,9 @@ namespace meta_hpp return family_id_detail::type_family::id(); } - template < auto V > + template < typename T, T V > family_id get_value_family_id() noexcept { - return family_id_detail::value_family::id(); + return family_id_detail::value_family::id(); } } @@ -124,7 +126,7 @@ namespace meta_hpp namespace meta_hpp::detail { - template < auto Arg > + template < typename TArg, TArg Arg > struct auto_arg_t { }; @@ -132,8 +134,8 @@ namespace meta_hpp::detail struct typename_arg_t { }; - template < auto Arg > - inline auto_arg_t auto_arg; + template < typename TArg, TArg Arg > + inline auto_arg_t auto_arg; template < typename Arg > inline typename_arg_t typename_arg; diff --git a/headers/meta.hpp/meta_method.hpp b/headers/meta.hpp/meta_method.hpp index a179cdf..883d3fe 100644 --- a/headers/meta.hpp/meta_method.hpp +++ b/headers/meta.hpp/meta_method.hpp @@ -20,7 +20,7 @@ namespace meta_hpp static_assert(std::is_member_function_pointer_v); explicit method_(std::string id) - : info_{detail::auto_arg, std::move(id)} {} + : info_{detail::auto_arg, std::move(id)} {} operator const method_info&() const { return info_; diff --git a/headers/meta.hpp/meta_method_info.hpp b/headers/meta.hpp/meta_method_info.hpp index 91ea929..f65ca29 100644 --- a/headers/meta.hpp/meta_method_info.hpp +++ b/headers/meta.hpp/meta_method_info.hpp @@ -15,9 +15,9 @@ namespace meta_hpp::method_detail { - template < auto Method, std::size_t... Is > + template < typename MethodType, MethodType Method, std::size_t... Is > std::optional invoke(instance instance, value* args, std::index_sequence) { - using mt = detail::method_traits; + using mt = detail::method_traits; using return_type = typename mt::return_type; using instance_type = typename mt::instance_type; using argument_types = typename mt::argument_types; @@ -43,20 +43,20 @@ namespace meta_hpp::method_detail } } - template < auto Method > + template < typename MethodType, MethodType Method > std::optional invoke(instance instance, value* args, std::size_t arg_count) { - using mt = detail::method_traits; + using mt = detail::method_traits; if ( arg_count != mt::arity ) { throw std::logic_error("an attempt to call a method with an incorrect arity"); } - return invoke(instance, args, std::make_index_sequence()); + return invoke(instance, args, std::make_index_sequence()); } - template < auto Method, std::size_t... Is > + template < typename MethodType, MethodType Method, std::size_t... Is > std::optional cinvoke([[maybe_unused]] cinstance instance, value* args, std::index_sequence) { - using mt = detail::method_traits; + using mt = detail::method_traits; using return_type = typename mt::return_type; using instance_type = typename mt::instance_type; using argument_types = typename mt::argument_types; @@ -86,15 +86,15 @@ namespace meta_hpp::method_detail } } - template < auto Method > + template < typename MethodType, MethodType Method > std::optional cinvoke(cinstance instance, value* args, std::size_t arg_count) { - using mt = detail::method_traits; + using mt = detail::method_traits; if ( arg_count != mt::arity ) { throw std::logic_error("an attempt to call a method with a different arity"); } - return cinvoke(instance, args, std::make_index_sequence()); + return cinvoke(instance, args, std::make_index_sequence()); } } @@ -164,12 +164,12 @@ namespace meta_hpp template < auto Method > friend class method_; - template < auto Method > - method_info(detail::auto_arg_t, std::string id) - : fid_{get_value_family_id()} + template < typename MethodType, MethodType Method > + method_info(detail::auto_arg_t, std::string id) + : fid_{get_value_family_id()} , id_{std::move(id)} - , invoke_{&method_detail::invoke} - , cinvoke_{&method_detail::cinvoke} {} + , invoke_{&method_detail::invoke} + , cinvoke_{&method_detail::cinvoke} {} private: family_id fid_; std::string id_; diff --git a/headers/meta.hpp/meta_registry.hpp b/headers/meta.hpp/meta_registry.hpp index 2fdda74..0c396c1 100644 --- a/headers/meta.hpp/meta_registry.hpp +++ b/headers/meta.hpp/meta_registry.hpp @@ -27,9 +27,9 @@ namespace meta_hpp return detail::find_opt(types_, fid); } - template < auto T > + template < typename T, T V > std::optional resolve() const { - const family_id fid = get_value_family_id(); + const family_id fid = get_value_family_id(); return detail::find_opt(types_, fid); } diff --git a/headers/meta.hpp/meta_variable.hpp b/headers/meta.hpp/meta_variable.hpp index eabd19f..688ef88 100644 --- a/headers/meta.hpp/meta_variable.hpp +++ b/headers/meta.hpp/meta_variable.hpp @@ -18,7 +18,7 @@ namespace meta_hpp class variable_ { public: explicit variable_(std::string id) - : info_{detail::auto_arg, std::move(id)} {} + : info_{detail::auto_arg, std::move(id)} {} operator const variable_info&() const noexcept { return info_; diff --git a/headers/meta.hpp/meta_variable_info.hpp b/headers/meta.hpp/meta_variable_info.hpp index a460254..a60a83b 100644 --- a/headers/meta.hpp/meta_variable_info.hpp +++ b/headers/meta.hpp/meta_variable_info.hpp @@ -14,18 +14,18 @@ namespace meta_hpp::variable_detail { - template < auto Variable > + template < typename VariableType, VariableType Variable > value getter() { - using vt = detail::variable_traits>; + using vt = detail::variable_traits>; using value_type = typename vt::value_type; value_type typed_value{*Variable}; return value{std::move(typed_value)}; } - template < auto Variable > + template < typename VariableType, VariableType Variable > void setter(value value) { - using vt = detail::variable_traits>; + using vt = detail::variable_traits>; using value_type = typename vt::value_type; if constexpr ( !vt::is_const ) { @@ -96,12 +96,12 @@ namespace meta_hpp template < auto Variable > friend class variable_; - template < auto Variable > - variable_info(detail::auto_arg_t, std::string id) - : fid_{get_value_family_id()} + template < typename VariableType, VariableType Variable > + variable_info(detail::auto_arg_t, std::string id) + : fid_{get_value_family_id()} , id_{std::move(id)} - , getter_{&variable_detail::getter} - , setter_{&variable_detail::setter} {} + , getter_{&variable_detail::getter} + , setter_{&variable_detail::setter} {} private: family_id fid_; std::string id_; diff --git a/untests/meta_registry_tests.cpp b/untests/meta_registry_tests.cpp index 532b6b1..3694e82 100644 --- a/untests/meta_registry_tests.cpp +++ b/untests/meta_registry_tests.cpp @@ -90,11 +90,11 @@ TEST_CASE("meta/registry") { } SUBCASE("field_template") { - REQUIRE(registry.resolve<&ivec2::x>()); - REQUIRE(registry.resolve<&ivec2::y>()); + REQUIRE(registry.resolve()); + REQUIRE(registry.resolve()); - const meta::type ivec2_x_type = registry.resolve<&ivec2::x>().value(); - const meta::type ivec2_y_type = registry.resolve<&ivec2::y>().value(); + const meta::type ivec2_x_type = registry.resolve().value(); + const meta::type ivec2_y_type = registry.resolve().value(); REQUIRE(ivec2_x_type.is_field()); REQUIRE(ivec2_y_type.is_field()); @@ -111,9 +111,9 @@ TEST_CASE("meta/registry") { } SUBCASE("function_template") { - REQUIRE(registry.resolve<&iadd2>()); + REQUIRE(registry.resolve()); - const meta::type iadd2_type = registry.resolve<&iadd2>().value(); + const meta::type iadd2_type = registry.resolve().value(); REQUIRE(iadd2_type.is_function()); const meta::function_info iadd2_info = iadd2_type.get_function().value(); @@ -125,9 +125,9 @@ TEST_CASE("meta/registry") { } SUBCASE("method_template") { - REQUIRE(registry.resolve<&ivec2::dot>()); + REQUIRE(registry.resolve()); - const meta::type ivec2_dot_type = registry.resolve<&ivec2::dot>().value(); + const meta::type ivec2_dot_type = registry.resolve().value(); REQUIRE(ivec2_dot_type.is_method()); const meta::method_info ivec2_dot_info = ivec2_dot_type.get_method().value(); @@ -139,9 +139,9 @@ TEST_CASE("meta/registry") { } SUBCASE("variable_template") { - REQUIRE(registry.resolve<&ivec2::zero>()); + REQUIRE(registry.resolve()); - const meta::type ivec2_zero_type = registry.resolve<&ivec2::zero>().value(); + const meta::type ivec2_zero_type = registry.resolve().value(); REQUIRE(ivec2_zero_type.is_variable()); const meta::variable_info ivec2_x_info = ivec2_zero_type.get_variable().value(); @@ -190,13 +190,13 @@ TEST_CASE("meta/registry") { } SUBCASE("resolve/field") { - REQUIRE(registry.resolve<&ivec2::x>()); - REQUIRE(registry.resolve<&ivec2::y>()); + REQUIRE(registry.resolve()); + REQUIRE(registry.resolve()); CHECK_FALSE(registry.resolve(&ivec2::x)); CHECK_FALSE(registry.resolve(&ivec2::y)); - REQUIRE(registry.resolve<&ivec3::x>()); - REQUIRE(registry.resolve<&ivec3::y>()); + REQUIRE(registry.resolve()); + REQUIRE(registry.resolve()); CHECK_FALSE(registry.resolve(&ivec3::x)); CHECK_FALSE(registry.resolve(&ivec3::y)); @@ -211,11 +211,11 @@ TEST_CASE("meta/registry") { CHECK(v2_x_info.fid() != v3_x_info.fid()); CHECK(v2_y_info.fid() != v3_y_info.fid()); - CHECK(v2_x_info.fid() == registry.resolve<&ivec2::x>()->get_field()->fid()); - CHECK(v2_y_info.fid() == registry.resolve<&ivec2::y>()->get_field()->fid()); + CHECK(v2_x_info.fid() == registry.resolve()->get_field()->fid()); + CHECK(v2_y_info.fid() == registry.resolve()->get_field()->fid()); - CHECK(v3_x_info.fid() == registry.resolve<&ivec3::x>()->get_field()->fid()); - CHECK(v3_y_info.fid() == registry.resolve<&ivec3::y>()->get_field()->fid()); + CHECK(v3_x_info.fid() == registry.resolve()->get_field()->fid()); + CHECK(v3_y_info.fid() == registry.resolve()->get_field()->fid()); { REQUIRE(registry.get_field_by_name("vmath::ivec2::x")); @@ -231,8 +231,8 @@ TEST_CASE("meta/registry") { } SUBCASE("resolve/function") { - REQUIRE(registry.resolve<&iadd2>()); - REQUIRE(registry.resolve<&iadd3>()); + REQUIRE(registry.resolve()); + REQUIRE(registry.resolve()); CHECK_FALSE(registry.resolve(&iadd2)); CHECK_FALSE(registry.resolve(&iadd3)); @@ -240,8 +240,8 @@ TEST_CASE("meta/registry") { const meta::function_info iadd3_info = meta::function_<&iadd3>("iadd3"); CHECK(iadd2_info.fid() != iadd3_info.fid()); - CHECK(iadd2_info.fid() == registry.resolve<&iadd2>()->get_function()->fid()); - CHECK(iadd3_info.fid() == registry.resolve<&iadd3>()->get_function()->fid()); + CHECK(iadd2_info.fid() == registry.resolve()->get_function()->fid()); + CHECK(iadd3_info.fid() == registry.resolve()->get_function()->fid()); { REQUIRE(registry.get_function_by_name("vmath::iadd2")); @@ -253,8 +253,8 @@ TEST_CASE("meta/registry") { } SUBCASE("resolve/method") { - REQUIRE(registry.resolve<&ivec2::dot>()); - REQUIRE(registry.resolve<&ivec3::dot>()); + REQUIRE(registry.resolve()); + REQUIRE(registry.resolve()); CHECK_FALSE(registry.resolve(&ivec2::dot)); CHECK_FALSE(registry.resolve(&ivec3::dot)); @@ -262,8 +262,8 @@ TEST_CASE("meta/registry") { const meta::method_info v3_dot_info = meta::method_<&ivec3::dot>("dot"); CHECK(v2_dot_info.fid() != v3_dot_info.fid()); - CHECK(v2_dot_info.fid() == registry.resolve<&ivec2::dot>()->get_method()->fid()); - CHECK(v3_dot_info.fid() == registry.resolve<&ivec3::dot>()->get_method()->fid()); + CHECK(v2_dot_info.fid() == registry.resolve()->get_method()->fid()); + CHECK(v3_dot_info.fid() == registry.resolve()->get_method()->fid()); { REQUIRE(registry.get_method_by_name("vmath::ivec2::dot")); @@ -275,8 +275,8 @@ TEST_CASE("meta/registry") { } SUBCASE("resolve/variable") { - REQUIRE(registry.resolve<&ivec2::zero>()); - REQUIRE(registry.resolve<&ivec3::zero>()); + REQUIRE(registry.resolve()); + REQUIRE(registry.resolve()); CHECK_FALSE(registry.resolve(&ivec2::zero)); CHECK_FALSE(registry.resolve(&ivec3::zero)); @@ -284,8 +284,8 @@ TEST_CASE("meta/registry") { const meta::variable_info v3_zero_info = meta::variable_<&ivec3::zero>("zero"); CHECK(v2_zero_info.fid() != v3_zero_info.fid()); - CHECK(v2_zero_info.fid() == registry.resolve<&ivec2::zero>()->get_variable()->fid()); - CHECK(v3_zero_info.fid() == registry.resolve<&ivec3::zero>()->get_variable()->fid()); + CHECK(v2_zero_info.fid() == registry.resolve()->get_variable()->fid()); + CHECK(v3_zero_info.fid() == registry.resolve()->get_variable()->fid()); { REQUIRE(registry.get_variable_by_name("vmath::ivec2::zero")); From d08fe88b85218cfb1b4245e99ac1e6de3b7c91bc Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Wed, 7 Jul 2021 00:19:30 +0700 Subject: [PATCH 041/233] remove all value family id --- headers/meta.hpp/meta_field_info.hpp | 11 +- headers/meta.hpp/meta_function_info.hpp | 10 +- headers/meta.hpp/meta_fwd.hpp | 15 -- headers/meta.hpp/meta_method_info.hpp | 10 +- headers/meta.hpp/meta_registry.hpp | 10 -- headers/meta.hpp/meta_variable_info.hpp | 10 +- untests/meta_family_tests.cpp | 47 ------- untests/meta_registry_tests.cpp | 174 +++--------------------- 8 files changed, 29 insertions(+), 258 deletions(-) diff --git a/headers/meta.hpp/meta_field_info.hpp b/headers/meta.hpp/meta_field_info.hpp index ce1c488..093f01c 100644 --- a/headers/meta.hpp/meta_field_info.hpp +++ b/headers/meta.hpp/meta_field_info.hpp @@ -66,13 +66,10 @@ namespace meta_hpp field_info& operator=(field_info&&) = default; field_info& operator=(const field_info&) = default; public: - const family_id& fid() const noexcept { - return fid_; - } - const std::string& id() const noexcept { return id_; } + value get(cinstance instance) const { return getter_(instance); } @@ -99,7 +96,7 @@ namespace meta_hpp } void merge(const field_info& other) { - if ( fid() != other.fid() ) { + if ( id() != other.id() ) { throw std::logic_error("field_info::merge failed"); } detail::merge_with(datas_, other.datas_, &data_info::merge); @@ -110,12 +107,10 @@ namespace meta_hpp template < typename FieldType, FieldType Field > field_info(detail::auto_arg_t, std::string id) - : fid_{get_value_family_id()} - , id_{std::move(id)} + : id_{std::move(id)} , getter_{&field_detail::getter} , setter_{&field_detail::setter} {} private: - family_id fid_; std::string id_; value(*getter_)(cinstance); void(*setter_)(instance, value); diff --git a/headers/meta.hpp/meta_function_info.hpp b/headers/meta.hpp/meta_function_info.hpp index b169858..4ad5c96 100644 --- a/headers/meta.hpp/meta_function_info.hpp +++ b/headers/meta.hpp/meta_function_info.hpp @@ -60,10 +60,6 @@ namespace meta_hpp function_info& operator=(function_info&&) = default; function_info& operator=(const function_info&) = default; public: - const family_id& fid() const noexcept { - return fid_; - } - const std::string& id() const noexcept { return id_; } @@ -95,7 +91,7 @@ namespace meta_hpp } void merge(const function_info& other) { - if ( fid() != other.fid() ) { + if ( id() != other.id() ) { throw std::logic_error("function_info::merge failed"); } detail::merge_with(datas_, other.datas_, &data_info::merge); @@ -106,11 +102,9 @@ namespace meta_hpp template < typename FunctionType, FunctionType Function > function_info(detail::auto_arg_t, std::string id) - : fid_{get_value_family_id()} - , id_{std::move(id)} + : id_{std::move(id)} , invoke_{&function_detail::invoke} {} private: - family_id fid_; std::string id_; std::optional(*invoke_)(value*, std::size_t); std::map> datas_; diff --git a/headers/meta.hpp/meta_fwd.hpp b/headers/meta.hpp/meta_fwd.hpp index 68513c1..607eefd 100644 --- a/headers/meta.hpp/meta_fwd.hpp +++ b/headers/meta.hpp/meta_fwd.hpp @@ -78,27 +78,12 @@ namespace meta_hpp return self_id; } }; - - template < typename T, T V > - class value_family final : public family_base<> { - public: - static family_id id() noexcept { - static family_id self_id{++last_id_}; - assert(self_id.id > 0u && "family_id overflow"); - return self_id; - } - }; } template < typename T > family_id get_type_family_id() noexcept { return family_id_detail::type_family::id(); } - - template < typename T, T V > - family_id get_value_family_id() noexcept { - return family_id_detail::value_family::id(); - } } namespace meta_hpp diff --git a/headers/meta.hpp/meta_method_info.hpp b/headers/meta.hpp/meta_method_info.hpp index f65ca29..efcf13f 100644 --- a/headers/meta.hpp/meta_method_info.hpp +++ b/headers/meta.hpp/meta_method_info.hpp @@ -110,10 +110,6 @@ namespace meta_hpp method_info& operator=(method_info&&) = default; method_info& operator=(const method_info&) = default; public: - const family_id& fid() const noexcept { - return fid_; - } - const std::string& id() const noexcept { return id_; } @@ -155,7 +151,7 @@ namespace meta_hpp } void merge(const method_info& other) { - if ( fid() != other.fid() ) { + if ( id() != other.id() ) { throw std::logic_error("method_info::merge failed"); } detail::merge_with(datas_, other.datas_, &data_info::merge); @@ -166,12 +162,10 @@ namespace meta_hpp template < typename MethodType, MethodType Method > method_info(detail::auto_arg_t, std::string id) - : fid_{get_value_family_id()} - , id_{std::move(id)} + : id_{std::move(id)} , invoke_{&method_detail::invoke} , cinvoke_{&method_detail::cinvoke} {} private: - family_id fid_; std::string id_; std::optional(*invoke_)(instance, value*, std::size_t); std::optional(*cinvoke_)(cinstance, value*, std::size_t); diff --git a/headers/meta.hpp/meta_registry.hpp b/headers/meta.hpp/meta_registry.hpp index 0c396c1..1975088 100644 --- a/headers/meta.hpp/meta_registry.hpp +++ b/headers/meta.hpp/meta_registry.hpp @@ -27,12 +27,6 @@ namespace meta_hpp return detail::find_opt(types_, fid); } - template < typename T, T V > - std::optional resolve() const { - const family_id fid = get_value_family_id(); - return detail::find_opt(types_, fid); - } - template < typename T > std::optional resolve(T&&) const { const family_id fid = get_type_family_id>(); @@ -149,7 +143,6 @@ namespace meta_hpp ? info.id() : prefix + "::" + info.id(); - detail::merge_with(types_, info.fid(), info, &type::merge); detail::merge_with(fields_, name, info, &field_info::merge); info.visit(overloaded { @@ -165,7 +158,6 @@ namespace meta_hpp ? info.id() : prefix + "::" + info.id(); - detail::merge_with(types_, info.fid(), info, &type::merge); detail::merge_with(functions_, name, info, &function_info::merge); info.visit(overloaded { @@ -181,7 +173,6 @@ namespace meta_hpp ? info.id() : prefix + "::" + info.id(); - detail::merge_with(types_, info.fid(), info, &type::merge); detail::merge_with(methods_, name, info, &method_info::merge); info.visit(overloaded { @@ -212,7 +203,6 @@ namespace meta_hpp ? info.id() : prefix + "::" + info.id(); - detail::merge_with(types_, info.fid(), info, &type::merge); detail::merge_with(variables_, name, info, &variable_info::merge); info.visit(overloaded { diff --git a/headers/meta.hpp/meta_variable_info.hpp b/headers/meta.hpp/meta_variable_info.hpp index a60a83b..9391b07 100644 --- a/headers/meta.hpp/meta_variable_info.hpp +++ b/headers/meta.hpp/meta_variable_info.hpp @@ -53,10 +53,6 @@ namespace meta_hpp variable_info& operator=(variable_info&&) = default; variable_info& operator=(const variable_info&) = default; public: - const family_id& fid() const noexcept { - return fid_; - } - const std::string& id() const noexcept { return id_; } @@ -87,7 +83,7 @@ namespace meta_hpp } void merge(const variable_info& other) { - if ( fid() != other.fid() ) { + if ( id() != other.id() ) { throw std::logic_error("variable_info::merge failed"); } detail::merge_with(datas_, other.datas_, &data_info::merge); @@ -98,12 +94,10 @@ namespace meta_hpp template < typename VariableType, VariableType Variable > variable_info(detail::auto_arg_t, std::string id) - : fid_{get_value_family_id()} - , id_{std::move(id)} + : id_{std::move(id)} , getter_{&variable_detail::getter} , setter_{&variable_detail::setter} {} private: - family_id fid_; std::string id_; value(*getter_)(); void(*setter_)(value); diff --git a/untests/meta_family_tests.cpp b/untests/meta_family_tests.cpp index ef38c47..48222d9 100644 --- a/untests/meta_family_tests.cpp +++ b/untests/meta_family_tests.cpp @@ -17,36 +17,13 @@ namespace struct ivec2 { int x{}; int y{}; - - static ivec2 zero; - - int dot(ivec2 other) const { - return x * other.x + y * other.y; - } }; struct ivec3 { int x{}; int y{}; int z{}; - - static ivec3 zero; - - int dot(ivec3 other) const { - return x * other.x + y * other.y + z * other.z; - } }; - - ivec2 ivec2::zero{}; - ivec3 ivec3::zero{}; - - ivec2 iadd2(ivec2 l, ivec2 r) { - return {l.x + r.x, l.y + r.y}; - } - - ivec3 iadd3(ivec3 l, ivec3 r) { - return {l.x + r.x, l.y + r.y, l.z + r.z}; - } } TEST_CASE("meta/family") { @@ -58,28 +35,4 @@ TEST_CASE("meta/family") { meta::class_info ivec3_info = meta::class_("ivec3"); CHECK_FALSE(ivec2_info.fid() == ivec3_info.fid()); } - - SUBCASE("field") { - meta::field_info x_info = meta::field_<&ivec2::x>("x"); - meta::field_info y_info = meta::field_<&ivec2::y>("y"); - CHECK_FALSE(x_info.fid() == y_info.fid()); - } - - SUBCASE("function") { - meta::function_info iadd2_info = meta::function_<&iadd2>("iadd2"); - meta::function_info iadd3_info = meta::function_<&iadd3>("iadd3"); - CHECK_FALSE(iadd2_info.fid() == iadd3_info.fid()); - } - - SUBCASE("method") { - meta::method_info dot2_info = meta::method_<&ivec2::dot>("dot"); - meta::method_info dot3_info = meta::method_<&ivec3::dot>("dot"); - CHECK_FALSE(dot2_info.fid() == dot3_info.fid()); - } - - SUBCASE("variable") { - meta::variable_info zero2_info = meta::variable_<&ivec2::zero>("zero"); - meta::variable_info zero3_info = meta::variable_<&ivec3::zero>("zero"); - CHECK_FALSE(zero2_info.fid() == zero3_info.fid()); - } } diff --git a/untests/meta_registry_tests.cpp b/untests/meta_registry_tests.cpp index 3694e82..548b1d1 100644 --- a/untests/meta_registry_tests.cpp +++ b/untests/meta_registry_tests.cpp @@ -89,69 +89,6 @@ TEST_CASE("meta/registry") { CHECK(ivec3_info.id() == "ivec3"); } - SUBCASE("field_template") { - REQUIRE(registry.resolve()); - REQUIRE(registry.resolve()); - - const meta::type ivec2_x_type = registry.resolve().value(); - const meta::type ivec2_y_type = registry.resolve().value(); - - REQUIRE(ivec2_x_type.is_field()); - REQUIRE(ivec2_y_type.is_field()); - - const meta::field_info ivec2_x_info = ivec2_x_type.get_field().value(); - const meta::field_info ivec2_y_info = ivec2_y_type.get_field().value(); - - CHECK(ivec2_x_info.id() == "x"); - CHECK(ivec2_y_info.id() == "y"); - } - - SUBCASE("field_instance") { - CHECK_FALSE(registry.resolve(&ivec2::x)); - } - - SUBCASE("function_template") { - REQUIRE(registry.resolve()); - - const meta::type iadd2_type = registry.resolve().value(); - REQUIRE(iadd2_type.is_function()); - - const meta::function_info iadd2_info = iadd2_type.get_function().value(); - CHECK(iadd2_info.id() == "iadd2"); - } - - SUBCASE("function_instance") { - CHECK_FALSE(registry.resolve(&iadd3)); - } - - SUBCASE("method_template") { - REQUIRE(registry.resolve()); - - const meta::type ivec2_dot_type = registry.resolve().value(); - REQUIRE(ivec2_dot_type.is_method()); - - const meta::method_info ivec2_dot_info = ivec2_dot_type.get_method().value(); - CHECK(ivec2_dot_info.id() == "dot"); - } - - SUBCASE("method_instance") { - CHECK_FALSE(registry.resolve(&ivec3::dot)); - } - - SUBCASE("variable_template") { - REQUIRE(registry.resolve()); - - const meta::type ivec2_zero_type = registry.resolve().value(); - REQUIRE(ivec2_zero_type.is_variable()); - - const meta::variable_info ivec2_x_info = ivec2_zero_type.get_variable().value(); - CHECK(ivec2_x_info.id() == "zero"); - } - - SUBCASE("variable_instance") { - CHECK_FALSE(registry.resolve(&ivec3::zero)); - } - SUBCASE("resolve/class") { ivec2 v2; ivec3 v3; @@ -190,110 +127,39 @@ TEST_CASE("meta/registry") { } SUBCASE("resolve/field") { - REQUIRE(registry.resolve()); - REQUIRE(registry.resolve()); - CHECK_FALSE(registry.resolve(&ivec2::x)); - CHECK_FALSE(registry.resolve(&ivec2::y)); + REQUIRE(registry.get_field_by_name("vmath::ivec2::x")); + REQUIRE(registry.get_field_by_name("vmath::ivec2::y")); + REQUIRE(registry.get_field_by_name("vmath::ivec3::x")); + REQUIRE(registry.get_field_by_name("vmath::ivec3::y")); - REQUIRE(registry.resolve()); - REQUIRE(registry.resolve()); - CHECK_FALSE(registry.resolve(&ivec3::x)); - CHECK_FALSE(registry.resolve(&ivec3::y)); - - const meta::field_info v2_x_info = meta::field_<&ivec2::x>("x"); - const meta::field_info v2_y_info = meta::field_<&ivec2::y>("y"); - CHECK(v2_x_info.fid() != v2_y_info.fid()); - - const meta::field_info v3_x_info = meta::field_<&ivec3::x>("x"); - const meta::field_info v3_y_info = meta::field_<&ivec3::y>("y"); - CHECK(v3_x_info.fid() != v3_y_info.fid()); - - CHECK(v2_x_info.fid() != v3_x_info.fid()); - CHECK(v2_y_info.fid() != v3_y_info.fid()); - - CHECK(v2_x_info.fid() == registry.resolve()->get_field()->fid()); - CHECK(v2_y_info.fid() == registry.resolve()->get_field()->fid()); - - CHECK(v3_x_info.fid() == registry.resolve()->get_field()->fid()); - CHECK(v3_y_info.fid() == registry.resolve()->get_field()->fid()); - - { - REQUIRE(registry.get_field_by_name("vmath::ivec2::x")); - REQUIRE(registry.get_field_by_name("vmath::ivec2::y")); - REQUIRE(registry.get_field_by_name("vmath::ivec3::x")); - REQUIRE(registry.get_field_by_name("vmath::ivec3::y")); - - CHECK(v2_x_info.fid() == registry.get_field_by_name("vmath::ivec2::x")->fid()); - CHECK(v2_y_info.fid() == registry.get_field_by_name("vmath::ivec2::y")->fid()); - CHECK(v3_x_info.fid() == registry.get_field_by_name("vmath::ivec3::x")->fid()); - CHECK(v3_y_info.fid() == registry.get_field_by_name("vmath::ivec3::y")->fid()); - } + CHECK("x" == registry.get_field_by_name("vmath::ivec2::x")->id()); + CHECK("y" == registry.get_field_by_name("vmath::ivec2::y")->id()); + CHECK("x" == registry.get_field_by_name("vmath::ivec3::x")->id()); + CHECK("y" == registry.get_field_by_name("vmath::ivec3::y")->id()); } SUBCASE("resolve/function") { - REQUIRE(registry.resolve()); - REQUIRE(registry.resolve()); - CHECK_FALSE(registry.resolve(&iadd2)); - CHECK_FALSE(registry.resolve(&iadd3)); + REQUIRE(registry.get_function_by_name("vmath::iadd2")); + REQUIRE(registry.get_function_by_name("vmath::iadd3")); - const meta::function_info iadd2_info = meta::function_<&iadd2>("iadd2"); - const meta::function_info iadd3_info = meta::function_<&iadd3>("iadd3"); - CHECK(iadd2_info.fid() != iadd3_info.fid()); - - CHECK(iadd2_info.fid() == registry.resolve()->get_function()->fid()); - CHECK(iadd3_info.fid() == registry.resolve()->get_function()->fid()); - - { - REQUIRE(registry.get_function_by_name("vmath::iadd2")); - REQUIRE(registry.get_function_by_name("vmath::iadd3")); - - CHECK(iadd2_info.fid() == registry.get_function_by_name("vmath::iadd2")->fid()); - CHECK(iadd3_info.fid() == registry.get_function_by_name("vmath::iadd3")->fid()); - } + CHECK("iadd2" == registry.get_function_by_name("vmath::iadd2")->id()); + CHECK("iadd3" == registry.get_function_by_name("vmath::iadd3")->id()); } SUBCASE("resolve/method") { - REQUIRE(registry.resolve()); - REQUIRE(registry.resolve()); - CHECK_FALSE(registry.resolve(&ivec2::dot)); - CHECK_FALSE(registry.resolve(&ivec3::dot)); + REQUIRE(registry.get_method_by_name("vmath::ivec2::dot")); + REQUIRE(registry.get_method_by_name("vmath::ivec3::dot")); - const meta::method_info v2_dot_info = meta::method_<&ivec2::dot>("dot"); - const meta::method_info v3_dot_info = meta::method_<&ivec3::dot>("dot"); - CHECK(v2_dot_info.fid() != v3_dot_info.fid()); - - CHECK(v2_dot_info.fid() == registry.resolve()->get_method()->fid()); - CHECK(v3_dot_info.fid() == registry.resolve()->get_method()->fid()); - - { - REQUIRE(registry.get_method_by_name("vmath::ivec2::dot")); - REQUIRE(registry.get_method_by_name("vmath::ivec3::dot")); - - CHECK(v2_dot_info.fid() == registry.get_method_by_name("vmath::ivec2::dot")->fid()); - CHECK(v3_dot_info.fid() == registry.get_method_by_name("vmath::ivec3::dot")->fid()); - } + CHECK("dot" == registry.get_method_by_name("vmath::ivec2::dot")->id()); + CHECK("dot" == registry.get_method_by_name("vmath::ivec3::dot")->id()); } SUBCASE("resolve/variable") { - REQUIRE(registry.resolve()); - REQUIRE(registry.resolve()); - CHECK_FALSE(registry.resolve(&ivec2::zero)); - CHECK_FALSE(registry.resolve(&ivec3::zero)); + REQUIRE(registry.get_variable_by_name("vmath::ivec2::zero")); + REQUIRE(registry.get_variable_by_name("vmath::ivec3::zero")); - const meta::variable_info v2_zero_info = meta::variable_<&ivec2::zero>("zero"); - const meta::variable_info v3_zero_info = meta::variable_<&ivec3::zero>("zero"); - CHECK(v2_zero_info.fid() != v3_zero_info.fid()); - - CHECK(v2_zero_info.fid() == registry.resolve()->get_variable()->fid()); - CHECK(v3_zero_info.fid() == registry.resolve()->get_variable()->fid()); - - { - REQUIRE(registry.get_variable_by_name("vmath::ivec2::zero")); - REQUIRE(registry.get_variable_by_name("vmath::ivec3::zero")); - - CHECK(v2_zero_info.fid() == registry.get_variable_by_name("vmath::ivec2::zero")->fid()); - CHECK(v3_zero_info.fid() == registry.get_variable_by_name("vmath::ivec3::zero")->fid()); - } + CHECK("zero" == registry.get_variable_by_name("vmath::ivec2::zero")->id()); + CHECK("zero" == registry.get_variable_by_name("vmath::ivec3::zero")->id()); } } From 7f29d73e550941ce2fb6042ec1766881f7397ce1 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Wed, 7 Jul 2021 00:27:16 +0700 Subject: [PATCH 042/233] resolve return only class_info --- headers/meta.hpp/meta_registry.hpp | 8 ++++---- untests/meta_registry_tests.cpp | 26 ++++++++++++-------------- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/headers/meta.hpp/meta_registry.hpp b/headers/meta.hpp/meta_registry.hpp index 1975088..72a1e15 100644 --- a/headers/meta.hpp/meta_registry.hpp +++ b/headers/meta.hpp/meta_registry.hpp @@ -22,13 +22,13 @@ namespace meta_hpp class registry { public: template < typename T > - std::optional resolve() const { + std::optional resolve() const { const family_id fid = get_type_family_id(); return detail::find_opt(types_, fid); } template < typename T > - std::optional resolve(T&&) const { + std::optional resolve(T&&) const { const family_id fid = get_type_family_id>(); return detail::find_opt(types_, fid); } @@ -127,7 +127,7 @@ namespace meta_hpp ? info.id() : prefix + "::" + info.id(); - detail::merge_with(types_, info.fid(), info, &type::merge); + detail::merge_with(types_, info.fid(), info, &class_info::merge); detail::merge_with(classes_, name, info, &class_info::merge); info.visit(overloaded { @@ -213,7 +213,7 @@ namespace meta_hpp }); } private: - std::map> types_; + std::map> types_; std::map> classes_; std::map> fields_; std::map> functions_; diff --git a/untests/meta_registry_tests.cpp b/untests/meta_registry_tests.cpp index 548b1d1..8ddc085 100644 --- a/untests/meta_registry_tests.cpp +++ b/untests/meta_registry_tests.cpp @@ -107,15 +107,15 @@ TEST_CASE("meta/registry") { const meta::class_info v3_info = meta::class_("ivec3"); CHECK(v2_info.fid() != v3_info.fid()); - CHECK(v2_info.fid() == registry.resolve()->get_class()->fid()); - CHECK(v2_info.fid() == registry.resolve(v2)->get_class()->fid()); - CHECK(v2_info.fid() == registry.resolve(std::as_const(v2))->get_class()->fid()); - CHECK(v2_info.fid() == registry.resolve(static_cast(v2))->get_class()->fid()); + CHECK(v2_info.fid() == registry.resolve()->fid()); + CHECK(v2_info.fid() == registry.resolve(v2)->fid()); + CHECK(v2_info.fid() == registry.resolve(std::as_const(v2))->fid()); + CHECK(v2_info.fid() == registry.resolve(static_cast(v2))->fid()); - CHECK(v3_info.fid() == registry.resolve()->get_class()->fid()); - CHECK(v3_info.fid() == registry.resolve(v3)->get_class()->fid()); - CHECK(v3_info.fid() == registry.resolve(std::as_const(v3))->get_class()->fid()); - CHECK(v3_info.fid() == registry.resolve(static_cast(v3))->get_class()->fid()); + CHECK(v3_info.fid() == registry.resolve()->fid()); + CHECK(v3_info.fid() == registry.resolve(v3)->fid()); + CHECK(v3_info.fid() == registry.resolve(std::as_const(v3))->fid()); + CHECK(v3_info.fid() == registry.resolve(static_cast(v3))->fid()); { REQUIRE(registry.get_class_by_name("vmath::ivec2")); @@ -181,14 +181,12 @@ TEST_CASE("meta/registry/merge") { )); CHECK(registry.resolve()); - CHECK(registry.resolve()->get_class()); - CHECK(registry.resolve()->get_class()->get_field("x")); - CHECK(registry.resolve()->get_class()->get_field("y")); + CHECK(registry.resolve()->get_field("x")); + CHECK(registry.resolve()->get_field("y")); CHECK(registry.resolve(ivec2{})); - CHECK(registry.resolve(ivec2{})->get_class()); - CHECK(registry.resolve(ivec2{})->get_class()->get_field("x")); - CHECK(registry.resolve(ivec2{})->get_class()->get_field("y")); + CHECK(registry.resolve(ivec2{})->get_field("x")); + CHECK(registry.resolve(ivec2{})->get_field("y")); CHECK(registry.get_class_by_name("ivec2")); CHECK(registry.get_class_by_name("ivec2")->get_field("x")); From 788ce044dcd3c79a669ae022354ab1ac2ebbaef9 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Wed, 7 Jul 2021 00:39:13 +0700 Subject: [PATCH 043/233] rename get_type_family_id to get_family_id --- headers/meta.hpp/meta_class_info.hpp | 2 +- headers/meta.hpp/meta_fwd.hpp | 28 +++++++++++----------------- headers/meta.hpp/meta_instance.hpp | 10 +++++----- headers/meta.hpp/meta_registry.hpp | 4 ++-- headers/meta.hpp/meta_value.hpp | 14 +++++++------- untests/meta_value_tests.cpp | 16 ++++++++-------- 6 files changed, 34 insertions(+), 40 deletions(-) diff --git a/headers/meta.hpp/meta_class_info.hpp b/headers/meta.hpp/meta_class_info.hpp index 0ca403a..488346d 100644 --- a/headers/meta.hpp/meta_class_info.hpp +++ b/headers/meta.hpp/meta_class_info.hpp @@ -128,7 +128,7 @@ namespace meta_hpp template < typename Class > class_info(detail::typename_arg_t, std::string id) - : fid_{get_type_family_id()} + : fid_{get_family_id()} , id_{std::move(id)} {} private: family_id fid_; diff --git a/headers/meta.hpp/meta_fwd.hpp b/headers/meta.hpp/meta_fwd.hpp index 607eefd..4f98e7f 100644 --- a/headers/meta.hpp/meta_fwd.hpp +++ b/headers/meta.hpp/meta_fwd.hpp @@ -57,32 +57,26 @@ namespace meta_hpp namespace family_id_detail { - template < typename Void = void > - class family_base { - static_assert( - std::is_void_v, - "unexpected internal error"); - protected: - static std::atomic last_id_; + struct family_id_sequence { + static family_id next() noexcept { + static std::atomic id{}; + return { ++id }; + } }; - template < typename Void > - std::atomic family_base::last_id_{}; - template < typename T > - class type_family final : public family_base<> { - public: + struct type_to_family_id { static family_id id() noexcept { - static family_id self_id{++last_id_}; - assert(self_id.id > 0u && "family_id overflow"); - return self_id; + static const family_id type_family_id = family_id_sequence::next(); + assert(type_family_id.id > 0u && "family_id overflow"); + return type_family_id; } }; } template < typename T > - family_id get_type_family_id() noexcept { - return family_id_detail::type_family::id(); + family_id get_family_id() noexcept { + return family_id_detail::type_to_family_id::id(); } } diff --git a/headers/meta.hpp/meta_instance.hpp b/headers/meta.hpp/meta_instance.hpp index 05ce486..94b48b3 100644 --- a/headers/meta.hpp/meta_instance.hpp +++ b/headers/meta.hpp/meta_instance.hpp @@ -34,7 +34,7 @@ namespace meta_hpp , typename = std::enable_if_t> > instance(T& v) : data_{std::addressof(v)} - , fid_{get_type_family_id()} {} + , fid_{get_family_id()} {} instance(value& v) : data_{v.data()} @@ -56,7 +56,7 @@ namespace meta_hpp std::add_pointer_t try_cast() noexcept { static_assert(!std::is_reference_v); - return fid() == get_type_family_id() + return fid() == get_family_id() ? static_cast>(data_) : nullptr; } @@ -65,7 +65,7 @@ namespace meta_hpp std::add_pointer_t> try_cast() const noexcept { static_assert(!std::is_reference_v); - return fid() == get_type_family_id() + return fid() == get_family_id() ? static_cast>>(data_) : nullptr; } @@ -93,7 +93,7 @@ namespace meta_hpp , typename = std::enable_if_t> > cinstance(const T& data) : data_{std::addressof(data)} - , fid_{get_type_family_id()} {} + , fid_{get_family_id()} {} cinstance(const value& v) : data_{v.data()} @@ -115,7 +115,7 @@ namespace meta_hpp std::add_pointer_t> try_cast() const noexcept { static_assert(!std::is_reference_v); - return fid() == get_type_family_id() + return fid() == get_family_id() ? static_cast>>(data_) : nullptr; } diff --git a/headers/meta.hpp/meta_registry.hpp b/headers/meta.hpp/meta_registry.hpp index 72a1e15..d37dd13 100644 --- a/headers/meta.hpp/meta_registry.hpp +++ b/headers/meta.hpp/meta_registry.hpp @@ -23,13 +23,13 @@ namespace meta_hpp public: template < typename T > std::optional resolve() const { - const family_id fid = get_type_family_id(); + const family_id fid = get_family_id(); return detail::find_opt(types_, fid); } template < typename T > std::optional resolve(T&&) const { - const family_id fid = get_type_family_id>(); + const family_id fid = get_family_id>(); return detail::find_opt(types_, fid); } diff --git a/headers/meta.hpp/meta_value.hpp b/headers/meta.hpp/meta_value.hpp index a2a8a7f..f353e71 100644 --- a/headers/meta.hpp/meta_value.hpp +++ b/headers/meta.hpp/meta_value.hpp @@ -63,7 +63,7 @@ namespace meta_hpp , typename = std::enable_if_t> > value(T&& val) : raw_{std::forward(val)} - , fid_{get_type_family_id()} + , fid_{get_family_id()} , traits_{value_detail::get_traits()} {} template < typename T @@ -77,13 +77,13 @@ namespace meta_hpp template < typename T, typename... Args > explicit value(std::in_place_type_t, Args&&... args) : raw_{std::in_place_type, std::forward(args)...} - , fid_{get_type_family_id()} + , fid_{get_family_id()} , traits_{value_detail::get_traits()} {} template < typename T, typename U, typename... Args > explicit value(std::in_place_type_t, std::initializer_list ilist, Args&&... args) : raw_{std::in_place_type, ilist, std::forward(args)...} - , fid_{get_type_family_id()} + , fid_{get_family_id()} , traits_{value_detail::get_traits()} {} template < typename T > @@ -139,7 +139,7 @@ namespace meta_hpp , typename = std::enable_if_t> , typename = std::enable_if_t, U, U>> > friend bool operator==(const value& l, T&& r) { - return l.fid() == get_type_family_id() + return l.fid() == get_family_id() && std::equal_to<>{}(*l.try_cast(), std::forward(r)); } @@ -148,7 +148,7 @@ namespace meta_hpp , typename = std::enable_if_t> , typename = std::enable_if_t, U, U>> > friend bool operator==(T&& l, const value& r) { - return get_type_family_id() == r.fid() + return get_family_id() == r.fid() && std::equal_to<>{}(std::forward(l), *r.try_cast()); } @@ -157,7 +157,7 @@ namespace meta_hpp , typename = std::enable_if_t> , typename = std::enable_if_t, U, U>> > friend bool operator!=(const value& l, T&& r) { - return l.fid() != get_type_family_id() + return l.fid() != get_family_id() || std::not_equal_to<>{}(*l.try_cast(), std::forward(r)); } @@ -166,7 +166,7 @@ namespace meta_hpp , typename = std::enable_if_t> , typename = std::enable_if_t, U, U>> > friend bool operator!=(T&& l, const value& r) { - return get_type_family_id() != r.fid() + return get_family_id() != r.fid() || std::not_equal_to<>{}(std::forward(l), *r.try_cast()); } diff --git a/untests/meta_value_tests.cpp b/untests/meta_value_tests.cpp index f54c276..e866ea7 100644 --- a/untests/meta_value_tests.cpp +++ b/untests/meta_value_tests.cpp @@ -75,19 +75,19 @@ TEST_CASE("meta/value/fid") { namespace meta = meta_hpp; using namespace std::string_literals; - CHECK(meta::value{clazz{}}.fid() == meta::get_type_family_id()); - CHECK(meta::value{clazz2{}}.fid() == meta::get_type_family_id()); + CHECK(meta::value{clazz{}}.fid() == meta::get_family_id()); + CHECK(meta::value{clazz2{}}.fid() == meta::get_family_id()); CHECK(meta::value{clazz{}}.fid() != meta::value{clazz2{}}.fid()); { meta::value v = clazz{}; - CHECK(v.fid() == meta::get_type_family_id()); + CHECK(v.fid() == meta::get_family_id()); v = clazz2{}; - CHECK(v.fid() == meta::get_type_family_id()); + CHECK(v.fid() == meta::get_family_id()); } - CHECK(meta::value{std::in_place_type, 1}.fid() == meta::get_type_family_id()); - CHECK(meta::value{std::in_place_type>, {1,2,3,4}}.fid() == meta::get_type_family_id>()); + CHECK(meta::value{std::in_place_type, 1}.fid() == meta::get_family_id()); + CHECK(meta::value{std::in_place_type>, {1,2,3,4}}.fid() == meta::get_family_id>()); } TEST_CASE("meta/value/data") { @@ -213,9 +213,9 @@ TEST_CASE("meta/value/swap") { meta::value v2{42}; meta::swap(v1, v2); - CHECK(v1.fid() == meta::get_type_family_id()); + CHECK(v1.fid() == meta::get_family_id()); CHECK(v1.to_int() == 42); - CHECK(v2.fid() == meta::get_type_family_id()); + CHECK(v2.fid() == meta::get_family_id()); CHECK(v2.to_string() == "hello"); } From 0a173e55a146a1f31c68e24e658598dc35c7aa06 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Wed, 7 Jul 2021 02:36:45 +0700 Subject: [PATCH 044/233] remove "auto Field" --- headers/meta.hpp/meta_field.hpp | 8 ++--- headers/meta.hpp/meta_field_info.hpp | 48 ++++++++++++++++++++-------- untests/CMakeLists.txt | 2 +- untests/meta_class_tests.cpp | 10 +++--- untests/meta_data_tests.cpp | 2 +- untests/meta_examples.cpp | 20 ++++++------ untests/meta_field_tests.cpp | 4 +-- untests/meta_registry_tests.cpp | 14 ++++---- untests/meta_type_tests.cpp | 4 +-- 9 files changed, 67 insertions(+), 45 deletions(-) diff --git a/headers/meta.hpp/meta_field.hpp b/headers/meta.hpp/meta_field.hpp index 2ba7475..dce9fad 100644 --- a/headers/meta.hpp/meta_field.hpp +++ b/headers/meta.hpp/meta_field.hpp @@ -14,13 +14,13 @@ namespace meta_hpp { - template < auto Field > + template < typename FieldType > class field_ { public: - static_assert(std::is_member_object_pointer_v); + static_assert(std::is_member_object_pointer_v); - explicit field_(std::string id) - : info_{detail::auto_arg, std::move(id)} {} + explicit field_(std::string id, FieldType field) + : info_{std::move(id), field} {} operator const field_info&() const noexcept { return info_; diff --git a/headers/meta.hpp/meta_field_info.hpp b/headers/meta.hpp/meta_field_info.hpp index 093f01c..f498831 100644 --- a/headers/meta.hpp/meta_field_info.hpp +++ b/headers/meta.hpp/meta_field_info.hpp @@ -15,8 +15,11 @@ namespace meta_hpp::field_detail { - template < typename FieldType, FieldType Field > - value getter(cinstance instance) { + template < typename FieldType > + value raw_getter( + FieldType field, + cinstance instance) + { using ft = detail::field_traits; using value_type = typename ft::value_type; using instance_type = typename ft::instance_type; @@ -26,12 +29,16 @@ namespace meta_hpp::field_detail throw std::logic_error("an attempt to get a field with incorrect instance type"); } - value_type typed_value{std::invoke(Field, *typed_instance)}; + value_type typed_value{std::invoke(field, *typed_instance)}; return value{std::move(typed_value)}; } - template < typename FieldType, FieldType Field > - void setter([[maybe_unused]] instance instance, value value) { + template < typename FieldType > + void raw_setter( + [[maybe_unused]] FieldType field, + [[maybe_unused]] instance instance, + value value) + { using ft = detail::field_traits; using value_type = typename ft::value_type; using instance_type = typename ft::instance_type; @@ -47,11 +54,26 @@ namespace meta_hpp::field_detail throw std::logic_error("an attempt to set a field with incorrect argument type"); } - std::invoke(Field, *typed_instance) = std::move(*typed_value); + std::invoke(field, *typed_instance) = std::move(*typed_value); } else { throw std::logic_error("an attempt to change a constant field"); } } + + using field_getter = std::function; + using field_setter = std::function; + + template < typename FieldType > + field_getter make_getter(FieldType field) { + using namespace std::placeholders; + return std::bind(&raw_getter, field, _1); + } + + template < typename FieldType > + field_setter make_setter(FieldType field) { + using namespace std::placeholders; + return std::bind(&raw_setter, field, _1, _2); + } } namespace meta_hpp @@ -102,18 +124,18 @@ namespace meta_hpp detail::merge_with(datas_, other.datas_, &data_info::merge); } private: - template < auto Field > + template < typename FieldType > friend class field_; - template < typename FieldType, FieldType Field > - field_info(detail::auto_arg_t, std::string id) + template < typename FieldType > + field_info(std::string id, FieldType field) : id_{std::move(id)} - , getter_{&field_detail::getter} - , setter_{&field_detail::setter} {} + , getter_{field_detail::make_getter(field)} + , setter_{field_detail::make_setter(field)} {} private: std::string id_; - value(*getter_)(cinstance); - void(*setter_)(instance, value); + field_detail::field_getter getter_; + field_detail::field_setter setter_; std::map> datas_; }; } diff --git a/untests/CMakeLists.txt b/untests/CMakeLists.txt index 2748725..524f30f 100644 --- a/untests/CMakeLists.txt +++ b/untests/CMakeLists.txt @@ -31,7 +31,7 @@ target_compile_options(${PROJECT_NAME} $<$,$>: -Werror -Weverything -Wno-unknown-warning-option -Wconversion -Wimplicit-int-float-conversion - -Wno-c++98-compat-pedantic -Wno-ctad-maybe-unsupported + -Wno-c++98-compat-pedantic -Wno-ctad-maybe-unsupported -Wno-padded -Wno-float-equal -Wno-double-promotion -Wno-shadow-field-in-constructor>) add_test(${PROJECT_NAME} ${PROJECT_NAME}) diff --git a/untests/meta_class_tests.cpp b/untests/meta_class_tests.cpp index 0df71d1..081ba66 100644 --- a/untests/meta_class_tests.cpp +++ b/untests/meta_class_tests.cpp @@ -61,8 +61,8 @@ TEST_CASE("meta/class") { class_( meta::class_("clazz2"), - meta::field_<&clazz::field>("field"), - meta::field_<&clazz::cfield>("cfield"), + meta::field_("field", &clazz::field), + meta::field_("cfield", &clazz::cfield), meta::function_<&clazz::func>("func"), meta::method_<&clazz::method>("method"), meta::method_<&clazz::cmethod>("cmethod"), @@ -128,19 +128,19 @@ TEST_CASE("meta/class/merge") { SUBCASE("merge") { CHECK_NOTHROW(clazz_( meta::class_("child")( - meta::field_<&clazz::clazz2::field>("field") + meta::field_("field", &clazz::clazz2::field) ) )); CHECK_NOTHROW(clazz_( meta::class_("child")( - meta::field_<&clazz::clazz2::cfield>("cfield") + meta::field_("cfield", &clazz::clazz2::cfield) ) )); CHECK_THROWS_AS(clazz_( meta::class_("child")( - meta::field_<&clazz::clazz3::field>("field") + meta::field_("field", &clazz::clazz3::field) ) ), std::logic_error); diff --git a/untests/meta_data_tests.cpp b/untests/meta_data_tests.cpp index c66c520..5a37204 100644 --- a/untests/meta_data_tests.cpp +++ b/untests/meta_data_tests.cpp @@ -100,7 +100,7 @@ TEST_CASE("meta/data/field") { using namespace std::string_literals; const meta::class_info clazz_info = meta::class_("clazz")( - meta::field_<&clazz::field>("field")( + meta::field_("field", &clazz::field)( meta::data_("hello"s, "world"s) ) ); diff --git a/untests/meta_examples.cpp b/untests/meta_examples.cpp index ba0959b..7daa2f1 100644 --- a/untests/meta_examples.cpp +++ b/untests/meta_examples.cpp @@ -89,23 +89,23 @@ TEST_CASE("meta/examples/simple") { namespace_info vmath_info = namespace_("vmath")( class_("ivec2")( - field_<&ivec2::x>("x")( + field_("x", &ivec2::x)( data_("tooltip", "x-coordinate field") ), - field_<&ivec2::y>("y")( + field_("y", &ivec2::y)( data_("tooltip", "y-coordinate field") ), method_<&ivec2::dot>("dot"), method_<&ivec2::length2>("length2") ), class_("ivec3")( - field_<&ivec3::x>("x")( + field_("x", &ivec3::x)( data_("tooltip", "x-coordinate field") ), - field_<&ivec3::y>("y")( + field_("y", &ivec3::y)( data_("tooltip", "y-coordinate field") ), - field_<&ivec3::z>("z")( + field_("z", &ivec3::z)( data_("tooltip", "z-coordinate field") ), method_<&ivec3::dot>("dot"), @@ -156,15 +156,15 @@ TEST_CASE("meta/examples/advanced") { auto db = registry{}( class_("ivec2")( - field_<&ivec2::x>("x"), - field_<&ivec2::y>("y"), + field_("x", &ivec2::x), + field_("y", &ivec2::y), method_<&ivec2::dot>("dot"), method_<&ivec2::length2>("length2") ), class_("ivec3")( - field_<&ivec3::x>("x"), - field_<&ivec3::y>("y"), - field_<&ivec3::z>("z"), + field_("x", &ivec3::x), + field_("y", &ivec3::y), + field_("z", &ivec3::z), method_<&ivec3::dot>("dot"), method_<&ivec3::length2>("length2") ) diff --git a/untests/meta_field_tests.cpp b/untests/meta_field_tests.cpp index 3b0ce40..46c854d 100644 --- a/untests/meta_field_tests.cpp +++ b/untests/meta_field_tests.cpp @@ -19,8 +19,8 @@ namespace TEST_CASE("meta/field") { namespace meta = meta_hpp; - meta::field_<&clazz::field> field_{"field"}; - meta::field_<&clazz::cfield> cfield_{"cfield"}; + meta::field_ field_{"field", &clazz::field}; + meta::field_ cfield_{"cfield", &clazz::cfield}; const meta::field_info& field_info = field_; const meta::field_info& cfield_info = cfield_; diff --git a/untests/meta_registry_tests.cpp b/untests/meta_registry_tests.cpp index 8ddc085..2d5d121 100644 --- a/untests/meta_registry_tests.cpp +++ b/untests/meta_registry_tests.cpp @@ -51,15 +51,15 @@ TEST_CASE("meta/registry") { auto registry = meta::registry{}( meta::namespace_("vmath")( meta::class_("ivec2")( - meta::field_<&ivec2::x>("x"), - meta::field_<&ivec2::y>("y"), + meta::field_("x", &ivec2::x), + meta::field_("y", &ivec2::y), meta::method_<&ivec2::dot>("dot"), meta::variable_<&ivec2::zero>("zero") ), meta::class_("ivec3")( - meta::field_<&ivec3::x>("x"), - meta::field_<&ivec3::y>("y"), - meta::field_<&ivec3::z>("z"), + meta::field_("x", &ivec3::x), + meta::field_("y", &ivec3::y), + meta::field_("z", &ivec3::z), meta::method_<&ivec3::dot>("dot"), meta::variable_<&ivec3::zero>("zero") ), @@ -172,12 +172,12 @@ TEST_CASE("meta/registry/merge") { SUBCASE("class") { registry( meta::class_("ivec2")( - meta::field_<&ivec2::x>("x") + meta::field_("x", &ivec2::x) )); registry( meta::class_("ivec2")( - meta::field_<&ivec2::y>("y") + meta::field_("y", &ivec2::y) )); CHECK(registry.resolve()); diff --git a/untests/meta_type_tests.cpp b/untests/meta_type_tests.cpp index 4e94218..ff98110 100644 --- a/untests/meta_type_tests.cpp +++ b/untests/meta_type_tests.cpp @@ -35,7 +35,7 @@ TEST_CASE("meta/type") { CHECK(class_type.is_class()); CHECK(class_type.get_class()->id() == "clazz"); - meta::type field_type = meta::field_<&clazz::field>("field"); + meta::type field_type = meta::field_("field", &clazz::field); CHECK(field_type.is_field()); CHECK(field_type.get_field()->id() == "field"); @@ -62,7 +62,7 @@ TEST_CASE("meta/type/merge") { { meta::type clazz_type = meta::class_("clazz")( - meta::field_<&clazz::field>("field") + meta::field_("field", &clazz::field) ); clazz_type.merge(meta::class_("clazz")( From 60674de7da440350d5abcf9d4b03b83ac68d6ac2 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Wed, 7 Jul 2021 02:53:58 +0700 Subject: [PATCH 045/233] remove "auto Method" --- headers/meta.hpp/meta_method.hpp | 8 +-- headers/meta.hpp/meta_method_info.hpp | 77 +++++++++++++++++++-------- untests/meta_class_tests.cpp | 4 +- untests/meta_data_tests.cpp | 2 +- untests/meta_examples.cpp | 16 +++--- untests/meta_method_tests.cpp | 24 ++++----- untests/meta_registry_tests.cpp | 4 +- untests/meta_type_tests.cpp | 2 +- 8 files changed, 86 insertions(+), 51 deletions(-) diff --git a/headers/meta.hpp/meta_method.hpp b/headers/meta.hpp/meta_method.hpp index 883d3fe..ccdd9d8 100644 --- a/headers/meta.hpp/meta_method.hpp +++ b/headers/meta.hpp/meta_method.hpp @@ -14,13 +14,13 @@ namespace meta_hpp { - template < auto Method > + template < typename MethodType > class method_ { public: - static_assert(std::is_member_function_pointer_v); + static_assert(std::is_member_function_pointer_v); - explicit method_(std::string id) - : info_{detail::auto_arg, std::move(id)} {} + explicit method_(std::string id, MethodType method) + : info_{std::move(id), method} {} operator const method_info&() const { return info_; diff --git a/headers/meta.hpp/meta_method_info.hpp b/headers/meta.hpp/meta_method_info.hpp index efcf13f..46d35de 100644 --- a/headers/meta.hpp/meta_method_info.hpp +++ b/headers/meta.hpp/meta_method_info.hpp @@ -15,8 +15,13 @@ namespace meta_hpp::method_detail { - template < typename MethodType, MethodType Method, std::size_t... Is > - std::optional invoke(instance instance, value* args, std::index_sequence) { + template < typename MethodType, std::size_t... Is > + std::optional raw_invoke_impl( + MethodType method, + instance instance, + value* args, + std::index_sequence) + { using mt = detail::method_traits; using return_type = typename mt::return_type; using instance_type = typename mt::instance_type; @@ -35,27 +40,37 @@ namespace meta_hpp::method_detail } if constexpr ( std::is_void_v ) { - std::invoke(Method, *typed_instance, std::move(*std::get(typed_arguments))...); + std::invoke(method, *typed_instance, std::move(*std::get(typed_arguments))...); return std::nullopt; } else { - return_type return_value{std::invoke(Method, *typed_instance, std::move(*std::get(typed_arguments))...)}; + return_type return_value{std::invoke(method, *typed_instance, std::move(*std::get(typed_arguments))...)}; return value{std::move(return_value)}; } } - template < typename MethodType, MethodType Method > - std::optional invoke(instance instance, value* args, std::size_t arg_count) { + template < typename MethodType > + std::optional raw_invoke( + MethodType method, + instance instance, + value* args, + std::size_t arg_count) + { using mt = detail::method_traits; if ( arg_count != mt::arity ) { throw std::logic_error("an attempt to call a method with an incorrect arity"); } - return invoke(instance, args, std::make_index_sequence()); + return raw_invoke_impl(method, instance, args, std::make_index_sequence()); } - template < typename MethodType, MethodType Method, std::size_t... Is > - std::optional cinvoke([[maybe_unused]] cinstance instance, value* args, std::index_sequence) { + template < typename MethodType, std::size_t... Is > + std::optional raw_cinvoke_impl( + [[maybe_unused]] MethodType method, + [[maybe_unused]] cinstance instance, + value* args, + std::index_sequence) + { using mt = detail::method_traits; using return_type = typename mt::return_type; using instance_type = typename mt::instance_type; @@ -75,10 +90,10 @@ namespace meta_hpp::method_detail } if constexpr ( std::is_void_v ) { - std::invoke(Method, *typed_instance, std::move(*std::get(typed_arguments))...); + std::invoke(method, *typed_instance, std::move(*std::get(typed_arguments))...); return std::nullopt; } else { - return_type return_value{std::invoke(Method, *typed_instance, std::move(*std::get(typed_arguments))...)}; + return_type return_value{std::invoke(method, *typed_instance, std::move(*std::get(typed_arguments))...)}; return value{std::move(return_value)}; } } else { @@ -86,15 +101,35 @@ namespace meta_hpp::method_detail } } - template < typename MethodType, MethodType Method > - std::optional cinvoke(cinstance instance, value* args, std::size_t arg_count) { + template < typename MethodType > + std::optional raw_cinvoke( + MethodType method, + cinstance instance, + value* args, + std::size_t arg_count) + { using mt = detail::method_traits; if ( arg_count != mt::arity ) { throw std::logic_error("an attempt to call a method with a different arity"); } - return cinvoke(instance, args, std::make_index_sequence()); + return raw_cinvoke_impl(method, instance, args, std::make_index_sequence()); + } + + using method_invoke = std::function(instance, value*, std::size_t)>; + using method_cinvoke = std::function(cinstance, value*, std::size_t)>; + + template < typename MethodType > + method_invoke make_invoke(MethodType method) { + using namespace std::placeholders; + return std::bind(&raw_invoke, method, _1, _2, _3); + } + + template < typename MethodType > + method_cinvoke make_cinvoke(MethodType method) { + using namespace std::placeholders; + return std::bind(&raw_cinvoke, method, _1, _2, _3); } } @@ -157,18 +192,18 @@ namespace meta_hpp detail::merge_with(datas_, other.datas_, &data_info::merge); } private: - template < auto Method > + template < typename MethodType > friend class method_; - template < typename MethodType, MethodType Method > - method_info(detail::auto_arg_t, std::string id) + template < typename MethodType > + method_info(std::string id, MethodType method) : id_{std::move(id)} - , invoke_{&method_detail::invoke} - , cinvoke_{&method_detail::cinvoke} {} + , invoke_{method_detail::make_invoke(method)} + , cinvoke_{method_detail::make_cinvoke(method)} {} private: std::string id_; - std::optional(*invoke_)(instance, value*, std::size_t); - std::optional(*cinvoke_)(cinstance, value*, std::size_t); + method_detail::method_invoke invoke_; + method_detail::method_cinvoke cinvoke_; std::map> datas_; }; } diff --git a/untests/meta_class_tests.cpp b/untests/meta_class_tests.cpp index 081ba66..9f81810 100644 --- a/untests/meta_class_tests.cpp +++ b/untests/meta_class_tests.cpp @@ -64,8 +64,8 @@ TEST_CASE("meta/class") { meta::field_("field", &clazz::field), meta::field_("cfield", &clazz::cfield), meta::function_<&clazz::func>("func"), - meta::method_<&clazz::method>("method"), - meta::method_<&clazz::cmethod>("cmethod"), + meta::method_("method", &clazz::method), + meta::method_("cmethod", &clazz::cmethod), meta::variable_<&clazz::variable>("variable"), meta::variable_<&clazz::cvariable>("cvariable")); diff --git a/untests/meta_data_tests.cpp b/untests/meta_data_tests.cpp index 5a37204..ad89cfa 100644 --- a/untests/meta_data_tests.cpp +++ b/untests/meta_data_tests.cpp @@ -130,7 +130,7 @@ TEST_CASE("meta/data/method") { using namespace std::string_literals; const meta::class_info clazz_info = meta::class_("clazz")( - meta::method_<&clazz::method>("method")( + meta::method_("method", &clazz::method)( meta::data_("hello"s, "world"s) ) ); diff --git a/untests/meta_examples.cpp b/untests/meta_examples.cpp index 7daa2f1..84cd7b8 100644 --- a/untests/meta_examples.cpp +++ b/untests/meta_examples.cpp @@ -95,8 +95,8 @@ TEST_CASE("meta/examples/simple") { field_("y", &ivec2::y)( data_("tooltip", "y-coordinate field") ), - method_<&ivec2::dot>("dot"), - method_<&ivec2::length2>("length2") + method_("dot", &ivec2::dot), + method_("length2", &ivec2::length2) ), class_("ivec3")( field_("x", &ivec3::x)( @@ -108,8 +108,8 @@ TEST_CASE("meta/examples/simple") { field_("z", &ivec3::z)( data_("tooltip", "z-coordinate field") ), - method_<&ivec3::dot>("dot"), - method_<&ivec3::length2>("length2") + method_("dot", &ivec3::dot), + method_("length2", &ivec3::length2) ), function_(&add)>("iadd2"), function_(&add)>("iadd3") @@ -158,15 +158,15 @@ TEST_CASE("meta/examples/advanced") { class_("ivec2")( field_("x", &ivec2::x), field_("y", &ivec2::y), - method_<&ivec2::dot>("dot"), - method_<&ivec2::length2>("length2") + method_("dot", &ivec2::dot), + method_("length2", &ivec2::length2) ), class_("ivec3")( field_("x", &ivec3::x), field_("y", &ivec3::y), field_("z", &ivec3::z), - method_<&ivec3::dot>("dot"), - method_<&ivec3::length2>("length2") + method_("dot", &ivec3::dot), + method_("length2", &ivec3::length2) ) ); diff --git a/untests/meta_method_tests.cpp b/untests/meta_method_tests.cpp index d8000a1..8d233ed 100644 --- a/untests/meta_method_tests.cpp +++ b/untests/meta_method_tests.cpp @@ -34,13 +34,13 @@ namespace TEST_CASE("meta/non_const_method") { namespace meta = meta_hpp; - meta::method_<&clazz::void_f_void> void_f_void_method_("void_f_void"); - meta::method_<&clazz::void_f_int> void_f_int_method_("void_f_int"); - meta::method_<&clazz::void_f_int2> void_f_int2_method_("void_f_int2"); + meta::method_ void_f_void_method_("void_f_void", &clazz::void_f_void); + meta::method_ void_f_int_method_("void_f_int", &clazz::void_f_int); + meta::method_ void_f_int2_method_("void_f_int2", &clazz::void_f_int2); - meta::method_<&clazz::int_f_void> int_f_void_method_("int_f_void"); - meta::method_<&clazz::int_f_int> int_f_int_method_("int_f_int"); - meta::method_<&clazz::int_f_int2> int_f_int2_method_("int_f_int2"); + meta::method_ int_f_void_method_("int_f_void", &clazz::int_f_void); + meta::method_ int_f_int_method_("int_f_int", &clazz::int_f_int); + meta::method_ int_f_int2_method_("int_f_int2", &clazz::int_f_int2); const meta::method_info& void_f_void_info = void_f_void_method_; const meta::method_info& void_f_int_info = void_f_int_method_; @@ -116,13 +116,13 @@ TEST_CASE("meta/non_const_method") { TEST_CASE("meta/const_method") { namespace meta = meta_hpp; - meta::method_<&clazz::const_void_f_void> void_f_void_method_("void_f_void"); - meta::method_<&clazz::const_void_f_int> void_f_int_method_("void_f_int"); - meta::method_<&clazz::const_void_f_int2> void_f_int2_method_("void_f_int2"); + meta::method_ void_f_void_method_("void_f_void", &clazz::const_void_f_void); + meta::method_ void_f_int_method_("void_f_int", &clazz::const_void_f_int); + meta::method_ void_f_int2_method_("void_f_int2", &clazz::const_void_f_int2); - meta::method_<&clazz::const_int_f_void> int_f_void_method_("int_f_void"); - meta::method_<&clazz::const_int_f_int> int_f_int_method_("int_f_int"); - meta::method_<&clazz::const_int_f_int2> int_f_int2_method_("int_f_int2"); + meta::method_ int_f_void_method_("int_f_void", &clazz::const_int_f_void); + meta::method_ int_f_int_method_("int_f_int", &clazz::const_int_f_int); + meta::method_ int_f_int2_method_("int_f_int2", &clazz::const_int_f_int2); const meta::method_info& void_f_void_info = void_f_void_method_; const meta::method_info& void_f_int_info = void_f_int_method_; diff --git a/untests/meta_registry_tests.cpp b/untests/meta_registry_tests.cpp index 2d5d121..6ce1dda 100644 --- a/untests/meta_registry_tests.cpp +++ b/untests/meta_registry_tests.cpp @@ -53,14 +53,14 @@ TEST_CASE("meta/registry") { meta::class_("ivec2")( meta::field_("x", &ivec2::x), meta::field_("y", &ivec2::y), - meta::method_<&ivec2::dot>("dot"), + meta::method_("dot", &ivec2::dot), meta::variable_<&ivec2::zero>("zero") ), meta::class_("ivec3")( meta::field_("x", &ivec3::x), meta::field_("y", &ivec3::y), meta::field_("z", &ivec3::z), - meta::method_<&ivec3::dot>("dot"), + meta::method_("dot", &ivec3::dot), meta::variable_<&ivec3::zero>("zero") ), meta::function_<&iadd2>("iadd2"), diff --git a/untests/meta_type_tests.cpp b/untests/meta_type_tests.cpp index ff98110..7f1656b 100644 --- a/untests/meta_type_tests.cpp +++ b/untests/meta_type_tests.cpp @@ -43,7 +43,7 @@ TEST_CASE("meta/type") { CHECK(function_type.is_function()); CHECK(function_type.get_function()->id() == "function"); - meta::type method_type = meta::method_<&clazz::method>("method"); + meta::type method_type = meta::method_("method", &clazz::method); CHECK(method_type.is_method()); CHECK(method_type.get_method()->id() == "method"); From 4e829bc7b7c52b25f323430ae9071355e4dc81aa Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Wed, 7 Jul 2021 03:01:39 +0700 Subject: [PATCH 046/233] remove "auto Function" --- headers/meta.hpp/meta_function.hpp | 8 ++--- headers/meta.hpp/meta_function_info.hpp | 40 +++++++++++++++++-------- untests/meta_class_tests.cpp | 2 +- untests/meta_data_tests.cpp | 2 +- untests/meta_examples.cpp | 4 +-- untests/meta_function_tests.cpp | 12 ++++---- untests/meta_namespace_tests.cpp | 6 ++-- untests/meta_registry_tests.cpp | 4 +-- untests/meta_type_tests.cpp | 4 +-- 9 files changed, 49 insertions(+), 33 deletions(-) diff --git a/headers/meta.hpp/meta_function.hpp b/headers/meta.hpp/meta_function.hpp index 94a85d1..75aa470 100644 --- a/headers/meta.hpp/meta_function.hpp +++ b/headers/meta.hpp/meta_function.hpp @@ -14,13 +14,13 @@ namespace meta_hpp { - template < auto Function > + template < typename FunctionType > class function_ { public: - static_assert(std::is_function_v>); + static_assert(std::is_function_v>); - explicit function_(std::string id) - : info_{detail::auto_arg, std::move(id)} {} + explicit function_(std::string id, FunctionType function) + : info_{std::move(id), function} {} operator const function_info&() const noexcept { return info_; diff --git a/headers/meta.hpp/meta_function_info.hpp b/headers/meta.hpp/meta_function_info.hpp index 4ad5c96..a0be8cc 100644 --- a/headers/meta.hpp/meta_function_info.hpp +++ b/headers/meta.hpp/meta_function_info.hpp @@ -14,8 +14,12 @@ namespace meta_hpp::function_detail { - template < typename FunctionType, FunctionType Function, std::size_t... Is > - std::optional invoke(value* args, std::index_sequence) { + template < typename FunctionType, std::size_t... Is > + std::optional raw_invoke_impl( + FunctionType function, + value* args, + std::index_sequence) + { using ft = detail::function_traits; using return_type = typename ft::return_type; using argument_types = typename ft::argument_types; @@ -28,23 +32,35 @@ namespace meta_hpp::function_detail } if constexpr ( std::is_void_v ) { - std::invoke(Function, std::move(*std::get(typed_arguments))...); + std::invoke(function, std::move(*std::get(typed_arguments))...); return std::nullopt; } else { - return_type return_value{std::invoke(Function, std::move(*std::get(typed_arguments))...)}; + return_type return_value{std::invoke(function, std::move(*std::get(typed_arguments))...)}; return value{std::move(return_value)}; } } - template < typename FunctionType, FunctionType Function > - std::optional invoke(value* args, std::size_t arg_count) { + template < typename FunctionType > + std::optional raw_invoke( + FunctionType function, + value* args, + std::size_t arg_count) + { using ft = detail::function_traits; if ( arg_count != ft::arity ) { throw std::logic_error("an attempt to call a function with an incorrect arity"); } - return invoke(args, std::make_index_sequence()); + return raw_invoke_impl(function, args, std::make_index_sequence()); + } + + using function_invoke = std::function(value*, std::size_t)>; + + template < typename FunctionType > + function_invoke make_invoke(FunctionType function) { + using namespace std::placeholders; + return std::bind(&raw_invoke, function, _1, _2); } } @@ -97,16 +113,16 @@ namespace meta_hpp detail::merge_with(datas_, other.datas_, &data_info::merge); } private: - template < auto Function > + template < typename FunctionType > friend class function_; - template < typename FunctionType, FunctionType Function > - function_info(detail::auto_arg_t, std::string id) + template < typename FunctionType > + function_info(std::string id, FunctionType function) : id_{std::move(id)} - , invoke_{&function_detail::invoke} {} + , invoke_{function_detail::make_invoke(function)} {} private: std::string id_; - std::optional(*invoke_)(value*, std::size_t); + function_detail::function_invoke invoke_; std::map> datas_; }; } diff --git a/untests/meta_class_tests.cpp b/untests/meta_class_tests.cpp index 9f81810..b52898a 100644 --- a/untests/meta_class_tests.cpp +++ b/untests/meta_class_tests.cpp @@ -63,7 +63,7 @@ TEST_CASE("meta/class") { meta::class_("clazz2"), meta::field_("field", &clazz::field), meta::field_("cfield", &clazz::cfield), - meta::function_<&clazz::func>("func"), + meta::function_("func", &clazz::func), meta::method_("method", &clazz::method), meta::method_("cmethod", &clazz::cmethod), meta::variable_<&clazz::variable>("variable"), diff --git a/untests/meta_data_tests.cpp b/untests/meta_data_tests.cpp index ad89cfa..f467ace 100644 --- a/untests/meta_data_tests.cpp +++ b/untests/meta_data_tests.cpp @@ -115,7 +115,7 @@ TEST_CASE("meta/data/function") { using namespace std::string_literals; const meta::class_info clazz_info = meta::class_("clazz")( - meta::function_<&clazz::function>("function")( + meta::function_("function", &clazz::function)( meta::data_("hello"s, "world"s) ) ); diff --git a/untests/meta_examples.cpp b/untests/meta_examples.cpp index 84cd7b8..e7af521 100644 --- a/untests/meta_examples.cpp +++ b/untests/meta_examples.cpp @@ -111,8 +111,8 @@ TEST_CASE("meta/examples/simple") { method_("dot", &ivec3::dot), method_("length2", &ivec3::length2) ), - function_(&add)>("iadd2"), - function_(&add)>("iadd3") + function_("iadd2", select(&add)), + function_("iadd3", select(&add)) ); class_info ivec2_info = vmath_info.get_class("ivec2").value(); diff --git a/untests/meta_function_tests.cpp b/untests/meta_function_tests.cpp index 05f23f2..d4b2e46 100644 --- a/untests/meta_function_tests.cpp +++ b/untests/meta_function_tests.cpp @@ -21,13 +21,13 @@ namespace TEST_CASE("meta/function") { namespace meta = meta_hpp; - meta::function_<&void_f_void> void_f_void_function_("void_f_void"); - meta::function_<&void_f_int> void_f_int_function_("void_f_int"); - meta::function_<&void_f_int2> void_f_int2_function_("void_f_int2"); + meta::function_ void_f_void_function_("void_f_void", &void_f_void); + meta::function_ void_f_int_function_("void_f_int", &void_f_int); + meta::function_ void_f_int2_function_("void_f_int2", &void_f_int2); - meta::function_<&int_f_void> int_f_void_function_("int_f_void"); - meta::function_<&int_f_int> int_f_int_function_("int_f_int"); - meta::function_<&int_f_int2> int_f_int2_function_("int_f_int2"); + meta::function_ int_f_void_function_("int_f_void", &int_f_void); + meta::function_ int_f_int_function_("int_f_int", &int_f_int); + meta::function_ int_f_int2_function_("int_f_int2", &int_f_int2); const meta::function_info& void_f_void_info = void_f_void_function_; const meta::function_info& void_f_int_info = void_f_int_function_; diff --git a/untests/meta_namespace_tests.cpp b/untests/meta_namespace_tests.cpp index 5613b87..d31e165 100644 --- a/untests/meta_namespace_tests.cpp +++ b/untests/meta_namespace_tests.cpp @@ -34,7 +34,7 @@ TEST_CASE("meta/namespace") { namespace_( meta::class_("clazz"), - meta::function_<&func>("func"), + meta::function_("func", &func), meta::namespace_("ns2"), meta::variable_<&variable>("variable"), meta::variable_<&cvariable>("cvariable")); @@ -80,7 +80,7 @@ TEST_CASE("meta/namespace/merge") { namespace_( meta::namespace_{"ns2"}( meta::class_{"clazz"}, - meta::function_<&func>("func"), + meta::function_("func", &func), meta::namespace_{"ns3"}, meta::variable_<&variable>("variable") ) @@ -89,7 +89,7 @@ TEST_CASE("meta/namespace/merge") { namespace_( meta::namespace_{"ns2"}( meta::class_{"clazz"}, - meta::function_<&func>("func2"), + meta::function_("func2", &func), meta::namespace_{"ns3"}( meta::namespace_{"ns4"}, meta::variable_<&variable>("variable2") diff --git a/untests/meta_registry_tests.cpp b/untests/meta_registry_tests.cpp index 6ce1dda..728c057 100644 --- a/untests/meta_registry_tests.cpp +++ b/untests/meta_registry_tests.cpp @@ -63,8 +63,8 @@ TEST_CASE("meta/registry") { meta::method_("dot", &ivec3::dot), meta::variable_<&ivec3::zero>("zero") ), - meta::function_<&iadd2>("iadd2"), - meta::function_<&iadd3>("iadd3") + meta::function_("iadd2", &iadd2), + meta::function_("iadd3", &iadd3) ) ); diff --git a/untests/meta_type_tests.cpp b/untests/meta_type_tests.cpp index 7f1656b..3e8fac6 100644 --- a/untests/meta_type_tests.cpp +++ b/untests/meta_type_tests.cpp @@ -39,7 +39,7 @@ TEST_CASE("meta/type") { CHECK(field_type.is_field()); CHECK(field_type.get_field()->id() == "field"); - meta::type function_type = meta::function_<&clazz::function>("function"); + meta::type function_type = meta::function_("function", &clazz::function); CHECK(function_type.is_function()); CHECK(function_type.get_function()->id() == "function"); @@ -66,7 +66,7 @@ TEST_CASE("meta/type/merge") { ); clazz_type.merge(meta::class_("clazz")( - meta::function_<&clazz::function>("function") + meta::function_("function", &clazz::function) )); REQUIRE(clazz_type.is_class()); From 014a1c4491a4995353460f79d6b0c0e7bfeb1460 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Wed, 7 Jul 2021 03:11:17 +0700 Subject: [PATCH 047/233] remove "auto Variable" --- headers/meta.hpp/meta_field_info.hpp | 2 +- headers/meta.hpp/meta_method_info.hpp | 2 +- headers/meta.hpp/meta_variable.hpp | 6 ++-- headers/meta.hpp/meta_variable_info.hpp | 46 ++++++++++++++++++------- untests/meta_class_tests.cpp | 4 +-- untests/meta_data_tests.cpp | 2 +- untests/meta_namespace_tests.cpp | 8 ++--- untests/meta_registry_tests.cpp | 4 +-- untests/meta_type_tests.cpp | 2 +- untests/meta_variable_tests.cpp | 8 ++--- 10 files changed, 52 insertions(+), 32 deletions(-) diff --git a/headers/meta.hpp/meta_field_info.hpp b/headers/meta.hpp/meta_field_info.hpp index f498831..80068e7 100644 --- a/headers/meta.hpp/meta_field_info.hpp +++ b/headers/meta.hpp/meta_field_info.hpp @@ -37,7 +37,7 @@ namespace meta_hpp::field_detail void raw_setter( [[maybe_unused]] FieldType field, [[maybe_unused]] instance instance, - value value) + [[maybe_unused]] value value) { using ft = detail::field_traits; using value_type = typename ft::value_type; diff --git a/headers/meta.hpp/meta_method_info.hpp b/headers/meta.hpp/meta_method_info.hpp index 46d35de..4d9d5ce 100644 --- a/headers/meta.hpp/meta_method_info.hpp +++ b/headers/meta.hpp/meta_method_info.hpp @@ -68,7 +68,7 @@ namespace meta_hpp::method_detail std::optional raw_cinvoke_impl( [[maybe_unused]] MethodType method, [[maybe_unused]] cinstance instance, - value* args, + [[maybe_unused]] value* args, std::index_sequence) { using mt = detail::method_traits; diff --git a/headers/meta.hpp/meta_variable.hpp b/headers/meta.hpp/meta_variable.hpp index 688ef88..09e3498 100644 --- a/headers/meta.hpp/meta_variable.hpp +++ b/headers/meta.hpp/meta_variable.hpp @@ -14,11 +14,11 @@ namespace meta_hpp { - template < auto Variable > + template < typename VariableType > class variable_ { public: - explicit variable_(std::string id) - : info_{detail::auto_arg, std::move(id)} {} + explicit variable_(std::string id, VariableType variable) + : info_{std::move(id), variable} {} operator const variable_info&() const noexcept { return info_; diff --git a/headers/meta.hpp/meta_variable_info.hpp b/headers/meta.hpp/meta_variable_info.hpp index 9391b07..789bb5f 100644 --- a/headers/meta.hpp/meta_variable_info.hpp +++ b/headers/meta.hpp/meta_variable_info.hpp @@ -14,17 +14,22 @@ namespace meta_hpp::variable_detail { - template < typename VariableType, VariableType Variable > - value getter() { + template < typename VariableType > + value raw_getter( + VariableType variable) + { using vt = detail::variable_traits>; using value_type = typename vt::value_type; - value_type typed_value{*Variable}; + value_type typed_value{*variable}; return value{std::move(typed_value)}; } - template < typename VariableType, VariableType Variable > - void setter(value value) { + template < typename VariableType > + void raw_setter( + [[maybe_unused]] VariableType variable, + [[maybe_unused]] value value) + { using vt = detail::variable_traits>; using value_type = typename vt::value_type; @@ -34,11 +39,26 @@ namespace meta_hpp::variable_detail throw std::logic_error("an attempt to set a variable with incorrect argument type"); } - *Variable = std::move(*typed_value); + *variable = std::move(*typed_value); } else { throw std::logic_error("an attempt to set a constant variable"); } } + + using variable_getter = std::function; + using variable_setter = std::function; + + template < typename VariableType > + variable_getter make_getter(VariableType variable) { + using namespace std::placeholders; + return std::bind(&raw_getter, variable); + } + + template < typename VariableType > + variable_setter make_setter(VariableType variable) { + using namespace std::placeholders; + return std::bind(&raw_setter, variable, _1); + } } namespace meta_hpp @@ -89,18 +109,18 @@ namespace meta_hpp detail::merge_with(datas_, other.datas_, &data_info::merge); } private: - template < auto Variable > + template < typename VariableType > friend class variable_; - template < typename VariableType, VariableType Variable > - variable_info(detail::auto_arg_t, std::string id) + template < typename VariableType > + variable_info(std::string id, VariableType variable) : id_{std::move(id)} - , getter_{&variable_detail::getter} - , setter_{&variable_detail::setter} {} + , getter_{variable_detail::make_getter(variable)} + , setter_{variable_detail::make_setter(variable)} {} private: std::string id_; - value(*getter_)(); - void(*setter_)(value); + variable_detail::variable_getter getter_; + variable_detail::variable_setter setter_; std::map> datas_; }; } diff --git a/untests/meta_class_tests.cpp b/untests/meta_class_tests.cpp index b52898a..fd61813 100644 --- a/untests/meta_class_tests.cpp +++ b/untests/meta_class_tests.cpp @@ -66,8 +66,8 @@ TEST_CASE("meta/class") { meta::function_("func", &clazz::func), meta::method_("method", &clazz::method), meta::method_("cmethod", &clazz::cmethod), - meta::variable_<&clazz::variable>("variable"), - meta::variable_<&clazz::cvariable>("cvariable")); + meta::variable_("variable", &clazz::variable), + meta::variable_("cvariable", &clazz::cvariable)); CHECK(clazz_info.get_class("clazz2")); CHECK(clazz_info.get_field("field")); diff --git a/untests/meta_data_tests.cpp b/untests/meta_data_tests.cpp index f467ace..b1cb5af 100644 --- a/untests/meta_data_tests.cpp +++ b/untests/meta_data_tests.cpp @@ -157,7 +157,7 @@ TEST_CASE("meta/data/variable") { using namespace std::string_literals; const meta::class_info clazz_info = meta::class_("clazz")( - meta::variable_<&clazz::variable>("variable")( + meta::variable_("variable", &clazz::variable)( meta::data_("hello"s, "world"s) ) ); diff --git a/untests/meta_namespace_tests.cpp b/untests/meta_namespace_tests.cpp index d31e165..24c8346 100644 --- a/untests/meta_namespace_tests.cpp +++ b/untests/meta_namespace_tests.cpp @@ -36,8 +36,8 @@ TEST_CASE("meta/namespace") { meta::class_("clazz"), meta::function_("func", &func), meta::namespace_("ns2"), - meta::variable_<&variable>("variable"), - meta::variable_<&cvariable>("cvariable")); + meta::variable_("variable", &variable), + meta::variable_("cvariable", &cvariable)); CHECK(ns_info.get_class("clazz")); CHECK(ns_info.get_function("func")); @@ -82,7 +82,7 @@ TEST_CASE("meta/namespace/merge") { meta::class_{"clazz"}, meta::function_("func", &func), meta::namespace_{"ns3"}, - meta::variable_<&variable>("variable") + meta::variable_("variable", &variable) ) ); @@ -92,7 +92,7 @@ TEST_CASE("meta/namespace/merge") { meta::function_("func2", &func), meta::namespace_{"ns3"}( meta::namespace_{"ns4"}, - meta::variable_<&variable>("variable2") + meta::variable_("variable2", &variable) ) ) ); diff --git a/untests/meta_registry_tests.cpp b/untests/meta_registry_tests.cpp index 728c057..eaf3b77 100644 --- a/untests/meta_registry_tests.cpp +++ b/untests/meta_registry_tests.cpp @@ -54,14 +54,14 @@ TEST_CASE("meta/registry") { meta::field_("x", &ivec2::x), meta::field_("y", &ivec2::y), meta::method_("dot", &ivec2::dot), - meta::variable_<&ivec2::zero>("zero") + meta::variable_("zero", &ivec2::zero) ), meta::class_("ivec3")( meta::field_("x", &ivec3::x), meta::field_("y", &ivec3::y), meta::field_("z", &ivec3::z), meta::method_("dot", &ivec3::dot), - meta::variable_<&ivec3::zero>("zero") + meta::variable_("zero", &ivec3::zero) ), meta::function_("iadd2", &iadd2), meta::function_("iadd3", &iadd3) diff --git a/untests/meta_type_tests.cpp b/untests/meta_type_tests.cpp index 3e8fac6..d90d4df 100644 --- a/untests/meta_type_tests.cpp +++ b/untests/meta_type_tests.cpp @@ -51,7 +51,7 @@ TEST_CASE("meta/type") { CHECK(namespace_type.is_namespace()); CHECK(namespace_type.get_namespace()->id() == "ns"); - meta::type variable_type = meta::variable_<&clazz::variable>("variable"); + meta::type variable_type = meta::variable_("variable", &clazz::variable); CHECK(variable_type.is_variable()); CHECK(variable_type.get_variable()->id() == "variable"); } diff --git a/untests/meta_variable_tests.cpp b/untests/meta_variable_tests.cpp index 868abfd..4746856 100644 --- a/untests/meta_variable_tests.cpp +++ b/untests/meta_variable_tests.cpp @@ -26,8 +26,8 @@ TEST_CASE("meta/variable") { namespace meta = meta_hpp; SUBCASE("in_namespace") { - meta::variable_<&variable> variable_{"variable"}; - meta::variable_<&cvariable> cvariable_{"cvariable"}; + meta::variable_ variable_{"variable", &variable}; + meta::variable_ cvariable_{"cvariable", &cvariable}; const meta::variable_info& variable_info = variable_; const meta::variable_info& cvariable_info = cvariable_; @@ -60,8 +60,8 @@ TEST_CASE("meta/variable") { } SUBCASE("in_class") { - meta::variable_<&clazz::variable> variable_{"variable"}; - meta::variable_<&clazz::cvariable> cvariable_{"cvariable"}; + meta::variable_ variable_{"variable", &clazz::variable}; + meta::variable_ cvariable_{"cvariable", &clazz::cvariable}; const meta::variable_info& variable_info = variable_; const meta::variable_info& cvariable_info = cvariable_; From f97cd9492eae237a2ecc2565dda9520068175cfa Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Wed, 7 Jul 2021 03:27:28 +0700 Subject: [PATCH 048/233] fix msvc warnings --- headers/meta.hpp/meta_field.hpp | 4 ++-- headers/meta.hpp/meta_field_info.hpp | 6 +++--- headers/meta.hpp/meta_function.hpp | 4 ++-- headers/meta.hpp/meta_function_info.hpp | 4 ++-- headers/meta.hpp/meta_method.hpp | 4 ++-- headers/meta.hpp/meta_method_info.hpp | 6 +++--- headers/meta.hpp/meta_variable.hpp | 6 ++++-- headers/meta.hpp/meta_variable_info.hpp | 6 +++--- 8 files changed, 21 insertions(+), 19 deletions(-) diff --git a/headers/meta.hpp/meta_field.hpp b/headers/meta.hpp/meta_field.hpp index dce9fad..ceb758e 100644 --- a/headers/meta.hpp/meta_field.hpp +++ b/headers/meta.hpp/meta_field.hpp @@ -19,8 +19,8 @@ namespace meta_hpp public: static_assert(std::is_member_object_pointer_v); - explicit field_(std::string id, FieldType field) - : info_{std::move(id), field} {} + explicit field_(std::string id, FieldType field_ptr) + : info_{std::move(id), field_ptr} {} operator const field_info&() const noexcept { return info_; diff --git a/headers/meta.hpp/meta_field_info.hpp b/headers/meta.hpp/meta_field_info.hpp index 80068e7..08eff3c 100644 --- a/headers/meta.hpp/meta_field_info.hpp +++ b/headers/meta.hpp/meta_field_info.hpp @@ -128,10 +128,10 @@ namespace meta_hpp friend class field_; template < typename FieldType > - field_info(std::string id, FieldType field) + field_info(std::string id, FieldType field_ptr) : id_{std::move(id)} - , getter_{field_detail::make_getter(field)} - , setter_{field_detail::make_setter(field)} {} + , getter_{field_detail::make_getter(field_ptr)} + , setter_{field_detail::make_setter(field_ptr)} {} private: std::string id_; field_detail::field_getter getter_; diff --git a/headers/meta.hpp/meta_function.hpp b/headers/meta.hpp/meta_function.hpp index 75aa470..6fb5d41 100644 --- a/headers/meta.hpp/meta_function.hpp +++ b/headers/meta.hpp/meta_function.hpp @@ -19,8 +19,8 @@ namespace meta_hpp public: static_assert(std::is_function_v>); - explicit function_(std::string id, FunctionType function) - : info_{std::move(id), function} {} + explicit function_(std::string id, FunctionType function_ptr) + : info_{std::move(id), function_ptr} {} operator const function_info&() const noexcept { return info_; diff --git a/headers/meta.hpp/meta_function_info.hpp b/headers/meta.hpp/meta_function_info.hpp index a0be8cc..d5333fc 100644 --- a/headers/meta.hpp/meta_function_info.hpp +++ b/headers/meta.hpp/meta_function_info.hpp @@ -117,9 +117,9 @@ namespace meta_hpp friend class function_; template < typename FunctionType > - function_info(std::string id, FunctionType function) + function_info(std::string id, FunctionType function_ptr) : id_{std::move(id)} - , invoke_{function_detail::make_invoke(function)} {} + , invoke_{function_detail::make_invoke(function_ptr)} {} private: std::string id_; function_detail::function_invoke invoke_; diff --git a/headers/meta.hpp/meta_method.hpp b/headers/meta.hpp/meta_method.hpp index ccdd9d8..a89393d 100644 --- a/headers/meta.hpp/meta_method.hpp +++ b/headers/meta.hpp/meta_method.hpp @@ -19,8 +19,8 @@ namespace meta_hpp public: static_assert(std::is_member_function_pointer_v); - explicit method_(std::string id, MethodType method) - : info_{std::move(id), method} {} + explicit method_(std::string id, MethodType method_ptr) + : info_{std::move(id), method_ptr} {} operator const method_info&() const { return info_; diff --git a/headers/meta.hpp/meta_method_info.hpp b/headers/meta.hpp/meta_method_info.hpp index 4d9d5ce..d5ea0d2 100644 --- a/headers/meta.hpp/meta_method_info.hpp +++ b/headers/meta.hpp/meta_method_info.hpp @@ -196,10 +196,10 @@ namespace meta_hpp friend class method_; template < typename MethodType > - method_info(std::string id, MethodType method) + method_info(std::string id, MethodType method_ptr) : id_{std::move(id)} - , invoke_{method_detail::make_invoke(method)} - , cinvoke_{method_detail::make_cinvoke(method)} {} + , invoke_{method_detail::make_invoke(method_ptr)} + , cinvoke_{method_detail::make_cinvoke(method_ptr)} {} private: std::string id_; method_detail::method_invoke invoke_; diff --git a/headers/meta.hpp/meta_variable.hpp b/headers/meta.hpp/meta_variable.hpp index 09e3498..33059eb 100644 --- a/headers/meta.hpp/meta_variable.hpp +++ b/headers/meta.hpp/meta_variable.hpp @@ -17,8 +17,10 @@ namespace meta_hpp template < typename VariableType > class variable_ { public: - explicit variable_(std::string id, VariableType variable) - : info_{std::move(id), variable} {} + static_assert(std::is_pointer_v); + + explicit variable_(std::string id, VariableType variable_ptr) + : info_{std::move(id), variable_ptr} {} operator const variable_info&() const noexcept { return info_; diff --git a/headers/meta.hpp/meta_variable_info.hpp b/headers/meta.hpp/meta_variable_info.hpp index 789bb5f..b1a2506 100644 --- a/headers/meta.hpp/meta_variable_info.hpp +++ b/headers/meta.hpp/meta_variable_info.hpp @@ -113,10 +113,10 @@ namespace meta_hpp friend class variable_; template < typename VariableType > - variable_info(std::string id, VariableType variable) + variable_info(std::string id, VariableType variable_ptr) : id_{std::move(id)} - , getter_{variable_detail::make_getter(variable)} - , setter_{variable_detail::make_setter(variable)} {} + , getter_{variable_detail::make_getter(variable_ptr)} + , setter_{variable_detail::make_setter(variable_ptr)} {} private: std::string id_; variable_detail::variable_getter getter_; From ae0fb0285c02087b3b958104c0f8fa8156ca183c Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Wed, 7 Jul 2021 04:43:23 +0700 Subject: [PATCH 049/233] return msvc 2017 --- .github/workflows/windows.yml | 2 + README.md | 2 +- headers/meta.hpp/meta_value.hpp | 79 +++++-------------------------- untests/meta_value_tests.cpp | 82 ++++++++++----------------------- 4 files changed, 39 insertions(+), 126 deletions(-) diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 985cf43..1c48908 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -10,6 +10,8 @@ jobs: matrix: config: # https://github.com/actions/virtual-environments/tree/main/images/win + - { os: "windows-2016", vs: "Visual Studio 2017", arch: "x86" } + - { os: "windows-2016", vs: "Visual Studio 2017", arch: "x64" } - { os: "windows-2019", vs: "Visual Studio 2019", arch: "x86" } - { os: "windows-2019", vs: "Visual Studio 2019", arch: "x64" } name: "${{matrix.config.vs}} ${{matrix.config.arch}}" diff --git a/README.md b/README.md index c02fbbe..28a7de1 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ - [gcc](https://www.gnu.org/software/gcc/) **>= 7** - [clang](https://clang.llvm.org/) **>= 7** -- [msvc](https://visualstudio.microsoft.com/) **>= 2019** +- [msvc](https://visualstudio.microsoft.com/) **>= 2017** ## Installation diff --git a/headers/meta.hpp/meta_value.hpp b/headers/meta.hpp/meta_value.hpp index f353e71..12737f2 100644 --- a/headers/meta.hpp/meta_value.hpp +++ b/headers/meta.hpp/meta_value.hpp @@ -18,8 +18,7 @@ namespace meta_hpp::value_detail struct traits { void*(*data)(value&); const void*(*cdata)(const value&); - bool(*equal)(const value&, const value&){}; - bool(*not_equal)(const value&, const value&){}; + bool(*equals)(const value&, const value&){}; }; template < typename T > @@ -29,18 +28,14 @@ namespace meta_hpp::value_detail const void* value_cdata(const value& v); template < typename T > - bool value_equal(const value& l, const value& r); - - template < typename T > - bool value_not_equal(const value& l, const value& r); + bool value_equals(const value& l, const value& r); template < typename T > const traits* get_traits() noexcept { static traits traits{ &value_data, &value_cdata, - &value_equal, - &value_not_equal, + &value_equals, }; return &traits; } @@ -136,46 +131,14 @@ namespace meta_hpp template < typename T , typename U = std::decay_t - , typename = std::enable_if_t> - , typename = std::enable_if_t, U, U>> > - friend bool operator==(const value& l, T&& r) { - return l.fid() == get_family_id() - && std::equal_to<>{}(*l.try_cast(), std::forward(r)); + , typename = std::enable_if_t> > + bool equals(T&& other) const { + return fid() == get_family_id() + && std::equal_to<>{}(*try_cast(), std::forward(other)); } - template < typename T - , typename U = std::decay_t - , typename = std::enable_if_t> - , typename = std::enable_if_t, U, U>> > - friend bool operator==(T&& l, const value& r) { - return get_family_id() == r.fid() - && std::equal_to<>{}(std::forward(l), *r.try_cast()); - } - - template < typename T - , typename U = std::decay_t - , typename = std::enable_if_t> - , typename = std::enable_if_t, U, U>> > - friend bool operator!=(const value& l, T&& r) { - return l.fid() != get_family_id() - || std::not_equal_to<>{}(*l.try_cast(), std::forward(r)); - } - - template < typename T - , typename U = std::decay_t - , typename = std::enable_if_t> - , typename = std::enable_if_t, U, U>> > - friend bool operator!=(T&& l, const value& r) { - return get_family_id() != r.fid() - || std::not_equal_to<>{}(std::forward(l), *r.try_cast()); - } - - friend bool operator==(const value& l, const value& r) { - return l.traits_->equal(l, r); - } - - friend bool operator!=(const value& l, const value& r) { - return l.traits_->not_equal(l, r); + bool equals(const value& other) const { + return traits_->equals(*this, other); } public: bool to_bool() const { return cast(); } @@ -225,14 +188,6 @@ namespace meta_hpp const value_detail::traits* traits_{}; }; - inline void* data(value& v) noexcept { - return v.data(); - } - - inline const void* data(const value& v) noexcept { - return v.data(); - } - inline void swap(value& l, value& r) noexcept { l.swap(r); } @@ -251,26 +206,14 @@ namespace meta_hpp::value_detail } template < typename T > - bool value_equal(const value& l, const value& r) { + bool value_equals(const value& l, const value& r) { if ( l.fid() != r.fid() ) { return false; } if constexpr ( std::is_invocable_v, T, T> ) { - return std::equal_to<>{}(*l.try_cast(), *(r.try_cast())); + return std::equal_to<>{}(*l.try_cast(), *r.try_cast()); } else { return std::addressof(l) == std::addressof(r); } } - - template < typename T > - bool value_not_equal(const value& l, const value& r) { - if ( l.fid() != r.fid() ) { - return true; - } - if constexpr ( std::is_invocable_v, T, T> ) { - return std::not_equal_to<>{}(*l.try_cast(), *(r.try_cast())); - } else { - return std::addressof(l) != std::addressof(r); - } - } } diff --git a/untests/meta_value_tests.cpp b/untests/meta_value_tests.cpp index e866ea7..9231483 100644 --- a/untests/meta_value_tests.cpp +++ b/untests/meta_value_tests.cpp @@ -106,86 +106,55 @@ TEST_CASE("meta/value/equal") { using namespace std::string_literals; { - CHECK(meta::value{1} == 1); - CHECK(meta::value{1} != 0); - CHECK(meta::value{1} != "hello"s); - - CHECK_FALSE(meta::value{1} != 1); - CHECK_FALSE(meta::value{1} == 0); - CHECK_FALSE(meta::value{1} == "hello"s); - } - - { - CHECK(1 == meta::value{1}); - CHECK(0 != meta::value{1}); - CHECK("hello"s != meta::value{1}); - - CHECK_FALSE(1 != meta::value{1}); - CHECK_FALSE(0 == meta::value{1}); - CHECK_FALSE("hello"s == meta::value{1}); + CHECK(meta::value{1}.equals(1)); + CHECK_FALSE(meta::value{1}.equals(0)); + CHECK_FALSE(meta::value{1}.equals("hello"s)); } { int i = 1; - CHECK(meta::value{1} == i); - CHECK(meta::value{1} == std::as_const(i)); - CHECK_FALSE(meta::value{1} != i); - CHECK_FALSE(meta::value{1} != std::as_const(i)); - - CHECK(i == meta::value{1}); - CHECK(std::as_const(i) == meta::value{1}); - CHECK_FALSE(i != meta::value{1}); - CHECK_FALSE(std::as_const(i) != meta::value{1}); + CHECK(meta::value{1}.equals(i)); + CHECK(meta::value{1}.equals(std::as_const(i))); + CHECK_FALSE(meta::value{2}.equals(i)); + CHECK_FALSE(meta::value{2}.equals(std::as_const(i))); } { - CHECK(meta::value{1} == meta::value{1}); - CHECK(meta::value{1} != meta::value{0}); - CHECK(meta::value{1} != meta::value{"hello"s}); - CHECK_FALSE(meta::value{1} != meta::value{1}); - CHECK_FALSE(meta::value{1} == meta::value{0}); - CHECK_FALSE(meta::value{1} == meta::value{"hello"s}); + CHECK(meta::value{1}.equals(meta::value{1})); + CHECK_FALSE(meta::value{1}.equals(meta::value{0})); + CHECK_FALSE(meta::value{1}.equals(meta::value{"hello"s})); - CHECK(meta::value{1} == meta::value{1}); - CHECK(meta::value{0} != meta::value{1}); - CHECK(meta::value{"hello"s} != meta::value{1}); - CHECK_FALSE(meta::value{1} != meta::value{1}); - CHECK_FALSE(meta::value{0} == meta::value{1}); - CHECK_FALSE(meta::value{"hello"s} == meta::value{1}); + CHECK(meta::value{1}.equals(meta::value{1})); + CHECK_FALSE(meta::value{0}.equals(meta::value{1})); + CHECK_FALSE(meta::value{"hello"s}.equals(meta::value{1})); } { - CHECK(meta::value{std::in_place_type, 1} == meta::value{1}); - CHECK(meta::value{1} == meta::value{std::in_place_type, 1}); + CHECK(meta::value{std::in_place_type, 1}.equals(meta::value{1})); + CHECK(meta::value{1}.equals(meta::value{std::in_place_type, 1})); using vi = std::vector; - CHECK(meta::value{std::in_place_type, {1,2,3}} == meta::value{vi{1,2,3}}); - CHECK(meta::value{vi{1,2,3}} == meta::value{std::in_place_type, {1,2,3}}); - CHECK_FALSE(meta::value{std::in_place_type, {1,2,3}} == meta::value{vi{1,2,4}}); - CHECK_FALSE(meta::value{vi{1,2,4}} == meta::value{std::in_place_type, {1,2,3}}); + CHECK(meta::value{std::in_place_type, {1,2,3}}.equals(meta::value{vi{1,2,3}})); + CHECK(meta::value{vi{1,2,3}}.equals(meta::value{std::in_place_type, {1,2,3}})); + CHECK_FALSE(meta::value{std::in_place_type, {1,2,3}}.equals(meta::value{vi{1,2,4}})); + CHECK_FALSE(meta::value{vi{1,2,4}}.equals(meta::value{std::in_place_type, {1,2,3}})); } { meta::value v1{&func}; meta::value v2{&func}; - CHECK(v1 == v1); - CHECK_FALSE(v1 != v1); - - CHECK(v1 == v2); - CHECK_FALSE(v1 != v2); + CHECK(v1.equals(v1)); + CHECK(v1.equals(v2)); } { meta::value v1{clazz{}}; meta::value v2{clazz{}}; - CHECK(v1 == v1); - CHECK_FALSE(v1 != v1); - - CHECK(v1 != v2); - CHECK_FALSE(v1 == v2); + CHECK(v1.equals(v1)); + CHECK_FALSE(v1.equals(v2)); } { @@ -194,14 +163,13 @@ TEST_CASE("meta/value/equal") { meta::value v1{&rv}; meta::value v2{&rv}; - CHECK(v1 == v1); - CHECK_FALSE(v1 != v1); + CHECK(v1.equals(v1)); } { meta::value v1{"hello"s}; meta::value{1}.swap(v1); - CHECK(v1 == meta::value{1}); + CHECK(v1.equals(meta::value{1})); } } From 997687d2191343398ae490625663ec9ccf536b06 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Wed, 7 Jul 2021 05:02:08 +0700 Subject: [PATCH 050/233] arity for method and function infos --- headers/meta.hpp/meta_function_info.hpp | 6 ++++++ headers/meta.hpp/meta_fwd.hpp | 7 ------- headers/meta.hpp/meta_method_info.hpp | 6 ++++++ untests/meta_function_tests.cpp | 10 ++++++++++ untests/meta_method_tests.cpp | 10 ++++++++++ 5 files changed, 32 insertions(+), 7 deletions(-) diff --git a/headers/meta.hpp/meta_function_info.hpp b/headers/meta.hpp/meta_function_info.hpp index d5333fc..12793b9 100644 --- a/headers/meta.hpp/meta_function_info.hpp +++ b/headers/meta.hpp/meta_function_info.hpp @@ -80,6 +80,10 @@ namespace meta_hpp return id_; } + std::size_t arity() const noexcept { + return arity_; + } + template < typename... Args > std::optional invoke(Args&&... args) const { if constexpr ( sizeof...(Args) > 0u ) { @@ -119,9 +123,11 @@ namespace meta_hpp template < typename FunctionType > function_info(std::string id, FunctionType function_ptr) : id_{std::move(id)} + , arity_{detail::function_traits::arity} , invoke_{function_detail::make_invoke(function_ptr)} {} private: std::string id_; + std::size_t arity_; function_detail::function_invoke invoke_; std::map> datas_; }; diff --git a/headers/meta.hpp/meta_fwd.hpp b/headers/meta.hpp/meta_fwd.hpp index 4f98e7f..19b7c34 100644 --- a/headers/meta.hpp/meta_fwd.hpp +++ b/headers/meta.hpp/meta_fwd.hpp @@ -105,17 +105,10 @@ namespace meta_hpp namespace meta_hpp::detail { - template < typename TArg, TArg Arg > - struct auto_arg_t { - }; - template < typename Arg > struct typename_arg_t { }; - template < typename TArg, TArg Arg > - inline auto_arg_t auto_arg; - template < typename Arg > inline typename_arg_t typename_arg; } diff --git a/headers/meta.hpp/meta_method_info.hpp b/headers/meta.hpp/meta_method_info.hpp index d5ea0d2..2decffd 100644 --- a/headers/meta.hpp/meta_method_info.hpp +++ b/headers/meta.hpp/meta_method_info.hpp @@ -149,6 +149,10 @@ namespace meta_hpp return id_; } + std::size_t arity() const noexcept { + return arity_; + } + template < typename T, typename... Args > std::optional invoke(T& inst, Args&&... args) const { if constexpr ( sizeof...(Args) > 0u ) { @@ -198,10 +202,12 @@ namespace meta_hpp template < typename MethodType > method_info(std::string id, MethodType method_ptr) : id_{std::move(id)} + , arity_{detail::method_traits::arity} , invoke_{method_detail::make_invoke(method_ptr)} , cinvoke_{method_detail::make_cinvoke(method_ptr)} {} private: std::string id_; + std::size_t arity_; method_detail::method_invoke invoke_; method_detail::method_cinvoke cinvoke_; std::map> datas_; diff --git a/untests/meta_function_tests.cpp b/untests/meta_function_tests.cpp index d4b2e46..a29c424 100644 --- a/untests/meta_function_tests.cpp +++ b/untests/meta_function_tests.cpp @@ -37,6 +37,16 @@ TEST_CASE("meta/function") { const meta::function_info& int_f_int_info = int_f_int_function_; const meta::function_info& int_f_int2_info = int_f_int2_function_; + SUBCASE("arity") { + CHECK(void_f_void_info.arity() == 0); + CHECK(void_f_int_info.arity() == 1); + CHECK(void_f_int2_info.arity() == 2); + + CHECK(int_f_void_info.arity() == 0); + CHECK(int_f_int_info.arity() == 1); + CHECK(int_f_int2_info.arity() == 2); + } + SUBCASE("void_return") { CHECK_NOTHROW(void_f_void_info.invoke()); CHECK_THROWS_AS(void_f_void_info.invoke(1), std::logic_error); diff --git a/untests/meta_method_tests.cpp b/untests/meta_method_tests.cpp index 8d233ed..f939d6b 100644 --- a/untests/meta_method_tests.cpp +++ b/untests/meta_method_tests.cpp @@ -50,6 +50,16 @@ TEST_CASE("meta/non_const_method") { const meta::method_info& int_f_int_info = int_f_int_method_; const meta::method_info& int_f_int2_info = int_f_int2_method_; + SUBCASE("arity") { + CHECK(void_f_void_info.arity() == 0); + CHECK(void_f_int_info.arity() == 1); + CHECK(void_f_int2_info.arity() == 2); + + CHECK(int_f_void_info.arity() == 0); + CHECK(int_f_int_info.arity() == 1); + CHECK(int_f_int2_info.arity() == 2); + } + SUBCASE("another_instance") { clazz2 instance; CHECK_THROWS_AS(void_f_void_info.invoke(instance), std::logic_error); From 3336d8cc67d53a269623f76fcfac75a6ce8ff3de Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Wed, 7 Jul 2021 05:55:18 +0700 Subject: [PATCH 051/233] return and argument types for method and function infos --- headers/meta.hpp/meta_function_info.hpp | 44 +++++++++++++++++++++++-- headers/meta.hpp/meta_fwd.hpp | 1 + headers/meta.hpp/meta_method_info.hpp | 44 +++++++++++++++++++++++-- untests/meta_function_tests.cpp | 16 +++++++++ untests/meta_method_tests.cpp | 16 +++++++++ 5 files changed, 115 insertions(+), 6 deletions(-) diff --git a/headers/meta.hpp/meta_function_info.hpp b/headers/meta.hpp/meta_function_info.hpp index 12793b9..93f1213 100644 --- a/headers/meta.hpp/meta_function_info.hpp +++ b/headers/meta.hpp/meta_function_info.hpp @@ -62,6 +62,31 @@ namespace meta_hpp::function_detail using namespace std::placeholders; return std::bind(&raw_invoke, function, _1, _2); } + + template < typename FunctionType > + std::optional make_return_type() { + using ft = detail::function_traits; + using return_type = typename ft::return_type; + + if constexpr ( !std::is_void_v ) { + return get_family_id(); + } else { + return std::nullopt; + } + } + + template < typename FunctionType, std::size_t... Is > + std::vector make_argument_types_impl(std::index_sequence) { + using ft = detail::function_traits; + using argument_types = typename ft::argument_types; + return { get_family_id>()... }; + } + + template < typename FunctionType > + std::vector make_argument_types() { + using ft = detail::function_traits; + return make_argument_types_impl(std::make_index_sequence()); + } } namespace meta_hpp @@ -81,7 +106,18 @@ namespace meta_hpp } std::size_t arity() const noexcept { - return arity_; + return argument_types_.size(); + } + + std::optional return_type() const noexcept { + return return_type_; + } + + std::optional argument_type(std::size_t index) const noexcept { + if ( index < argument_types_.size() ) { + return argument_types_[index]; + } + return std::nullopt; } template < typename... Args > @@ -123,11 +159,13 @@ namespace meta_hpp template < typename FunctionType > function_info(std::string id, FunctionType function_ptr) : id_{std::move(id)} - , arity_{detail::function_traits::arity} + , return_type_{function_detail::make_return_type()} + , argument_types_{function_detail::make_argument_types()} , invoke_{function_detail::make_invoke(function_ptr)} {} private: std::string id_; - std::size_t arity_; + std::optional return_type_; + std::vector argument_types_; function_detail::function_invoke invoke_; std::map> datas_; }; diff --git a/headers/meta.hpp/meta_fwd.hpp b/headers/meta.hpp/meta_fwd.hpp index 19b7c34..4d9f82f 100644 --- a/headers/meta.hpp/meta_fwd.hpp +++ b/headers/meta.hpp/meta_fwd.hpp @@ -22,6 +22,7 @@ #include #include #include +#include #define META_HPP_AUTO_T(V) decltype(V), V diff --git a/headers/meta.hpp/meta_method_info.hpp b/headers/meta.hpp/meta_method_info.hpp index 2decffd..ef7c4c4 100644 --- a/headers/meta.hpp/meta_method_info.hpp +++ b/headers/meta.hpp/meta_method_info.hpp @@ -131,6 +131,31 @@ namespace meta_hpp::method_detail using namespace std::placeholders; return std::bind(&raw_cinvoke, method, _1, _2, _3); } + + template < typename MethodType > + std::optional make_return_type() { + using ft = detail::method_traits; + using return_type = typename ft::return_type; + + if constexpr ( !std::is_void_v ) { + return get_family_id(); + } else { + return std::nullopt; + } + } + + template < typename MethodType, std::size_t... Is > + std::vector make_argument_types_impl(std::index_sequence) { + using ft = detail::method_traits; + using argument_types = typename ft::argument_types; + return { get_family_id>()... }; + } + + template < typename MethodType > + std::vector make_argument_types() { + using ft = detail::method_traits; + return make_argument_types_impl(std::make_index_sequence()); + } } namespace meta_hpp @@ -150,7 +175,18 @@ namespace meta_hpp } std::size_t arity() const noexcept { - return arity_; + return argument_types_.size(); + } + + std::optional return_type() const noexcept { + return return_type_; + } + + std::optional argument_type(std::size_t index) const noexcept { + if ( index < argument_types_.size() ) { + return argument_types_[index]; + } + return std::nullopt; } template < typename T, typename... Args > @@ -202,12 +238,14 @@ namespace meta_hpp template < typename MethodType > method_info(std::string id, MethodType method_ptr) : id_{std::move(id)} - , arity_{detail::method_traits::arity} + , return_type_{method_detail::make_return_type()} + , argument_types_{method_detail::make_argument_types()} , invoke_{method_detail::make_invoke(method_ptr)} , cinvoke_{method_detail::make_cinvoke(method_ptr)} {} private: std::string id_; - std::size_t arity_; + std::optional return_type_; + std::vector argument_types_; method_detail::method_invoke invoke_; method_detail::method_cinvoke cinvoke_; std::map> datas_; diff --git a/untests/meta_function_tests.cpp b/untests/meta_function_tests.cpp index a29c424..9beb9f4 100644 --- a/untests/meta_function_tests.cpp +++ b/untests/meta_function_tests.cpp @@ -47,6 +47,22 @@ TEST_CASE("meta/function") { CHECK(int_f_int2_info.arity() == 2); } + SUBCASE("return_type") { + CHECK_FALSE(void_f_void_info.return_type()); + CHECK(int_f_void_info.return_type() == meta::get_family_id()); + } + + SUBCASE("argument_types") { + CHECK_FALSE(void_f_void_info.argument_type(0u)); + + CHECK(int_f_int_info.argument_type(0u) == meta::get_family_id()); + CHECK_FALSE(int_f_int_info.argument_type(1u)); + + CHECK(int_f_int2_info.argument_type(0u) == meta::get_family_id()); + CHECK(int_f_int2_info.argument_type(1u) == meta::get_family_id()); + CHECK_FALSE(int_f_int2_info.argument_type(2u)); + } + SUBCASE("void_return") { CHECK_NOTHROW(void_f_void_info.invoke()); CHECK_THROWS_AS(void_f_void_info.invoke(1), std::logic_error); diff --git a/untests/meta_method_tests.cpp b/untests/meta_method_tests.cpp index f939d6b..88b3798 100644 --- a/untests/meta_method_tests.cpp +++ b/untests/meta_method_tests.cpp @@ -60,6 +60,22 @@ TEST_CASE("meta/non_const_method") { CHECK(int_f_int2_info.arity() == 2); } + SUBCASE("return_type") { + CHECK_FALSE(void_f_void_info.return_type()); + CHECK(int_f_void_info.return_type() == meta::get_family_id()); + } + + SUBCASE("argument_types") { + CHECK_FALSE(void_f_void_info.argument_type(0u)); + + CHECK(int_f_int_info.argument_type(0u) == meta::get_family_id()); + CHECK_FALSE(int_f_int_info.argument_type(1u)); + + CHECK(int_f_int2_info.argument_type(0u) == meta::get_family_id()); + CHECK(int_f_int2_info.argument_type(1u) == meta::get_family_id()); + CHECK_FALSE(int_f_int2_info.argument_type(2u)); + } + SUBCASE("another_instance") { clazz2 instance; CHECK_THROWS_AS(void_f_void_info.invoke(instance), std::logic_error); From 065b5751e949e7cdc324d6245308e39ab1e26b1d Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Wed, 7 Jul 2021 06:03:19 +0700 Subject: [PATCH 052/233] value type for field and variable infos --- headers/meta.hpp/meta_field_info.hpp | 13 +++++++++++++ headers/meta.hpp/meta_variable_info.hpp | 13 +++++++++++++ untests/meta_field_tests.cpp | 5 +++++ untests/meta_variable_tests.cpp | 10 ++++++++++ 4 files changed, 41 insertions(+) diff --git a/headers/meta.hpp/meta_field_info.hpp b/headers/meta.hpp/meta_field_info.hpp index 08eff3c..9535050 100644 --- a/headers/meta.hpp/meta_field_info.hpp +++ b/headers/meta.hpp/meta_field_info.hpp @@ -74,6 +74,13 @@ namespace meta_hpp::field_detail using namespace std::placeholders; return std::bind(&raw_setter, field, _1, _2); } + + template < typename FieldType > + family_id make_value_type() noexcept { + using ft = detail::field_traits; + using value_type = typename ft::value_type; + return get_family_id(); + } } namespace meta_hpp @@ -92,6 +99,10 @@ namespace meta_hpp return id_; } + family_id value_type() const noexcept { + return value_type_; + } + value get(cinstance instance) const { return getter_(instance); } @@ -130,10 +141,12 @@ namespace meta_hpp template < typename FieldType > field_info(std::string id, FieldType field_ptr) : id_{std::move(id)} + , value_type_{field_detail::make_value_type()} , getter_{field_detail::make_getter(field_ptr)} , setter_{field_detail::make_setter(field_ptr)} {} private: std::string id_; + family_id value_type_; field_detail::field_getter getter_; field_detail::field_setter setter_; std::map> datas_; diff --git a/headers/meta.hpp/meta_variable_info.hpp b/headers/meta.hpp/meta_variable_info.hpp index b1a2506..461e043 100644 --- a/headers/meta.hpp/meta_variable_info.hpp +++ b/headers/meta.hpp/meta_variable_info.hpp @@ -59,6 +59,13 @@ namespace meta_hpp::variable_detail using namespace std::placeholders; return std::bind(&raw_setter, variable, _1); } + + template < typename VariableType > + family_id make_value_type() noexcept { + using vt = detail::variable_traits; + using value_type = typename vt::value_type; + return get_family_id(); + } } namespace meta_hpp @@ -77,6 +84,10 @@ namespace meta_hpp return id_; } + family_id value_type() const noexcept { + return value_type_; + } + value get() const { return getter_(); } @@ -115,10 +126,12 @@ namespace meta_hpp template < typename VariableType > variable_info(std::string id, VariableType variable_ptr) : id_{std::move(id)} + , value_type_{variable_detail::make_value_type()} , getter_{variable_detail::make_getter(variable_ptr)} , setter_{variable_detail::make_setter(variable_ptr)} {} private: std::string id_; + family_id value_type_; variable_detail::variable_getter getter_; variable_detail::variable_setter setter_; std::map> datas_; diff --git a/untests/meta_field_tests.cpp b/untests/meta_field_tests.cpp index 46c854d..4f488ad 100644 --- a/untests/meta_field_tests.cpp +++ b/untests/meta_field_tests.cpp @@ -25,6 +25,11 @@ TEST_CASE("meta/field") { const meta::field_info& field_info = field_; const meta::field_info& cfield_info = cfield_; + { + CHECK(field_info.value_type() == meta::get_family_id()); + CHECK(cfield_info.value_type() == meta::get_family_id()); + } + { clazz instance; diff --git a/untests/meta_variable_tests.cpp b/untests/meta_variable_tests.cpp index 4746856..1ddf254 100644 --- a/untests/meta_variable_tests.cpp +++ b/untests/meta_variable_tests.cpp @@ -32,6 +32,11 @@ TEST_CASE("meta/variable") { const meta::variable_info& variable_info = variable_; const meta::variable_info& cvariable_info = cvariable_; + { + CHECK(variable_info.value_type() == meta::get_family_id()); + CHECK(cvariable_info.value_type() == meta::get_family_id()); + } + { CHECK(variable == 1); CHECK(variable_info.get().cast() == 1); @@ -66,6 +71,11 @@ TEST_CASE("meta/variable") { const meta::variable_info& variable_info = variable_; const meta::variable_info& cvariable_info = cvariable_; + { + CHECK(variable_info.value_type() == meta::get_family_id()); + CHECK(cvariable_info.value_type() == meta::get_family_id()); + } + { CHECK(clazz::variable == 1); CHECK(variable_info.get().cast() == 1); From 028ab8eb2b089636e7c2ca4c11eaad501fab9924 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Wed, 7 Jul 2021 06:12:54 +0700 Subject: [PATCH 053/233] instance type for field and method infos --- headers/meta.hpp/meta_field_info.hpp | 13 +++++++++++++ headers/meta.hpp/meta_method_info.hpp | 25 +++++++++++++++++++------ untests/meta_field_tests.cpp | 3 +++ untests/meta_method_tests.cpp | 26 ++++++++++++++++++++++++++ 4 files changed, 61 insertions(+), 6 deletions(-) diff --git a/headers/meta.hpp/meta_field_info.hpp b/headers/meta.hpp/meta_field_info.hpp index 9535050..634a44f 100644 --- a/headers/meta.hpp/meta_field_info.hpp +++ b/headers/meta.hpp/meta_field_info.hpp @@ -81,6 +81,13 @@ namespace meta_hpp::field_detail using value_type = typename ft::value_type; return get_family_id(); } + + template < typename FieldType > + family_id make_instance_type() noexcept { + using ft = detail::field_traits; + using instance_type = typename ft::instance_type; + return get_family_id(); + } } namespace meta_hpp @@ -103,6 +110,10 @@ namespace meta_hpp return value_type_; } + family_id instance_type() const noexcept { + return instance_type_; + } + value get(cinstance instance) const { return getter_(instance); } @@ -142,11 +153,13 @@ namespace meta_hpp field_info(std::string id, FieldType field_ptr) : id_{std::move(id)} , value_type_{field_detail::make_value_type()} + , instance_type_{field_detail::make_instance_type()} , getter_{field_detail::make_getter(field_ptr)} , setter_{field_detail::make_setter(field_ptr)} {} private: std::string id_; family_id value_type_; + family_id instance_type_; field_detail::field_getter getter_; field_detail::field_setter setter_; std::map> datas_; diff --git a/headers/meta.hpp/meta_method_info.hpp b/headers/meta.hpp/meta_method_info.hpp index ef7c4c4..75bd1d1 100644 --- a/headers/meta.hpp/meta_method_info.hpp +++ b/headers/meta.hpp/meta_method_info.hpp @@ -132,10 +132,17 @@ namespace meta_hpp::method_detail return std::bind(&raw_cinvoke, method, _1, _2, _3); } + template < typename MethodType > + family_id make_instance_type() noexcept { + using mt = detail::method_traits; + using instance_type = typename mt::instance_type; + return get_family_id(); + } + template < typename MethodType > std::optional make_return_type() { - using ft = detail::method_traits; - using return_type = typename ft::return_type; + using mt = detail::method_traits; + using return_type = typename mt::return_type; if constexpr ( !std::is_void_v ) { return get_family_id(); @@ -146,15 +153,15 @@ namespace meta_hpp::method_detail template < typename MethodType, std::size_t... Is > std::vector make_argument_types_impl(std::index_sequence) { - using ft = detail::method_traits; - using argument_types = typename ft::argument_types; + using mt = detail::method_traits; + using argument_types = typename mt::argument_types; return { get_family_id>()... }; } template < typename MethodType > std::vector make_argument_types() { - using ft = detail::method_traits; - return make_argument_types_impl(std::make_index_sequence()); + using mt = detail::method_traits; + return make_argument_types_impl(std::make_index_sequence()); } } @@ -178,6 +185,10 @@ namespace meta_hpp return argument_types_.size(); } + family_id instance_type() const noexcept { + return instance_type_; + } + std::optional return_type() const noexcept { return return_type_; } @@ -238,12 +249,14 @@ namespace meta_hpp template < typename MethodType > method_info(std::string id, MethodType method_ptr) : id_{std::move(id)} + , instance_type_{method_detail::make_instance_type()} , return_type_{method_detail::make_return_type()} , argument_types_{method_detail::make_argument_types()} , invoke_{method_detail::make_invoke(method_ptr)} , cinvoke_{method_detail::make_cinvoke(method_ptr)} {} private: std::string id_; + family_id instance_type_; std::optional return_type_; std::vector argument_types_; method_detail::method_invoke invoke_; diff --git a/untests/meta_field_tests.cpp b/untests/meta_field_tests.cpp index 4f488ad..3efcd57 100644 --- a/untests/meta_field_tests.cpp +++ b/untests/meta_field_tests.cpp @@ -28,6 +28,9 @@ TEST_CASE("meta/field") { { CHECK(field_info.value_type() == meta::get_family_id()); CHECK(cfield_info.value_type() == meta::get_family_id()); + + CHECK(field_info.instance_type() == meta::get_family_id()); + CHECK(cfield_info.instance_type() == meta::get_family_id()); } { diff --git a/untests/meta_method_tests.cpp b/untests/meta_method_tests.cpp index 88b3798..03f57c3 100644 --- a/untests/meta_method_tests.cpp +++ b/untests/meta_method_tests.cpp @@ -60,6 +60,11 @@ TEST_CASE("meta/non_const_method") { CHECK(int_f_int2_info.arity() == 2); } + SUBCASE("instance_type") { + CHECK(void_f_void_info.instance_type() == meta::get_family_id()); + CHECK(int_f_void_info.instance_type() == meta::get_family_id()); + } + SUBCASE("return_type") { CHECK_FALSE(void_f_void_info.return_type()); CHECK(int_f_void_info.return_type() == meta::get_family_id()); @@ -158,6 +163,27 @@ TEST_CASE("meta/const_method") { const meta::method_info& int_f_int_info = int_f_int_method_; const meta::method_info& int_f_int2_info = int_f_int2_method_; + SUBCASE("instance_type") { + CHECK(void_f_void_info.instance_type() == meta::get_family_id()); + CHECK(int_f_void_info.instance_type() == meta::get_family_id()); + } + + SUBCASE("return_type") { + CHECK_FALSE(void_f_void_info.return_type()); + CHECK(int_f_void_info.return_type() == meta::get_family_id()); + } + + SUBCASE("argument_types") { + CHECK_FALSE(void_f_void_info.argument_type(0u)); + + CHECK(int_f_int_info.argument_type(0u) == meta::get_family_id()); + CHECK_FALSE(int_f_int_info.argument_type(1u)); + + CHECK(int_f_int2_info.argument_type(0u) == meta::get_family_id()); + CHECK(int_f_int2_info.argument_type(1u) == meta::get_family_id()); + CHECK_FALSE(int_f_int2_info.argument_type(2u)); + } + SUBCASE("another_instance") { const clazz2 instance; CHECK_THROWS_AS(void_f_void_info.invoke(instance), std::logic_error); From 5da043763eec5b0669e6330de5d649d049a83e85 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Wed, 7 Jul 2021 06:28:08 +0700 Subject: [PATCH 054/233] fix const reference argument and return types --- headers/meta.hpp/meta_fwd.hpp | 4 ++-- untests/meta_function_tests.cpp | 8 ++++---- untests/meta_method_tests.cpp | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/headers/meta.hpp/meta_fwd.hpp b/headers/meta.hpp/meta_fwd.hpp index 4d9f82f..87b9c64 100644 --- a/headers/meta.hpp/meta_fwd.hpp +++ b/headers/meta.hpp/meta_fwd.hpp @@ -169,8 +169,8 @@ namespace meta_hpp::detail struct function_traits { static constexpr bool is_noexcept = false; static constexpr std::size_t arity = sizeof...(Args); - using return_type = R; - using argument_types = std::tuple; + using return_type = std::decay_t; + using argument_types = std::tuple...>; }; template < typename R, typename... Args > diff --git a/untests/meta_function_tests.cpp b/untests/meta_function_tests.cpp index 9beb9f4..c26a3ff 100644 --- a/untests/meta_function_tests.cpp +++ b/untests/meta_function_tests.cpp @@ -11,11 +11,11 @@ namespace { void void_f_void() noexcept {} void void_f_int(int a) { (void)a; } - void void_f_int2(int a, int b) { (void)a; (void)b; } + void void_f_int2(const int& a, int b) { (void)a; (void)b; } - int int_f_void() noexcept { return 1; } - int int_f_int(int a) { return a; } - int int_f_int2(int a, int b) { return a + b; } + const int& int_f_void() noexcept { static int i = 1; return i; } + int int_f_int(const int a) { return a; } + int int_f_int2(int a, const int& b) { return a + b; } } TEST_CASE("meta/function") { diff --git a/untests/meta_method_tests.cpp b/untests/meta_method_tests.cpp index 03f57c3..af89930 100644 --- a/untests/meta_method_tests.cpp +++ b/untests/meta_method_tests.cpp @@ -13,11 +13,11 @@ namespace public: void void_f_void() noexcept {} void void_f_int(int a) { (void)a; } - void void_f_int2(int a, int b) { (void)a; (void)b; } + void void_f_int2(const int& a, int b) { (void)a; (void)b; } - int int_f_void() noexcept { return 1; } - int int_f_int(int a) { return a; } - int int_f_int2(int a, int b) { return a + b; } + const int& int_f_void() noexcept { static int i = 1; return i; } + int int_f_int(const int a) { return a; } + int int_f_int2(int a, const int& b) { return a + b; } void const_void_f_void() const noexcept {} void const_void_f_int(int a) const { (void)a; } From 06e5f2508b9453094002cfe858f3658243223931 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Thu, 8 Jul 2021 00:32:24 +0700 Subject: [PATCH 055/233] fix family id safety --- headers/meta.hpp/meta_fwd.hpp | 51 ++++++++++++++---------------- headers/meta.hpp/meta_instance.hpp | 4 +-- 2 files changed, 25 insertions(+), 30 deletions(-) diff --git a/headers/meta.hpp/meta_fwd.hpp b/headers/meta.hpp/meta_fwd.hpp index 87b9c64..e23d02e 100644 --- a/headers/meta.hpp/meta_fwd.hpp +++ b/headers/meta.hpp/meta_fwd.hpp @@ -24,8 +24,6 @@ #include #include -#define META_HPP_AUTO_T(V) decltype(V), V - namespace meta_hpp { template < typename... Ts > @@ -39,45 +37,42 @@ namespace meta_hpp namespace meta_hpp { - struct family_id { - using underlying_type = std::size_t; - underlying_type id{}; + class family_id { + public: + family_id(const family_id&) = default; + family_id& operator=(const family_id&) = default; friend bool operator<(family_id l, family_id r) noexcept { - return l.id < r.id; + return l.id_ < r.id_; } friend bool operator==(family_id l, family_id r) noexcept { - return l.id == r.id; + return l.id_ == r.id_; } friend bool operator!=(family_id l, family_id r) noexcept { - return l.id != r.id; + return l.id_ != r.id_; + } + private: + using underlying_type = std::size_t; + underlying_type id_{}; + private: + template < typename T > + friend family_id get_family_id() noexcept; + + family_id() noexcept + : id_{next()} {} + + static underlying_type next() noexcept { + static std::atomic id{}; + return ++id; } }; - namespace family_id_detail - { - struct family_id_sequence { - static family_id next() noexcept { - static std::atomic id{}; - return { ++id }; - } - }; - - template < typename T > - struct type_to_family_id { - static family_id id() noexcept { - static const family_id type_family_id = family_id_sequence::next(); - assert(type_family_id.id > 0u && "family_id overflow"); - return type_family_id; - } - }; - } - template < typename T > family_id get_family_id() noexcept { - return family_id_detail::type_to_family_id::id(); + static const family_id id = family_id{}; + return id; } } diff --git a/headers/meta.hpp/meta_instance.hpp b/headers/meta.hpp/meta_instance.hpp index 94b48b3..cd8e5b2 100644 --- a/headers/meta.hpp/meta_instance.hpp +++ b/headers/meta.hpp/meta_instance.hpp @@ -71,7 +71,7 @@ namespace meta_hpp } private: void* data_{}; - family_id fid_{}; + family_id fid_; }; } @@ -121,6 +121,6 @@ namespace meta_hpp } private: const void* data_{}; - family_id fid_{}; + family_id fid_; }; } From 6b185028b1b9035f4e54f87f034125ac7040ff77 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Thu, 8 Jul 2021 00:54:46 +0700 Subject: [PATCH 056/233] return family id to infos --- headers/meta.hpp/meta_class_info.hpp | 16 ++-- headers/meta.hpp/meta_field_info.hpp | 8 +- headers/meta.hpp/meta_function_info.hpp | 8 +- headers/meta.hpp/meta_method_info.hpp | 8 +- headers/meta.hpp/meta_registry.hpp | 2 +- headers/meta.hpp/meta_variable_info.hpp | 8 +- untests/meta_family_tests.cpp | 111 +++++++++++++++++++++++- untests/meta_registry_tests.cpp | 22 ++--- 8 files changed, 158 insertions(+), 25 deletions(-) diff --git a/headers/meta.hpp/meta_class_info.hpp b/headers/meta.hpp/meta_class_info.hpp index 488346d..74a63ee 100644 --- a/headers/meta.hpp/meta_class_info.hpp +++ b/headers/meta.hpp/meta_class_info.hpp @@ -27,14 +27,14 @@ namespace meta_hpp class_info& operator=(class_info&&) = default; class_info& operator=(const class_info&) = default; public: - const family_id& fid() const noexcept { - return fid_; - } - const std::string& id() const noexcept { return id_; } + family_id family() const noexcept { + return family_; + } + template < typename F > void each_class(F&& f) const { for ( auto&& id_info : classes_ ) { @@ -112,7 +112,7 @@ namespace meta_hpp } void merge(const class_info& other) { - if ( fid() != other.fid() ) { + if ( id() != other.id() || family() != other.family() ) { throw std::logic_error("class_info::merge failed"); } detail::merge_with(classes_, other.classes_, &class_info::merge); @@ -128,11 +128,11 @@ namespace meta_hpp template < typename Class > class_info(detail::typename_arg_t, std::string id) - : fid_{get_family_id()} - , id_{std::move(id)} {} + : id_{std::move(id)} + , family_{get_family_id()} {} private: - family_id fid_; std::string id_; + family_id family_; std::map> classes_; std::map> datas_; std::map> fields_; diff --git a/headers/meta.hpp/meta_field_info.hpp b/headers/meta.hpp/meta_field_info.hpp index 634a44f..a69ba00 100644 --- a/headers/meta.hpp/meta_field_info.hpp +++ b/headers/meta.hpp/meta_field_info.hpp @@ -106,6 +106,10 @@ namespace meta_hpp return id_; } + family_id family() const noexcept { + return family_; + } + family_id value_type() const noexcept { return value_type_; } @@ -140,7 +144,7 @@ namespace meta_hpp } void merge(const field_info& other) { - if ( id() != other.id() ) { + if ( id() != other.id() || family() != other.family() ) { throw std::logic_error("field_info::merge failed"); } detail::merge_with(datas_, other.datas_, &data_info::merge); @@ -152,12 +156,14 @@ namespace meta_hpp template < typename FieldType > field_info(std::string id, FieldType field_ptr) : id_{std::move(id)} + , family_{get_family_id()} , value_type_{field_detail::make_value_type()} , instance_type_{field_detail::make_instance_type()} , getter_{field_detail::make_getter(field_ptr)} , setter_{field_detail::make_setter(field_ptr)} {} private: std::string id_; + family_id family_; family_id value_type_; family_id instance_type_; field_detail::field_getter getter_; diff --git a/headers/meta.hpp/meta_function_info.hpp b/headers/meta.hpp/meta_function_info.hpp index 93f1213..30c10f9 100644 --- a/headers/meta.hpp/meta_function_info.hpp +++ b/headers/meta.hpp/meta_function_info.hpp @@ -105,6 +105,10 @@ namespace meta_hpp return id_; } + family_id family() const noexcept { + return family_; + } + std::size_t arity() const noexcept { return argument_types_.size(); } @@ -147,7 +151,7 @@ namespace meta_hpp } void merge(const function_info& other) { - if ( id() != other.id() ) { + if ( id() != other.id() || family() != other.family() ) { throw std::logic_error("function_info::merge failed"); } detail::merge_with(datas_, other.datas_, &data_info::merge); @@ -159,11 +163,13 @@ namespace meta_hpp template < typename FunctionType > function_info(std::string id, FunctionType function_ptr) : id_{std::move(id)} + , family_{get_family_id()} , return_type_{function_detail::make_return_type()} , argument_types_{function_detail::make_argument_types()} , invoke_{function_detail::make_invoke(function_ptr)} {} private: std::string id_; + family_id family_; std::optional return_type_; std::vector argument_types_; function_detail::function_invoke invoke_; diff --git a/headers/meta.hpp/meta_method_info.hpp b/headers/meta.hpp/meta_method_info.hpp index 75bd1d1..8c5167e 100644 --- a/headers/meta.hpp/meta_method_info.hpp +++ b/headers/meta.hpp/meta_method_info.hpp @@ -181,6 +181,10 @@ namespace meta_hpp return id_; } + family_id family() const noexcept { + return family_; + } + std::size_t arity() const noexcept { return argument_types_.size(); } @@ -237,7 +241,7 @@ namespace meta_hpp } void merge(const method_info& other) { - if ( id() != other.id() ) { + if ( id() != other.id() || family() != other.family() ) { throw std::logic_error("method_info::merge failed"); } detail::merge_with(datas_, other.datas_, &data_info::merge); @@ -249,6 +253,7 @@ namespace meta_hpp template < typename MethodType > method_info(std::string id, MethodType method_ptr) : id_{std::move(id)} + , family_{get_family_id()} , instance_type_{method_detail::make_instance_type()} , return_type_{method_detail::make_return_type()} , argument_types_{method_detail::make_argument_types()} @@ -256,6 +261,7 @@ namespace meta_hpp , cinvoke_{method_detail::make_cinvoke(method_ptr)} {} private: std::string id_; + family_id family_; family_id instance_type_; std::optional return_type_; std::vector argument_types_; diff --git a/headers/meta.hpp/meta_registry.hpp b/headers/meta.hpp/meta_registry.hpp index d37dd13..c371aec 100644 --- a/headers/meta.hpp/meta_registry.hpp +++ b/headers/meta.hpp/meta_registry.hpp @@ -127,7 +127,7 @@ namespace meta_hpp ? info.id() : prefix + "::" + info.id(); - detail::merge_with(types_, info.fid(), info, &class_info::merge); + detail::merge_with(types_, info.family(), info, &class_info::merge); detail::merge_with(classes_, name, info, &class_info::merge); info.visit(overloaded { diff --git a/headers/meta.hpp/meta_variable_info.hpp b/headers/meta.hpp/meta_variable_info.hpp index 461e043..01f25f6 100644 --- a/headers/meta.hpp/meta_variable_info.hpp +++ b/headers/meta.hpp/meta_variable_info.hpp @@ -84,6 +84,10 @@ namespace meta_hpp return id_; } + family_id family() const noexcept { + return family_; + } + family_id value_type() const noexcept { return value_type_; } @@ -114,7 +118,7 @@ namespace meta_hpp } void merge(const variable_info& other) { - if ( id() != other.id() ) { + if ( id() != other.id() || family() != other.family() ) { throw std::logic_error("variable_info::merge failed"); } detail::merge_with(datas_, other.datas_, &data_info::merge); @@ -126,11 +130,13 @@ namespace meta_hpp template < typename VariableType > variable_info(std::string id, VariableType variable_ptr) : id_{std::move(id)} + , family_{get_family_id()} , value_type_{variable_detail::make_value_type()} , getter_{variable_detail::make_getter(variable_ptr)} , setter_{variable_detail::make_setter(variable_ptr)} {} private: std::string id_; + family_id family_; family_id value_type_; variable_detail::variable_getter getter_; variable_detail::variable_setter setter_; diff --git a/untests/meta_family_tests.cpp b/untests/meta_family_tests.cpp index 48222d9..bc27408 100644 --- a/untests/meta_family_tests.cpp +++ b/untests/meta_family_tests.cpp @@ -17,13 +17,67 @@ namespace struct ivec2 { int x{}; int y{}; + + static ivec2 zero; + static ivec2 unit; + + ivec2& add(const ivec2 other) { + x += other.x; + y += other.y; + return *this; + } + + ivec2& sub(const ivec2 other) { + x -= other.x; + y -= other.y; + return *this; + } }; struct ivec3 { int x{}; int y{}; int z{}; + + static ivec3 zero; + static ivec3 unit; + + ivec3& add(const ivec3 other) { + x += other.x; + y += other.y; + z += other.z; + return *this; + } + + ivec3& sub(const ivec3 other) { + x -= other.x; + y -= other.y; + z -= other.z; + return *this; + } }; + + ivec2 ivec2::zero{0, 0}; + ivec2 ivec2::unit{1, 1}; + + ivec3 ivec3::zero{0, 0, 0}; + ivec3 ivec3::unit{1, 1, 1}; + + ivec2 iadd2(ivec2 l, ivec2 r) { + return {l.x + r.x, l.y + r.y}; + } + + ivec2 isub2(ivec2 l, ivec2 r) { + return {l.x - r.x, l.y - r.y}; + } + + ivec3 iadd3(ivec3 l, ivec3 r) { + return {l.x + r.x, l.y + r.y, l.z + r.z}; + } + + ivec3 isub3(ivec3 l, ivec3 r) { + return {l.x - r.x, l.y - r.y, l.z - r.z}; + } } TEST_CASE("meta/family") { @@ -33,6 +87,61 @@ TEST_CASE("meta/family") { SUBCASE("class") { meta::class_info ivec2_info = meta::class_("ivec2"); meta::class_info ivec3_info = meta::class_("ivec3"); - CHECK_FALSE(ivec2_info.fid() == ivec3_info.fid()); + CHECK(ivec2_info.family() != ivec3_info.family()); + } + + SUBCASE("field") { + meta::field_info ivec2_x_info = meta::field_("x", &ivec2::x); + meta::field_info ivec2_y_info = meta::field_("y", &ivec2::y); + + meta::field_info ivec3_x_info = meta::field_("x", &ivec3::x); + meta::field_info ivec3_y_info = meta::field_("y", &ivec3::y); + + CHECK(ivec2_x_info.family() == ivec2_y_info.family()); + + CHECK(ivec2_x_info.family() != ivec3_x_info.family()); + CHECK(ivec2_x_info.family() != ivec3_y_info.family()); + } + + SUBCASE("function") { + meta::function_info iadd2_info = meta::function_("iadd2", &iadd2); + meta::function_info isub2_info = meta::function_("isub2", &isub2); + + meta::function_info iadd3_info = meta::function_("iadd3", &iadd3); + meta::function_info isub3_info = meta::function_("isub3", &isub3); + + CHECK(iadd2_info.family() == isub2_info.family()); + CHECK(iadd3_info.family() == isub3_info.family()); + + CHECK(iadd2_info.family() != iadd3_info.family()); + CHECK(iadd2_info.family() != isub3_info.family()); + } + + SUBCASE("method") { + meta::method_info add2_info = meta::method_("add", &ivec2::add); + meta::method_info sub2_info = meta::method_("sub", &ivec2::sub); + + meta::method_info add3_info = meta::method_("add", &ivec3::add); + meta::method_info sub3_info = meta::method_("sub", &ivec3::sub); + + CHECK(add2_info.family() == sub2_info.family()); + CHECK(add3_info.family() == sub3_info.family()); + + CHECK(add2_info.family() != add3_info.family()); + CHECK(add2_info.family() != sub3_info.family()); + } + + SUBCASE("variable") { + meta::variable_info zero2_info = meta::variable_("zero", &ivec2::zero); + meta::variable_info unit2_info = meta::variable_("unit", &ivec2::unit); + + meta::variable_info zero3_info = meta::variable_("zero", &ivec3::zero); + meta::variable_info unit3_info = meta::variable_("unit", &ivec3::unit); + + CHECK(zero2_info.family() == unit2_info.family()); + CHECK(zero3_info.family() == unit3_info.family()); + + CHECK(zero2_info.family() != zero3_info.family()); + CHECK(zero2_info.family() != unit3_info.family()); } } diff --git a/untests/meta_registry_tests.cpp b/untests/meta_registry_tests.cpp index eaf3b77..a4990e5 100644 --- a/untests/meta_registry_tests.cpp +++ b/untests/meta_registry_tests.cpp @@ -105,24 +105,24 @@ TEST_CASE("meta/registry") { const meta::class_info v2_info = meta::class_("ivec2"); const meta::class_info v3_info = meta::class_("ivec3"); - CHECK(v2_info.fid() != v3_info.fid()); + CHECK(v2_info.family() != v3_info.family()); - CHECK(v2_info.fid() == registry.resolve()->fid()); - CHECK(v2_info.fid() == registry.resolve(v2)->fid()); - CHECK(v2_info.fid() == registry.resolve(std::as_const(v2))->fid()); - CHECK(v2_info.fid() == registry.resolve(static_cast(v2))->fid()); + CHECK(v2_info.family() == registry.resolve()->family()); + CHECK(v2_info.family() == registry.resolve(v2)->family()); + CHECK(v2_info.family() == registry.resolve(std::as_const(v2))->family()); + CHECK(v2_info.family() == registry.resolve(static_cast(v2))->family()); - CHECK(v3_info.fid() == registry.resolve()->fid()); - CHECK(v3_info.fid() == registry.resolve(v3)->fid()); - CHECK(v3_info.fid() == registry.resolve(std::as_const(v3))->fid()); - CHECK(v3_info.fid() == registry.resolve(static_cast(v3))->fid()); + CHECK(v3_info.family() == registry.resolve()->family()); + CHECK(v3_info.family() == registry.resolve(v3)->family()); + CHECK(v3_info.family() == registry.resolve(std::as_const(v3))->family()); + CHECK(v3_info.family() == registry.resolve(static_cast(v3))->family()); { REQUIRE(registry.get_class_by_name("vmath::ivec2")); REQUIRE(registry.get_class_by_name("vmath::ivec3")); - CHECK(v2_info.fid() == registry.get_class_by_name("vmath::ivec2")->fid()); - CHECK(v3_info.fid() == registry.get_class_by_name("vmath::ivec3")->fid()); + CHECK(v2_info.family() == registry.get_class_by_name("vmath::ivec2")->family()); + CHECK(v3_info.family() == registry.get_class_by_name("vmath::ivec3")->family()); } } From cdb3d0de54d73468b1b1fd492114f3e9c39eaa4f Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Mon, 12 Jul 2021 23:05:18 +0700 Subject: [PATCH 057/233] explicit make_info function --- headers/meta.hpp/meta_class.hpp | 25 ++++-- headers/meta.hpp/meta_data.hpp | 5 +- headers/meta.hpp/meta_field.hpp | 5 +- headers/meta.hpp/meta_function.hpp | 5 +- headers/meta.hpp/meta_method.hpp | 5 +- headers/meta.hpp/meta_namespace.hpp | 20 +++-- headers/meta.hpp/meta_registry.hpp | 19 +++++ headers/meta.hpp/meta_variable.hpp | 5 +- untests/meta_class_tests.cpp | 120 +++++++++++++++------------- untests/meta_data_tests.cpp | 51 +++++++----- untests/meta_examples.cpp | 2 +- untests/meta_family_tests.cpp | 36 ++++----- untests/meta_field_tests.cpp | 4 +- untests/meta_function_tests.cpp | 12 +-- untests/meta_method_tests.cpp | 24 +++--- untests/meta_namespace_tests.cpp | 69 +++++++++------- untests/meta_registry_tests.cpp | 4 +- untests/meta_type_tests.cpp | 16 ++-- untests/meta_variable_tests.cpp | 8 +- 19 files changed, 252 insertions(+), 183 deletions(-) diff --git a/headers/meta.hpp/meta_class.hpp b/headers/meta.hpp/meta_class.hpp index 31a510a..2912fb1 100644 --- a/headers/meta.hpp/meta_class.hpp +++ b/headers/meta.hpp/meta_class.hpp @@ -24,7 +24,7 @@ namespace meta_hpp explicit class_(std::string id) : info_{detail::typename_arg, std::move(id)} {} - operator const class_info&() const noexcept { + const class_info& make_info() const { return info_; } @@ -34,27 +34,38 @@ namespace meta_hpp return *this; } private: - void add_(const class_info& info) { + template < typename InternalClass > + void add_(class_ internal) { + class_info info = std::move(internal).make_info(); detail::merge_with(info_.classes_, info.id(), info, &class_info::merge); } - void add_(const data_info& info) { + void add_(data_ internal) { + data_info info = std::move(internal).make_info(); detail::merge_with(info_.datas_, info.id(), info, &data_info::merge); } - void add_(const field_info& info) { + template < typename FieldType > + void add_(field_ internal) { + field_info info = std::move(internal).make_info(); detail::merge_with(info_.fields_, info.id(), info, &field_info::merge); } - void add_(const function_info& info) { + template < typename FunctionType > + void add_(function_ internal) { + function_info info = std::move(internal).make_info(); detail::merge_with(info_.functions_, info.id(), info, &function_info::merge); } - void add_(const method_info& info) { + template < typename MethodType > + void add_(method_ internal) { + method_info info = std::move(internal).make_info(); detail::merge_with(info_.methods_, info.id(), info, &method_info::merge); } - void add_(const variable_info& info) { + template < typename VariableType > + void add_(variable_ internal) { + variable_info info = std::move(internal).make_info(); detail::merge_with(info_.variables_, info.id(), info, &variable_info::merge); } private: diff --git a/headers/meta.hpp/meta_data.hpp b/headers/meta.hpp/meta_data.hpp index f68a9b3..3ce39f8 100644 --- a/headers/meta.hpp/meta_data.hpp +++ b/headers/meta.hpp/meta_data.hpp @@ -17,7 +17,7 @@ namespace meta_hpp explicit data_(std::string id, value value) : info_{std::move(id), std::move(value)} {} - operator const data_info&() const noexcept { + const data_info& make_info() const { return info_; } @@ -27,7 +27,8 @@ namespace meta_hpp return *this; } private: - void add_(const data_info& info) { + void add_(data_ internal) { + data_info info = std::move(internal).make_info(); detail::merge_with(info_.datas_, info.id(), info, &data_info::merge); } private: diff --git a/headers/meta.hpp/meta_field.hpp b/headers/meta.hpp/meta_field.hpp index ceb758e..0b5481b 100644 --- a/headers/meta.hpp/meta_field.hpp +++ b/headers/meta.hpp/meta_field.hpp @@ -22,7 +22,7 @@ namespace meta_hpp explicit field_(std::string id, FieldType field_ptr) : info_{std::move(id), field_ptr} {} - operator const field_info&() const noexcept { + const field_info& make_info() const { return info_; } @@ -32,7 +32,8 @@ namespace meta_hpp return *this; } private: - void add_(const data_info& info) { + void add_(data_ internal) { + data_info info = std::move(internal).make_info(); detail::merge_with(info_.datas_, info.id(), info, &data_info::merge); } private: diff --git a/headers/meta.hpp/meta_function.hpp b/headers/meta.hpp/meta_function.hpp index 6fb5d41..c1ab125 100644 --- a/headers/meta.hpp/meta_function.hpp +++ b/headers/meta.hpp/meta_function.hpp @@ -22,7 +22,7 @@ namespace meta_hpp explicit function_(std::string id, FunctionType function_ptr) : info_{std::move(id), function_ptr} {} - operator const function_info&() const noexcept { + const function_info& make_info() const { return info_; } @@ -32,7 +32,8 @@ namespace meta_hpp return *this; } private: - void add_(const data_info& info) { + void add_(data_ internal) { + data_info info = std::move(internal).make_info(); detail::merge_with(info_.datas_, info.id(), info, &data_info::merge); } private: diff --git a/headers/meta.hpp/meta_method.hpp b/headers/meta.hpp/meta_method.hpp index a89393d..f01a5bc 100644 --- a/headers/meta.hpp/meta_method.hpp +++ b/headers/meta.hpp/meta_method.hpp @@ -22,7 +22,7 @@ namespace meta_hpp explicit method_(std::string id, MethodType method_ptr) : info_{std::move(id), method_ptr} {} - operator const method_info&() const { + const method_info& make_info() const { return info_; } @@ -32,7 +32,8 @@ namespace meta_hpp return *this; } private: - void add_(const data_info& info) { + void add_(data_ internal) { + data_info info = std::move(internal).make_info(); detail::merge_with(info_.datas_, info.id(), info, &data_info::merge); } private: diff --git a/headers/meta.hpp/meta_namespace.hpp b/headers/meta.hpp/meta_namespace.hpp index 9a05806..6fe4ce2 100644 --- a/headers/meta.hpp/meta_namespace.hpp +++ b/headers/meta.hpp/meta_namespace.hpp @@ -22,7 +22,7 @@ namespace meta_hpp explicit namespace_(std::string id) : info_{std::move(id)} {} - operator const namespace_info&() const noexcept { + const namespace_info& make_info() const { return info_; } @@ -32,23 +32,31 @@ namespace meta_hpp return *this; } private: - void add_(const class_info& info) { + template < typename InternalClass > + void add_(class_ internal) { + class_info info = std::move(internal).make_info(); detail::merge_with(info_.classes_, info.id(), info, &class_info::merge); } - void add_(const data_info& info) { + void add_(data_ internal) { + data_info info = std::move(internal).make_info(); detail::merge_with(info_.datas_, info.id(), info, &data_info::merge); } - void add_(const function_info& info) { + template < typename FunctionType > + void add_(function_ internal) { + function_info info = std::move(internal).make_info(); detail::merge_with(info_.functions_, info.id(), info, &function_info::merge); } - void add_(const namespace_info& info) { + void add_(namespace_ internal) { + namespace_info info = std::move(internal).make_info(); detail::merge_with(info_.namespaces_, info.id(), info, &namespace_info::merge); } - void add_(const variable_info& info) { + template < typename VariableType > + void add_(variable_ internal) { + variable_info info = std::move(internal).make_info(); detail::merge_with(info_.variables_, info.id(), info, &variable_info::merge); } private: diff --git a/headers/meta.hpp/meta_registry.hpp b/headers/meta.hpp/meta_registry.hpp index c371aec..5b9f41b 100644 --- a/headers/meta.hpp/meta_registry.hpp +++ b/headers/meta.hpp/meta_registry.hpp @@ -121,6 +121,25 @@ namespace meta_hpp (add_(std::string{}, std::forward(internals)), ...); return *this; } + private: + template < typename InternalClass > + void add_(const std::string& prefix, class_ internal) { + add_(prefix, std::move(internal).make_info()); + } + + template < typename FunctionType > + void add_(const std::string& prefix, function_ internal) { + add_(prefix, std::move(internal).make_info()); + } + + void add_(const std::string& prefix, namespace_ internal) { + add_(prefix, std::move(internal).make_info()); + } + + template < typename VariableType > + void add_(const std::string& prefix, variable_ internal) { + add_(prefix, std::move(internal).make_info()); + } private: void add_(const std::string& prefix, const class_info& info) { const std::string name = prefix.empty() diff --git a/headers/meta.hpp/meta_variable.hpp b/headers/meta.hpp/meta_variable.hpp index 33059eb..e8a8e49 100644 --- a/headers/meta.hpp/meta_variable.hpp +++ b/headers/meta.hpp/meta_variable.hpp @@ -22,7 +22,7 @@ namespace meta_hpp explicit variable_(std::string id, VariableType variable_ptr) : info_{std::move(id), variable_ptr} {} - operator const variable_info&() const noexcept { + const variable_info& make_info() const { return info_; } @@ -32,7 +32,8 @@ namespace meta_hpp return *this; } private: - void add_(const data_info& info) { + void add_(data_ internal) { + data_info info = std::move(internal).make_info(); detail::merge_with(info_.datas_, info.id(), info, &data_info::merge); } private: diff --git a/untests/meta_class_tests.cpp b/untests/meta_class_tests.cpp index fd61813..109126e 100644 --- a/untests/meta_class_tests.cpp +++ b/untests/meta_class_tests.cpp @@ -48,16 +48,18 @@ TEST_CASE("meta/class") { namespace meta = meta_hpp; meta::class_ class_{"clazz"}; - const meta::class_info& clazz_info = class_; - CHECK_FALSE(clazz_info.get_class("clazz2")); - CHECK_FALSE(clazz_info.get_field("field")); - CHECK_FALSE(clazz_info.get_field("cfield")); - CHECK_FALSE(clazz_info.get_function("func")); - CHECK_FALSE(clazz_info.get_method("method")); - CHECK_FALSE(clazz_info.get_method("cmethod")); - CHECK_FALSE(clazz_info.get_variable("variable")); - CHECK_FALSE(clazz_info.get_variable("cvariable")); + { + const meta::class_info info = class_.make_info(); + CHECK_FALSE(info.get_class("clazz2")); + CHECK_FALSE(info.get_field("field")); + CHECK_FALSE(info.get_field("cfield")); + CHECK_FALSE(info.get_function("func")); + CHECK_FALSE(info.get_method("method")); + CHECK_FALSE(info.get_method("cmethod")); + CHECK_FALSE(info.get_variable("variable")); + CHECK_FALSE(info.get_variable("cvariable")); + } class_( meta::class_("clazz2"), @@ -69,53 +71,56 @@ TEST_CASE("meta/class") { meta::variable_("variable", &clazz::variable), meta::variable_("cvariable", &clazz::cvariable)); - CHECK(clazz_info.get_class("clazz2")); - CHECK(clazz_info.get_field("field")); - CHECK(clazz_info.get_field("cfield")); - CHECK(clazz_info.get_function("func")); - CHECK(clazz_info.get_method("method")); - CHECK(clazz_info.get_method("cmethod")); - CHECK(clazz_info.get_variable("variable")); - CHECK(clazz_info.get_variable("cvariable")); - { - meta::class_info clazz2_info = clazz_info.get_class("clazz2").value(); - CHECK(clazz2_info.id() == "clazz2"); - } + const meta::class_info info = class_.make_info(); + CHECK(info.get_class("clazz2")); + CHECK(info.get_field("field")); + CHECK(info.get_field("cfield")); + CHECK(info.get_function("func")); + CHECK(info.get_method("method")); + CHECK(info.get_method("cmethod")); + CHECK(info.get_variable("variable")); + CHECK(info.get_variable("cvariable")); - { - meta::field_info field_info = clazz_info.get_field("field").value(); - CHECK(field_info.id() == "field"); - } + { + meta::class_info clazz2_info = info.get_class("clazz2").value(); + CHECK(clazz2_info.id() == "clazz2"); + } - { - meta::field_info cfield_info = clazz_info.get_field("cfield").value(); - CHECK(cfield_info.id() == "cfield"); - } + { + meta::field_info field_info = info.get_field("field").value(); + CHECK(field_info.id() == "field"); + } - { - meta::function_info function_info = clazz_info.get_function("func").value(); - CHECK(function_info.id() == "func"); - } + { + meta::field_info cfield_info = info.get_field("cfield").value(); + CHECK(cfield_info.id() == "cfield"); + } - { - meta::method_info method_info = clazz_info.get_method("method").value(); - CHECK(method_info.id() == "method"); - } + { + meta::function_info function_info = info.get_function("func").value(); + CHECK(function_info.id() == "func"); + } - { - meta::method_info cmethod_info = clazz_info.get_method("cmethod").value(); - CHECK(cmethod_info.id() == "cmethod"); - } + { + meta::method_info method_info = info.get_method("method").value(); + CHECK(method_info.id() == "method"); + } - { - meta::variable_info variable_info = clazz_info.get_variable("variable").value(); - CHECK(variable_info.id() == "variable"); - } + { + meta::method_info cmethod_info = info.get_method("cmethod").value(); + CHECK(cmethod_info.id() == "cmethod"); + } - { - meta::variable_info cvariable_info = clazz_info.get_variable("cvariable").value(); - CHECK(cvariable_info.id() == "cvariable"); + { + meta::variable_info variable_info = info.get_variable("variable").value(); + CHECK(variable_info.id() == "variable"); + } + + { + meta::variable_info cvariable_info = info.get_variable("cvariable").value(); + CHECK(cvariable_info.id() == "cvariable"); + } } } @@ -123,7 +128,6 @@ TEST_CASE("meta/class/merge") { namespace meta = meta_hpp; meta::class_ clazz_{"clazz"}; - const meta::class_info& clazz_info = clazz_; SUBCASE("merge") { CHECK_NOTHROW(clazz_( @@ -144,14 +148,18 @@ TEST_CASE("meta/class/merge") { ) ), std::logic_error); - CHECK(clazz_info.get_class("child")); - CHECK(clazz_info.get_class("child")->get_field("field")); - CHECK(clazz_info.get_class("child")->get_field("cfield")); - { - clazz::clazz2 instance{}; - CHECK(clazz_info.get_class("child")->get_field("field")->get(instance).to_int() == 21); - CHECK(clazz_info.get_class("child")->get_field("cfield")->get(instance).to_int() == 22); + const meta::class_info info = clazz_.make_info(); + + CHECK(info.get_class("child")); + CHECK(info.get_class("child")->get_field("field")); + CHECK(info.get_class("child")->get_field("cfield")); + + { + clazz::clazz2 instance{}; + CHECK(info.get_class("child")->get_field("field")->get(instance).to_int() == 21); + CHECK(info.get_class("child")->get_field("cfield")->get(instance).to_int() == 22); + } } } } diff --git a/untests/meta_data_tests.cpp b/untests/meta_data_tests.cpp index b1cb5af..7dd63aa 100644 --- a/untests/meta_data_tests.cpp +++ b/untests/meta_data_tests.cpp @@ -31,10 +31,13 @@ TEST_CASE("meta/data") { using namespace std::string_literals; meta::data_ data_("key"s, "value"s); - const meta::data_info& data_info = data_; - CHECK(data_info.id() == "key"); - CHECK(data_info.get().to_string() == "value"); + { + const meta::data_info info = data_.make_info(); + + CHECK(info.id() == "key"); + CHECK(info.get().to_string() == "value"); + } { data_( @@ -43,11 +46,15 @@ TEST_CASE("meta/data") { ) ); - CHECK(data_info.get_data("key2")); - CHECK(data_info.get_data("key2")->get().to_string() == "value2"); + { + const meta::data_info info = data_.make_info(); - CHECK(data_info.get_data("key2")->get_data("key3")); - CHECK(data_info.get_data("key2")->get_data("key3")->get().to_string() == "value3"); + CHECK(info.get_data("key2")); + CHECK(info.get_data("key2")->get().to_string() == "value2"); + + CHECK(info.get_data("key2")->get_data("key3")); + CHECK(info.get_data("key2")->get_data("key3")->get().to_string() == "value3"); + } } { @@ -57,14 +64,18 @@ TEST_CASE("meta/data") { ) ); - CHECK(data_info.get_data("key2")); - CHECK(data_info.get_data("key2")->get().to_string() == "value2"); + { + const meta::data_info info = data_.make_info(); - CHECK(data_info.get_data("key2")->get_data("key3")); - CHECK(data_info.get_data("key2")->get_data("key3")->get().to_string() == "value3"); + CHECK(info.get_data("key2")); + CHECK(info.get_data("key2")->get().to_string() == "value2"); - CHECK(data_info.get_data("key2")->get_data("key4")); - CHECK(data_info.get_data("key2")->get_data("key4")->get().to_string() == "value4"); + CHECK(info.get_data("key2")->get_data("key3")); + CHECK(info.get_data("key2")->get_data("key3")->get().to_string() == "value3"); + + CHECK(info.get_data("key2")->get_data("key4")); + CHECK(info.get_data("key2")->get_data("key4")->get().to_string() == "value4"); + } } } @@ -74,7 +85,7 @@ TEST_CASE("meta/data/class") { const meta::class_info clazz_info = meta::class_("clazz")( meta::data_("hello"s, "world"s) - ); + ).make_info(); CHECK(clazz_info.get_data("hello")); CHECK(clazz_info.get_data("hello")->get().to_string() == "world"); @@ -88,7 +99,7 @@ TEST_CASE("meta/data/data") { meta::data_("hello"s, "world"s)( meta::data_("hello2"s, "world2"s) ) - ); + ).make_info(); CHECK(clazz_info.get_data("hello")); CHECK(clazz_info.get_data("hello")->get_data("hello2")); @@ -103,7 +114,7 @@ TEST_CASE("meta/data/field") { meta::field_("field", &clazz::field)( meta::data_("hello"s, "world"s) ) - ); + ).make_info(); CHECK(clazz_info.get_field("field")); CHECK(clazz_info.get_field("field")->get_data("hello")); @@ -118,7 +129,7 @@ TEST_CASE("meta/data/function") { meta::function_("function", &clazz::function)( meta::data_("hello"s, "world"s) ) - ); + ).make_info(); CHECK(clazz_info.get_function("function")); CHECK(clazz_info.get_function("function")->get_data("hello")); @@ -133,7 +144,7 @@ TEST_CASE("meta/data/method") { meta::method_("method", &clazz::method)( meta::data_("hello"s, "world"s) ) - ); + ).make_info(); CHECK(clazz_info.get_method("method")); CHECK(clazz_info.get_method("method")->get_data("hello")); @@ -146,7 +157,7 @@ TEST_CASE("meta/data/namespace") { const meta::namespace_info ns_info = meta::namespace_("ns")( meta::data_("hello"s, "world"s) - ); + ).make_info(); CHECK(ns_info.get_data("hello")); CHECK(ns_info.get_data("hello")->get().to_string() == "world"); @@ -160,7 +171,7 @@ TEST_CASE("meta/data/variable") { meta::variable_("variable", &clazz::variable)( meta::data_("hello"s, "world"s) ) - ); + ).make_info(); CHECK(clazz_info.get_variable("variable")); CHECK(clazz_info.get_variable("variable")->get_data("hello")); diff --git a/untests/meta_examples.cpp b/untests/meta_examples.cpp index e7af521..0aa3a4a 100644 --- a/untests/meta_examples.cpp +++ b/untests/meta_examples.cpp @@ -113,7 +113,7 @@ TEST_CASE("meta/examples/simple") { ), function_("iadd2", select(&add)), function_("iadd3", select(&add)) - ); + ).make_info(); class_info ivec2_info = vmath_info.get_class("ivec2").value(); diff --git a/untests/meta_family_tests.cpp b/untests/meta_family_tests.cpp index bc27408..f491e12 100644 --- a/untests/meta_family_tests.cpp +++ b/untests/meta_family_tests.cpp @@ -85,17 +85,17 @@ TEST_CASE("meta/family") { using namespace std::string_literals; SUBCASE("class") { - meta::class_info ivec2_info = meta::class_("ivec2"); - meta::class_info ivec3_info = meta::class_("ivec3"); + meta::class_info ivec2_info = meta::class_("ivec2").make_info(); + meta::class_info ivec3_info = meta::class_("ivec3").make_info(); CHECK(ivec2_info.family() != ivec3_info.family()); } SUBCASE("field") { - meta::field_info ivec2_x_info = meta::field_("x", &ivec2::x); - meta::field_info ivec2_y_info = meta::field_("y", &ivec2::y); + meta::field_info ivec2_x_info = meta::field_("x", &ivec2::x).make_info(); + meta::field_info ivec2_y_info = meta::field_("y", &ivec2::y).make_info(); - meta::field_info ivec3_x_info = meta::field_("x", &ivec3::x); - meta::field_info ivec3_y_info = meta::field_("y", &ivec3::y); + meta::field_info ivec3_x_info = meta::field_("x", &ivec3::x).make_info(); + meta::field_info ivec3_y_info = meta::field_("y", &ivec3::y).make_info(); CHECK(ivec2_x_info.family() == ivec2_y_info.family()); @@ -104,11 +104,11 @@ TEST_CASE("meta/family") { } SUBCASE("function") { - meta::function_info iadd2_info = meta::function_("iadd2", &iadd2); - meta::function_info isub2_info = meta::function_("isub2", &isub2); + meta::function_info iadd2_info = meta::function_("iadd2", &iadd2).make_info(); + meta::function_info isub2_info = meta::function_("isub2", &isub2).make_info(); - meta::function_info iadd3_info = meta::function_("iadd3", &iadd3); - meta::function_info isub3_info = meta::function_("isub3", &isub3); + meta::function_info iadd3_info = meta::function_("iadd3", &iadd3).make_info(); + meta::function_info isub3_info = meta::function_("isub3", &isub3).make_info(); CHECK(iadd2_info.family() == isub2_info.family()); CHECK(iadd3_info.family() == isub3_info.family()); @@ -118,11 +118,11 @@ TEST_CASE("meta/family") { } SUBCASE("method") { - meta::method_info add2_info = meta::method_("add", &ivec2::add); - meta::method_info sub2_info = meta::method_("sub", &ivec2::sub); + meta::method_info add2_info = meta::method_("add", &ivec2::add).make_info(); + meta::method_info sub2_info = meta::method_("sub", &ivec2::sub).make_info(); - meta::method_info add3_info = meta::method_("add", &ivec3::add); - meta::method_info sub3_info = meta::method_("sub", &ivec3::sub); + meta::method_info add3_info = meta::method_("add", &ivec3::add).make_info(); + meta::method_info sub3_info = meta::method_("sub", &ivec3::sub).make_info(); CHECK(add2_info.family() == sub2_info.family()); CHECK(add3_info.family() == sub3_info.family()); @@ -132,11 +132,11 @@ TEST_CASE("meta/family") { } SUBCASE("variable") { - meta::variable_info zero2_info = meta::variable_("zero", &ivec2::zero); - meta::variable_info unit2_info = meta::variable_("unit", &ivec2::unit); + meta::variable_info zero2_info = meta::variable_("zero", &ivec2::zero).make_info(); + meta::variable_info unit2_info = meta::variable_("unit", &ivec2::unit).make_info(); - meta::variable_info zero3_info = meta::variable_("zero", &ivec3::zero); - meta::variable_info unit3_info = meta::variable_("unit", &ivec3::unit); + meta::variable_info zero3_info = meta::variable_("zero", &ivec3::zero).make_info(); + meta::variable_info unit3_info = meta::variable_("unit", &ivec3::unit).make_info(); CHECK(zero2_info.family() == unit2_info.family()); CHECK(zero3_info.family() == unit3_info.family()); diff --git a/untests/meta_field_tests.cpp b/untests/meta_field_tests.cpp index 3efcd57..759276a 100644 --- a/untests/meta_field_tests.cpp +++ b/untests/meta_field_tests.cpp @@ -22,8 +22,8 @@ TEST_CASE("meta/field") { meta::field_ field_{"field", &clazz::field}; meta::field_ cfield_{"cfield", &clazz::cfield}; - const meta::field_info& field_info = field_; - const meta::field_info& cfield_info = cfield_; + const meta::field_info field_info = field_.make_info(); + const meta::field_info cfield_info = cfield_.make_info(); { CHECK(field_info.value_type() == meta::get_family_id()); diff --git a/untests/meta_function_tests.cpp b/untests/meta_function_tests.cpp index c26a3ff..f5c508a 100644 --- a/untests/meta_function_tests.cpp +++ b/untests/meta_function_tests.cpp @@ -29,13 +29,13 @@ TEST_CASE("meta/function") { meta::function_ int_f_int_function_("int_f_int", &int_f_int); meta::function_ int_f_int2_function_("int_f_int2", &int_f_int2); - const meta::function_info& void_f_void_info = void_f_void_function_; - const meta::function_info& void_f_int_info = void_f_int_function_; - const meta::function_info& void_f_int2_info = void_f_int2_function_; + const meta::function_info& void_f_void_info = void_f_void_function_.make_info(); + const meta::function_info& void_f_int_info = void_f_int_function_.make_info(); + const meta::function_info& void_f_int2_info = void_f_int2_function_.make_info(); - const meta::function_info& int_f_void_info = int_f_void_function_; - const meta::function_info& int_f_int_info = int_f_int_function_; - const meta::function_info& int_f_int2_info = int_f_int2_function_; + const meta::function_info& int_f_void_info = int_f_void_function_.make_info(); + const meta::function_info& int_f_int_info = int_f_int_function_.make_info(); + const meta::function_info& int_f_int2_info = int_f_int2_function_.make_info(); SUBCASE("arity") { CHECK(void_f_void_info.arity() == 0); diff --git a/untests/meta_method_tests.cpp b/untests/meta_method_tests.cpp index af89930..dcd0881 100644 --- a/untests/meta_method_tests.cpp +++ b/untests/meta_method_tests.cpp @@ -42,13 +42,13 @@ TEST_CASE("meta/non_const_method") { meta::method_ int_f_int_method_("int_f_int", &clazz::int_f_int); meta::method_ int_f_int2_method_("int_f_int2", &clazz::int_f_int2); - const meta::method_info& void_f_void_info = void_f_void_method_; - const meta::method_info& void_f_int_info = void_f_int_method_; - const meta::method_info& void_f_int2_info = void_f_int2_method_; + const meta::method_info& void_f_void_info = void_f_void_method_.make_info(); + const meta::method_info& void_f_int_info = void_f_int_method_.make_info(); + const meta::method_info& void_f_int2_info = void_f_int2_method_.make_info(); - const meta::method_info& int_f_void_info = int_f_void_method_; - const meta::method_info& int_f_int_info = int_f_int_method_; - const meta::method_info& int_f_int2_info = int_f_int2_method_; + const meta::method_info& int_f_void_info = int_f_void_method_.make_info(); + const meta::method_info& int_f_int_info = int_f_int_method_.make_info(); + const meta::method_info& int_f_int2_info = int_f_int2_method_.make_info(); SUBCASE("arity") { CHECK(void_f_void_info.arity() == 0); @@ -155,13 +155,13 @@ TEST_CASE("meta/const_method") { meta::method_ int_f_int_method_("int_f_int", &clazz::const_int_f_int); meta::method_ int_f_int2_method_("int_f_int2", &clazz::const_int_f_int2); - const meta::method_info& void_f_void_info = void_f_void_method_; - const meta::method_info& void_f_int_info = void_f_int_method_; - const meta::method_info& void_f_int2_info = void_f_int2_method_; + const meta::method_info& void_f_void_info = void_f_void_method_.make_info(); + const meta::method_info& void_f_int_info = void_f_int_method_.make_info(); + const meta::method_info& void_f_int2_info = void_f_int2_method_.make_info(); - const meta::method_info& int_f_void_info = int_f_void_method_; - const meta::method_info& int_f_int_info = int_f_int_method_; - const meta::method_info& int_f_int2_info = int_f_int2_method_; + const meta::method_info& int_f_void_info = int_f_void_method_.make_info(); + const meta::method_info& int_f_int_info = int_f_int_method_.make_info(); + const meta::method_info& int_f_int2_info = int_f_int2_method_.make_info(); SUBCASE("instance_type") { CHECK(void_f_void_info.instance_type() == meta::get_family_id()); diff --git a/untests/meta_namespace_tests.cpp b/untests/meta_namespace_tests.cpp index 24c8346..4cef931 100644 --- a/untests/meta_namespace_tests.cpp +++ b/untests/meta_namespace_tests.cpp @@ -24,13 +24,16 @@ TEST_CASE("meta/namespace") { meta::namespace_ namespace_{"ns"}; const meta::namespace_& cnamespace_ = namespace_; - const meta::namespace_info& ns_info = cnamespace_; - CHECK_FALSE(ns_info.get_class("clazz")); - CHECK_FALSE(ns_info.get_function("func")); - CHECK_FALSE(ns_info.get_namespace("ns")); - CHECK_FALSE(ns_info.get_variable("variable")); - CHECK_FALSE(ns_info.get_variable("cvariable")); + { + const meta::namespace_info& ns_info = cnamespace_.make_info(); + + CHECK_FALSE(ns_info.get_class("clazz")); + CHECK_FALSE(ns_info.get_function("func")); + CHECK_FALSE(ns_info.get_namespace("ns")); + CHECK_FALSE(ns_info.get_variable("variable")); + CHECK_FALSE(ns_info.get_variable("cvariable")); + } namespace_( meta::class_("clazz"), @@ -39,35 +42,39 @@ TEST_CASE("meta/namespace") { meta::variable_("variable", &variable), meta::variable_("cvariable", &cvariable)); - CHECK(ns_info.get_class("clazz")); - CHECK(ns_info.get_function("func")); - CHECK(ns_info.get_namespace("ns2")); - CHECK(ns_info.get_variable("variable")); - CHECK(ns_info.get_variable("cvariable")); - { - meta::class_info clazz_info = ns_info.get_class("clazz").value(); - CHECK(clazz_info.id() == "clazz"); - } + const meta::namespace_info& ns_info = cnamespace_.make_info(); - { - meta::function_info clazz_info = ns_info.get_function("func").value(); - CHECK(clazz_info.id() == "func"); - } + CHECK(ns_info.get_class("clazz")); + CHECK(ns_info.get_function("func")); + CHECK(ns_info.get_namespace("ns2")); + CHECK(ns_info.get_variable("variable")); + CHECK(ns_info.get_variable("cvariable")); - { - meta::namespace_info namespace_info = ns_info.get_namespace("ns2").value(); - CHECK(namespace_info.id() == "ns2"); - } + { + meta::class_info clazz_info = ns_info.get_class("clazz").value(); + CHECK(clazz_info.id() == "clazz"); + } - { - meta::variable_info variable_info = ns_info.get_variable("variable").value(); - CHECK(variable_info.id() == "variable"); - } + { + meta::function_info clazz_info = ns_info.get_function("func").value(); + CHECK(clazz_info.id() == "func"); + } - { - meta::variable_info cvariable_info = ns_info.get_variable("cvariable").value(); - CHECK(cvariable_info.id() == "cvariable"); + { + meta::namespace_info namespace_info = ns_info.get_namespace("ns2").value(); + CHECK(namespace_info.id() == "ns2"); + } + + { + meta::variable_info variable_info = ns_info.get_variable("variable").value(); + CHECK(variable_info.id() == "variable"); + } + + { + meta::variable_info cvariable_info = ns_info.get_variable("cvariable").value(); + CHECK(cvariable_info.id() == "cvariable"); + } } } @@ -75,7 +82,6 @@ TEST_CASE("meta/namespace/merge") { namespace meta = meta_hpp; meta::namespace_ namespace_{"ns"}; - const meta::namespace_info& ns_info = namespace_; namespace_( meta::namespace_{"ns2"}( @@ -97,6 +103,7 @@ TEST_CASE("meta/namespace/merge") { ) ); + const meta::namespace_info ns_info = namespace_.make_info(); const meta::namespace_info ns2_info = ns_info.get_namespace("ns2").value(); const meta::namespace_info ns3_info = ns2_info.get_namespace("ns3").value(); diff --git a/untests/meta_registry_tests.cpp b/untests/meta_registry_tests.cpp index a4990e5..8112fce 100644 --- a/untests/meta_registry_tests.cpp +++ b/untests/meta_registry_tests.cpp @@ -103,8 +103,8 @@ TEST_CASE("meta/registry") { REQUIRE(registry.resolve(std::as_const(v3))); REQUIRE(registry.resolve(static_cast(v3))); - const meta::class_info v2_info = meta::class_("ivec2"); - const meta::class_info v3_info = meta::class_("ivec3"); + const meta::class_info v2_info = meta::class_("ivec2").make_info(); + const meta::class_info v3_info = meta::class_("ivec3").make_info(); CHECK(v2_info.family() != v3_info.family()); CHECK(v2_info.family() == registry.resolve()->family()); diff --git a/untests/meta_type_tests.cpp b/untests/meta_type_tests.cpp index d90d4df..13953f5 100644 --- a/untests/meta_type_tests.cpp +++ b/untests/meta_type_tests.cpp @@ -31,27 +31,27 @@ TEST_CASE("meta/type") { namespace meta = meta_hpp; using namespace std::string_literals; - meta::type class_type = meta::class_("clazz"); + meta::type class_type = meta::class_("clazz").make_info(); CHECK(class_type.is_class()); CHECK(class_type.get_class()->id() == "clazz"); - meta::type field_type = meta::field_("field", &clazz::field); + meta::type field_type = meta::field_("field", &clazz::field).make_info(); CHECK(field_type.is_field()); CHECK(field_type.get_field()->id() == "field"); - meta::type function_type = meta::function_("function", &clazz::function); + meta::type function_type = meta::function_("function", &clazz::function).make_info(); CHECK(function_type.is_function()); CHECK(function_type.get_function()->id() == "function"); - meta::type method_type = meta::method_("method", &clazz::method); + meta::type method_type = meta::method_("method", &clazz::method).make_info(); CHECK(method_type.is_method()); CHECK(method_type.get_method()->id() == "method"); - meta::type namespace_type = meta::namespace_("ns"); + meta::type namespace_type = meta::namespace_("ns").make_info(); CHECK(namespace_type.is_namespace()); CHECK(namespace_type.get_namespace()->id() == "ns"); - meta::type variable_type = meta::variable_("variable", &clazz::variable); + meta::type variable_type = meta::variable_("variable", &clazz::variable).make_info(); CHECK(variable_type.is_variable()); CHECK(variable_type.get_variable()->id() == "variable"); } @@ -63,11 +63,11 @@ TEST_CASE("meta/type/merge") { { meta::type clazz_type = meta::class_("clazz")( meta::field_("field", &clazz::field) - ); + ).make_info(); clazz_type.merge(meta::class_("clazz")( meta::function_("function", &clazz::function) - )); + ).make_info()); REQUIRE(clazz_type.is_class()); CHECK(clazz_type.get_class()->get_field("field")); diff --git a/untests/meta_variable_tests.cpp b/untests/meta_variable_tests.cpp index 1ddf254..69318bc 100644 --- a/untests/meta_variable_tests.cpp +++ b/untests/meta_variable_tests.cpp @@ -29,8 +29,8 @@ TEST_CASE("meta/variable") { meta::variable_ variable_{"variable", &variable}; meta::variable_ cvariable_{"cvariable", &cvariable}; - const meta::variable_info& variable_info = variable_; - const meta::variable_info& cvariable_info = cvariable_; + const meta::variable_info& variable_info = variable_.make_info(); + const meta::variable_info& cvariable_info = cvariable_.make_info(); { CHECK(variable_info.value_type() == meta::get_family_id()); @@ -68,8 +68,8 @@ TEST_CASE("meta/variable") { meta::variable_ variable_{"variable", &clazz::variable}; meta::variable_ cvariable_{"cvariable", &clazz::cvariable}; - const meta::variable_info& variable_info = variable_; - const meta::variable_info& cvariable_info = cvariable_; + const meta::variable_info& variable_info = variable_.make_info(); + const meta::variable_info& cvariable_info = cvariable_.make_info(); { CHECK(variable_info.value_type() == meta::get_family_id()); From 2ea9a01f323bd702de356df9c6c43271b67e3ef1 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Tue, 13 Jul 2021 09:24:07 +0700 Subject: [PATCH 058/233] basic ctors --- headers/meta.hpp/meta.hpp | 3 + headers/meta.hpp/meta_class.hpp | 7 ++ headers/meta.hpp/meta_class_info.hpp | 21 ++++ headers/meta.hpp/meta_ctor.hpp | 43 +++++++ headers/meta.hpp/meta_ctor_info.hpp | 178 +++++++++++++++++++++++++++ headers/meta.hpp/meta_fwd.hpp | 17 +++ headers/meta.hpp/meta_registry.hpp | 3 + untests/meta_ctor_tests.cpp | 108 ++++++++++++++++ 8 files changed, 380 insertions(+) create mode 100644 headers/meta.hpp/meta_ctor.hpp create mode 100644 headers/meta.hpp/meta_ctor_info.hpp create mode 100644 untests/meta_ctor_tests.cpp diff --git a/headers/meta.hpp/meta.hpp b/headers/meta.hpp/meta.hpp index 125d059..eb2532c 100644 --- a/headers/meta.hpp/meta.hpp +++ b/headers/meta.hpp/meta.hpp @@ -17,6 +17,9 @@ #include "meta_class.hpp" #include "meta_class_info.hpp" +#include "meta_ctor.hpp" +#include "meta_ctor_info.hpp" + #include "meta_data.hpp" #include "meta_data_info.hpp" diff --git a/headers/meta.hpp/meta_class.hpp b/headers/meta.hpp/meta_class.hpp index 2912fb1..545acff 100644 --- a/headers/meta.hpp/meta_class.hpp +++ b/headers/meta.hpp/meta_class.hpp @@ -8,6 +8,7 @@ #include "meta_fwd.hpp" +#include "meta_ctor.hpp" #include "meta_data.hpp" #include "meta_field.hpp" #include "meta_function.hpp" @@ -40,6 +41,12 @@ namespace meta_hpp detail::merge_with(info_.classes_, info.id(), info, &class_info::merge); } + template < typename... Args > + void add_(ctor_ internal) { + ctor_info info = std::move(internal).template make_info(); + detail::merge_with(info_.ctors_, info.family(), info, &ctor_info::merge); + } + void add_(data_ internal) { data_info info = std::move(internal).make_info(); detail::merge_with(info_.datas_, info.id(), info, &data_info::merge); diff --git a/headers/meta.hpp/meta_class_info.hpp b/headers/meta.hpp/meta_class_info.hpp index 74a63ee..e4eb838 100644 --- a/headers/meta.hpp/meta_class_info.hpp +++ b/headers/meta.hpp/meta_class_info.hpp @@ -9,6 +9,7 @@ #include "meta_fwd.hpp" #include "meta_value.hpp" +#include "meta_ctor_info.hpp" #include "meta_data_info.hpp" #include "meta_field_info.hpp" #include "meta_function_info.hpp" @@ -42,6 +43,13 @@ namespace meta_hpp } } + template < typename F > + void each_ctor(F&& f) const { + for ( auto&& family_info : ctors_ ) { + std::invoke(f, family_info.second); + } + } + template < typename F > void each_data(F&& f) const { for ( auto&& id_info : datas_ ) { @@ -80,6 +88,7 @@ namespace meta_hpp template < typename F > void visit(F&& f) const { each_class(f); + each_ctor(f); each_data(f); each_field(f); each_function(f); @@ -91,6 +100,16 @@ namespace meta_hpp return detail::find_opt(classes_, id); } + template < typename... Args > + std::optional get_ctor() const { + for ( auto&& family_info : ctors_ ) { + if ( family_info.second.is_invocable_with() ) { + return family_info.second; + } + } + return std::nullopt; + } + std::optional get_data(std::string_view id) const { return detail::find_opt(datas_, id); } @@ -116,6 +135,7 @@ namespace meta_hpp throw std::logic_error("class_info::merge failed"); } detail::merge_with(classes_, other.classes_, &class_info::merge); + detail::merge_with(ctors_, other.ctors_, &ctor_info::merge); detail::merge_with(datas_, other.datas_, &data_info::merge); detail::merge_with(fields_, other.fields_, &field_info::merge); detail::merge_with(functions_, other.functions_, &function_info::merge); @@ -134,6 +154,7 @@ namespace meta_hpp std::string id_; family_id family_; std::map> classes_; + std::map> ctors_; std::map> datas_; std::map> fields_; std::map> functions_; diff --git a/headers/meta.hpp/meta_ctor.hpp b/headers/meta.hpp/meta_ctor.hpp new file mode 100644 index 0000000..d338ced --- /dev/null +++ b/headers/meta.hpp/meta_ctor.hpp @@ -0,0 +1,43 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "meta_fwd.hpp" + +#include "meta_data.hpp" + +#include "meta_ctor_info.hpp" + +namespace meta_hpp +{ + template < typename... Args > + class ctor_ { + public: + ctor_() = default; + + template < typename Class > + ctor_info make_info() const { + static_assert(std::is_constructible_v); + ctor_info info{detail::typename_arg, detail::typename_args}; + detail::merge_with(info.datas_, datas_, &data_info::merge); + return info; + } + + template < typename... Internals > + ctor_& operator()(Internals&&...internals) { + (add_(std::forward(internals)), ...); + return *this; + } + private: + void add_(data_ internal) { + data_info info = std::move(internal).make_info(); + detail::merge_with(datas_, info.id(), info, &data_info::merge); + } + private: + std::map> datas_; + }; +} diff --git a/headers/meta.hpp/meta_ctor_info.hpp b/headers/meta.hpp/meta_ctor_info.hpp new file mode 100644 index 0000000..eb1d4a8 --- /dev/null +++ b/headers/meta.hpp/meta_ctor_info.hpp @@ -0,0 +1,178 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "meta_fwd.hpp" + +#include "meta_value.hpp" + +#include "meta_data_info.hpp" + +namespace meta_hpp::ctor_detail +{ + template < typename Class, typename... Args, std::size_t... Is > + value raw_invoke_impl( + value* args, + std::index_sequence) + { + using ct = detail::ctor_traits; + using return_type = typename ct::return_type; + using argument_types = typename ct::argument_types; + + [[maybe_unused]] auto typed_arguments = std::make_tuple( + (args + Is)->try_cast>()...); + + if ( !(std::get(typed_arguments) && ...) ) { + throw std::logic_error("an attempt to call a ctor with incorrect argument types"); + } + + return_type return_value{std::move(*std::get(typed_arguments))...}; + return value{std::move(return_value)}; + } + + template < typename Class, typename... Args > + value raw_invoke( + value* args, + std::size_t arg_count) + { + using ct = detail::ctor_traits; + + if ( arg_count != ct::arity ) { + throw std::logic_error("an attempt to call a ctor with an incorrect arity"); + } + + return raw_invoke_impl(args, std::make_index_sequence()); + } + + using ctor_invoke = std::function; + + template < typename Class, typename... Args > + ctor_invoke make_invoke() { + using namespace std::placeholders; + return std::bind(&raw_invoke, _1, _2); + } + + template < typename Class, typename... Args > + family_id make_return_type() { + using ct = detail::ctor_traits; + using return_type = typename ct::return_type; + return get_family_id(); + } + + template < typename Class, typename... Args, std::size_t... Is > + std::vector make_argument_types_impl(std::index_sequence) { + using ct = detail::ctor_traits; + using argument_types = typename ct::argument_types; + return { get_family_id>()... }; + } + + template < typename Class, typename... Args > + std::vector make_argument_types() { + using ct = detail::ctor_traits; + return make_argument_types_impl(std::make_index_sequence()); + } + + template < typename... Args, std::size_t... Is > + bool parameters_equal(const std::vector& parameters, std::index_sequence) { + if ( parameters.size() != sizeof...(Args) ) { + return false; + } + return ((get_family_id>>() == parameters[Is]) && ... ); + } + + template < typename... Args > + bool parameters_equal(const std::vector& parameters) { + return parameters_equal(parameters, std::make_index_sequence()); + } +} + +namespace meta_hpp +{ + class ctor_info { + public: + ctor_info() = delete; + + ctor_info(ctor_info&&) = default; + ctor_info(const ctor_info&) = default; + + ctor_info& operator=(ctor_info&&) = default; + ctor_info& operator=(const ctor_info&) = default; + public: + family_id family() const noexcept { + return family_; + } + + std::size_t arity() const noexcept { + return argument_types_.size(); + } + + family_id return_type() const noexcept { + return return_type_; + } + + std::optional argument_type(std::size_t index) const noexcept { + if ( index < argument_types_.size() ) { + return argument_types_[index]; + } + return std::nullopt; + } + + template < typename... Args > + value invoke(Args&&... args) const { + if constexpr ( sizeof...(Args) > 0u ) { + std::array vargs{std::forward(args)...}; + return invoke_(vargs.data(), vargs.size()); + } else { + return invoke_(nullptr, 0u); + } + } + + template < typename... Args > + bool is_invocable_with() const noexcept { + return ctor_detail::parameters_equal(argument_types_); + } + + template < typename F > + void each_data(F&& f) const { + for ( auto&& id_info : datas_ ) { + std::invoke(f, id_info.second); + } + } + + template < typename F > + void visit(F&& f) const { + each_data(f); + } + + std::optional get_data(std::string_view id) const { + return detail::find_opt(datas_, id); + } + + void merge(const ctor_info& other) { + if ( family() != other.family() ) { + throw std::logic_error("ctor_info::merge failed"); + } + detail::merge_with(datas_, other.datas_, &data_info::merge); + } + private: + template < typename... Args > + friend class ctor_; + + template < typename Class, typename... Args > + ctor_info(detail::typename_arg_t, detail::typename_args_t) + : family_{get_family_id>()} + , return_type_{ctor_detail::make_return_type()} + , argument_types_{ctor_detail::make_argument_types()} + , invoke_{ctor_detail::make_invoke()} {} + private: + family_id family_; + family_id return_type_; + std::vector argument_types_; + ctor_detail::ctor_invoke invoke_; + std::map> datas_; + }; +} diff --git a/headers/meta.hpp/meta_fwd.hpp b/headers/meta.hpp/meta_fwd.hpp index e23d02e..65773b2 100644 --- a/headers/meta.hpp/meta_fwd.hpp +++ b/headers/meta.hpp/meta_fwd.hpp @@ -105,8 +105,15 @@ namespace meta_hpp::detail struct typename_arg_t { }; + template < typename... Args > + struct typename_args_t { + }; + template < typename Arg > inline typename_arg_t typename_arg; + + template < typename... Args > + inline typename_args_t typename_args; } namespace meta_hpp::detail @@ -136,6 +143,16 @@ namespace meta_hpp::detail } } +namespace meta_hpp::detail +{ + template < typename Class, typename... Args > + struct ctor_traits { + static constexpr std::size_t arity = sizeof...(Args); + using return_type = std::decay_t; + using argument_types = std::tuple...>; + }; +} + namespace meta_hpp::detail { template < typename Field > diff --git a/headers/meta.hpp/meta_registry.hpp b/headers/meta.hpp/meta_registry.hpp index 5b9f41b..450c0e3 100644 --- a/headers/meta.hpp/meta_registry.hpp +++ b/headers/meta.hpp/meta_registry.hpp @@ -11,6 +11,8 @@ #include "meta_type.hpp" #include "meta_class.hpp" +#include "meta_ctor.hpp" +#include "meta_data.hpp" #include "meta_field.hpp" #include "meta_function.hpp" #include "meta_method.hpp" @@ -150,6 +152,7 @@ namespace meta_hpp detail::merge_with(classes_, name, info, &class_info::merge); info.visit(overloaded { + [](const ctor_info&) {}, [](const data_info&) {}, [this, &name](const auto& internal){ add_(name, internal); diff --git a/untests/meta_ctor_tests.cpp b/untests/meta_ctor_tests.cpp new file mode 100644 index 0000000..31240c0 --- /dev/null +++ b/untests/meta_ctor_tests.cpp @@ -0,0 +1,108 @@ +/******************************************************************************* + * 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 +#include + +#include "doctest/doctest.hpp" + +namespace +{ + class clazz { + public: + int v1{1}; + int v2{2}; + + clazz() = default; + clazz(int v): v1{v}, v2{v} {} + clazz(int v1, int v2): v1{v1}, v2{v2} {} + }; +} + +TEST_CASE("meta/ctor") { + namespace meta = meta_hpp; + + const meta::ctor_info ctor0 = meta::ctor_<>().make_info(); + const meta::ctor_info ctor1 = meta::ctor_().make_info(); + const meta::ctor_info ctor2 = meta::ctor_().make_info(); + + SUBCASE("arity") { + CHECK(ctor0.arity() == 0u); + CHECK(ctor1.arity() == 1u); + CHECK(ctor2.arity() == 2u); + } + + SUBCASE("return_type") { + CHECK(ctor0.return_type() == meta::get_family_id()); + CHECK(ctor1.return_type() == meta::get_family_id()); + CHECK(ctor2.return_type() == meta::get_family_id()); + } + + SUBCASE("argument_types") { + CHECK_FALSE(ctor0.argument_type(0u)); + + CHECK(ctor1.argument_type(0u) == meta::get_family_id()); + CHECK_FALSE(ctor1.argument_type(1u)); + + CHECK(ctor2.argument_type(0u) == meta::get_family_id()); + CHECK(ctor2.argument_type(1u) == meta::get_family_id()); + CHECK_FALSE(ctor2.argument_type(2u)); + } + + SUBCASE("invoke0") { + CHECK(ctor0.invoke().cast().v1 == 1); + CHECK(ctor0.invoke().cast().v2 == 2); + CHECK_THROWS_AS(ctor0.invoke(1), std::logic_error); + } + + SUBCASE("invoke1") { + CHECK(ctor1.invoke(42).cast().v1 == 42); + CHECK(ctor1.invoke(42).cast().v2 == 42); + CHECK_THROWS_AS(ctor1.invoke(), std::logic_error); + CHECK_THROWS_AS(ctor1.invoke(1,1), std::logic_error); + } + + SUBCASE("invoke2") { + CHECK(ctor2.invoke(21,42).cast().v1 == 21); + CHECK(ctor2.invoke(21,42).cast().v2 == 42); + CHECK_THROWS_AS(ctor2.invoke(), std::logic_error); + CHECK_THROWS_AS(ctor2.invoke(1), std::logic_error); + CHECK_THROWS_AS(ctor2.invoke(1,1,1), std::logic_error); + } + + SUBCASE("is_invocable_with") { + CHECK(ctor0.is_invocable_with<>()); + CHECK_FALSE(ctor0.is_invocable_with()); + + CHECK(ctor1.is_invocable_with()); + CHECK_FALSE(ctor1.is_invocable_with()); + CHECK_FALSE(ctor1.is_invocable_with<>()); + CHECK_FALSE(ctor1.is_invocable_with()); + + CHECK(ctor2.is_invocable_with()); + CHECK_FALSE(ctor2.is_invocable_with()); + CHECK_FALSE(ctor2.is_invocable_with<>()); + CHECK_FALSE(ctor2.is_invocable_with()); + } +} + +TEST_CASE("meta/ctor/class") { + namespace meta = meta_hpp; + + const meta::class_info clazz_info = meta::class_("clazz")( + meta::ctor_<>(), + meta::ctor_(), + meta::ctor_() + ).make_info(); + + CHECK(clazz_info.get_ctor<>()); + CHECK(clazz_info.get_ctor()); + CHECK(clazz_info.get_ctor()); + + CHECK_FALSE(clazz_info.get_ctor()); + CHECK_FALSE(clazz_info.get_ctor()); + CHECK_FALSE(clazz_info.get_ctor()); +} From 6677514faf0162d504237a40a16a20d091e8cfba Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Tue, 13 Jul 2021 13:19:09 +0700 Subject: [PATCH 059/233] invoke syntactic sugar --- headers/meta.hpp/meta_class_info.hpp | 2 +- headers/meta.hpp/meta_ctor_info.hpp | 12 +++- headers/meta.hpp/meta_field_info.hpp | 16 ++++- headers/meta.hpp/meta_function_info.hpp | 13 ++++ headers/meta.hpp/meta_method_info.hpp | 29 ++++++--- headers/meta.hpp/meta_variable_info.hpp | 14 ++++ untests/meta_ctor_tests.cpp | 52 +++++++++++---- untests/meta_field_tests.cpp | 23 +++++++ untests/meta_function_tests.cpp | 25 ++++++- untests/meta_method_tests.cpp | 87 ++++++++++++++++++++++--- untests/meta_variable_tests.cpp | 25 +++++++ 11 files changed, 263 insertions(+), 35 deletions(-) diff --git a/headers/meta.hpp/meta_class_info.hpp b/headers/meta.hpp/meta_class_info.hpp index e4eb838..afe0277 100644 --- a/headers/meta.hpp/meta_class_info.hpp +++ b/headers/meta.hpp/meta_class_info.hpp @@ -103,7 +103,7 @@ namespace meta_hpp template < typename... Args > std::optional get_ctor() const { for ( auto&& family_info : ctors_ ) { - if ( family_info.second.is_invocable_with() ) { + if ( family_info.second.is_invocable() ) { return family_info.second; } } diff --git a/headers/meta.hpp/meta_ctor_info.hpp b/headers/meta.hpp/meta_ctor_info.hpp index eb1d4a8..4a41981 100644 --- a/headers/meta.hpp/meta_ctor_info.hpp +++ b/headers/meta.hpp/meta_ctor_info.hpp @@ -131,8 +131,18 @@ namespace meta_hpp } } + template < typename R, typename... Args > + R invoke_r(Args&&... args) const { + return invoke(std::forward(args)...).template cast(); + } + template < typename... Args > - bool is_invocable_with() const noexcept { + value operator()(Args&&... args) const { + return invoke(std::forward(args)...); + } + + template < typename... Args > + bool is_invocable() const noexcept { return ctor_detail::parameters_equal(argument_types_); } diff --git a/headers/meta.hpp/meta_field_info.hpp b/headers/meta.hpp/meta_field_info.hpp index a69ba00..f6e27b1 100644 --- a/headers/meta.hpp/meta_field_info.hpp +++ b/headers/meta.hpp/meta_field_info.hpp @@ -122,9 +122,23 @@ namespace meta_hpp return getter_(instance); } + template < typename R > + R get_r(cinstance instance) const { + return get(instance).cast(); + } + template < typename Value > void set(instance instance, Value&& value) const { - return setter_(instance, std::forward(value)); + setter_(instance, std::forward(value)); + } + + value operator()(cinstance instance) const { + return get(instance); + } + + template < typename Value > + void operator()(instance instance, Value&& value) const { + set(instance, std::forward(value)); } template < typename F > diff --git a/headers/meta.hpp/meta_function_info.hpp b/headers/meta.hpp/meta_function_info.hpp index 30c10f9..c130614 100644 --- a/headers/meta.hpp/meta_function_info.hpp +++ b/headers/meta.hpp/meta_function_info.hpp @@ -134,6 +134,19 @@ namespace meta_hpp } } + template < typename R, typename... Args > + std::optional invoke_r(Args&&... args) const { + if ( std::optional r = invoke(std::forward(args)...) ) { + return std::move(r)->template cast(); + } + return std::nullopt; + } + + template < typename... Args > + std::optional operator()(Args&&... args) const { + return invoke(std::forward(args)...); + } + template < typename F > void each_data(F&& f) const { for ( auto&& id_info : datas_ ) { diff --git a/headers/meta.hpp/meta_method_info.hpp b/headers/meta.hpp/meta_method_info.hpp index 8c5167e..017c973 100644 --- a/headers/meta.hpp/meta_method_info.hpp +++ b/headers/meta.hpp/meta_method_info.hpp @@ -208,20 +208,31 @@ namespace meta_hpp std::optional invoke(T& inst, Args&&... args) const { if constexpr ( sizeof...(Args) > 0u ) { std::array vargs{std::forward(args)...}; - return invoke_(inst, vargs.data(), vargs.size()); + if constexpr ( std::is_const_v ) { + return cinvoke_(inst, vargs.data(), vargs.size()); + } else { + return invoke_(inst, vargs.data(), vargs.size()); + } } else { - return invoke_(inst, nullptr, 0u); + if constexpr ( std::is_const_v ) { + return cinvoke_(inst, nullptr, 0u); + } else { + return invoke_(inst, nullptr, 0u); + } } } - template < typename T, typename... Args > - std::optional invoke(const T& inst, Args&&... args) const { - if constexpr ( sizeof...(Args) > 0u ) { - std::array vargs{std::forward(args)...}; - return cinvoke_(inst, vargs.data(), vargs.size()); - } else { - return cinvoke_(inst, nullptr, 0u); + template < typename R, typename T, typename... Args > + std::optional invoke_r(T& inst, Args&&... args) const { + if ( std::optional r = invoke(inst, std::forward(args)...) ) { + return std::move(r)->template cast(); } + return std::nullopt; + } + + template < typename T, typename... Args > + std::optional operator()(T& inst, Args&&... args) const { + return invoke(inst, std::forward(args)...); } template < typename F > diff --git a/headers/meta.hpp/meta_variable_info.hpp b/headers/meta.hpp/meta_variable_info.hpp index 01f25f6..2c2a6d7 100644 --- a/headers/meta.hpp/meta_variable_info.hpp +++ b/headers/meta.hpp/meta_variable_info.hpp @@ -96,11 +96,25 @@ namespace meta_hpp return getter_(); } + template < typename R > + R get_r() const { + return get().cast(); + } + template < typename Value > void set(Value&& value) const { return setter_(std::forward(value)); } + value operator()() const { + return get(); + } + + template < typename Value > + void operator()(Value&& value) const { + return set(std::forward(value)); + } + template < typename F > void each_data(F&& f) const { for ( auto&& id_info : datas_ ) { diff --git a/untests/meta_ctor_tests.cpp b/untests/meta_ctor_tests.cpp index 31240c0..d284373 100644 --- a/untests/meta_ctor_tests.cpp +++ b/untests/meta_ctor_tests.cpp @@ -53,39 +53,69 @@ TEST_CASE("meta/ctor") { } SUBCASE("invoke0") { + CHECK(ctor0().cast().v1 == 1); + CHECK(ctor0().cast().v2 == 2); + CHECK_THROWS_AS(ctor0(1), std::logic_error); + CHECK(ctor0.invoke().cast().v1 == 1); CHECK(ctor0.invoke().cast().v2 == 2); CHECK_THROWS_AS(ctor0.invoke(1), std::logic_error); + + CHECK(ctor0.invoke_r().v1 == 1); + CHECK(ctor0.invoke_r().v2 == 2); + CHECK_THROWS_AS(ctor0.invoke_r(1), std::logic_error); } SUBCASE("invoke1") { + CHECK(ctor1(42).cast().v1 == 42); + CHECK(ctor1(42).cast().v2 == 42); + CHECK_THROWS_AS(ctor1(), std::logic_error); + CHECK_THROWS_AS(ctor1(1,1), std::logic_error); + CHECK(ctor1.invoke(42).cast().v1 == 42); CHECK(ctor1.invoke(42).cast().v2 == 42); CHECK_THROWS_AS(ctor1.invoke(), std::logic_error); CHECK_THROWS_AS(ctor1.invoke(1,1), std::logic_error); + + CHECK(ctor1.invoke_r(42).v1 == 42); + CHECK(ctor1.invoke_r(42).v2 == 42); + CHECK_THROWS_AS(ctor1.invoke_r(), std::logic_error); + CHECK_THROWS_AS(ctor1.invoke_r(1,1), std::logic_error); } SUBCASE("invoke2") { + CHECK(ctor2(21,42).cast().v1 == 21); + CHECK(ctor2(21,42).cast().v2 == 42); + CHECK_THROWS_AS(ctor2(), std::logic_error); + CHECK_THROWS_AS(ctor2(1), std::logic_error); + CHECK_THROWS_AS(ctor2(1,1,1), std::logic_error); + CHECK(ctor2.invoke(21,42).cast().v1 == 21); CHECK(ctor2.invoke(21,42).cast().v2 == 42); CHECK_THROWS_AS(ctor2.invoke(), std::logic_error); CHECK_THROWS_AS(ctor2.invoke(1), std::logic_error); CHECK_THROWS_AS(ctor2.invoke(1,1,1), std::logic_error); + + CHECK(ctor2.invoke_r(21,42).v1 == 21); + CHECK(ctor2.invoke_r(21,42).v2 == 42); + CHECK_THROWS_AS(ctor2.invoke_r(), std::logic_error); + CHECK_THROWS_AS(ctor2.invoke_r(1), std::logic_error); + CHECK_THROWS_AS(ctor2.invoke_r(1,1,1), std::logic_error); } - SUBCASE("is_invocable_with") { - CHECK(ctor0.is_invocable_with<>()); - CHECK_FALSE(ctor0.is_invocable_with()); + SUBCASE("is_invocable") { + CHECK(ctor0.is_invocable<>()); + CHECK_FALSE(ctor0.is_invocable()); - CHECK(ctor1.is_invocable_with()); - CHECK_FALSE(ctor1.is_invocable_with()); - CHECK_FALSE(ctor1.is_invocable_with<>()); - CHECK_FALSE(ctor1.is_invocable_with()); + CHECK(ctor1.is_invocable()); + CHECK_FALSE(ctor1.is_invocable()); + CHECK_FALSE(ctor1.is_invocable<>()); + CHECK_FALSE(ctor1.is_invocable()); - CHECK(ctor2.is_invocable_with()); - CHECK_FALSE(ctor2.is_invocable_with()); - CHECK_FALSE(ctor2.is_invocable_with<>()); - CHECK_FALSE(ctor2.is_invocable_with()); + CHECK(ctor2.is_invocable()); + CHECK_FALSE(ctor2.is_invocable()); + CHECK_FALSE(ctor2.is_invocable<>()); + CHECK_FALSE(ctor2.is_invocable()); } } diff --git a/untests/meta_field_tests.cpp b/untests/meta_field_tests.cpp index 759276a..b27afdc 100644 --- a/untests/meta_field_tests.cpp +++ b/untests/meta_field_tests.cpp @@ -37,14 +37,24 @@ TEST_CASE("meta/field") { clazz instance; CHECK(instance.field == 1); + CHECK(field_info.get_r(instance) == 1); + CHECK(field_info(instance).cast() == 1); CHECK(field_info.get(instance).cast() == 1); + CHECK(field_info.get_r(std::as_const(instance)) == 1); + CHECK(field_info(std::as_const(instance)).cast() == 1); CHECK(field_info.get(std::as_const(instance)).cast() == 1); + CHECK_NOTHROW(field_info(instance, 3)); CHECK_NOTHROW(field_info.set(instance, 3)); + CHECK_THROWS_AS(field_info(instance, 4.f), std::logic_error); CHECK_THROWS_AS(field_info.set(instance, 4.f), std::logic_error); CHECK(instance.field == 3); + CHECK(field_info.get_r(instance) == 3); + CHECK(field_info(instance).cast() == 3); CHECK(field_info.get(instance).cast() == 3); + CHECK(field_info.get_r(std::as_const(instance)) == 3); + CHECK(field_info(std::as_const(instance)).cast() == 3); CHECK(field_info.get(std::as_const(instance)).cast() == 3); } @@ -52,13 +62,22 @@ TEST_CASE("meta/field") { clazz instance; CHECK(instance.cfield == 2); + CHECK(cfield_info.get_r(instance) == 2); + CHECK(cfield_info(instance).cast() == 2); CHECK(cfield_info.get(instance).cast() == 2); + CHECK(cfield_info.get_r(std::as_const(instance)) == 2); + CHECK(cfield_info(std::as_const(instance)).cast() == 2); CHECK(cfield_info.get(std::as_const(instance)).cast() == 2); + CHECK_THROWS_AS(cfield_info(instance, 4), std::logic_error); CHECK_THROWS_AS(cfield_info.set(instance, 4), std::logic_error); CHECK(instance.cfield == 2); + CHECK(cfield_info.get_r(instance) == 2); + CHECK(cfield_info(instance).cast() == 2); CHECK(cfield_info.get(instance).cast() == 2); + CHECK(cfield_info.get_r(std::as_const(instance)) == 2); + CHECK(cfield_info(std::as_const(instance)).cast() == 2); CHECK(cfield_info.get(std::as_const(instance)).cast() == 2); } @@ -66,7 +85,11 @@ TEST_CASE("meta/field") { clazz instance; instance.field = 5; + CHECK(field_info.get_r(instance) == 5); + CHECK(field_info(instance).cast() == 5); CHECK(field_info.get(instance).cast() == 5); + CHECK(field_info.get_r(std::as_const(instance)) == 5); + CHECK(field_info(std::as_const(instance)).cast() == 5); CHECK(field_info.get(std::as_const(instance)).cast() == 5); } } diff --git a/untests/meta_function_tests.cpp b/untests/meta_function_tests.cpp index f5c508a..93cbc2c 100644 --- a/untests/meta_function_tests.cpp +++ b/untests/meta_function_tests.cpp @@ -64,33 +64,52 @@ TEST_CASE("meta/function") { } SUBCASE("void_return") { - CHECK_NOTHROW(void_f_void_info.invoke()); + CHECK_FALSE(void_f_void_info()); + CHECK_FALSE(void_f_void_info.invoke()); + CHECK_FALSE(void_f_void_info.invoke_r()); + CHECK_THROWS_AS(void_f_void_info(1), std::logic_error); CHECK_THROWS_AS(void_f_void_info.invoke(1), std::logic_error); + CHECK_THROWS_AS(void_f_int_info(), std::logic_error); CHECK_THROWS_AS(void_f_int_info.invoke(), std::logic_error); - CHECK_NOTHROW(void_f_int_info.invoke(1)); + CHECK_FALSE(void_f_int_info(1)); + CHECK_FALSE(void_f_int_info.invoke(1)); + CHECK_FALSE(void_f_int_info.invoke_r(1)); + CHECK_THROWS_AS(void_f_int_info(1.f), std::logic_error); CHECK_THROWS_AS(void_f_int_info.invoke(1.f), std::logic_error); + CHECK_THROWS_AS(void_f_int_info(1, 2), std::logic_error); CHECK_THROWS_AS(void_f_int_info.invoke(1, 2), std::logic_error); + CHECK_THROWS_AS(void_f_int2_info(), std::logic_error); CHECK_THROWS_AS(void_f_int2_info.invoke(), std::logic_error); + CHECK_THROWS_AS(void_f_int2_info(1), std::logic_error); CHECK_THROWS_AS(void_f_int2_info.invoke(1), std::logic_error); - CHECK_NOTHROW(void_f_int2_info.invoke(1, 2)); + CHECK_FALSE(void_f_int2_info(1, 2)); + CHECK_FALSE(void_f_int2_info.invoke(1, 2)); + CHECK_FALSE(void_f_int2_info.invoke_r(1, 2)); + CHECK_THROWS_AS(void_f_int2_info(1.f, 2), std::logic_error); CHECK_THROWS_AS(void_f_int2_info.invoke(1.f, 2), std::logic_error); + CHECK_THROWS_AS(void_f_int2_info(1, 2.f), std::logic_error); CHECK_THROWS_AS(void_f_int2_info.invoke(1, 2.f), std::logic_error); + CHECK_THROWS_AS(void_f_int2_info(1, 2, 3), std::logic_error); CHECK_THROWS_AS(void_f_int2_info.invoke(1, 2, 3), std::logic_error); } SUBCASE("int_return") { + CHECK(int_f_void_info.invoke_r() == 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_void_info.invoke_r(1), std::logic_error); CHECK_THROWS_AS(int_f_int_info.invoke(), std::logic_error); + CHECK(int_f_int_info.invoke_r(1) == 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_r(1, 2) == 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); diff --git a/untests/meta_method_tests.cpp b/untests/meta_method_tests.cpp index dcd0881..c277ae6 100644 --- a/untests/meta_method_tests.cpp +++ b/untests/meta_method_tests.cpp @@ -83,64 +83,106 @@ TEST_CASE("meta/non_const_method") { SUBCASE("another_instance") { clazz2 instance; + CHECK_THROWS_AS(void_f_void_info(instance), std::logic_error); CHECK_THROWS_AS(void_f_void_info.invoke(instance), std::logic_error); + CHECK_THROWS_AS(void_f_void_info.invoke_r(instance), std::logic_error); + + CHECK_THROWS_AS(void_f_int_info(instance, 1), std::logic_error); CHECK_THROWS_AS(void_f_int_info.invoke(instance, 1), std::logic_error); + CHECK_THROWS_AS(void_f_int_info.invoke_r(instance, 1), std::logic_error); + + CHECK_THROWS_AS(void_f_int2_info(instance, 1, 2), std::logic_error); CHECK_THROWS_AS(void_f_int2_info.invoke(instance, 1, 2), std::logic_error); + CHECK_THROWS_AS(void_f_int2_info.invoke_r(instance, 1, 2), std::logic_error); } SUBCASE("void_return") { clazz instance; - CHECK_NOTHROW(void_f_void_info.invoke(instance)); + CHECK_FALSE(void_f_void_info(instance)); + CHECK_FALSE(void_f_void_info.invoke(instance)); + CHECK_FALSE(void_f_void_info.invoke_r(instance)); + CHECK_THROWS_AS(void_f_void_info(instance, 1), std::logic_error); CHECK_THROWS_AS(void_f_void_info.invoke(instance, 1), std::logic_error); + CHECK_THROWS_AS(void_f_void_info.invoke_r(instance, 1), std::logic_error); CHECK_THROWS_AS(void_f_int_info.invoke(instance), std::logic_error); - CHECK_NOTHROW(void_f_int_info.invoke(instance, 1)); + CHECK_FALSE(void_f_int_info(instance, 1)); + CHECK_FALSE(void_f_int_info.invoke(instance, 1)); + CHECK_FALSE(void_f_int_info.invoke_r(instance, 1)); CHECK_THROWS_AS(void_f_int_info.invoke(instance, 1.f), std::logic_error); CHECK_THROWS_AS(void_f_int_info.invoke(instance, 1, 2), std::logic_error); CHECK_THROWS_AS(void_f_int2_info.invoke(instance), std::logic_error); CHECK_THROWS_AS(void_f_int2_info.invoke(instance, 1), std::logic_error); - CHECK_NOTHROW(void_f_int2_info.invoke(instance, 1, 2)); + CHECK_FALSE(void_f_int2_info(instance, 1, 2)); + CHECK_FALSE(void_f_int2_info.invoke(instance, 1, 2)); + CHECK_FALSE(void_f_int2_info.invoke_r(instance, 1, 2)); CHECK_THROWS_AS(void_f_int2_info.invoke(instance, 1.f, 2), std::logic_error); CHECK_THROWS_AS(void_f_int2_info.invoke(instance, 1, 2.f), std::logic_error); CHECK_THROWS_AS(void_f_int2_info.invoke(instance, 1, 2, 3), std::logic_error); const clazz& cinstance = instance; + CHECK_THROWS_AS(void_f_void_info(cinstance), std::logic_error); CHECK_THROWS_AS(void_f_void_info.invoke(cinstance), std::logic_error); + CHECK_THROWS_AS(void_f_void_info.invoke_r(cinstance), std::logic_error); + CHECK_THROWS_AS(void_f_int_info(cinstance, 1), std::logic_error); CHECK_THROWS_AS(void_f_int_info.invoke(cinstance, 1), std::logic_error); + CHECK_THROWS_AS(void_f_int_info.invoke_r(cinstance, 1), std::logic_error); + CHECK_THROWS_AS(void_f_int2_info(cinstance, 1, 2), std::logic_error); CHECK_THROWS_AS(void_f_int2_info.invoke(cinstance, 1, 2), std::logic_error); + CHECK_THROWS_AS(void_f_int2_info.invoke_r(cinstance, 1, 2), std::logic_error); } SUBCASE("int_return") { clazz instance; + CHECK(int_f_void_info(instance)->cast() == 1); CHECK(int_f_void_info.invoke(instance)->cast() == 1); + CHECK(int_f_void_info.invoke_r(instance) == 1); + CHECK_THROWS_AS(int_f_void_info(instance, 1), std::logic_error); CHECK_THROWS_AS(int_f_void_info.invoke(instance, 1), std::logic_error); + CHECK_THROWS_AS(int_f_void_info.invoke_r(instance, 1), std::logic_error); CHECK_THROWS_AS(int_f_int_info.invoke(instance), std::logic_error); + CHECK(int_f_int_info(instance, 1)->cast() == 1); CHECK(int_f_int_info.invoke(instance, 1)->cast() == 1); + CHECK(int_f_int_info.invoke_r(instance, 1) == 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(instance, 1, 2)->cast() == 3); CHECK(int_f_int2_info.invoke(instance, 1, 2)->cast() == 3); + CHECK(int_f_int2_info.invoke_r(instance, 1, 2) == 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_THROWS_AS(int_f_void_info(cinstance), std::logic_error); CHECK_THROWS_AS(int_f_void_info.invoke(cinstance), std::logic_error); + CHECK_THROWS_AS(int_f_void_info.invoke_r(cinstance), std::logic_error); + CHECK_THROWS_AS(int_f_int_info(cinstance, 1), std::logic_error); CHECK_THROWS_AS(int_f_int_info.invoke(cinstance, 1), std::logic_error); + CHECK_THROWS_AS(int_f_int_info.invoke_r(cinstance, 1), std::logic_error); + CHECK_THROWS_AS(int_f_int2_info(cinstance, 1, 2), std::logic_error); CHECK_THROWS_AS(int_f_int2_info.invoke(cinstance, 1, 2), std::logic_error); + CHECK_THROWS_AS(int_f_int2_info.invoke_r(cinstance, 1, 2), std::logic_error); } SUBCASE("int_return_by_value") { meta::value instance{clazz{}}; + CHECK(int_f_void_info(instance)->cast() == 1); CHECK(int_f_void_info.invoke(instance)->cast() == 1); + CHECK(int_f_void_info.invoke_r(instance) == 1); + CHECK(int_f_int_info(instance, 1)->cast() == 1); CHECK(int_f_int_info.invoke(instance, 1)->cast() == 1); + CHECK(int_f_int_info.invoke_r(instance, 1) == 1); + CHECK(int_f_int2_info(instance, 1, 2)->cast() == 3); CHECK(int_f_int2_info.invoke(instance, 1, 2)->cast() == 3); + CHECK(int_f_int2_info.invoke_r(instance, 1, 2) == 3); } } @@ -186,63 +228,90 @@ TEST_CASE("meta/const_method") { SUBCASE("another_instance") { const clazz2 instance; + CHECK_THROWS_AS(void_f_void_info(instance), std::logic_error); CHECK_THROWS_AS(void_f_void_info.invoke(instance), std::logic_error); + CHECK_THROWS_AS(void_f_int_info(instance, 1), std::logic_error); CHECK_THROWS_AS(void_f_int_info.invoke(instance, 1), std::logic_error); + CHECK_THROWS_AS(void_f_int2_info(instance, 1, 2), std::logic_error); CHECK_THROWS_AS(void_f_int2_info.invoke(instance, 1, 2), std::logic_error); } SUBCASE("void_return") { clazz instance; - CHECK_NOTHROW(void_f_void_info.invoke(instance)); + CHECK_FALSE(void_f_void_info(instance)); + CHECK_FALSE(void_f_void_info.invoke(instance)); CHECK_THROWS_AS(void_f_void_info.invoke(instance, 1), std::logic_error); CHECK_THROWS_AS(void_f_int_info.invoke(instance), std::logic_error); - CHECK_NOTHROW(void_f_int_info.invoke(instance, 1)); + CHECK_FALSE(void_f_int_info(instance, 1)); + CHECK_FALSE(void_f_int_info.invoke(instance, 1)); CHECK_THROWS_AS(void_f_int_info.invoke(instance, 1.f), std::logic_error); CHECK_THROWS_AS(void_f_int_info.invoke(instance, 1, 2), std::logic_error); CHECK_THROWS_AS(void_f_int2_info.invoke(instance), std::logic_error); CHECK_THROWS_AS(void_f_int2_info.invoke(instance, 1), std::logic_error); - CHECK_NOTHROW(void_f_int2_info.invoke(instance, 1, 2)); + CHECK_FALSE(void_f_int2_info(instance, 1, 2)); + CHECK_FALSE(void_f_int2_info.invoke(instance, 1, 2)); CHECK_THROWS_AS(void_f_int2_info.invoke(instance, 1.f, 2), std::logic_error); CHECK_THROWS_AS(void_f_int2_info.invoke(instance, 1, 2.f), std::logic_error); CHECK_THROWS_AS(void_f_int2_info.invoke(instance, 1, 2, 3), std::logic_error); const clazz& cinstance = instance; - CHECK_NOTHROW(void_f_void_info.invoke(cinstance)); - CHECK_NOTHROW(void_f_int_info.invoke(cinstance, 1)); - CHECK_NOTHROW(void_f_int2_info.invoke(cinstance, 1, 2)); + CHECK_FALSE(void_f_void_info(cinstance)); + CHECK_FALSE(void_f_void_info.invoke(cinstance)); + CHECK_FALSE(void_f_int_info(cinstance, 1)); + CHECK_FALSE(void_f_int_info.invoke(cinstance, 1)); + CHECK_FALSE(void_f_int2_info(cinstance, 1, 2)); + CHECK_FALSE(void_f_int2_info.invoke(cinstance, 1, 2)); } SUBCASE("int_return") { clazz instance; + CHECK(int_f_void_info(instance)->cast() == 1); CHECK(int_f_void_info.invoke(instance)->cast() == 1); + CHECK(int_f_void_info.invoke_r(instance) == 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(instance, 1)->cast() == 1); CHECK(int_f_int_info.invoke(instance, 1)->cast() == 1); + CHECK(int_f_int_info.invoke_r(instance, 1) == 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(instance, 1, 2)->cast() == 3); CHECK(int_f_int2_info.invoke(instance, 1, 2)->cast() == 3); + CHECK(int_f_int2_info.invoke_r(instance, 1, 2) == 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(cinstance)->cast() == 1); CHECK(int_f_void_info.invoke(cinstance)->cast() == 1); + CHECK(int_f_void_info.invoke_r(cinstance) == 1); + CHECK(int_f_int_info(cinstance, 1)->cast() == 1); CHECK(int_f_int_info.invoke(cinstance, 1)->cast() == 1); + CHECK(int_f_int_info.invoke_r(cinstance, 1) == 1); + CHECK(int_f_int2_info(cinstance, 1, 2)->cast() == 3); CHECK(int_f_int2_info.invoke(cinstance, 1, 2)->cast() == 3); + CHECK(int_f_int2_info.invoke_r(cinstance, 1, 2) == 3); } SUBCASE("int_return_by_value") { meta::value instance{clazz{}}; + CHECK(int_f_void_info(instance)->cast() == 1); CHECK(int_f_void_info.invoke(instance)->cast() == 1); + CHECK(int_f_void_info.invoke_r(instance) == 1); + CHECK(int_f_int_info(instance, 1)->cast() == 1); CHECK(int_f_int_info.invoke(instance, 1)->cast() == 1); + CHECK(int_f_int_info.invoke_r(instance, 1) == 1); + CHECK(int_f_int2_info(instance, 1, 2)->cast() == 3); CHECK(int_f_int2_info.invoke(instance, 1, 2)->cast() == 3); + CHECK(int_f_int2_info.invoke_r(instance, 1, 2) == 3); } } diff --git a/untests/meta_variable_tests.cpp b/untests/meta_variable_tests.cpp index 69318bc..0acc5b8 100644 --- a/untests/meta_variable_tests.cpp +++ b/untests/meta_variable_tests.cpp @@ -39,28 +39,41 @@ TEST_CASE("meta/variable") { { CHECK(variable == 1); + CHECK(variable_info().cast() == 1); CHECK(variable_info.get().cast() == 1); + CHECK(variable_info.get_r() == 1); + CHECK_NOTHROW(variable_info(3)); CHECK_NOTHROW(variable_info.set(3)); + CHECK_THROWS_AS(variable_info(4.f), std::logic_error); CHECK_THROWS_AS(variable_info.set(4.f), std::logic_error); CHECK(variable == 3); + CHECK(variable_info().cast() == 3); CHECK(variable_info.get().cast() == 3); + CHECK(variable_info.get_r() == 3); } { CHECK(cvariable == 2); + CHECK(cvariable_info().cast() == 2); CHECK(cvariable_info.get().cast() == 2); + CHECK(cvariable_info.get_r() == 2); + CHECK_THROWS_AS(cvariable_info(4), std::logic_error); CHECK_THROWS_AS(cvariable_info.set(4), std::logic_error); CHECK(cvariable == 2); + CHECK(cvariable_info().cast() == 2); CHECK(cvariable_info.get().cast() == 2); + CHECK(cvariable_info.get_r() == 2); } { variable = 5; + CHECK(variable_info().cast() == 5); CHECK(variable_info.get().cast() == 5); + CHECK(variable_info.get_r() == 5); } } @@ -78,27 +91,39 @@ TEST_CASE("meta/variable") { { CHECK(clazz::variable == 1); + CHECK(variable_info().cast() == 1); CHECK(variable_info.get().cast() == 1); + CHECK(variable_info.get_r() == 1); + CHECK_NOTHROW(variable_info(3)); CHECK_NOTHROW(variable_info.set(3)); CHECK(clazz::variable == 3); + CHECK(variable_info().cast() == 3); CHECK(variable_info.get().cast() == 3); + CHECK(variable_info.get_r() == 3); } { CHECK(clazz::cvariable == 2); + CHECK(cvariable_info().cast() == 2); CHECK(cvariable_info.get().cast() == 2); + CHECK(cvariable_info.get_r() == 2); + CHECK_THROWS_AS(cvariable_info(4), std::logic_error); CHECK_THROWS_AS(cvariable_info.set(4), std::logic_error); CHECK(clazz::cvariable == 2); + CHECK(cvariable_info().cast() == 2); CHECK(cvariable_info.get().cast() == 2); + CHECK(cvariable_info.get_r() == 2); } { clazz::variable = 5; + CHECK(variable_info().cast() == 5); CHECK(variable_info.get().cast() == 5); + CHECK(variable_info.get_r() == 5); } } } From 093c1fffc6006f479da7942843fd39b866b1523b Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Tue, 13 Jul 2021 14:36:24 +0700 Subject: [PATCH 060/233] value: fix in place const types --- headers/meta.hpp/meta_instance.hpp | 10 ++--- headers/meta.hpp/meta_value.hpp | 65 ++++++++++++++++-------------- untests/meta_value_tests.cpp | 11 +++++ 3 files changed, 51 insertions(+), 35 deletions(-) diff --git a/headers/meta.hpp/meta_instance.hpp b/headers/meta.hpp/meta_instance.hpp index cd8e5b2..229bc03 100644 --- a/headers/meta.hpp/meta_instance.hpp +++ b/headers/meta.hpp/meta_instance.hpp @@ -56,7 +56,7 @@ namespace meta_hpp std::add_pointer_t try_cast() noexcept { static_assert(!std::is_reference_v); - return fid() == get_family_id() + return fid_ == get_family_id() ? static_cast>(data_) : nullptr; } @@ -65,7 +65,7 @@ namespace meta_hpp std::add_pointer_t> try_cast() const noexcept { static_assert(!std::is_reference_v); - return fid() == get_family_id() + return fid_ == get_family_id() ? static_cast>>(data_) : nullptr; } @@ -91,8 +91,8 @@ namespace meta_hpp , typename = std::enable_if_t> , typename = std::enable_if_t> , typename = std::enable_if_t> > - cinstance(const T& data) - : data_{std::addressof(data)} + cinstance(const T& v) + : data_{std::addressof(v)} , fid_{get_family_id()} {} cinstance(const value& v) @@ -115,7 +115,7 @@ namespace meta_hpp std::add_pointer_t> try_cast() const noexcept { static_assert(!std::is_reference_v); - return fid() == get_family_id() + return fid_ == get_family_id() ? static_cast>>(data_) : nullptr; } diff --git a/headers/meta.hpp/meta_value.hpp b/headers/meta.hpp/meta_value.hpp index 12737f2..5c221ed 100644 --- a/headers/meta.hpp/meta_value.hpp +++ b/headers/meta.hpp/meta_value.hpp @@ -69,17 +69,22 @@ namespace meta_hpp return *this; } - template < typename T, typename... Args > + template < typename T, typename U = std::decay_t, typename... Args > explicit value(std::in_place_type_t, Args&&... args) - : raw_{std::in_place_type, std::forward(args)...} - , fid_{get_family_id()} - , traits_{value_detail::get_traits()} {} + : raw_{std::in_place_type, std::forward(args)...} + , fid_{get_family_id()} + , traits_{value_detail::get_traits()} {} - template < typename T, typename U, typename... Args > - explicit value(std::in_place_type_t, std::initializer_list ilist, Args&&... args) - : raw_{std::in_place_type, ilist, std::forward(args)...} - , fid_{get_family_id()} - , traits_{value_detail::get_traits()} {} + template < typename T, typename U = std::decay_t, typename I, typename... Args > + explicit value(std::in_place_type_t, std::initializer_list ilist, Args&&... args) + : raw_{std::in_place_type, ilist, std::forward(args)...} + , fid_{get_family_id()} + , traits_{value_detail::get_traits()} {} + + template < typename T > + bool has_type() const noexcept { + return fid_ == get_family_id(); + } template < typename T > T cast() && { @@ -133,7 +138,7 @@ namespace meta_hpp , typename U = std::decay_t , typename = std::enable_if_t> > bool equals(T&& other) const { - return fid() == get_family_id() + return fid_ == get_family_id() && std::equal_to<>{}(*try_cast(), std::forward(other)); } @@ -146,7 +151,7 @@ namespace meta_hpp unsigned to_uint() const { return cast(); } float to_float() const { return cast(); } double to_double() const { return cast(); } - std::string to_string() const { return cast(); } + const std::string& to_string() const { return cast(); } std::int8_t to_int8() const { return cast(); } std::int16_t to_int16() const { return cast(); } @@ -162,26 +167,26 @@ namespace meta_hpp std::size_t to_size_t() const { return cast(); } std::uintptr_t to_uintptr_t() const { return cast(); } public: - bool is_bool() const noexcept { return !!try_cast(); } - bool is_int() const noexcept { return !!try_cast(); } - bool is_uint() const noexcept { return !!try_cast(); } - bool is_float() const noexcept { return !!try_cast(); } - bool is_double() const noexcept { return !!try_cast(); } - bool is_string() const noexcept { return !!try_cast(); } + bool is_bool() const noexcept { return has_type(); } + bool is_int() const noexcept { return has_type(); } + bool is_uint() const noexcept { return has_type(); } + bool is_float() const noexcept { return has_type(); } + bool is_double() const noexcept { return has_type(); } + bool is_string() const noexcept { return has_type(); } - bool is_int8() const noexcept { return !!try_cast(); } - bool is_int16() const noexcept { return !!try_cast(); } - bool is_int32() const noexcept { return !!try_cast(); } - bool is_int64() const noexcept { return !!try_cast(); } - bool is_ptrdiff_t() const noexcept { return !!try_cast(); } - bool is_intptr_t() const noexcept { return !!try_cast(); } + bool is_int8() const noexcept { return has_type(); } + bool is_int16() const noexcept { return has_type(); } + bool is_int32() const noexcept { return has_type(); } + bool is_int64() const noexcept { return has_type(); } + bool is_ptrdiff_t() const noexcept { return has_type(); } + bool is_intptr_t() const noexcept { return has_type(); } - bool is_uint8() const noexcept { return !!try_cast(); } - bool is_uint16() const noexcept { return !!try_cast(); } - bool is_uint32() const noexcept { return !!try_cast(); } - bool is_uint64() const noexcept { return !!try_cast(); } - bool is_size_t() const noexcept { return !!try_cast(); } - bool is_uintptr_t() const noexcept { return !!try_cast(); } + bool is_uint8() const noexcept { return has_type(); } + bool is_uint16() const noexcept { return has_type(); } + bool is_uint32() const noexcept { return has_type(); } + bool is_uint64() const noexcept { return has_type(); } + bool is_size_t() const noexcept { return has_type(); } + bool is_uintptr_t() const noexcept { return has_type(); } private: std::any raw_; family_id fid_; @@ -213,7 +218,7 @@ namespace meta_hpp::value_detail if constexpr ( std::is_invocable_v, T, T> ) { return std::equal_to<>{}(*l.try_cast(), *r.try_cast()); } else { - return std::addressof(l) == std::addressof(r); + return value_cdata(l) == value_cdata(r); } } } diff --git a/untests/meta_value_tests.cpp b/untests/meta_value_tests.cpp index 9231483..bb06099 100644 --- a/untests/meta_value_tests.cpp +++ b/untests/meta_value_tests.cpp @@ -69,14 +69,25 @@ TEST_CASE("meta/value") { CHECK(meta::value{std::in_place_type, std::uint64_t{1}}.is_uint64()); CHECK(meta::value{std::in_place_type, std::size_t{1}}.is_size_t()); CHECK(meta::value{std::in_place_type, std::uintptr_t{1}}.is_uintptr_t()); + + SUBCASE("in_place") { + CHECK(meta::value{std::in_place_type, std::uint8_t{1}}.is_uint8()); + CHECK(meta::value{std::in_place_type, std::uint8_t{1}}.is_uint8()); + CHECK(meta::value{std::in_place_type, std::uint8_t{1}}.is_uint8()); + CHECK(meta::value{std::in_place_type, std::uint8_t{1}}.is_uint8()); + } } TEST_CASE("meta/value/fid") { namespace meta = meta_hpp; using namespace std::string_literals; + CHECK(meta::value{clazz{}}.has_type()); CHECK(meta::value{clazz{}}.fid() == meta::get_family_id()); + + CHECK(meta::value{clazz2{}}.has_type()); CHECK(meta::value{clazz2{}}.fid() == meta::get_family_id()); + CHECK(meta::value{clazz{}}.fid() != meta::value{clazz2{}}.fid()); { From ae9c4b11b46888b7aba01f3bf6b113278086d562 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Tue, 13 Jul 2021 15:01:27 +0700 Subject: [PATCH 061/233] fix return local scope variable after cast --- headers/meta.hpp/meta_ctor_info.hpp | 6 ++-- headers/meta.hpp/meta_field_info.hpp | 6 ++-- headers/meta.hpp/meta_function_info.hpp | 6 ++-- headers/meta.hpp/meta_method_info.hpp | 6 ++-- headers/meta.hpp/meta_value.hpp | 39 ++++++++++++------------- headers/meta.hpp/meta_variable_info.hpp | 6 ++-- 6 files changed, 33 insertions(+), 36 deletions(-) diff --git a/headers/meta.hpp/meta_ctor_info.hpp b/headers/meta.hpp/meta_ctor_info.hpp index 4a41981..b646da7 100644 --- a/headers/meta.hpp/meta_ctor_info.hpp +++ b/headers/meta.hpp/meta_ctor_info.hpp @@ -131,9 +131,9 @@ namespace meta_hpp } } - template < typename R, typename... Args > - R invoke_r(Args&&... args) const { - return invoke(std::forward(args)...).template cast(); + template < typename R, typename Rp = std::decay_t, typename... Args > + Rp invoke_r(Args&&... args) const { + return invoke(std::forward(args)...).template cast(); } template < typename... Args > diff --git a/headers/meta.hpp/meta_field_info.hpp b/headers/meta.hpp/meta_field_info.hpp index f6e27b1..4241694 100644 --- a/headers/meta.hpp/meta_field_info.hpp +++ b/headers/meta.hpp/meta_field_info.hpp @@ -122,9 +122,9 @@ namespace meta_hpp return getter_(instance); } - template < typename R > - R get_r(cinstance instance) const { - return get(instance).cast(); + template < typename R, typename Rp = std::decay_t > + Rp get_r(cinstance instance) const { + return get(instance).template cast(); } template < typename Value > diff --git a/headers/meta.hpp/meta_function_info.hpp b/headers/meta.hpp/meta_function_info.hpp index c130614..4ae51cd 100644 --- a/headers/meta.hpp/meta_function_info.hpp +++ b/headers/meta.hpp/meta_function_info.hpp @@ -134,10 +134,10 @@ namespace meta_hpp } } - template < typename R, typename... Args > - std::optional invoke_r(Args&&... args) const { + template < typename R, typename Rp = std::decay_t, typename... Args > + std::optional invoke_r(Args&&... args) const { if ( std::optional r = invoke(std::forward(args)...) ) { - return std::move(r)->template cast(); + return std::move(r)->template cast(); } return std::nullopt; } diff --git a/headers/meta.hpp/meta_method_info.hpp b/headers/meta.hpp/meta_method_info.hpp index 017c973..c6a13b0 100644 --- a/headers/meta.hpp/meta_method_info.hpp +++ b/headers/meta.hpp/meta_method_info.hpp @@ -222,10 +222,10 @@ namespace meta_hpp } } - template < typename R, typename T, typename... Args > - std::optional invoke_r(T& inst, Args&&... args) const { + template < typename R, typename Rp = std::decay_t, typename T, typename... Args > + std::optional invoke_r(T& inst, Args&&... args) const { if ( std::optional r = invoke(inst, std::forward(args)...) ) { - return std::move(r)->template cast(); + return std::move(r)->template cast(); } return std::nullopt; } diff --git a/headers/meta.hpp/meta_value.hpp b/headers/meta.hpp/meta_value.hpp index 5c221ed..e88a78c 100644 --- a/headers/meta.hpp/meta_value.hpp +++ b/headers/meta.hpp/meta_value.hpp @@ -53,33 +53,31 @@ namespace meta_hpp value& operator=(value&&) = default; value& operator=(const value&) = default; - template < typename T - , typename U = std::decay_t - , typename = std::enable_if_t> > + template < typename T, typename Tp = std::decay_t + , typename = std::enable_if_t> > value(T&& val) : raw_{std::forward(val)} - , fid_{get_family_id()} - , traits_{value_detail::get_traits()} {} + , fid_{get_family_id()} + , traits_{value_detail::get_traits()} {} - template < typename T - , typename U = std::decay_t - , typename = std::enable_if_t> > + template < typename T, typename Tp = std::decay_t + , typename = std::enable_if_t> > value& operator=(T&& val) { value{std::forward(val)}.swap(*this); return *this; } - template < typename T, typename U = std::decay_t, typename... Args > + template < typename T, typename Tp = std::decay_t, typename... Args > explicit value(std::in_place_type_t, Args&&... args) - : raw_{std::in_place_type, std::forward(args)...} - , fid_{get_family_id()} - , traits_{value_detail::get_traits()} {} + : raw_{std::in_place_type, std::forward(args)...} + , fid_{get_family_id()} + , traits_{value_detail::get_traits()} {} - template < typename T, typename U = std::decay_t, typename I, typename... Args > + template < typename T, typename Tp = std::decay_t, typename I, typename... Args > explicit value(std::in_place_type_t, std::initializer_list ilist, Args&&... args) - : raw_{std::in_place_type, ilist, std::forward(args)...} - , fid_{get_family_id()} - , traits_{value_detail::get_traits()} {} + : raw_{std::in_place_type, ilist, std::forward(args)...} + , fid_{get_family_id()} + , traits_{value_detail::get_traits()} {} template < typename T > bool has_type() const noexcept { @@ -134,12 +132,11 @@ namespace meta_hpp swap(traits_, other.traits_); } - template < typename T - , typename U = std::decay_t - , typename = std::enable_if_t> > + template < typename T, typename Tp = std::decay_t + , typename = std::enable_if_t> > bool equals(T&& other) const { - return fid_ == get_family_id() - && std::equal_to<>{}(*try_cast(), std::forward(other)); + return fid_ == get_family_id() + && std::equal_to<>{}(*try_cast(), std::forward(other)); } bool equals(const value& other) const { diff --git a/headers/meta.hpp/meta_variable_info.hpp b/headers/meta.hpp/meta_variable_info.hpp index 2c2a6d7..a338e78 100644 --- a/headers/meta.hpp/meta_variable_info.hpp +++ b/headers/meta.hpp/meta_variable_info.hpp @@ -96,9 +96,9 @@ namespace meta_hpp return getter_(); } - template < typename R > - R get_r() const { - return get().cast(); + template < typename R, typename Rp = std::decay_t > + Rp get_r() const { + return get().template cast(); } template < typename Value > From df54d1c9f477e01b53c405f716419044371112d4 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Mon, 2 Aug 2021 19:46:59 +0700 Subject: [PATCH 062/233] start again from scratch --- headers/meta.hpp/meta.hpp | 32 --- headers/meta.hpp/meta_class.hpp | 81 ------ headers/meta.hpp/meta_class_info.hpp | 164 ------------ headers/meta.hpp/meta_ctor.hpp | 43 --- headers/meta.hpp/meta_ctor_info.hpp | 188 -------------- headers/meta.hpp/meta_data.hpp | 37 --- headers/meta.hpp/meta_data_info.hpp | 63 ----- headers/meta.hpp/meta_field.hpp | 42 --- headers/meta.hpp/meta_field_info.hpp | 187 ------------- headers/meta.hpp/meta_function.hpp | 42 --- headers/meta.hpp/meta_function_info.hpp | 191 -------------- headers/meta.hpp/meta_fwd.hpp | 257 ------------------ headers/meta.hpp/meta_instance.hpp | 126 --------- headers/meta.hpp/meta_method.hpp | 42 --- headers/meta.hpp/meta_method_info.hpp | 283 -------------------- headers/meta.hpp/meta_namespace.hpp | 65 ----- headers/meta.hpp/meta_namespace_info.hpp | 117 --------- headers/meta.hpp/meta_registry.hpp | 246 ------------------ headers/meta.hpp/meta_type.hpp | 120 --------- headers/meta.hpp/meta_value.hpp | 221 ---------------- headers/meta.hpp/meta_variable.hpp | 42 --- headers/meta.hpp/meta_variable_info.hpp | 159 ------------ untests/meta_class_tests.cpp | 165 ------------ untests/meta_ctor_tests.cpp | 138 ---------- untests/meta_data_tests.cpp | 179 ------------- untests/meta_examples.cpp | 190 -------------- untests/meta_family_tests.cpp | 147 ----------- untests/meta_field_tests.cpp | 95 ------- untests/meta_function_tests.cpp | 118 --------- untests/meta_method_tests.cpp | 317 ----------------------- untests/meta_namespace_tests.cpp | 119 --------- untests/meta_registry_tests.cpp | 209 --------------- untests/meta_tests.cpp | 15 ++ untests/meta_type_tests.cpp | 76 ------ untests/meta_value_tests.cpp | 200 -------------- untests/meta_variable_tests.cpp | 129 --------- 36 files changed, 15 insertions(+), 4830 deletions(-) delete mode 100644 headers/meta.hpp/meta_class.hpp delete mode 100644 headers/meta.hpp/meta_class_info.hpp delete mode 100644 headers/meta.hpp/meta_ctor.hpp delete mode 100644 headers/meta.hpp/meta_ctor_info.hpp delete mode 100644 headers/meta.hpp/meta_data.hpp delete mode 100644 headers/meta.hpp/meta_data_info.hpp delete mode 100644 headers/meta.hpp/meta_field.hpp delete mode 100644 headers/meta.hpp/meta_field_info.hpp delete mode 100644 headers/meta.hpp/meta_function.hpp delete mode 100644 headers/meta.hpp/meta_function_info.hpp delete mode 100644 headers/meta.hpp/meta_fwd.hpp delete mode 100644 headers/meta.hpp/meta_instance.hpp delete mode 100644 headers/meta.hpp/meta_method.hpp delete mode 100644 headers/meta.hpp/meta_method_info.hpp delete mode 100644 headers/meta.hpp/meta_namespace.hpp delete mode 100644 headers/meta.hpp/meta_namespace_info.hpp delete mode 100644 headers/meta.hpp/meta_registry.hpp delete mode 100644 headers/meta.hpp/meta_type.hpp delete mode 100644 headers/meta.hpp/meta_value.hpp delete mode 100644 headers/meta.hpp/meta_variable.hpp delete mode 100644 headers/meta.hpp/meta_variable_info.hpp delete mode 100644 untests/meta_class_tests.cpp delete mode 100644 untests/meta_ctor_tests.cpp delete mode 100644 untests/meta_data_tests.cpp delete mode 100644 untests/meta_examples.cpp delete mode 100644 untests/meta_family_tests.cpp delete mode 100644 untests/meta_field_tests.cpp delete mode 100644 untests/meta_function_tests.cpp delete mode 100644 untests/meta_method_tests.cpp delete mode 100644 untests/meta_namespace_tests.cpp delete mode 100644 untests/meta_registry_tests.cpp create mode 100644 untests/meta_tests.cpp delete mode 100644 untests/meta_type_tests.cpp delete mode 100644 untests/meta_value_tests.cpp delete mode 100644 untests/meta_variable_tests.cpp diff --git a/headers/meta.hpp/meta.hpp b/headers/meta.hpp/meta.hpp index eb2532c..1c5f3b4 100644 --- a/headers/meta.hpp/meta.hpp +++ b/headers/meta.hpp/meta.hpp @@ -5,35 +5,3 @@ ******************************************************************************/ #pragma once - -#include "meta_fwd.hpp" - -#include "meta_instance.hpp" -#include "meta_value.hpp" - -#include "meta_registry.hpp" -#include "meta_type.hpp" - -#include "meta_class.hpp" -#include "meta_class_info.hpp" - -#include "meta_ctor.hpp" -#include "meta_ctor_info.hpp" - -#include "meta_data.hpp" -#include "meta_data_info.hpp" - -#include "meta_field.hpp" -#include "meta_field_info.hpp" - -#include "meta_function.hpp" -#include "meta_function_info.hpp" - -#include "meta_method.hpp" -#include "meta_method_info.hpp" - -#include "meta_namespace.hpp" -#include "meta_namespace_info.hpp" - -#include "meta_variable.hpp" -#include "meta_variable_info.hpp" diff --git a/headers/meta.hpp/meta_class.hpp b/headers/meta.hpp/meta_class.hpp deleted file mode 100644 index 545acff..0000000 --- a/headers/meta.hpp/meta_class.hpp +++ /dev/null @@ -1,81 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "meta_fwd.hpp" - -#include "meta_ctor.hpp" -#include "meta_data.hpp" -#include "meta_field.hpp" -#include "meta_function.hpp" -#include "meta_method.hpp" -#include "meta_variable.hpp" - -#include "meta_class_info.hpp" - -namespace meta_hpp -{ - template < typename Class > - class class_ { - public: - explicit class_(std::string id) - : info_{detail::typename_arg, std::move(id)} {} - - const class_info& make_info() const { - return info_; - } - - template < typename... Internals > - class_& operator()(Internals&&...internals) { - (add_(std::forward(internals)), ...); - return *this; - } - private: - template < typename InternalClass > - void add_(class_ internal) { - class_info info = std::move(internal).make_info(); - detail::merge_with(info_.classes_, info.id(), info, &class_info::merge); - } - - template < typename... Args > - void add_(ctor_ internal) { - ctor_info info = std::move(internal).template make_info(); - detail::merge_with(info_.ctors_, info.family(), info, &ctor_info::merge); - } - - void add_(data_ internal) { - data_info info = std::move(internal).make_info(); - detail::merge_with(info_.datas_, info.id(), info, &data_info::merge); - } - - template < typename FieldType > - void add_(field_ internal) { - field_info info = std::move(internal).make_info(); - detail::merge_with(info_.fields_, info.id(), info, &field_info::merge); - } - - template < typename FunctionType > - void add_(function_ internal) { - function_info info = std::move(internal).make_info(); - detail::merge_with(info_.functions_, info.id(), info, &function_info::merge); - } - - template < typename MethodType > - void add_(method_ internal) { - method_info info = std::move(internal).make_info(); - detail::merge_with(info_.methods_, info.id(), info, &method_info::merge); - } - - template < typename VariableType > - void add_(variable_ internal) { - variable_info info = std::move(internal).make_info(); - detail::merge_with(info_.variables_, info.id(), info, &variable_info::merge); - } - private: - class_info info_; - }; -} diff --git a/headers/meta.hpp/meta_class_info.hpp b/headers/meta.hpp/meta_class_info.hpp deleted file mode 100644 index afe0277..0000000 --- a/headers/meta.hpp/meta_class_info.hpp +++ /dev/null @@ -1,164 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "meta_fwd.hpp" -#include "meta_value.hpp" - -#include "meta_ctor_info.hpp" -#include "meta_data_info.hpp" -#include "meta_field_info.hpp" -#include "meta_function_info.hpp" -#include "meta_method_info.hpp" -#include "meta_variable_info.hpp" - -namespace meta_hpp -{ - class class_info { - public: - class_info() = delete; - - class_info(class_info&&) = default; - class_info(const class_info&) = default; - - class_info& operator=(class_info&&) = default; - class_info& operator=(const class_info&) = default; - public: - const std::string& id() const noexcept { - return id_; - } - - family_id family() const noexcept { - return family_; - } - - template < typename F > - void each_class(F&& f) const { - for ( auto&& id_info : classes_ ) { - std::invoke(f, id_info.second); - } - } - - template < typename F > - void each_ctor(F&& f) const { - for ( auto&& family_info : ctors_ ) { - std::invoke(f, family_info.second); - } - } - - template < typename F > - void each_data(F&& f) const { - for ( auto&& id_info : datas_ ) { - std::invoke(f, id_info.second); - } - } - - template < typename F > - void each_field(F&& f) const { - for ( auto&& id_info : fields_ ) { - std::invoke(f, id_info.second); - } - } - - template < typename F > - void each_function(F&& f) const { - for ( auto&& id_info : functions_ ) { - std::invoke(f, id_info.second); - } - } - - template < typename F > - void each_method(F&& f) const { - for ( auto&& id_info : methods_ ) { - std::invoke(f, id_info.second); - } - } - - template < typename F > - void each_variable(F&& f) const { - for ( auto&& id_info : variables_ ) { - std::invoke(f, id_info.second); - } - } - - template < typename F > - void visit(F&& f) const { - each_class(f); - each_ctor(f); - each_data(f); - each_field(f); - each_function(f); - each_method(f); - each_variable(f); - } - - std::optional get_class(std::string_view id) const { - return detail::find_opt(classes_, id); - } - - template < typename... Args > - std::optional get_ctor() const { - for ( auto&& family_info : ctors_ ) { - if ( family_info.second.is_invocable() ) { - return family_info.second; - } - } - return std::nullopt; - } - - std::optional get_data(std::string_view id) const { - return detail::find_opt(datas_, id); - } - - std::optional get_field(std::string_view id) const { - return detail::find_opt(fields_, id); - } - - std::optional get_function(std::string_view id) const { - return detail::find_opt(functions_, id); - } - - std::optional get_method(std::string_view id) const { - return detail::find_opt(methods_, id); - } - - std::optional get_variable(std::string_view id) const { - return detail::find_opt(variables_, id); - } - - void merge(const class_info& other) { - if ( id() != other.id() || family() != other.family() ) { - throw std::logic_error("class_info::merge failed"); - } - detail::merge_with(classes_, other.classes_, &class_info::merge); - detail::merge_with(ctors_, other.ctors_, &ctor_info::merge); - detail::merge_with(datas_, other.datas_, &data_info::merge); - detail::merge_with(fields_, other.fields_, &field_info::merge); - detail::merge_with(functions_, other.functions_, &function_info::merge); - detail::merge_with(methods_, other.methods_, &method_info::merge); - detail::merge_with(variables_, other.variables_, &variable_info::merge); - } - private: - template < typename Class > - friend class class_; - - template < typename Class > - class_info(detail::typename_arg_t, std::string id) - : id_{std::move(id)} - , family_{get_family_id()} {} - private: - std::string id_; - family_id family_; - std::map> classes_; - std::map> ctors_; - std::map> datas_; - std::map> fields_; - std::map> functions_; - std::map> methods_; - std::map> variables_; - }; -} diff --git a/headers/meta.hpp/meta_ctor.hpp b/headers/meta.hpp/meta_ctor.hpp deleted file mode 100644 index d338ced..0000000 --- a/headers/meta.hpp/meta_ctor.hpp +++ /dev/null @@ -1,43 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "meta_fwd.hpp" - -#include "meta_data.hpp" - -#include "meta_ctor_info.hpp" - -namespace meta_hpp -{ - template < typename... Args > - class ctor_ { - public: - ctor_() = default; - - template < typename Class > - ctor_info make_info() const { - static_assert(std::is_constructible_v); - ctor_info info{detail::typename_arg, detail::typename_args}; - detail::merge_with(info.datas_, datas_, &data_info::merge); - return info; - } - - template < typename... Internals > - ctor_& operator()(Internals&&...internals) { - (add_(std::forward(internals)), ...); - return *this; - } - private: - void add_(data_ internal) { - data_info info = std::move(internal).make_info(); - detail::merge_with(datas_, info.id(), info, &data_info::merge); - } - private: - std::map> datas_; - }; -} diff --git a/headers/meta.hpp/meta_ctor_info.hpp b/headers/meta.hpp/meta_ctor_info.hpp deleted file mode 100644 index b646da7..0000000 --- a/headers/meta.hpp/meta_ctor_info.hpp +++ /dev/null @@ -1,188 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "meta_fwd.hpp" - -#include "meta_value.hpp" - -#include "meta_data_info.hpp" - -namespace meta_hpp::ctor_detail -{ - template < typename Class, typename... Args, std::size_t... Is > - value raw_invoke_impl( - value* args, - std::index_sequence) - { - using ct = detail::ctor_traits; - using return_type = typename ct::return_type; - using argument_types = typename ct::argument_types; - - [[maybe_unused]] auto typed_arguments = std::make_tuple( - (args + Is)->try_cast>()...); - - if ( !(std::get(typed_arguments) && ...) ) { - throw std::logic_error("an attempt to call a ctor with incorrect argument types"); - } - - return_type return_value{std::move(*std::get(typed_arguments))...}; - return value{std::move(return_value)}; - } - - template < typename Class, typename... Args > - value raw_invoke( - value* args, - std::size_t arg_count) - { - using ct = detail::ctor_traits; - - if ( arg_count != ct::arity ) { - throw std::logic_error("an attempt to call a ctor with an incorrect arity"); - } - - return raw_invoke_impl(args, std::make_index_sequence()); - } - - using ctor_invoke = std::function; - - template < typename Class, typename... Args > - ctor_invoke make_invoke() { - using namespace std::placeholders; - return std::bind(&raw_invoke, _1, _2); - } - - template < typename Class, typename... Args > - family_id make_return_type() { - using ct = detail::ctor_traits; - using return_type = typename ct::return_type; - return get_family_id(); - } - - template < typename Class, typename... Args, std::size_t... Is > - std::vector make_argument_types_impl(std::index_sequence) { - using ct = detail::ctor_traits; - using argument_types = typename ct::argument_types; - return { get_family_id>()... }; - } - - template < typename Class, typename... Args > - std::vector make_argument_types() { - using ct = detail::ctor_traits; - return make_argument_types_impl(std::make_index_sequence()); - } - - template < typename... Args, std::size_t... Is > - bool parameters_equal(const std::vector& parameters, std::index_sequence) { - if ( parameters.size() != sizeof...(Args) ) { - return false; - } - return ((get_family_id>>() == parameters[Is]) && ... ); - } - - template < typename... Args > - bool parameters_equal(const std::vector& parameters) { - return parameters_equal(parameters, std::make_index_sequence()); - } -} - -namespace meta_hpp -{ - class ctor_info { - public: - ctor_info() = delete; - - ctor_info(ctor_info&&) = default; - ctor_info(const ctor_info&) = default; - - ctor_info& operator=(ctor_info&&) = default; - ctor_info& operator=(const ctor_info&) = default; - public: - family_id family() const noexcept { - return family_; - } - - std::size_t arity() const noexcept { - return argument_types_.size(); - } - - family_id return_type() const noexcept { - return return_type_; - } - - std::optional argument_type(std::size_t index) const noexcept { - if ( index < argument_types_.size() ) { - return argument_types_[index]; - } - return std::nullopt; - } - - template < typename... Args > - value invoke(Args&&... args) const { - if constexpr ( sizeof...(Args) > 0u ) { - std::array vargs{std::forward(args)...}; - return invoke_(vargs.data(), vargs.size()); - } else { - return invoke_(nullptr, 0u); - } - } - - template < typename R, typename Rp = std::decay_t, typename... Args > - Rp invoke_r(Args&&... args) const { - return invoke(std::forward(args)...).template cast(); - } - - template < typename... Args > - value operator()(Args&&... args) const { - return invoke(std::forward(args)...); - } - - template < typename... Args > - bool is_invocable() const noexcept { - return ctor_detail::parameters_equal(argument_types_); - } - - template < typename F > - void each_data(F&& f) const { - for ( auto&& id_info : datas_ ) { - std::invoke(f, id_info.second); - } - } - - template < typename F > - void visit(F&& f) const { - each_data(f); - } - - std::optional get_data(std::string_view id) const { - return detail::find_opt(datas_, id); - } - - void merge(const ctor_info& other) { - if ( family() != other.family() ) { - throw std::logic_error("ctor_info::merge failed"); - } - detail::merge_with(datas_, other.datas_, &data_info::merge); - } - private: - template < typename... Args > - friend class ctor_; - - template < typename Class, typename... Args > - ctor_info(detail::typename_arg_t, detail::typename_args_t) - : family_{get_family_id>()} - , return_type_{ctor_detail::make_return_type()} - , argument_types_{ctor_detail::make_argument_types()} - , invoke_{ctor_detail::make_invoke()} {} - private: - family_id family_; - family_id return_type_; - std::vector argument_types_; - ctor_detail::ctor_invoke invoke_; - std::map> datas_; - }; -} diff --git a/headers/meta.hpp/meta_data.hpp b/headers/meta.hpp/meta_data.hpp deleted file mode 100644 index 3ce39f8..0000000 --- a/headers/meta.hpp/meta_data.hpp +++ /dev/null @@ -1,37 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "meta_fwd.hpp" - -#include "meta_data_info.hpp" - -namespace meta_hpp -{ - class data_ { - public: - explicit data_(std::string id, value value) - : info_{std::move(id), std::move(value)} {} - - const data_info& make_info() const { - return info_; - } - - template < typename... Internals > - data_& operator()(Internals&&...internals) { - (add_(std::forward(internals)), ...); - return *this; - } - private: - void add_(data_ internal) { - data_info info = std::move(internal).make_info(); - detail::merge_with(info_.datas_, info.id(), info, &data_info::merge); - } - private: - data_info info_; - }; -} diff --git a/headers/meta.hpp/meta_data_info.hpp b/headers/meta.hpp/meta_data_info.hpp deleted file mode 100644 index fc32ab4..0000000 --- a/headers/meta.hpp/meta_data_info.hpp +++ /dev/null @@ -1,63 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "meta_fwd.hpp" -#include "meta_value.hpp" - -namespace meta_hpp -{ - class data_info { - public: - data_info() = delete; - - data_info(data_info&&) = default; - data_info(const data_info&) = default; - - data_info& operator=(data_info&&) = default; - data_info& operator=(const data_info&) = default; - public: - const std::string& id() const noexcept { - return id_; - } - - const value& get() const noexcept { - return value_; - } - - template < typename F > - void each_data(F&& f) const { - for ( auto&& id_info : datas_ ) { - std::invoke(f, id_info.second); - } - } - - template < typename F > - void visit(F&& f) const { - each_data(f); - } - - std::optional get_data(std::string_view id) const { - return detail::find_opt(datas_, id); - } - - void merge(const data_info& other) { - value_ = other.value_; - detail::merge_with(datas_, other.datas_, &data_info::merge); - } - private: - friend class data_; - - data_info(std::string id, value value) - : id_{std::move(id)} - , value_{std::move(value)} {} - private: - std::string id_; - value value_; - std::map> datas_; - }; -} diff --git a/headers/meta.hpp/meta_field.hpp b/headers/meta.hpp/meta_field.hpp deleted file mode 100644 index 0b5481b..0000000 --- a/headers/meta.hpp/meta_field.hpp +++ /dev/null @@ -1,42 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "meta_fwd.hpp" - -#include "meta_data.hpp" - -#include "meta_field_info.hpp" - -namespace meta_hpp -{ - template < typename FieldType > - class field_ { - public: - static_assert(std::is_member_object_pointer_v); - - explicit field_(std::string id, FieldType field_ptr) - : info_{std::move(id), field_ptr} {} - - const field_info& make_info() const { - return info_; - } - - template < typename... Internals > - field_& operator()(Internals&&...internals) { - (add_(std::forward(internals)), ...); - return *this; - } - private: - void add_(data_ internal) { - data_info info = std::move(internal).make_info(); - detail::merge_with(info_.datas_, info.id(), info, &data_info::merge); - } - private: - field_info info_; - }; -} diff --git a/headers/meta.hpp/meta_field_info.hpp b/headers/meta.hpp/meta_field_info.hpp deleted file mode 100644 index 4241694..0000000 --- a/headers/meta.hpp/meta_field_info.hpp +++ /dev/null @@ -1,187 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "meta_fwd.hpp" - -#include "meta_instance.hpp" -#include "meta_value.hpp" - -#include "meta_data_info.hpp" - -namespace meta_hpp::field_detail -{ - template < typename FieldType > - value raw_getter( - FieldType field, - cinstance instance) - { - using ft = detail::field_traits; - using value_type = typename ft::value_type; - using instance_type = typename ft::instance_type; - - const instance_type* typed_instance{instance.try_cast()}; - if ( !typed_instance ) { - throw std::logic_error("an attempt to get a field with incorrect instance type"); - } - - value_type typed_value{std::invoke(field, *typed_instance)}; - return value{std::move(typed_value)}; - } - - template < typename FieldType > - void raw_setter( - [[maybe_unused]] FieldType field, - [[maybe_unused]] instance instance, - [[maybe_unused]] value value) - { - using ft = detail::field_traits; - using value_type = typename ft::value_type; - using instance_type = typename ft::instance_type; - - if constexpr ( !ft::is_const ) { - instance_type* typed_instance{instance.try_cast()}; - if ( !typed_instance ) { - throw std::logic_error("an attempt to set a field with incorrect instance type"); - } - - value_type* typed_value{value.try_cast()}; - if ( !typed_value ) { - throw std::logic_error("an attempt to set a field with incorrect argument type"); - } - - std::invoke(field, *typed_instance) = std::move(*typed_value); - } else { - throw std::logic_error("an attempt to change a constant field"); - } - } - - using field_getter = std::function; - using field_setter = std::function; - - template < typename FieldType > - field_getter make_getter(FieldType field) { - using namespace std::placeholders; - return std::bind(&raw_getter, field, _1); - } - - template < typename FieldType > - field_setter make_setter(FieldType field) { - using namespace std::placeholders; - return std::bind(&raw_setter, field, _1, _2); - } - - template < typename FieldType > - family_id make_value_type() noexcept { - using ft = detail::field_traits; - using value_type = typename ft::value_type; - return get_family_id(); - } - - template < typename FieldType > - family_id make_instance_type() noexcept { - using ft = detail::field_traits; - using instance_type = typename ft::instance_type; - return get_family_id(); - } -} - -namespace meta_hpp -{ - class field_info { - public: - field_info() = delete; - - field_info(field_info&&) = default; - field_info(const field_info&) = default; - - field_info& operator=(field_info&&) = default; - field_info& operator=(const field_info&) = default; - public: - const std::string& id() const noexcept { - return id_; - } - - family_id family() const noexcept { - return family_; - } - - family_id value_type() const noexcept { - return value_type_; - } - - family_id instance_type() const noexcept { - return instance_type_; - } - - value get(cinstance instance) const { - return getter_(instance); - } - - template < typename R, typename Rp = std::decay_t > - Rp get_r(cinstance instance) const { - return get(instance).template cast(); - } - - template < typename Value > - void set(instance instance, Value&& value) const { - setter_(instance, std::forward(value)); - } - - value operator()(cinstance instance) const { - return get(instance); - } - - template < typename Value > - void operator()(instance instance, Value&& value) const { - set(instance, std::forward(value)); - } - - template < typename F > - void each_data(F&& f) const { - for ( auto&& id_info : datas_ ) { - std::invoke(f, id_info.second); - } - } - - template < typename F > - void visit(F&& f) const { - each_data(f); - } - - std::optional get_data(std::string_view id) const { - return detail::find_opt(datas_, id); - } - - void merge(const field_info& other) { - if ( id() != other.id() || family() != other.family() ) { - throw std::logic_error("field_info::merge failed"); - } - detail::merge_with(datas_, other.datas_, &data_info::merge); - } - private: - template < typename FieldType > - friend class field_; - - template < typename FieldType > - field_info(std::string id, FieldType field_ptr) - : id_{std::move(id)} - , family_{get_family_id()} - , value_type_{field_detail::make_value_type()} - , instance_type_{field_detail::make_instance_type()} - , getter_{field_detail::make_getter(field_ptr)} - , setter_{field_detail::make_setter(field_ptr)} {} - private: - std::string id_; - family_id family_; - family_id value_type_; - family_id instance_type_; - field_detail::field_getter getter_; - field_detail::field_setter setter_; - std::map> datas_; - }; -} diff --git a/headers/meta.hpp/meta_function.hpp b/headers/meta.hpp/meta_function.hpp deleted file mode 100644 index c1ab125..0000000 --- a/headers/meta.hpp/meta_function.hpp +++ /dev/null @@ -1,42 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "meta_fwd.hpp" - -#include "meta_data.hpp" - -#include "meta_function_info.hpp" - -namespace meta_hpp -{ - template < typename FunctionType > - class function_ { - public: - static_assert(std::is_function_v>); - - explicit function_(std::string id, FunctionType function_ptr) - : info_{std::move(id), function_ptr} {} - - const function_info& make_info() const { - return info_; - } - - template < typename... Internals > - function_& operator()(Internals&&...internals) { - (add_(std::forward(internals)), ...); - return *this; - } - private: - void add_(data_ internal) { - data_info info = std::move(internal).make_info(); - detail::merge_with(info_.datas_, info.id(), info, &data_info::merge); - } - private: - function_info info_; - }; -} diff --git a/headers/meta.hpp/meta_function_info.hpp b/headers/meta.hpp/meta_function_info.hpp deleted file mode 100644 index 4ae51cd..0000000 --- a/headers/meta.hpp/meta_function_info.hpp +++ /dev/null @@ -1,191 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "meta_fwd.hpp" - -#include "meta_value.hpp" - -#include "meta_data_info.hpp" - -namespace meta_hpp::function_detail -{ - template < typename FunctionType, std::size_t... Is > - std::optional raw_invoke_impl( - FunctionType function, - value* args, - std::index_sequence) - { - using ft = detail::function_traits; - using return_type = typename ft::return_type; - using argument_types = typename ft::argument_types; - - [[maybe_unused]] auto typed_arguments = std::make_tuple( - (args + Is)->try_cast>()...); - - if ( !(std::get(typed_arguments) && ...) ) { - throw std::logic_error("an attempt to call a function with incorrect argument types"); - } - - if constexpr ( std::is_void_v ) { - std::invoke(function, std::move(*std::get(typed_arguments))...); - return std::nullopt; - } else { - return_type return_value{std::invoke(function, std::move(*std::get(typed_arguments))...)}; - return value{std::move(return_value)}; - } - } - - template < typename FunctionType > - std::optional raw_invoke( - FunctionType function, - value* args, - std::size_t arg_count) - { - using ft = detail::function_traits; - - if ( arg_count != ft::arity ) { - throw std::logic_error("an attempt to call a function with an incorrect arity"); - } - - return raw_invoke_impl(function, args, std::make_index_sequence()); - } - - using function_invoke = std::function(value*, std::size_t)>; - - template < typename FunctionType > - function_invoke make_invoke(FunctionType function) { - using namespace std::placeholders; - return std::bind(&raw_invoke, function, _1, _2); - } - - template < typename FunctionType > - std::optional make_return_type() { - using ft = detail::function_traits; - using return_type = typename ft::return_type; - - if constexpr ( !std::is_void_v ) { - return get_family_id(); - } else { - return std::nullopt; - } - } - - template < typename FunctionType, std::size_t... Is > - std::vector make_argument_types_impl(std::index_sequence) { - using ft = detail::function_traits; - using argument_types = typename ft::argument_types; - return { get_family_id>()... }; - } - - template < typename FunctionType > - std::vector make_argument_types() { - using ft = detail::function_traits; - return make_argument_types_impl(std::make_index_sequence()); - } -} - -namespace meta_hpp -{ - class function_info { - public: - function_info() = delete; - - function_info(function_info&&) = default; - function_info(const function_info&) = default; - - function_info& operator=(function_info&&) = default; - function_info& operator=(const function_info&) = default; - public: - const std::string& id() const noexcept { - return id_; - } - - family_id family() const noexcept { - return family_; - } - - std::size_t arity() const noexcept { - return argument_types_.size(); - } - - std::optional return_type() const noexcept { - return return_type_; - } - - std::optional argument_type(std::size_t index) const noexcept { - if ( index < argument_types_.size() ) { - return argument_types_[index]; - } - return std::nullopt; - } - - template < typename... Args > - std::optional invoke(Args&&... args) const { - if constexpr ( sizeof...(Args) > 0u ) { - std::array vargs{std::forward(args)...}; - return invoke_(vargs.data(), vargs.size()); - } else { - return invoke_(nullptr, 0u); - } - } - - template < typename R, typename Rp = std::decay_t, typename... Args > - std::optional invoke_r(Args&&... args) const { - if ( std::optional r = invoke(std::forward(args)...) ) { - return std::move(r)->template cast(); - } - return std::nullopt; - } - - template < typename... Args > - std::optional operator()(Args&&... args) const { - return invoke(std::forward(args)...); - } - - template < typename F > - void each_data(F&& f) const { - for ( auto&& id_info : datas_ ) { - std::invoke(f, id_info.second); - } - } - - template < typename F > - void visit(F&& f) const { - each_data(f); - } - - std::optional get_data(std::string_view id) const { - return detail::find_opt(datas_, id); - } - - void merge(const function_info& other) { - if ( id() != other.id() || family() != other.family() ) { - throw std::logic_error("function_info::merge failed"); - } - detail::merge_with(datas_, other.datas_, &data_info::merge); - } - private: - template < typename FunctionType > - friend class function_; - - template < typename FunctionType > - function_info(std::string id, FunctionType function_ptr) - : id_{std::move(id)} - , family_{get_family_id()} - , return_type_{function_detail::make_return_type()} - , argument_types_{function_detail::make_argument_types()} - , invoke_{function_detail::make_invoke(function_ptr)} {} - private: - std::string id_; - family_id family_; - std::optional return_type_; - std::vector argument_types_; - function_detail::function_invoke invoke_; - std::map> datas_; - }; -} diff --git a/headers/meta.hpp/meta_fwd.hpp b/headers/meta.hpp/meta_fwd.hpp deleted file mode 100644 index 65773b2..0000000 --- a/headers/meta.hpp/meta_fwd.hpp +++ /dev/null @@ -1,257 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace meta_hpp -{ - template < typename... Ts > - struct overloaded : Ts... { - using Ts::operator()...; - }; - - template < typename... Ts > - overloaded(Ts...) -> overloaded; -} - -namespace meta_hpp -{ - class family_id { - public: - family_id(const family_id&) = default; - family_id& operator=(const family_id&) = default; - - friend bool operator<(family_id l, family_id r) noexcept { - return l.id_ < r.id_; - } - - friend bool operator==(family_id l, family_id r) noexcept { - return l.id_ == r.id_; - } - - friend bool operator!=(family_id l, family_id r) noexcept { - return l.id_ != r.id_; - } - private: - using underlying_type = std::size_t; - underlying_type id_{}; - private: - template < typename T > - friend family_id get_family_id() noexcept; - - family_id() noexcept - : id_{next()} {} - - static underlying_type next() noexcept { - static std::atomic id{}; - return ++id; - } - }; - - template < typename T > - family_id get_family_id() noexcept { - static const family_id id = family_id{}; - return id; - } -} - -namespace meta_hpp -{ - template < typename Signature > - constexpr auto select(Signature* f) noexcept { - return f; - } - - template < typename Signature, typename Base > - constexpr auto select(Signature Base::*f) noexcept { - return f; - } - - template < typename R, typename Base, typename... Args > - constexpr auto select_const(R (Base::*f)(Args...) const) noexcept { - return f; - } - - template < typename R, typename Base, typename... Args > - constexpr auto select_non_const(R(Base::*f)(Args...)) noexcept { - return f; - } -} - -namespace meta_hpp::detail -{ - template < typename Arg > - struct typename_arg_t { - }; - - template < typename... Args > - struct typename_args_t { - }; - - template < typename Arg > - inline typename_arg_t typename_arg; - - template < typename... Args > - inline typename_args_t typename_args; -} - -namespace meta_hpp::detail -{ - template < typename K, typename V, typename C, typename K2 > - std::optional find_opt(const std::map& src, K2&& key) { - if ( auto iter = src.find(key); iter != src.end() ) { - return iter->second; - } - return std::nullopt; - } - - template < typename K, typename V, typename C, typename K2, typename V2, typename F > - void merge_with(std::map& dst, K2&& key, V2&& value, F&& f) { - if ( auto iter = dst.find(key); iter != dst.end() ) { - std::invoke(std::forward(f), iter->second, std::forward(value)); - } else { - dst.emplace(std::forward(key), std::forward(value)); - } - } - - template < typename K, typename V, typename C, typename F > - void merge_with(std::map& dst, const std::map& src, F&& f) { - for ( auto [key, value] : src ) { - merge_with(dst, key, value, f); - } - } -} - -namespace meta_hpp::detail -{ - template < typename Class, typename... Args > - struct ctor_traits { - static constexpr std::size_t arity = sizeof...(Args); - using return_type = std::decay_t; - using argument_types = std::tuple...>; - }; -} - -namespace meta_hpp::detail -{ - template < typename Field > - struct field_traits; - - template < typename T, typename I > - struct field_traits { - static constexpr bool is_const = false; - using value_type = T; - using instance_type = I; - }; - - template < typename T, typename I > - struct field_traits - : field_traits { - static constexpr bool is_const = true; - }; -} - -namespace meta_hpp::detail -{ - template < typename Function > - struct function_traits; - - template < typename R, typename... Args > - struct function_traits { - static constexpr bool is_noexcept = false; - static constexpr std::size_t arity = sizeof...(Args); - using return_type = std::decay_t; - using argument_types = std::tuple...>; - }; - - template < typename R, typename... Args > - struct function_traits - : function_traits {}; - - template < typename R, typename... Args > - struct function_traits - : function_traits {}; - - template < typename R, typename... Args > - struct function_traits - : function_traits { - static constexpr bool is_noexcept = true; - }; - - template < typename R, typename... Args > - struct function_traits - : function_traits { - static constexpr bool is_noexcept = true; - }; -} - -namespace meta_hpp::detail -{ - template < typename Method > - struct method_traits; - - template < typename R, typename I, typename... Args > - struct method_traits - : function_traits { - static constexpr bool is_const = false; - using instance_type = I; - }; - - template < typename R, typename I, typename... Args > - struct method_traits - : method_traits { - static constexpr bool is_const = true; - }; - - template < typename R, typename I, typename... Args > - struct method_traits - : method_traits { - static constexpr bool is_noexcept = true; - }; - - template < typename R, typename I, typename... Args > - struct method_traits - : method_traits { - static constexpr bool is_const = true; - static constexpr bool is_noexcept = true; - }; -} - -namespace meta_hpp::detail -{ - template < typename Variable > - struct variable_traits; - - template < typename T > - struct variable_traits { - static constexpr bool is_const = false; - using value_type = T; - }; - - template < typename T > - struct variable_traits - : variable_traits { - static constexpr bool is_const = true; - }; -} diff --git a/headers/meta.hpp/meta_instance.hpp b/headers/meta.hpp/meta_instance.hpp deleted file mode 100644 index 229bc03..0000000 --- a/headers/meta.hpp/meta_instance.hpp +++ /dev/null @@ -1,126 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "meta_fwd.hpp" - -#include "meta_value.hpp" - -namespace meta_hpp -{ - class instance; - class cinstance; -} - -namespace meta_hpp -{ - class instance { - public: - instance() = delete; - - instance(instance&&) = default; - instance(const instance&) = default; - - instance& operator=(instance&&) = default; - instance& operator=(const instance&) = default; - - template < typename T - , typename = std::enable_if_t> - , typename = std::enable_if_t> - , typename = std::enable_if_t> > - instance(T& v) - : data_{std::addressof(v)} - , fid_{get_family_id()} {} - - instance(value& v) - : data_{v.data()} - , fid_{v.fid()} {} - - void* data() noexcept { - return data_; - } - - const void* data() const noexcept { - return data_; - } - - family_id fid() const noexcept { - return fid_; - } - - template < typename T > - std::add_pointer_t - try_cast() noexcept { - static_assert(!std::is_reference_v); - return fid_ == get_family_id() - ? static_cast>(data_) - : nullptr; - } - - template < typename T > - std::add_pointer_t> - try_cast() const noexcept { - static_assert(!std::is_reference_v); - return fid_ == get_family_id() - ? static_cast>>(data_) - : nullptr; - } - private: - void* data_{}; - family_id fid_; - }; -} - -namespace meta_hpp -{ - class cinstance { - public: - cinstance() = delete; - - cinstance(cinstance&&) = default; - cinstance(const cinstance&) = default; - - cinstance& operator=(cinstance&&) = default; - cinstance& operator=(const cinstance&) = default; - - template < typename T - , typename = std::enable_if_t> - , typename = std::enable_if_t> - , typename = std::enable_if_t> > - cinstance(const T& v) - : data_{std::addressof(v)} - , fid_{get_family_id()} {} - - cinstance(const value& v) - : data_{v.data()} - , fid_{v.fid()} {} - - cinstance(const instance& v) - : data_{v.data()} - , fid_{v.fid()} {} - - const void* data() const noexcept { - return data_; - } - - family_id fid() const noexcept { - return fid_; - } - - template < typename T > - std::add_pointer_t> - try_cast() const noexcept { - static_assert(!std::is_reference_v); - return fid_ == get_family_id() - ? static_cast>>(data_) - : nullptr; - } - private: - const void* data_{}; - family_id fid_; - }; -} diff --git a/headers/meta.hpp/meta_method.hpp b/headers/meta.hpp/meta_method.hpp deleted file mode 100644 index f01a5bc..0000000 --- a/headers/meta.hpp/meta_method.hpp +++ /dev/null @@ -1,42 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "meta_fwd.hpp" - -#include "meta_data.hpp" - -#include "meta_method_info.hpp" - -namespace meta_hpp -{ - template < typename MethodType > - class method_ { - public: - static_assert(std::is_member_function_pointer_v); - - explicit method_(std::string id, MethodType method_ptr) - : info_{std::move(id), method_ptr} {} - - const method_info& make_info() const { - return info_; - } - - template < typename... Internals > - method_& operator()(Internals&&...internals) { - (add_(std::forward(internals)), ...); - return *this; - } - private: - void add_(data_ internal) { - data_info info = std::move(internal).make_info(); - detail::merge_with(info_.datas_, info.id(), info, &data_info::merge); - } - private: - method_info info_; - }; -} diff --git a/headers/meta.hpp/meta_method_info.hpp b/headers/meta.hpp/meta_method_info.hpp deleted file mode 100644 index c6a13b0..0000000 --- a/headers/meta.hpp/meta_method_info.hpp +++ /dev/null @@ -1,283 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "meta_fwd.hpp" - -#include "meta_instance.hpp" -#include "meta_value.hpp" - -#include "meta_data_info.hpp" - -namespace meta_hpp::method_detail -{ - template < typename MethodType, std::size_t... Is > - std::optional raw_invoke_impl( - MethodType method, - instance instance, - value* args, - std::index_sequence) - { - using mt = detail::method_traits; - using return_type = typename mt::return_type; - using instance_type = typename mt::instance_type; - using argument_types = typename mt::argument_types; - - instance_type* typed_instance{instance.try_cast()}; - if ( !typed_instance ) { - throw std::logic_error("an attempt to call a method with incorrect instance type"); - } - - [[maybe_unused]] auto typed_arguments = std::make_tuple( - (args + Is)->try_cast>()...); - - if ( !(std::get(typed_arguments) && ...) ) { - throw std::logic_error("an attempt to call a method with incorrect argument types"); - } - - if constexpr ( std::is_void_v ) { - std::invoke(method, *typed_instance, std::move(*std::get(typed_arguments))...); - return std::nullopt; - } else { - return_type return_value{std::invoke(method, *typed_instance, std::move(*std::get(typed_arguments))...)}; - return value{std::move(return_value)}; - } - } - - template < typename MethodType > - std::optional raw_invoke( - MethodType method, - instance instance, - value* args, - std::size_t arg_count) - { - using mt = detail::method_traits; - - if ( arg_count != mt::arity ) { - throw std::logic_error("an attempt to call a method with an incorrect arity"); - } - - return raw_invoke_impl(method, instance, args, std::make_index_sequence()); - } - - template < typename MethodType, std::size_t... Is > - std::optional raw_cinvoke_impl( - [[maybe_unused]] MethodType method, - [[maybe_unused]] cinstance instance, - [[maybe_unused]] value* args, - std::index_sequence) - { - using mt = detail::method_traits; - using return_type = typename mt::return_type; - using instance_type = typename mt::instance_type; - using argument_types = typename mt::argument_types; - - if constexpr ( mt::is_const ) { - const instance_type* typed_instance{instance.try_cast()}; - if ( !typed_instance ) { - throw std::logic_error("an attempt to call a method with incorrect instance type"); - } - - [[maybe_unused]] auto typed_arguments = std::make_tuple( - (args + Is)->try_cast>()...); - - if ( !(std::get(typed_arguments) && ...) ) { - throw std::logic_error("an attempt to call a method with incorrect argument types"); - } - - if constexpr ( std::is_void_v ) { - std::invoke(method, *typed_instance, std::move(*std::get(typed_arguments))...); - return std::nullopt; - } else { - return_type return_value{std::invoke(method, *typed_instance, std::move(*std::get(typed_arguments))...)}; - return value{std::move(return_value)}; - } - } else { - throw std::logic_error("an attempt to call a non-constant method by constant instance"); - } - } - - template < typename MethodType > - std::optional raw_cinvoke( - MethodType method, - cinstance instance, - value* args, - std::size_t arg_count) - { - using mt = detail::method_traits; - - if ( arg_count != mt::arity ) { - throw std::logic_error("an attempt to call a method with a different arity"); - } - - return raw_cinvoke_impl(method, instance, args, std::make_index_sequence()); - } - - using method_invoke = std::function(instance, value*, std::size_t)>; - using method_cinvoke = std::function(cinstance, value*, std::size_t)>; - - template < typename MethodType > - method_invoke make_invoke(MethodType method) { - using namespace std::placeholders; - return std::bind(&raw_invoke, method, _1, _2, _3); - } - - template < typename MethodType > - method_cinvoke make_cinvoke(MethodType method) { - using namespace std::placeholders; - return std::bind(&raw_cinvoke, method, _1, _2, _3); - } - - template < typename MethodType > - family_id make_instance_type() noexcept { - using mt = detail::method_traits; - using instance_type = typename mt::instance_type; - return get_family_id(); - } - - template < typename MethodType > - std::optional make_return_type() { - using mt = detail::method_traits; - using return_type = typename mt::return_type; - - if constexpr ( !std::is_void_v ) { - return get_family_id(); - } else { - return std::nullopt; - } - } - - template < typename MethodType, std::size_t... Is > - std::vector make_argument_types_impl(std::index_sequence) { - using mt = detail::method_traits; - using argument_types = typename mt::argument_types; - return { get_family_id>()... }; - } - - template < typename MethodType > - std::vector make_argument_types() { - using mt = detail::method_traits; - return make_argument_types_impl(std::make_index_sequence()); - } -} - -namespace meta_hpp -{ - class method_info { - public: - method_info() = delete; - - method_info(method_info&&) = default; - method_info(const method_info&) = default; - - method_info& operator=(method_info&&) = default; - method_info& operator=(const method_info&) = default; - public: - const std::string& id() const noexcept { - return id_; - } - - family_id family() const noexcept { - return family_; - } - - std::size_t arity() const noexcept { - return argument_types_.size(); - } - - family_id instance_type() const noexcept { - return instance_type_; - } - - std::optional return_type() const noexcept { - return return_type_; - } - - std::optional argument_type(std::size_t index) const noexcept { - if ( index < argument_types_.size() ) { - return argument_types_[index]; - } - return std::nullopt; - } - - template < typename T, typename... Args > - std::optional invoke(T& inst, Args&&... args) const { - if constexpr ( sizeof...(Args) > 0u ) { - std::array vargs{std::forward(args)...}; - if constexpr ( std::is_const_v ) { - return cinvoke_(inst, vargs.data(), vargs.size()); - } else { - return invoke_(inst, vargs.data(), vargs.size()); - } - } else { - if constexpr ( std::is_const_v ) { - return cinvoke_(inst, nullptr, 0u); - } else { - return invoke_(inst, nullptr, 0u); - } - } - } - - template < typename R, typename Rp = std::decay_t, typename T, typename... Args > - std::optional invoke_r(T& inst, Args&&... args) const { - if ( std::optional r = invoke(inst, std::forward(args)...) ) { - return std::move(r)->template cast(); - } - return std::nullopt; - } - - template < typename T, typename... Args > - std::optional operator()(T& inst, Args&&... args) const { - return invoke(inst, std::forward(args)...); - } - - template < typename F > - void each_data(F&& f) const { - for ( auto&& id_info : datas_ ) { - std::invoke(f, id_info.second); - } - } - - template < typename F > - void visit(F&& f) const { - each_data(f); - } - - std::optional get_data(std::string_view id) const { - return detail::find_opt(datas_, id); - } - - void merge(const method_info& other) { - if ( id() != other.id() || family() != other.family() ) { - throw std::logic_error("method_info::merge failed"); - } - detail::merge_with(datas_, other.datas_, &data_info::merge); - } - private: - template < typename MethodType > - friend class method_; - - template < typename MethodType > - method_info(std::string id, MethodType method_ptr) - : id_{std::move(id)} - , family_{get_family_id()} - , instance_type_{method_detail::make_instance_type()} - , return_type_{method_detail::make_return_type()} - , argument_types_{method_detail::make_argument_types()} - , invoke_{method_detail::make_invoke(method_ptr)} - , cinvoke_{method_detail::make_cinvoke(method_ptr)} {} - private: - std::string id_; - family_id family_; - family_id instance_type_; - std::optional return_type_; - std::vector argument_types_; - method_detail::method_invoke invoke_; - method_detail::method_cinvoke cinvoke_; - std::map> datas_; - }; -} diff --git a/headers/meta.hpp/meta_namespace.hpp b/headers/meta.hpp/meta_namespace.hpp deleted file mode 100644 index 6fe4ce2..0000000 --- a/headers/meta.hpp/meta_namespace.hpp +++ /dev/null @@ -1,65 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "meta_fwd.hpp" - -#include "meta_class.hpp" -#include "meta_data.hpp" -#include "meta_function.hpp" -#include "meta_variable.hpp" - -#include "meta_namespace_info.hpp" - -namespace meta_hpp -{ - class namespace_ { - public: - explicit namespace_(std::string id) - : info_{std::move(id)} {} - - const namespace_info& make_info() const { - return info_; - } - - template < typename... Internals > - namespace_& operator()(Internals&&...internals) { - (add_(std::forward(internals)), ...); - return *this; - } - private: - template < typename InternalClass > - void add_(class_ internal) { - class_info info = std::move(internal).make_info(); - detail::merge_with(info_.classes_, info.id(), info, &class_info::merge); - } - - void add_(data_ internal) { - data_info info = std::move(internal).make_info(); - detail::merge_with(info_.datas_, info.id(), info, &data_info::merge); - } - - template < typename FunctionType > - void add_(function_ internal) { - function_info info = std::move(internal).make_info(); - detail::merge_with(info_.functions_, info.id(), info, &function_info::merge); - } - - void add_(namespace_ internal) { - namespace_info info = std::move(internal).make_info(); - detail::merge_with(info_.namespaces_, info.id(), info, &namespace_info::merge); - } - - template < typename VariableType > - void add_(variable_ internal) { - variable_info info = std::move(internal).make_info(); - detail::merge_with(info_.variables_, info.id(), info, &variable_info::merge); - } - private: - namespace_info info_; - }; -} diff --git a/headers/meta.hpp/meta_namespace_info.hpp b/headers/meta.hpp/meta_namespace_info.hpp deleted file mode 100644 index 4df3cc3..0000000 --- a/headers/meta.hpp/meta_namespace_info.hpp +++ /dev/null @@ -1,117 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "meta_fwd.hpp" -#include "meta_value.hpp" - -#include "meta_class_info.hpp" -#include "meta_data_info.hpp" -#include "meta_function_info.hpp" -#include "meta_variable_info.hpp" - -namespace meta_hpp -{ - class namespace_info { - public: - namespace_info() = delete; - - namespace_info(namespace_info&&) = default; - namespace_info(const namespace_info&) = default; - - namespace_info& operator=(namespace_info&&) = default; - namespace_info& operator=(const namespace_info&) = default; - public: - const std::string& id() const noexcept { - return id_; - } - - template < typename F > - void each_class(F&& f) const { - for ( auto&& id_info : classes_ ) { - std::invoke(f, id_info.second); - } - } - - template < typename F > - void each_data(F&& f) const { - for ( auto&& id_info : datas_ ) { - std::invoke(f, id_info.second); - } - } - - template < typename F > - void each_function(F&& f) const { - for ( auto&& id_info : functions_ ) { - std::invoke(f, id_info.second); - } - } - - template < typename F > - void each_namespace(F&& f) const { - for ( auto&& id_info : namespaces_ ) { - std::invoke(f, id_info.second); - } - } - - template < typename F > - void each_variable(F&& f) const { - for ( auto&& id_info : variables_ ) { - std::invoke(f, id_info.second); - } - } - - template < typename F > - void visit(F&& f) const { - each_class(f); - each_data(f); - each_function(f); - each_namespace(f); - each_variable(f); - } - - std::optional get_class(std::string_view id) const { - return detail::find_opt(classes_, id); - } - - std::optional get_data(std::string_view id) const { - return detail::find_opt(datas_, id); - } - - std::optional get_function(std::string_view id) const { - return detail::find_opt(functions_, id); - } - - std::optional get_namespace(std::string_view id) const { - return detail::find_opt(namespaces_, id); - } - - std::optional get_variable(std::string_view id) const { - return detail::find_opt(variables_, id); - } - - void merge(const namespace_info& other) { - detail::merge_with(classes_, other.classes_, &class_info::merge); - detail::merge_with(datas_, other.datas_, &data_info::merge); - detail::merge_with(functions_, other.functions_, &function_info::merge); - detail::merge_with(namespaces_, other.namespaces_, &namespace_info::merge); - detail::merge_with(variables_, other.variables_, &variable_info::merge); - } - private: - friend class namespace_; - - namespace_info(std::string id) - : id_{std::move(id)} {} - private: - std::string id_; - std::map> classes_; - std::map> datas_; - std::map> functions_; - std::map> namespaces_; - std::map> variables_; - }; -} diff --git a/headers/meta.hpp/meta_registry.hpp b/headers/meta.hpp/meta_registry.hpp deleted file mode 100644 index 450c0e3..0000000 --- a/headers/meta.hpp/meta_registry.hpp +++ /dev/null @@ -1,246 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "meta_fwd.hpp" - -#include "meta_type.hpp" - -#include "meta_class.hpp" -#include "meta_ctor.hpp" -#include "meta_data.hpp" -#include "meta_field.hpp" -#include "meta_function.hpp" -#include "meta_method.hpp" -#include "meta_namespace.hpp" -#include "meta_variable.hpp" - -namespace meta_hpp -{ - class registry { - public: - template < typename T > - std::optional resolve() const { - const family_id fid = get_family_id(); - return detail::find_opt(types_, fid); - } - - template < typename T > - std::optional resolve(T&&) const { - const family_id fid = get_family_id>(); - return detail::find_opt(types_, fid); - } - - std::optional get_class_by_name(std::string_view name) const { - return detail::find_opt(classes_, name); - } - - std::optional get_field_by_name(std::string_view name) const { - return detail::find_opt(fields_, name); - } - - std::optional get_function_by_name(std::string_view name) const { - return detail::find_opt(functions_, name); - } - - std::optional get_method_by_name(std::string_view name) const { - return detail::find_opt(methods_, name); - } - - std::optional get_namespace_by_name(std::string_view name) const { - return detail::find_opt(namespaces_, name); - } - - std::optional get_variable_by_name(std::string_view name) const { - return detail::find_opt(variables_, name); - } - - template < typename F > - void each_type(F&& f) const { - for ( auto&& id_type : types_ ) { - std::invoke(f, id_type.second); - } - } - - template < typename F > - void each_class(F&& f) const { - for ( auto&& id_info : classes_ ) { - std::invoke(f, id_info.second); - } - } - - template < typename F > - void each_field(F&& f) const { - for ( auto&& id_info : fields_ ) { - std::invoke(f, id_info.second); - } - } - - template < typename F > - void each_function(F&& f) const { - for ( auto&& id_info : functions_ ) { - std::invoke(f, id_info.second); - } - } - - template < typename F > - void each_method(F&& f) const { - for ( auto&& id_info : methods_ ) { - std::invoke(f, id_info.second); - } - } - - template < typename F > - void each_namespace(F&& f) const { - for ( auto&& id_info : namespaces_ ) { - std::invoke(f, id_info.second); - } - } - - template < typename F > - void each_variable(F&& f) const { - for ( auto&& id_info : variables_ ) { - std::invoke(f, id_info.second); - } - } - - template < typename F > - void visit(F&& f) const { - each_class(f); - each_field(f); - each_function(f); - each_method(f); - each_namespace(f); - each_variable(f); - } - - template < typename... Internals > - registry& operator()(Internals&&...internals) { - (add_(std::string{}, std::forward(internals)), ...); - return *this; - } - private: - template < typename InternalClass > - void add_(const std::string& prefix, class_ internal) { - add_(prefix, std::move(internal).make_info()); - } - - template < typename FunctionType > - void add_(const std::string& prefix, function_ internal) { - add_(prefix, std::move(internal).make_info()); - } - - void add_(const std::string& prefix, namespace_ internal) { - add_(prefix, std::move(internal).make_info()); - } - - template < typename VariableType > - void add_(const std::string& prefix, variable_ internal) { - add_(prefix, std::move(internal).make_info()); - } - private: - void add_(const std::string& prefix, const class_info& info) { - const std::string name = prefix.empty() - ? info.id() - : prefix + "::" + info.id(); - - detail::merge_with(types_, info.family(), info, &class_info::merge); - detail::merge_with(classes_, name, info, &class_info::merge); - - info.visit(overloaded { - [](const ctor_info&) {}, - [](const data_info&) {}, - [this, &name](const auto& internal){ - add_(name, internal); - } - }); - } - - void add_(const std::string& prefix, const field_info& info) { - const std::string name = prefix.empty() - ? info.id() - : prefix + "::" + info.id(); - - detail::merge_with(fields_, name, info, &field_info::merge); - - info.visit(overloaded { - [](const data_info&) {}, - [this, &name](const auto& internal){ - add_(name, internal); - } - }); - } - - void add_(const std::string& prefix, const function_info& info) { - const std::string name = prefix.empty() - ? info.id() - : prefix + "::" + info.id(); - - detail::merge_with(functions_, name, info, &function_info::merge); - - info.visit(overloaded { - [](const data_info&) {}, - [this, &name](const auto& internal){ - add_(name, internal); - } - }); - } - - void add_(const std::string& prefix, const method_info& info) { - const std::string name = prefix.empty() - ? info.id() - : prefix + "::" + info.id(); - - detail::merge_with(methods_, name, info, &method_info::merge); - - info.visit(overloaded { - [](const data_info&) {}, - [this, &name](const auto& internal){ - add_(name, internal); - } - }); - } - - void add_(const std::string& prefix, const namespace_info& info) { - const std::string name = prefix.empty() - ? info.id() - : prefix + "::" + info.id(); - - detail::merge_with(namespaces_, name, info, &namespace_info::merge); - - info.visit(overloaded { - [](const data_info&) {}, - [this, &name](const auto& internal){ - add_(name, internal); - } - }); - } - - void add_(const std::string& prefix, const variable_info& info) { - const std::string name = prefix.empty() - ? info.id() - : prefix + "::" + info.id(); - - detail::merge_with(variables_, name, info, &variable_info::merge); - - info.visit(overloaded { - [](const data_info&) {}, - [this, &name](const auto& internal){ - add_(name, internal); - } - }); - } - private: - std::map> types_; - std::map> classes_; - std::map> fields_; - std::map> functions_; - std::map> methods_; - std::map> namespaces_; - std::map> variables_; - }; -} diff --git a/headers/meta.hpp/meta_type.hpp b/headers/meta.hpp/meta_type.hpp deleted file mode 100644 index 01033e9..0000000 --- a/headers/meta.hpp/meta_type.hpp +++ /dev/null @@ -1,120 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "meta_fwd.hpp" - -#include "meta_class_info.hpp" -#include "meta_field_info.hpp" -#include "meta_function_info.hpp" -#include "meta_method_info.hpp" -#include "meta_namespace_info.hpp" -#include "meta_variable_info.hpp" - -namespace meta_hpp -{ - class type { - public: - type() = delete; - - type(type&&) = default; - type(const type&) = default; - - type& operator=(type&&) = default; - type& operator=(const type&) = default; - - template < typename Info > - type(Info&& info) - : info_{std::forward(info)} {} - - bool is_class() const noexcept { - return std::holds_alternative(info_); - } - - bool is_field() const noexcept { - return std::holds_alternative(info_); - } - - bool is_function() const noexcept { - return std::holds_alternative(info_); - } - - bool is_method() const noexcept { - return std::holds_alternative(info_); - } - - bool is_namespace() const noexcept { - return std::holds_alternative(info_); - } - - bool is_variable() const noexcept { - return std::holds_alternative(info_); - } - - std::optional get_class() const { - if ( const class_info* info = std::get_if(&info_); info ) { - return *info; - } - return std::nullopt; - } - - std::optional get_field() const { - if ( const field_info* info = std::get_if(&info_); info ) { - return *info; - } - return std::nullopt; - } - - std::optional get_function() const { - if ( const function_info* info = std::get_if(&info_); info ) { - return *info; - } - return std::nullopt; - } - - std::optional get_method() const { - if ( const method_info* info = std::get_if(&info_); info ) { - return *info; - } - return std::nullopt; - } - - std::optional get_namespace() const { - if ( const namespace_info* info = std::get_if(&info_); info ) { - return *info; - } - return std::nullopt; - } - - std::optional get_variable() const { - if ( const variable_info* info = std::get_if(&info_); info ) { - return *info; - } - return std::nullopt; - } - - void merge(const type& other) { - if ( info_.index() != other.info_.index() ) { - throw std::logic_error("type::merge failed"); - } - std::visit(overloaded { - [&other](auto& info){ - using info_type = std::remove_reference_t; - info.merge(std::get(other.info_)); - } - }, info_); - } - private: - std::variant< - class_info, - field_info, - function_info, - method_info, - namespace_info, - variable_info> info_; - }; -} diff --git a/headers/meta.hpp/meta_value.hpp b/headers/meta.hpp/meta_value.hpp deleted file mode 100644 index e88a78c..0000000 --- a/headers/meta.hpp/meta_value.hpp +++ /dev/null @@ -1,221 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "meta_fwd.hpp" - -namespace meta_hpp -{ - class value; -} - -namespace meta_hpp::value_detail -{ - struct traits { - void*(*data)(value&); - const void*(*cdata)(const value&); - bool(*equals)(const value&, const value&){}; - }; - - template < typename T > - void* value_data(value& v); - - template < typename T > - const void* value_cdata(const value& v); - - template < typename T > - bool value_equals(const value& l, const value& r); - - template < typename T > - const traits* get_traits() noexcept { - static traits traits{ - &value_data, - &value_cdata, - &value_equals, - }; - return &traits; - } -} - -namespace meta_hpp -{ - class value { - public: - value() = delete; - - value(value&&) = default; - value(const value&) = default; - - value& operator=(value&&) = default; - value& operator=(const value&) = default; - - template < typename T, typename Tp = std::decay_t - , typename = std::enable_if_t> > - value(T&& val) - : raw_{std::forward(val)} - , fid_{get_family_id()} - , traits_{value_detail::get_traits()} {} - - template < typename T, typename Tp = std::decay_t - , typename = std::enable_if_t> > - value& operator=(T&& val) { - value{std::forward(val)}.swap(*this); - return *this; - } - - template < typename T, typename Tp = std::decay_t, typename... Args > - explicit value(std::in_place_type_t, Args&&... args) - : raw_{std::in_place_type, std::forward(args)...} - , fid_{get_family_id()} - , traits_{value_detail::get_traits()} {} - - template < typename T, typename Tp = std::decay_t, typename I, typename... Args > - explicit value(std::in_place_type_t, std::initializer_list ilist, Args&&... args) - : raw_{std::in_place_type, ilist, std::forward(args)...} - , fid_{get_family_id()} - , traits_{value_detail::get_traits()} {} - - template < typename T > - bool has_type() const noexcept { - return fid_ == get_family_id(); - } - - template < typename T > - T cast() && { - return std::any_cast(std::move(raw_)); - } - - template < typename T > - T cast() & { - return std::any_cast(raw_); - } - - template < typename T > - T cast() const & { - return std::any_cast(raw_); - } - - template < typename T > - std::add_pointer_t - try_cast() noexcept { - static_assert(!std::is_reference_v); - return std::any_cast(&raw_); - } - - template < typename T > - std::add_pointer_t> - try_cast() const noexcept { - static_assert(!std::is_reference_v); - return std::any_cast(&raw_); - } - - family_id fid() const noexcept { - return fid_; - } - - void* data() noexcept { - return traits_->data(*this); - } - - const void* data() const noexcept { - return traits_->cdata(*this); - } - - void swap(value& other) noexcept { - using std::swap; - swap(raw_, other.raw_); - swap(fid_, other.fid_); - swap(traits_, other.traits_); - } - - template < typename T, typename Tp = std::decay_t - , typename = std::enable_if_t> > - bool equals(T&& other) const { - return fid_ == get_family_id() - && std::equal_to<>{}(*try_cast(), std::forward(other)); - } - - bool equals(const value& other) const { - return traits_->equals(*this, other); - } - public: - bool to_bool() const { return cast(); } - int to_int() const { return cast(); } - unsigned to_uint() const { return cast(); } - float to_float() const { return cast(); } - double to_double() const { return cast(); } - const std::string& to_string() const { return cast(); } - - std::int8_t to_int8() const { return cast(); } - std::int16_t to_int16() const { return cast(); } - std::int32_t to_int32() const { return cast(); } - std::int64_t to_int64() const { return cast(); } - std::ptrdiff_t to_ptrdiff_t() const { return cast(); } - std::intptr_t to_intptr_t() const { return cast(); } - - std::uint8_t to_uint8() const { return cast(); } - std::uint16_t to_uint16() const { return cast(); } - std::uint32_t to_uint32() const { return cast(); } - std::uint64_t to_uint64() const { return cast(); } - std::size_t to_size_t() const { return cast(); } - std::uintptr_t to_uintptr_t() const { return cast(); } - public: - bool is_bool() const noexcept { return has_type(); } - bool is_int() const noexcept { return has_type(); } - bool is_uint() const noexcept { return has_type(); } - bool is_float() const noexcept { return has_type(); } - bool is_double() const noexcept { return has_type(); } - bool is_string() const noexcept { return has_type(); } - - bool is_int8() const noexcept { return has_type(); } - bool is_int16() const noexcept { return has_type(); } - bool is_int32() const noexcept { return has_type(); } - bool is_int64() const noexcept { return has_type(); } - bool is_ptrdiff_t() const noexcept { return has_type(); } - bool is_intptr_t() const noexcept { return has_type(); } - - bool is_uint8() const noexcept { return has_type(); } - bool is_uint16() const noexcept { return has_type(); } - bool is_uint32() const noexcept { return has_type(); } - bool is_uint64() const noexcept { return has_type(); } - bool is_size_t() const noexcept { return has_type(); } - bool is_uintptr_t() const noexcept { return has_type(); } - private: - std::any raw_; - family_id fid_; - const value_detail::traits* traits_{}; - }; - - inline void swap(value& l, value& r) noexcept { - l.swap(r); - } -} - -namespace meta_hpp::value_detail -{ - template < typename T > - void* value_data(value& v) { - return v.try_cast(); - } - - template < typename T > - const void* value_cdata(const value& v) { - return v.try_cast(); - } - - template < typename T > - bool value_equals(const value& l, const value& r) { - if ( l.fid() != r.fid() ) { - return false; - } - if constexpr ( std::is_invocable_v, T, T> ) { - return std::equal_to<>{}(*l.try_cast(), *r.try_cast()); - } else { - return value_cdata(l) == value_cdata(r); - } - } -} diff --git a/headers/meta.hpp/meta_variable.hpp b/headers/meta.hpp/meta_variable.hpp deleted file mode 100644 index e8a8e49..0000000 --- a/headers/meta.hpp/meta_variable.hpp +++ /dev/null @@ -1,42 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "meta_fwd.hpp" - -#include "meta_data.hpp" - -#include "meta_variable_info.hpp" - -namespace meta_hpp -{ - template < typename VariableType > - class variable_ { - public: - static_assert(std::is_pointer_v); - - explicit variable_(std::string id, VariableType variable_ptr) - : info_{std::move(id), variable_ptr} {} - - const variable_info& make_info() const { - return info_; - } - - template < typename... Internals > - variable_& operator()(Internals&&...internals) { - (add_(std::forward(internals)), ...); - return *this; - } - private: - void add_(data_ internal) { - data_info info = std::move(internal).make_info(); - detail::merge_with(info_.datas_, info.id(), info, &data_info::merge); - } - private: - variable_info info_; - }; -} diff --git a/headers/meta.hpp/meta_variable_info.hpp b/headers/meta.hpp/meta_variable_info.hpp deleted file mode 100644 index a338e78..0000000 --- a/headers/meta.hpp/meta_variable_info.hpp +++ /dev/null @@ -1,159 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "meta_fwd.hpp" - -#include "meta_value.hpp" - -#include "meta_data_info.hpp" - -namespace meta_hpp::variable_detail -{ - template < typename VariableType > - value raw_getter( - VariableType variable) - { - using vt = detail::variable_traits>; - using value_type = typename vt::value_type; - - value_type typed_value{*variable}; - return value{std::move(typed_value)}; - } - - template < typename VariableType > - void raw_setter( - [[maybe_unused]] VariableType variable, - [[maybe_unused]] value value) - { - using vt = detail::variable_traits>; - using value_type = typename vt::value_type; - - if constexpr ( !vt::is_const ) { - value_type* typed_value{value.try_cast()}; - if ( !typed_value ) { - throw std::logic_error("an attempt to set a variable with incorrect argument type"); - } - - *variable = std::move(*typed_value); - } else { - throw std::logic_error("an attempt to set a constant variable"); - } - } - - using variable_getter = std::function; - using variable_setter = std::function; - - template < typename VariableType > - variable_getter make_getter(VariableType variable) { - using namespace std::placeholders; - return std::bind(&raw_getter, variable); - } - - template < typename VariableType > - variable_setter make_setter(VariableType variable) { - using namespace std::placeholders; - return std::bind(&raw_setter, variable, _1); - } - - template < typename VariableType > - family_id make_value_type() noexcept { - using vt = detail::variable_traits; - using value_type = typename vt::value_type; - return get_family_id(); - } -} - -namespace meta_hpp -{ - class variable_info { - public: - variable_info() = delete; - - variable_info(variable_info&&) = default; - variable_info(const variable_info&) = default; - - variable_info& operator=(variable_info&&) = default; - variable_info& operator=(const variable_info&) = default; - public: - const std::string& id() const noexcept { - return id_; - } - - family_id family() const noexcept { - return family_; - } - - family_id value_type() const noexcept { - return value_type_; - } - - value get() const { - return getter_(); - } - - template < typename R, typename Rp = std::decay_t > - Rp get_r() const { - return get().template cast(); - } - - template < typename Value > - void set(Value&& value) const { - return setter_(std::forward(value)); - } - - value operator()() const { - return get(); - } - - template < typename Value > - void operator()(Value&& value) const { - return set(std::forward(value)); - } - - template < typename F > - void each_data(F&& f) const { - for ( auto&& id_info : datas_ ) { - std::invoke(f, id_info.second); - } - } - - template < typename F > - void visit(F&& f) const { - each_data(f); - } - - std::optional get_data(std::string_view id) const { - return detail::find_opt(datas_, id); - } - - void merge(const variable_info& other) { - if ( id() != other.id() || family() != other.family() ) { - throw std::logic_error("variable_info::merge failed"); - } - detail::merge_with(datas_, other.datas_, &data_info::merge); - } - private: - template < typename VariableType > - friend class variable_; - - template < typename VariableType > - variable_info(std::string id, VariableType variable_ptr) - : id_{std::move(id)} - , family_{get_family_id()} - , value_type_{variable_detail::make_value_type()} - , getter_{variable_detail::make_getter(variable_ptr)} - , setter_{variable_detail::make_setter(variable_ptr)} {} - private: - std::string id_; - family_id family_; - family_id value_type_; - variable_detail::variable_getter getter_; - variable_detail::variable_setter setter_; - std::map> datas_; - }; -} diff --git a/untests/meta_class_tests.cpp b/untests/meta_class_tests.cpp deleted file mode 100644 index 109126e..0000000 --- a/untests/meta_class_tests.cpp +++ /dev/null @@ -1,165 +0,0 @@ -/******************************************************************************* - * 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 -#include -#include -#include -#include - -#include "doctest/doctest.hpp" - -namespace -{ - class clazz { - public: - class clazz2 { - public: - int field{21}; - const int cfield{22}; - }; - - class clazz3 { - public: - int field{31}; - const int cfield{32}; - }; - - int field{1}; - const int cfield{2}; - - static int func(int a) { return a; } - - int method(int a) { return a; } - int cmethod(int a) const { return a; } - - static int variable; - static const int cvariable; - }; - - int clazz::variable{1}; - const int clazz::cvariable{2}; -} - -TEST_CASE("meta/class") { - namespace meta = meta_hpp; - - meta::class_ class_{"clazz"}; - - { - const meta::class_info info = class_.make_info(); - CHECK_FALSE(info.get_class("clazz2")); - CHECK_FALSE(info.get_field("field")); - CHECK_FALSE(info.get_field("cfield")); - CHECK_FALSE(info.get_function("func")); - CHECK_FALSE(info.get_method("method")); - CHECK_FALSE(info.get_method("cmethod")); - CHECK_FALSE(info.get_variable("variable")); - CHECK_FALSE(info.get_variable("cvariable")); - } - - class_( - meta::class_("clazz2"), - meta::field_("field", &clazz::field), - meta::field_("cfield", &clazz::cfield), - meta::function_("func", &clazz::func), - meta::method_("method", &clazz::method), - meta::method_("cmethod", &clazz::cmethod), - meta::variable_("variable", &clazz::variable), - meta::variable_("cvariable", &clazz::cvariable)); - - { - const meta::class_info info = class_.make_info(); - CHECK(info.get_class("clazz2")); - CHECK(info.get_field("field")); - CHECK(info.get_field("cfield")); - CHECK(info.get_function("func")); - CHECK(info.get_method("method")); - CHECK(info.get_method("cmethod")); - CHECK(info.get_variable("variable")); - CHECK(info.get_variable("cvariable")); - - { - meta::class_info clazz2_info = info.get_class("clazz2").value(); - CHECK(clazz2_info.id() == "clazz2"); - } - - { - meta::field_info field_info = info.get_field("field").value(); - CHECK(field_info.id() == "field"); - } - - { - meta::field_info cfield_info = info.get_field("cfield").value(); - CHECK(cfield_info.id() == "cfield"); - } - - { - meta::function_info function_info = info.get_function("func").value(); - CHECK(function_info.id() == "func"); - } - - { - meta::method_info method_info = info.get_method("method").value(); - CHECK(method_info.id() == "method"); - } - - { - meta::method_info cmethod_info = info.get_method("cmethod").value(); - CHECK(cmethod_info.id() == "cmethod"); - } - - { - meta::variable_info variable_info = info.get_variable("variable").value(); - CHECK(variable_info.id() == "variable"); - } - - { - meta::variable_info cvariable_info = info.get_variable("cvariable").value(); - CHECK(cvariable_info.id() == "cvariable"); - } - } -} - -TEST_CASE("meta/class/merge") { - namespace meta = meta_hpp; - - meta::class_ clazz_{"clazz"}; - - SUBCASE("merge") { - CHECK_NOTHROW(clazz_( - meta::class_("child")( - meta::field_("field", &clazz::clazz2::field) - ) - )); - - CHECK_NOTHROW(clazz_( - meta::class_("child")( - meta::field_("cfield", &clazz::clazz2::cfield) - ) - )); - - CHECK_THROWS_AS(clazz_( - meta::class_("child")( - meta::field_("field", &clazz::clazz3::field) - ) - ), std::logic_error); - - { - const meta::class_info info = clazz_.make_info(); - - CHECK(info.get_class("child")); - CHECK(info.get_class("child")->get_field("field")); - CHECK(info.get_class("child")->get_field("cfield")); - - { - clazz::clazz2 instance{}; - CHECK(info.get_class("child")->get_field("field")->get(instance).to_int() == 21); - CHECK(info.get_class("child")->get_field("cfield")->get(instance).to_int() == 22); - } - } - } -} diff --git a/untests/meta_ctor_tests.cpp b/untests/meta_ctor_tests.cpp deleted file mode 100644 index d284373..0000000 --- a/untests/meta_ctor_tests.cpp +++ /dev/null @@ -1,138 +0,0 @@ -/******************************************************************************* - * 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 -#include - -#include "doctest/doctest.hpp" - -namespace -{ - class clazz { - public: - int v1{1}; - int v2{2}; - - clazz() = default; - clazz(int v): v1{v}, v2{v} {} - clazz(int v1, int v2): v1{v1}, v2{v2} {} - }; -} - -TEST_CASE("meta/ctor") { - namespace meta = meta_hpp; - - const meta::ctor_info ctor0 = meta::ctor_<>().make_info(); - const meta::ctor_info ctor1 = meta::ctor_().make_info(); - const meta::ctor_info ctor2 = meta::ctor_().make_info(); - - SUBCASE("arity") { - CHECK(ctor0.arity() == 0u); - CHECK(ctor1.arity() == 1u); - CHECK(ctor2.arity() == 2u); - } - - SUBCASE("return_type") { - CHECK(ctor0.return_type() == meta::get_family_id()); - CHECK(ctor1.return_type() == meta::get_family_id()); - CHECK(ctor2.return_type() == meta::get_family_id()); - } - - SUBCASE("argument_types") { - CHECK_FALSE(ctor0.argument_type(0u)); - - CHECK(ctor1.argument_type(0u) == meta::get_family_id()); - CHECK_FALSE(ctor1.argument_type(1u)); - - CHECK(ctor2.argument_type(0u) == meta::get_family_id()); - CHECK(ctor2.argument_type(1u) == meta::get_family_id()); - CHECK_FALSE(ctor2.argument_type(2u)); - } - - SUBCASE("invoke0") { - CHECK(ctor0().cast().v1 == 1); - CHECK(ctor0().cast().v2 == 2); - CHECK_THROWS_AS(ctor0(1), std::logic_error); - - CHECK(ctor0.invoke().cast().v1 == 1); - CHECK(ctor0.invoke().cast().v2 == 2); - CHECK_THROWS_AS(ctor0.invoke(1), std::logic_error); - - CHECK(ctor0.invoke_r().v1 == 1); - CHECK(ctor0.invoke_r().v2 == 2); - CHECK_THROWS_AS(ctor0.invoke_r(1), std::logic_error); - } - - SUBCASE("invoke1") { - CHECK(ctor1(42).cast().v1 == 42); - CHECK(ctor1(42).cast().v2 == 42); - CHECK_THROWS_AS(ctor1(), std::logic_error); - CHECK_THROWS_AS(ctor1(1,1), std::logic_error); - - CHECK(ctor1.invoke(42).cast().v1 == 42); - CHECK(ctor1.invoke(42).cast().v2 == 42); - CHECK_THROWS_AS(ctor1.invoke(), std::logic_error); - CHECK_THROWS_AS(ctor1.invoke(1,1), std::logic_error); - - CHECK(ctor1.invoke_r(42).v1 == 42); - CHECK(ctor1.invoke_r(42).v2 == 42); - CHECK_THROWS_AS(ctor1.invoke_r(), std::logic_error); - CHECK_THROWS_AS(ctor1.invoke_r(1,1), std::logic_error); - } - - SUBCASE("invoke2") { - CHECK(ctor2(21,42).cast().v1 == 21); - CHECK(ctor2(21,42).cast().v2 == 42); - CHECK_THROWS_AS(ctor2(), std::logic_error); - CHECK_THROWS_AS(ctor2(1), std::logic_error); - CHECK_THROWS_AS(ctor2(1,1,1), std::logic_error); - - CHECK(ctor2.invoke(21,42).cast().v1 == 21); - CHECK(ctor2.invoke(21,42).cast().v2 == 42); - CHECK_THROWS_AS(ctor2.invoke(), std::logic_error); - CHECK_THROWS_AS(ctor2.invoke(1), std::logic_error); - CHECK_THROWS_AS(ctor2.invoke(1,1,1), std::logic_error); - - CHECK(ctor2.invoke_r(21,42).v1 == 21); - CHECK(ctor2.invoke_r(21,42).v2 == 42); - CHECK_THROWS_AS(ctor2.invoke_r(), std::logic_error); - CHECK_THROWS_AS(ctor2.invoke_r(1), std::logic_error); - CHECK_THROWS_AS(ctor2.invoke_r(1,1,1), std::logic_error); - } - - SUBCASE("is_invocable") { - CHECK(ctor0.is_invocable<>()); - CHECK_FALSE(ctor0.is_invocable()); - - CHECK(ctor1.is_invocable()); - CHECK_FALSE(ctor1.is_invocable()); - CHECK_FALSE(ctor1.is_invocable<>()); - CHECK_FALSE(ctor1.is_invocable()); - - CHECK(ctor2.is_invocable()); - CHECK_FALSE(ctor2.is_invocable()); - CHECK_FALSE(ctor2.is_invocable<>()); - CHECK_FALSE(ctor2.is_invocable()); - } -} - -TEST_CASE("meta/ctor/class") { - namespace meta = meta_hpp; - - const meta::class_info clazz_info = meta::class_("clazz")( - meta::ctor_<>(), - meta::ctor_(), - meta::ctor_() - ).make_info(); - - CHECK(clazz_info.get_ctor<>()); - CHECK(clazz_info.get_ctor()); - CHECK(clazz_info.get_ctor()); - - CHECK_FALSE(clazz_info.get_ctor()); - CHECK_FALSE(clazz_info.get_ctor()); - CHECK_FALSE(clazz_info.get_ctor()); -} diff --git a/untests/meta_data_tests.cpp b/untests/meta_data_tests.cpp deleted file mode 100644 index 7dd63aa..0000000 --- a/untests/meta_data_tests.cpp +++ /dev/null @@ -1,179 +0,0 @@ -/******************************************************************************* - * 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 -#include -#include -#include -#include -#include -#include - -#include "doctest/doctest.hpp" - -namespace -{ - struct clazz { - int field{42}; - static int variable; - int method() const { return 42; } - static int function() { return 42; } - }; - - int clazz::variable{42}; -} - -TEST_CASE("meta/data") { - namespace meta = meta_hpp; - using namespace std::string_literals; - - meta::data_ data_("key"s, "value"s); - - { - const meta::data_info info = data_.make_info(); - - CHECK(info.id() == "key"); - CHECK(info.get().to_string() == "value"); - } - - { - data_( - meta::data_("key2"s, "value2"s)( - meta::data_("key3"s, "value3"s) - ) - ); - - { - const meta::data_info info = data_.make_info(); - - CHECK(info.get_data("key2")); - CHECK(info.get_data("key2")->get().to_string() == "value2"); - - CHECK(info.get_data("key2")->get_data("key3")); - CHECK(info.get_data("key2")->get_data("key3")->get().to_string() == "value3"); - } - } - - { - data_( - meta::data_("key2"s, "value2"s)( - meta::data_("key4"s, "value4"s) - ) - ); - - { - const meta::data_info info = data_.make_info(); - - CHECK(info.get_data("key2")); - CHECK(info.get_data("key2")->get().to_string() == "value2"); - - CHECK(info.get_data("key2")->get_data("key3")); - CHECK(info.get_data("key2")->get_data("key3")->get().to_string() == "value3"); - - CHECK(info.get_data("key2")->get_data("key4")); - CHECK(info.get_data("key2")->get_data("key4")->get().to_string() == "value4"); - } - } -} - -TEST_CASE("meta/data/class") { - namespace meta = meta_hpp; - using namespace std::string_literals; - - const meta::class_info clazz_info = meta::class_("clazz")( - meta::data_("hello"s, "world"s) - ).make_info(); - - CHECK(clazz_info.get_data("hello")); - CHECK(clazz_info.get_data("hello")->get().to_string() == "world"); -} - -TEST_CASE("meta/data/data") { - namespace meta = meta_hpp; - using namespace std::string_literals; - - const meta::class_info clazz_info = meta::class_("clazz")( - meta::data_("hello"s, "world"s)( - meta::data_("hello2"s, "world2"s) - ) - ).make_info(); - - CHECK(clazz_info.get_data("hello")); - CHECK(clazz_info.get_data("hello")->get_data("hello2")); - CHECK(clazz_info.get_data("hello")->get_data("hello2")->get().to_string() == "world2"); -} - -TEST_CASE("meta/data/field") { - namespace meta = meta_hpp; - using namespace std::string_literals; - - const meta::class_info clazz_info = meta::class_("clazz")( - meta::field_("field", &clazz::field)( - meta::data_("hello"s, "world"s) - ) - ).make_info(); - - CHECK(clazz_info.get_field("field")); - CHECK(clazz_info.get_field("field")->get_data("hello")); - CHECK(clazz_info.get_field("field")->get_data("hello")->get().to_string() == "world"); -} - -TEST_CASE("meta/data/function") { - namespace meta = meta_hpp; - using namespace std::string_literals; - - const meta::class_info clazz_info = meta::class_("clazz")( - meta::function_("function", &clazz::function)( - meta::data_("hello"s, "world"s) - ) - ).make_info(); - - CHECK(clazz_info.get_function("function")); - CHECK(clazz_info.get_function("function")->get_data("hello")); - CHECK(clazz_info.get_function("function")->get_data("hello")->get().to_string() == "world"); -} - -TEST_CASE("meta/data/method") { - namespace meta = meta_hpp; - using namespace std::string_literals; - - const meta::class_info clazz_info = meta::class_("clazz")( - meta::method_("method", &clazz::method)( - meta::data_("hello"s, "world"s) - ) - ).make_info(); - - CHECK(clazz_info.get_method("method")); - CHECK(clazz_info.get_method("method")->get_data("hello")); - CHECK(clazz_info.get_method("method")->get_data("hello")->get().to_string() == "world"); -} - -TEST_CASE("meta/data/namespace") { - namespace meta = meta_hpp; - using namespace std::string_literals; - - const meta::namespace_info ns_info = meta::namespace_("ns")( - meta::data_("hello"s, "world"s) - ).make_info(); - - CHECK(ns_info.get_data("hello")); - CHECK(ns_info.get_data("hello")->get().to_string() == "world"); -} - -TEST_CASE("meta/data/variable") { - namespace meta = meta_hpp; - using namespace std::string_literals; - - const meta::class_info clazz_info = meta::class_("clazz")( - meta::variable_("variable", &clazz::variable)( - meta::data_("hello"s, "world"s) - ) - ).make_info(); - - CHECK(clazz_info.get_variable("variable")); - CHECK(clazz_info.get_variable("variable")->get_data("hello")); - CHECK(clazz_info.get_variable("variable")->get_data("hello")->get().to_string() == "world"); -} diff --git a/untests/meta_examples.cpp b/untests/meta_examples.cpp deleted file mode 100644 index 0aa3a4a..0000000 --- a/untests/meta_examples.cpp +++ /dev/null @@ -1,190 +0,0 @@ -/******************************************************************************* - * 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 -#include "doctest/doctest.hpp" - -namespace -{ - class ivec2 { - public: - int x{}; - int y{}; - - ivec2() = default; - explicit ivec2(int v): x{v}, y{v} {} - ivec2(int x, int y): x{x}, y{y} {} - - int dot(ivec2 other) const { - return x * other.x + y * other.y; - } - - int length2() const { - return dot(*this); - } - }; - - class ivec3 { - public: - int x{}; - int y{}; - int z{}; - - ivec3() = default; - explicit ivec3(int v): x{v}, y{v}, z{v} {} - ivec3(int x, int y, int z): x{x}, y{y}, z{z} {} - - int dot(ivec3 other) const { - return x * other.x + y * other.y + z * other.z; - } - - int length2() const { - return dot(*this); - } - }; - - ivec2 add(ivec2 l, ivec2 r) { - return {l.x + r.x, l.y + r.y}; - } - - ivec3 add(ivec3 l, ivec3 r) { - return {l.x + r.x, l.y + r.y, l.z + r.z}; - } -} - -TEST_CASE("meta/examples/ivec2") { - SUBCASE("ctors") { - CHECK(ivec2{}.x == 0); - CHECK(ivec2{}.y == 0); - - CHECK(ivec2{1}.x == 1); - CHECK(ivec2{1}.y == 1); - - CHECK(ivec2{2,3}.x == 2); - CHECK(ivec2{2,3}.y == 3); - } -} - -TEST_CASE("meta/examples/ivec3") { - SUBCASE("ctors") { - CHECK(ivec3{}.x == 0); - CHECK(ivec3{}.y == 0); - CHECK(ivec3{}.z == 0); - - CHECK(ivec3{1}.x == 1); - CHECK(ivec3{1}.y == 1); - CHECK(ivec3{1}.z == 1); - - CHECK(ivec3{2,3,4}.x == 2); - CHECK(ivec3{2,3,4}.y == 3); - CHECK(ivec3{2,3,4}.z == 4); - } -} - -TEST_CASE("meta/examples/simple") { - using namespace meta_hpp; - - namespace_info vmath_info = namespace_("vmath")( - class_("ivec2")( - field_("x", &ivec2::x)( - data_("tooltip", "x-coordinate field") - ), - field_("y", &ivec2::y)( - data_("tooltip", "y-coordinate field") - ), - method_("dot", &ivec2::dot), - method_("length2", &ivec2::length2) - ), - class_("ivec3")( - field_("x", &ivec3::x)( - data_("tooltip", "x-coordinate field") - ), - field_("y", &ivec3::y)( - data_("tooltip", "y-coordinate field") - ), - field_("z", &ivec3::z)( - data_("tooltip", "z-coordinate field") - ), - method_("dot", &ivec3::dot), - method_("length2", &ivec3::length2) - ), - function_("iadd2", select(&add)), - function_("iadd3", select(&add)) - ).make_info(); - - class_info ivec2_info = vmath_info.get_class("ivec2").value(); - - field_info ivec2_x_info = ivec2_info.get_field("x").value(); - field_info ivec2_y_info = ivec2_info.get_field("y").value(); - - data_info ivec2_x_tooltip_info = ivec2_x_info.get_data("tooltip").value(); - data_info ivec2_y_tooltip_info = ivec2_y_info.get_data("tooltip").value(); - - method_info ivec2_dot_info = ivec2_info.get_method("dot").value(); - method_info ivec2_length2_info = ivec2_info.get_method("length2").value(); - - function_info iadd2_info = vmath_info.get_function("iadd2").value(); - function_info iadd3_info = vmath_info.get_function("iadd3").value(); - - { - 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); - } - - { - 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(); - CHECK(v.x == 4); - CHECK(v.y == 6); - CHECK(v.z == 8); - } -} - -TEST_CASE("meta/examples/advanced") { - using namespace meta_hpp; - - auto db = registry{}( - class_("ivec2")( - field_("x", &ivec2::x), - field_("y", &ivec2::y), - method_("dot", &ivec2::dot), - method_("length2", &ivec2::length2) - ), - class_("ivec3")( - field_("x", &ivec3::x), - field_("y", &ivec3::y), - field_("z", &ivec3::z), - method_("dot", &ivec3::dot), - method_("length2", &ivec3::length2) - ) - ); - - ivec3 v3{1,2,3}; - - type v3_type = db.resolve(v3).value(); - class_info v3_info = v3_type.get_class().value(); - - std::cout << "class " << v3_info.id() << std::endl; - - v3_info.each_field([&v3](const field_info& info){ - std::cout - << " - " << info.id() - << ": " << info.get(v3).to_int() << std::endl; - }); - - v3_info.each_method([](const method_info& info){ - std::cout - << " + " << info.id() << "()" << std::endl; - }); -} diff --git a/untests/meta_family_tests.cpp b/untests/meta_family_tests.cpp deleted file mode 100644 index f491e12..0000000 --- a/untests/meta_family_tests.cpp +++ /dev/null @@ -1,147 +0,0 @@ -/******************************************************************************* - * 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 -#include -#include -#include -#include - -#include "doctest/doctest.hpp" - -namespace -{ - struct ivec2 { - int x{}; - int y{}; - - static ivec2 zero; - static ivec2 unit; - - ivec2& add(const ivec2 other) { - x += other.x; - y += other.y; - return *this; - } - - ivec2& sub(const ivec2 other) { - x -= other.x; - y -= other.y; - return *this; - } - }; - - struct ivec3 { - int x{}; - int y{}; - int z{}; - - static ivec3 zero; - static ivec3 unit; - - ivec3& add(const ivec3 other) { - x += other.x; - y += other.y; - z += other.z; - return *this; - } - - ivec3& sub(const ivec3 other) { - x -= other.x; - y -= other.y; - z -= other.z; - return *this; - } - }; - - ivec2 ivec2::zero{0, 0}; - ivec2 ivec2::unit{1, 1}; - - ivec3 ivec3::zero{0, 0, 0}; - ivec3 ivec3::unit{1, 1, 1}; - - ivec2 iadd2(ivec2 l, ivec2 r) { - return {l.x + r.x, l.y + r.y}; - } - - ivec2 isub2(ivec2 l, ivec2 r) { - return {l.x - r.x, l.y - r.y}; - } - - ivec3 iadd3(ivec3 l, ivec3 r) { - return {l.x + r.x, l.y + r.y, l.z + r.z}; - } - - ivec3 isub3(ivec3 l, ivec3 r) { - return {l.x - r.x, l.y - r.y, l.z - r.z}; - } -} - -TEST_CASE("meta/family") { - namespace meta = meta_hpp; - using namespace std::string_literals; - - SUBCASE("class") { - meta::class_info ivec2_info = meta::class_("ivec2").make_info(); - meta::class_info ivec3_info = meta::class_("ivec3").make_info(); - CHECK(ivec2_info.family() != ivec3_info.family()); - } - - SUBCASE("field") { - meta::field_info ivec2_x_info = meta::field_("x", &ivec2::x).make_info(); - meta::field_info ivec2_y_info = meta::field_("y", &ivec2::y).make_info(); - - meta::field_info ivec3_x_info = meta::field_("x", &ivec3::x).make_info(); - meta::field_info ivec3_y_info = meta::field_("y", &ivec3::y).make_info(); - - CHECK(ivec2_x_info.family() == ivec2_y_info.family()); - - CHECK(ivec2_x_info.family() != ivec3_x_info.family()); - CHECK(ivec2_x_info.family() != ivec3_y_info.family()); - } - - SUBCASE("function") { - meta::function_info iadd2_info = meta::function_("iadd2", &iadd2).make_info(); - meta::function_info isub2_info = meta::function_("isub2", &isub2).make_info(); - - meta::function_info iadd3_info = meta::function_("iadd3", &iadd3).make_info(); - meta::function_info isub3_info = meta::function_("isub3", &isub3).make_info(); - - CHECK(iadd2_info.family() == isub2_info.family()); - CHECK(iadd3_info.family() == isub3_info.family()); - - CHECK(iadd2_info.family() != iadd3_info.family()); - CHECK(iadd2_info.family() != isub3_info.family()); - } - - SUBCASE("method") { - meta::method_info add2_info = meta::method_("add", &ivec2::add).make_info(); - meta::method_info sub2_info = meta::method_("sub", &ivec2::sub).make_info(); - - meta::method_info add3_info = meta::method_("add", &ivec3::add).make_info(); - meta::method_info sub3_info = meta::method_("sub", &ivec3::sub).make_info(); - - CHECK(add2_info.family() == sub2_info.family()); - CHECK(add3_info.family() == sub3_info.family()); - - CHECK(add2_info.family() != add3_info.family()); - CHECK(add2_info.family() != sub3_info.family()); - } - - SUBCASE("variable") { - meta::variable_info zero2_info = meta::variable_("zero", &ivec2::zero).make_info(); - meta::variable_info unit2_info = meta::variable_("unit", &ivec2::unit).make_info(); - - meta::variable_info zero3_info = meta::variable_("zero", &ivec3::zero).make_info(); - meta::variable_info unit3_info = meta::variable_("unit", &ivec3::unit).make_info(); - - CHECK(zero2_info.family() == unit2_info.family()); - CHECK(zero3_info.family() == unit3_info.family()); - - CHECK(zero2_info.family() != zero3_info.family()); - CHECK(zero2_info.family() != unit3_info.family()); - } -} diff --git a/untests/meta_field_tests.cpp b/untests/meta_field_tests.cpp deleted file mode 100644 index b27afdc..0000000 --- a/untests/meta_field_tests.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/******************************************************************************* - * 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 -#include "doctest/doctest.hpp" - -namespace -{ - class clazz { - public: - int field{1}; - const int cfield{2}; - }; -} - -TEST_CASE("meta/field") { - namespace meta = meta_hpp; - - meta::field_ field_{"field", &clazz::field}; - meta::field_ cfield_{"cfield", &clazz::cfield}; - - const meta::field_info field_info = field_.make_info(); - const meta::field_info cfield_info = cfield_.make_info(); - - { - CHECK(field_info.value_type() == meta::get_family_id()); - CHECK(cfield_info.value_type() == meta::get_family_id()); - - CHECK(field_info.instance_type() == meta::get_family_id()); - CHECK(cfield_info.instance_type() == meta::get_family_id()); - } - - { - clazz instance; - - CHECK(instance.field == 1); - CHECK(field_info.get_r(instance) == 1); - CHECK(field_info(instance).cast() == 1); - CHECK(field_info.get(instance).cast() == 1); - CHECK(field_info.get_r(std::as_const(instance)) == 1); - CHECK(field_info(std::as_const(instance)).cast() == 1); - CHECK(field_info.get(std::as_const(instance)).cast() == 1); - - CHECK_NOTHROW(field_info(instance, 3)); - CHECK_NOTHROW(field_info.set(instance, 3)); - CHECK_THROWS_AS(field_info(instance, 4.f), std::logic_error); - CHECK_THROWS_AS(field_info.set(instance, 4.f), std::logic_error); - - CHECK(instance.field == 3); - CHECK(field_info.get_r(instance) == 3); - CHECK(field_info(instance).cast() == 3); - CHECK(field_info.get(instance).cast() == 3); - CHECK(field_info.get_r(std::as_const(instance)) == 3); - CHECK(field_info(std::as_const(instance)).cast() == 3); - CHECK(field_info.get(std::as_const(instance)).cast() == 3); - } - - { - clazz instance; - - CHECK(instance.cfield == 2); - CHECK(cfield_info.get_r(instance) == 2); - CHECK(cfield_info(instance).cast() == 2); - CHECK(cfield_info.get(instance).cast() == 2); - CHECK(cfield_info.get_r(std::as_const(instance)) == 2); - CHECK(cfield_info(std::as_const(instance)).cast() == 2); - CHECK(cfield_info.get(std::as_const(instance)).cast() == 2); - - CHECK_THROWS_AS(cfield_info(instance, 4), std::logic_error); - CHECK_THROWS_AS(cfield_info.set(instance, 4), std::logic_error); - - CHECK(instance.cfield == 2); - CHECK(cfield_info.get_r(instance) == 2); - CHECK(cfield_info(instance).cast() == 2); - CHECK(cfield_info.get(instance).cast() == 2); - CHECK(cfield_info.get_r(std::as_const(instance)) == 2); - CHECK(cfield_info(std::as_const(instance)).cast() == 2); - CHECK(cfield_info.get(std::as_const(instance)).cast() == 2); - } - - { - clazz instance; - - instance.field = 5; - CHECK(field_info.get_r(instance) == 5); - CHECK(field_info(instance).cast() == 5); - CHECK(field_info.get(instance).cast() == 5); - CHECK(field_info.get_r(std::as_const(instance)) == 5); - CHECK(field_info(std::as_const(instance)).cast() == 5); - CHECK(field_info.get(std::as_const(instance)).cast() == 5); - } -} diff --git a/untests/meta_function_tests.cpp b/untests/meta_function_tests.cpp deleted file mode 100644 index 93cbc2c..0000000 --- a/untests/meta_function_tests.cpp +++ /dev/null @@ -1,118 +0,0 @@ -/******************************************************************************* - * 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 -#include "doctest/doctest.hpp" - -namespace -{ - void void_f_void() noexcept {} - void void_f_int(int a) { (void)a; } - void void_f_int2(const int& a, int b) { (void)a; (void)b; } - - const int& int_f_void() noexcept { static int i = 1; return i; } - int int_f_int(const int a) { return a; } - int int_f_int2(int a, const int& b) { return a + b; } -} - -TEST_CASE("meta/function") { - namespace meta = meta_hpp; - - meta::function_ void_f_void_function_("void_f_void", &void_f_void); - meta::function_ void_f_int_function_("void_f_int", &void_f_int); - meta::function_ void_f_int2_function_("void_f_int2", &void_f_int2); - - meta::function_ int_f_void_function_("int_f_void", &int_f_void); - meta::function_ int_f_int_function_("int_f_int", &int_f_int); - meta::function_ int_f_int2_function_("int_f_int2", &int_f_int2); - - const meta::function_info& void_f_void_info = void_f_void_function_.make_info(); - const meta::function_info& void_f_int_info = void_f_int_function_.make_info(); - const meta::function_info& void_f_int2_info = void_f_int2_function_.make_info(); - - const meta::function_info& int_f_void_info = int_f_void_function_.make_info(); - const meta::function_info& int_f_int_info = int_f_int_function_.make_info(); - const meta::function_info& int_f_int2_info = int_f_int2_function_.make_info(); - - SUBCASE("arity") { - CHECK(void_f_void_info.arity() == 0); - CHECK(void_f_int_info.arity() == 1); - CHECK(void_f_int2_info.arity() == 2); - - CHECK(int_f_void_info.arity() == 0); - CHECK(int_f_int_info.arity() == 1); - CHECK(int_f_int2_info.arity() == 2); - } - - SUBCASE("return_type") { - CHECK_FALSE(void_f_void_info.return_type()); - CHECK(int_f_void_info.return_type() == meta::get_family_id()); - } - - SUBCASE("argument_types") { - CHECK_FALSE(void_f_void_info.argument_type(0u)); - - CHECK(int_f_int_info.argument_type(0u) == meta::get_family_id()); - CHECK_FALSE(int_f_int_info.argument_type(1u)); - - CHECK(int_f_int2_info.argument_type(0u) == meta::get_family_id()); - CHECK(int_f_int2_info.argument_type(1u) == meta::get_family_id()); - CHECK_FALSE(int_f_int2_info.argument_type(2u)); - } - - SUBCASE("void_return") { - CHECK_FALSE(void_f_void_info()); - CHECK_FALSE(void_f_void_info.invoke()); - CHECK_FALSE(void_f_void_info.invoke_r()); - CHECK_THROWS_AS(void_f_void_info(1), std::logic_error); - CHECK_THROWS_AS(void_f_void_info.invoke(1), std::logic_error); - - CHECK_THROWS_AS(void_f_int_info(), std::logic_error); - CHECK_THROWS_AS(void_f_int_info.invoke(), std::logic_error); - CHECK_FALSE(void_f_int_info(1)); - CHECK_FALSE(void_f_int_info.invoke(1)); - CHECK_FALSE(void_f_int_info.invoke_r(1)); - CHECK_THROWS_AS(void_f_int_info(1.f), std::logic_error); - CHECK_THROWS_AS(void_f_int_info.invoke(1.f), std::logic_error); - CHECK_THROWS_AS(void_f_int_info(1, 2), std::logic_error); - CHECK_THROWS_AS(void_f_int_info.invoke(1, 2), std::logic_error); - - CHECK_THROWS_AS(void_f_int2_info(), std::logic_error); - CHECK_THROWS_AS(void_f_int2_info.invoke(), std::logic_error); - CHECK_THROWS_AS(void_f_int2_info(1), std::logic_error); - CHECK_THROWS_AS(void_f_int2_info.invoke(1), std::logic_error); - CHECK_FALSE(void_f_int2_info(1, 2)); - CHECK_FALSE(void_f_int2_info.invoke(1, 2)); - CHECK_FALSE(void_f_int2_info.invoke_r(1, 2)); - CHECK_THROWS_AS(void_f_int2_info(1.f, 2), std::logic_error); - CHECK_THROWS_AS(void_f_int2_info.invoke(1.f, 2), std::logic_error); - CHECK_THROWS_AS(void_f_int2_info(1, 2.f), std::logic_error); - CHECK_THROWS_AS(void_f_int2_info.invoke(1, 2.f), std::logic_error); - CHECK_THROWS_AS(void_f_int2_info(1, 2, 3), std::logic_error); - CHECK_THROWS_AS(void_f_int2_info.invoke(1, 2, 3), std::logic_error); - } - - SUBCASE("int_return") { - CHECK(int_f_void_info.invoke_r() == 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_void_info.invoke_r(1), std::logic_error); - - CHECK_THROWS_AS(int_f_int_info.invoke(), std::logic_error); - CHECK(int_f_int_info.invoke_r(1) == 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_r(1, 2) == 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 deleted file mode 100644 index c277ae6..0000000 --- a/untests/meta_method_tests.cpp +++ /dev/null @@ -1,317 +0,0 @@ -/******************************************************************************* - * 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 -#include "doctest/doctest.hpp" - -namespace -{ - class clazz { - public: - void void_f_void() noexcept {} - void void_f_int(int a) { (void)a; } - void void_f_int2(const int& a, int b) { (void)a; (void)b; } - - const int& int_f_void() noexcept { static int i = 1; return i; } - int int_f_int(const int a) { return a; } - int int_f_int2(int a, const int& b) { return a + b; } - - void const_void_f_void() const noexcept {} - void const_void_f_int(int a) const { (void)a; } - void const_void_f_int2(int a, int b) const { (void)a; (void)b; } - - int const_int_f_void() const noexcept { return 1; } - int const_int_f_int(int a) const { return a; } - int const_int_f_int2(int a, int b) const { return a + b; } - }; - - class clazz2 {}; -} - -TEST_CASE("meta/non_const_method") { - namespace meta = meta_hpp; - - meta::method_ void_f_void_method_("void_f_void", &clazz::void_f_void); - meta::method_ void_f_int_method_("void_f_int", &clazz::void_f_int); - meta::method_ void_f_int2_method_("void_f_int2", &clazz::void_f_int2); - - meta::method_ int_f_void_method_("int_f_void", &clazz::int_f_void); - meta::method_ int_f_int_method_("int_f_int", &clazz::int_f_int); - meta::method_ int_f_int2_method_("int_f_int2", &clazz::int_f_int2); - - const meta::method_info& void_f_void_info = void_f_void_method_.make_info(); - const meta::method_info& void_f_int_info = void_f_int_method_.make_info(); - const meta::method_info& void_f_int2_info = void_f_int2_method_.make_info(); - - const meta::method_info& int_f_void_info = int_f_void_method_.make_info(); - const meta::method_info& int_f_int_info = int_f_int_method_.make_info(); - const meta::method_info& int_f_int2_info = int_f_int2_method_.make_info(); - - SUBCASE("arity") { - CHECK(void_f_void_info.arity() == 0); - CHECK(void_f_int_info.arity() == 1); - CHECK(void_f_int2_info.arity() == 2); - - CHECK(int_f_void_info.arity() == 0); - CHECK(int_f_int_info.arity() == 1); - CHECK(int_f_int2_info.arity() == 2); - } - - SUBCASE("instance_type") { - CHECK(void_f_void_info.instance_type() == meta::get_family_id()); - CHECK(int_f_void_info.instance_type() == meta::get_family_id()); - } - - SUBCASE("return_type") { - CHECK_FALSE(void_f_void_info.return_type()); - CHECK(int_f_void_info.return_type() == meta::get_family_id()); - } - - SUBCASE("argument_types") { - CHECK_FALSE(void_f_void_info.argument_type(0u)); - - CHECK(int_f_int_info.argument_type(0u) == meta::get_family_id()); - CHECK_FALSE(int_f_int_info.argument_type(1u)); - - CHECK(int_f_int2_info.argument_type(0u) == meta::get_family_id()); - CHECK(int_f_int2_info.argument_type(1u) == meta::get_family_id()); - CHECK_FALSE(int_f_int2_info.argument_type(2u)); - } - - SUBCASE("another_instance") { - clazz2 instance; - CHECK_THROWS_AS(void_f_void_info(instance), std::logic_error); - CHECK_THROWS_AS(void_f_void_info.invoke(instance), std::logic_error); - CHECK_THROWS_AS(void_f_void_info.invoke_r(instance), std::logic_error); - - CHECK_THROWS_AS(void_f_int_info(instance, 1), std::logic_error); - CHECK_THROWS_AS(void_f_int_info.invoke(instance, 1), std::logic_error); - CHECK_THROWS_AS(void_f_int_info.invoke_r(instance, 1), std::logic_error); - - CHECK_THROWS_AS(void_f_int2_info(instance, 1, 2), std::logic_error); - CHECK_THROWS_AS(void_f_int2_info.invoke(instance, 1, 2), std::logic_error); - CHECK_THROWS_AS(void_f_int2_info.invoke_r(instance, 1, 2), std::logic_error); - } - - SUBCASE("void_return") { - clazz instance; - - CHECK_FALSE(void_f_void_info(instance)); - CHECK_FALSE(void_f_void_info.invoke(instance)); - CHECK_FALSE(void_f_void_info.invoke_r(instance)); - CHECK_THROWS_AS(void_f_void_info(instance, 1), std::logic_error); - CHECK_THROWS_AS(void_f_void_info.invoke(instance, 1), std::logic_error); - CHECK_THROWS_AS(void_f_void_info.invoke_r(instance, 1), std::logic_error); - - CHECK_THROWS_AS(void_f_int_info.invoke(instance), std::logic_error); - CHECK_FALSE(void_f_int_info(instance, 1)); - CHECK_FALSE(void_f_int_info.invoke(instance, 1)); - CHECK_FALSE(void_f_int_info.invoke_r(instance, 1)); - CHECK_THROWS_AS(void_f_int_info.invoke(instance, 1.f), std::logic_error); - CHECK_THROWS_AS(void_f_int_info.invoke(instance, 1, 2), std::logic_error); - - CHECK_THROWS_AS(void_f_int2_info.invoke(instance), std::logic_error); - CHECK_THROWS_AS(void_f_int2_info.invoke(instance, 1), std::logic_error); - CHECK_FALSE(void_f_int2_info(instance, 1, 2)); - CHECK_FALSE(void_f_int2_info.invoke(instance, 1, 2)); - CHECK_FALSE(void_f_int2_info.invoke_r(instance, 1, 2)); - CHECK_THROWS_AS(void_f_int2_info.invoke(instance, 1.f, 2), std::logic_error); - CHECK_THROWS_AS(void_f_int2_info.invoke(instance, 1, 2.f), std::logic_error); - CHECK_THROWS_AS(void_f_int2_info.invoke(instance, 1, 2, 3), std::logic_error); - - const clazz& cinstance = instance; - CHECK_THROWS_AS(void_f_void_info(cinstance), std::logic_error); - CHECK_THROWS_AS(void_f_void_info.invoke(cinstance), std::logic_error); - CHECK_THROWS_AS(void_f_void_info.invoke_r(cinstance), std::logic_error); - CHECK_THROWS_AS(void_f_int_info(cinstance, 1), std::logic_error); - CHECK_THROWS_AS(void_f_int_info.invoke(cinstance, 1), std::logic_error); - CHECK_THROWS_AS(void_f_int_info.invoke_r(cinstance, 1), std::logic_error); - CHECK_THROWS_AS(void_f_int2_info(cinstance, 1, 2), std::logic_error); - CHECK_THROWS_AS(void_f_int2_info.invoke(cinstance, 1, 2), std::logic_error); - CHECK_THROWS_AS(void_f_int2_info.invoke_r(cinstance, 1, 2), std::logic_error); - } - - SUBCASE("int_return") { - clazz instance; - - CHECK(int_f_void_info(instance)->cast() == 1); - CHECK(int_f_void_info.invoke(instance)->cast() == 1); - CHECK(int_f_void_info.invoke_r(instance) == 1); - CHECK_THROWS_AS(int_f_void_info(instance, 1), std::logic_error); - CHECK_THROWS_AS(int_f_void_info.invoke(instance, 1), std::logic_error); - CHECK_THROWS_AS(int_f_void_info.invoke_r(instance, 1), std::logic_error); - - CHECK_THROWS_AS(int_f_int_info.invoke(instance), std::logic_error); - CHECK(int_f_int_info(instance, 1)->cast() == 1); - CHECK(int_f_int_info.invoke(instance, 1)->cast() == 1); - CHECK(int_f_int_info.invoke_r(instance, 1) == 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(instance, 1, 2)->cast() == 3); - CHECK(int_f_int2_info.invoke(instance, 1, 2)->cast() == 3); - CHECK(int_f_int2_info.invoke_r(instance, 1, 2) == 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_THROWS_AS(int_f_void_info(cinstance), std::logic_error); - CHECK_THROWS_AS(int_f_void_info.invoke(cinstance), std::logic_error); - CHECK_THROWS_AS(int_f_void_info.invoke_r(cinstance), std::logic_error); - CHECK_THROWS_AS(int_f_int_info(cinstance, 1), std::logic_error); - CHECK_THROWS_AS(int_f_int_info.invoke(cinstance, 1), std::logic_error); - CHECK_THROWS_AS(int_f_int_info.invoke_r(cinstance, 1), std::logic_error); - CHECK_THROWS_AS(int_f_int2_info(cinstance, 1, 2), std::logic_error); - CHECK_THROWS_AS(int_f_int2_info.invoke(cinstance, 1, 2), std::logic_error); - CHECK_THROWS_AS(int_f_int2_info.invoke_r(cinstance, 1, 2), std::logic_error); - } - - SUBCASE("int_return_by_value") { - meta::value instance{clazz{}}; - CHECK(int_f_void_info(instance)->cast() == 1); - CHECK(int_f_void_info.invoke(instance)->cast() == 1); - CHECK(int_f_void_info.invoke_r(instance) == 1); - CHECK(int_f_int_info(instance, 1)->cast() == 1); - CHECK(int_f_int_info.invoke(instance, 1)->cast() == 1); - CHECK(int_f_int_info.invoke_r(instance, 1) == 1); - CHECK(int_f_int2_info(instance, 1, 2)->cast() == 3); - CHECK(int_f_int2_info.invoke(instance, 1, 2)->cast() == 3); - CHECK(int_f_int2_info.invoke_r(instance, 1, 2) == 3); - } -} - -TEST_CASE("meta/const_method") { - namespace meta = meta_hpp; - - meta::method_ void_f_void_method_("void_f_void", &clazz::const_void_f_void); - meta::method_ void_f_int_method_("void_f_int", &clazz::const_void_f_int); - meta::method_ void_f_int2_method_("void_f_int2", &clazz::const_void_f_int2); - - meta::method_ int_f_void_method_("int_f_void", &clazz::const_int_f_void); - meta::method_ int_f_int_method_("int_f_int", &clazz::const_int_f_int); - meta::method_ int_f_int2_method_("int_f_int2", &clazz::const_int_f_int2); - - const meta::method_info& void_f_void_info = void_f_void_method_.make_info(); - const meta::method_info& void_f_int_info = void_f_int_method_.make_info(); - const meta::method_info& void_f_int2_info = void_f_int2_method_.make_info(); - - const meta::method_info& int_f_void_info = int_f_void_method_.make_info(); - const meta::method_info& int_f_int_info = int_f_int_method_.make_info(); - const meta::method_info& int_f_int2_info = int_f_int2_method_.make_info(); - - SUBCASE("instance_type") { - CHECK(void_f_void_info.instance_type() == meta::get_family_id()); - CHECK(int_f_void_info.instance_type() == meta::get_family_id()); - } - - SUBCASE("return_type") { - CHECK_FALSE(void_f_void_info.return_type()); - CHECK(int_f_void_info.return_type() == meta::get_family_id()); - } - - SUBCASE("argument_types") { - CHECK_FALSE(void_f_void_info.argument_type(0u)); - - CHECK(int_f_int_info.argument_type(0u) == meta::get_family_id()); - CHECK_FALSE(int_f_int_info.argument_type(1u)); - - CHECK(int_f_int2_info.argument_type(0u) == meta::get_family_id()); - CHECK(int_f_int2_info.argument_type(1u) == meta::get_family_id()); - CHECK_FALSE(int_f_int2_info.argument_type(2u)); - } - - SUBCASE("another_instance") { - const clazz2 instance; - CHECK_THROWS_AS(void_f_void_info(instance), std::logic_error); - CHECK_THROWS_AS(void_f_void_info.invoke(instance), std::logic_error); - CHECK_THROWS_AS(void_f_int_info(instance, 1), std::logic_error); - CHECK_THROWS_AS(void_f_int_info.invoke(instance, 1), std::logic_error); - CHECK_THROWS_AS(void_f_int2_info(instance, 1, 2), std::logic_error); - CHECK_THROWS_AS(void_f_int2_info.invoke(instance, 1, 2), std::logic_error); - } - - SUBCASE("void_return") { - clazz instance; - - CHECK_FALSE(void_f_void_info(instance)); - CHECK_FALSE(void_f_void_info.invoke(instance)); - CHECK_THROWS_AS(void_f_void_info.invoke(instance, 1), std::logic_error); - - CHECK_THROWS_AS(void_f_int_info.invoke(instance), std::logic_error); - CHECK_FALSE(void_f_int_info(instance, 1)); - CHECK_FALSE(void_f_int_info.invoke(instance, 1)); - CHECK_THROWS_AS(void_f_int_info.invoke(instance, 1.f), std::logic_error); - CHECK_THROWS_AS(void_f_int_info.invoke(instance, 1, 2), std::logic_error); - - CHECK_THROWS_AS(void_f_int2_info.invoke(instance), std::logic_error); - CHECK_THROWS_AS(void_f_int2_info.invoke(instance, 1), std::logic_error); - CHECK_FALSE(void_f_int2_info(instance, 1, 2)); - CHECK_FALSE(void_f_int2_info.invoke(instance, 1, 2)); - CHECK_THROWS_AS(void_f_int2_info.invoke(instance, 1.f, 2), std::logic_error); - CHECK_THROWS_AS(void_f_int2_info.invoke(instance, 1, 2.f), std::logic_error); - CHECK_THROWS_AS(void_f_int2_info.invoke(instance, 1, 2, 3), std::logic_error); - - const clazz& cinstance = instance; - CHECK_FALSE(void_f_void_info(cinstance)); - CHECK_FALSE(void_f_void_info.invoke(cinstance)); - CHECK_FALSE(void_f_int_info(cinstance, 1)); - CHECK_FALSE(void_f_int_info.invoke(cinstance, 1)); - CHECK_FALSE(void_f_int2_info(cinstance, 1, 2)); - CHECK_FALSE(void_f_int2_info.invoke(cinstance, 1, 2)); - } - - SUBCASE("int_return") { - clazz instance; - - CHECK(int_f_void_info(instance)->cast() == 1); - CHECK(int_f_void_info.invoke(instance)->cast() == 1); - CHECK(int_f_void_info.invoke_r(instance) == 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(instance, 1)->cast() == 1); - CHECK(int_f_int_info.invoke(instance, 1)->cast() == 1); - CHECK(int_f_int_info.invoke_r(instance, 1) == 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(instance, 1, 2)->cast() == 3); - CHECK(int_f_int2_info.invoke(instance, 1, 2)->cast() == 3); - CHECK(int_f_int2_info.invoke_r(instance, 1, 2) == 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(cinstance)->cast() == 1); - CHECK(int_f_void_info.invoke(cinstance)->cast() == 1); - CHECK(int_f_void_info.invoke_r(cinstance) == 1); - CHECK(int_f_int_info(cinstance, 1)->cast() == 1); - CHECK(int_f_int_info.invoke(cinstance, 1)->cast() == 1); - CHECK(int_f_int_info.invoke_r(cinstance, 1) == 1); - CHECK(int_f_int2_info(cinstance, 1, 2)->cast() == 3); - CHECK(int_f_int2_info.invoke(cinstance, 1, 2)->cast() == 3); - CHECK(int_f_int2_info.invoke_r(cinstance, 1, 2) == 3); - } - - SUBCASE("int_return_by_value") { - meta::value instance{clazz{}}; - CHECK(int_f_void_info(instance)->cast() == 1); - CHECK(int_f_void_info.invoke(instance)->cast() == 1); - CHECK(int_f_void_info.invoke_r(instance) == 1); - CHECK(int_f_int_info(instance, 1)->cast() == 1); - CHECK(int_f_int_info.invoke(instance, 1)->cast() == 1); - CHECK(int_f_int_info.invoke_r(instance, 1) == 1); - CHECK(int_f_int2_info(instance, 1, 2)->cast() == 3); - CHECK(int_f_int2_info.invoke(instance, 1, 2)->cast() == 3); - CHECK(int_f_int2_info.invoke_r(instance, 1, 2) == 3); - } -} diff --git a/untests/meta_namespace_tests.cpp b/untests/meta_namespace_tests.cpp deleted file mode 100644 index 4cef931..0000000 --- a/untests/meta_namespace_tests.cpp +++ /dev/null @@ -1,119 +0,0 @@ -/******************************************************************************* - * 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 -#include -#include -#include - -#include "doctest/doctest.hpp" - -namespace -{ - class clazz {}; - int func(int a) { return a; } - int variable{1}; - const int cvariable{2}; -} - -TEST_CASE("meta/namespace") { - namespace meta = meta_hpp; - - meta::namespace_ namespace_{"ns"}; - const meta::namespace_& cnamespace_ = namespace_; - - { - const meta::namespace_info& ns_info = cnamespace_.make_info(); - - CHECK_FALSE(ns_info.get_class("clazz")); - CHECK_FALSE(ns_info.get_function("func")); - CHECK_FALSE(ns_info.get_namespace("ns")); - CHECK_FALSE(ns_info.get_variable("variable")); - CHECK_FALSE(ns_info.get_variable("cvariable")); - } - - namespace_( - meta::class_("clazz"), - meta::function_("func", &func), - meta::namespace_("ns2"), - meta::variable_("variable", &variable), - meta::variable_("cvariable", &cvariable)); - - { - const meta::namespace_info& ns_info = cnamespace_.make_info(); - - CHECK(ns_info.get_class("clazz")); - CHECK(ns_info.get_function("func")); - CHECK(ns_info.get_namespace("ns2")); - CHECK(ns_info.get_variable("variable")); - CHECK(ns_info.get_variable("cvariable")); - - { - meta::class_info clazz_info = ns_info.get_class("clazz").value(); - CHECK(clazz_info.id() == "clazz"); - } - - { - meta::function_info clazz_info = ns_info.get_function("func").value(); - CHECK(clazz_info.id() == "func"); - } - - { - meta::namespace_info namespace_info = ns_info.get_namespace("ns2").value(); - CHECK(namespace_info.id() == "ns2"); - } - - { - meta::variable_info variable_info = ns_info.get_variable("variable").value(); - CHECK(variable_info.id() == "variable"); - } - - { - meta::variable_info cvariable_info = ns_info.get_variable("cvariable").value(); - CHECK(cvariable_info.id() == "cvariable"); - } - } -} - -TEST_CASE("meta/namespace/merge") { - namespace meta = meta_hpp; - - meta::namespace_ namespace_{"ns"}; - - namespace_( - meta::namespace_{"ns2"}( - meta::class_{"clazz"}, - meta::function_("func", &func), - meta::namespace_{"ns3"}, - meta::variable_("variable", &variable) - ) - ); - - namespace_( - meta::namespace_{"ns2"}( - meta::class_{"clazz"}, - meta::function_("func2", &func), - meta::namespace_{"ns3"}( - meta::namespace_{"ns4"}, - meta::variable_("variable2", &variable) - ) - ) - ); - - const meta::namespace_info ns_info = namespace_.make_info(); - const meta::namespace_info ns2_info = ns_info.get_namespace("ns2").value(); - const meta::namespace_info ns3_info = ns2_info.get_namespace("ns3").value(); - - CHECK(ns2_info.get_class("clazz")); - CHECK(ns2_info.get_function("func")); - CHECK(ns2_info.get_function("func2")); - - CHECK(ns2_info.get_namespace("ns3")); - CHECK(ns2_info.get_variable("variable")); - - CHECK(ns3_info.get_namespace("ns4")); - CHECK(ns3_info.get_variable("variable2")); -} diff --git a/untests/meta_registry_tests.cpp b/untests/meta_registry_tests.cpp deleted file mode 100644 index 8112fce..0000000 --- a/untests/meta_registry_tests.cpp +++ /dev/null @@ -1,209 +0,0 @@ -/******************************************************************************* - * 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 -#include "doctest/doctest.hpp" - -namespace -{ - struct ivec2 { - int x{}; - int y{}; - - static ivec2 zero; - - int dot(ivec2 other) const { - return x * other.x + y * other.y; - } - }; - - struct ivec3 { - int x{}; - int y{}; - int z{}; - - static ivec3 zero; - - int dot(ivec3 other) const { - return x * other.x + y * other.y + z * other.z; - } - }; - - ivec2 ivec2::zero{}; - ivec3 ivec3::zero{}; - - ivec2 iadd2(ivec2 l, ivec2 r) { - return {l.x + r.x, l.y + r.y}; - } - - ivec3 iadd3(ivec3 l, ivec3 r) { - return {l.x + r.x, l.y + r.y, l.z + r.z}; - } -} - -TEST_CASE("meta/registry") { - namespace meta = meta_hpp; - using namespace std::string_literals; - - auto registry = meta::registry{}( - meta::namespace_("vmath")( - meta::class_("ivec2")( - meta::field_("x", &ivec2::x), - meta::field_("y", &ivec2::y), - meta::method_("dot", &ivec2::dot), - meta::variable_("zero", &ivec2::zero) - ), - meta::class_("ivec3")( - meta::field_("x", &ivec3::x), - meta::field_("y", &ivec3::y), - meta::field_("z", &ivec3::z), - meta::method_("dot", &ivec3::dot), - meta::variable_("zero", &ivec3::zero) - ), - meta::function_("iadd2", &iadd2), - meta::function_("iadd3", &iadd3) - ) - ); - - SUBCASE("class_template") { - CHECK(registry.resolve()); - - const meta::type ivec2_type = registry.resolve().value(); - CHECK(ivec2_type.is_class()); - - const meta::class_info ivec2_info = ivec2_type.get_class().value(); - CHECK(ivec2_info.id() == "ivec2"); - } - - SUBCASE("class_instance") { - ivec3 v3; - CHECK(registry.resolve(v3)); - - const meta::type ivec3_type = registry.resolve(v3).value(); - CHECK(ivec3_type.is_class()); - - const meta::class_info ivec3_info = ivec3_type.get_class().value(); - CHECK(ivec3_info.id() == "ivec3"); - } - - SUBCASE("resolve/class") { - ivec2 v2; - ivec3 v3; - - REQUIRE(registry.resolve()); - REQUIRE(registry.resolve(v2)); - REQUIRE(registry.resolve(std::as_const(v2))); - REQUIRE(registry.resolve(static_cast(v2))); - - REQUIRE(registry.resolve()); - REQUIRE(registry.resolve(v3)); - REQUIRE(registry.resolve(std::as_const(v3))); - REQUIRE(registry.resolve(static_cast(v3))); - - const meta::class_info v2_info = meta::class_("ivec2").make_info(); - const meta::class_info v3_info = meta::class_("ivec3").make_info(); - CHECK(v2_info.family() != v3_info.family()); - - CHECK(v2_info.family() == registry.resolve()->family()); - CHECK(v2_info.family() == registry.resolve(v2)->family()); - CHECK(v2_info.family() == registry.resolve(std::as_const(v2))->family()); - CHECK(v2_info.family() == registry.resolve(static_cast(v2))->family()); - - CHECK(v3_info.family() == registry.resolve()->family()); - CHECK(v3_info.family() == registry.resolve(v3)->family()); - CHECK(v3_info.family() == registry.resolve(std::as_const(v3))->family()); - CHECK(v3_info.family() == registry.resolve(static_cast(v3))->family()); - - { - REQUIRE(registry.get_class_by_name("vmath::ivec2")); - REQUIRE(registry.get_class_by_name("vmath::ivec3")); - - CHECK(v2_info.family() == registry.get_class_by_name("vmath::ivec2")->family()); - CHECK(v3_info.family() == registry.get_class_by_name("vmath::ivec3")->family()); - } - } - - SUBCASE("resolve/field") { - REQUIRE(registry.get_field_by_name("vmath::ivec2::x")); - REQUIRE(registry.get_field_by_name("vmath::ivec2::y")); - REQUIRE(registry.get_field_by_name("vmath::ivec3::x")); - REQUIRE(registry.get_field_by_name("vmath::ivec3::y")); - - CHECK("x" == registry.get_field_by_name("vmath::ivec2::x")->id()); - CHECK("y" == registry.get_field_by_name("vmath::ivec2::y")->id()); - CHECK("x" == registry.get_field_by_name("vmath::ivec3::x")->id()); - CHECK("y" == registry.get_field_by_name("vmath::ivec3::y")->id()); - } - - SUBCASE("resolve/function") { - REQUIRE(registry.get_function_by_name("vmath::iadd2")); - REQUIRE(registry.get_function_by_name("vmath::iadd3")); - - CHECK("iadd2" == registry.get_function_by_name("vmath::iadd2")->id()); - CHECK("iadd3" == registry.get_function_by_name("vmath::iadd3")->id()); - } - - SUBCASE("resolve/method") { - REQUIRE(registry.get_method_by_name("vmath::ivec2::dot")); - REQUIRE(registry.get_method_by_name("vmath::ivec3::dot")); - - CHECK("dot" == registry.get_method_by_name("vmath::ivec2::dot")->id()); - CHECK("dot" == registry.get_method_by_name("vmath::ivec3::dot")->id()); - } - - SUBCASE("resolve/variable") { - REQUIRE(registry.get_variable_by_name("vmath::ivec2::zero")); - REQUIRE(registry.get_variable_by_name("vmath::ivec3::zero")); - - CHECK("zero" == registry.get_variable_by_name("vmath::ivec2::zero")->id()); - CHECK("zero" == registry.get_variable_by_name("vmath::ivec3::zero")->id()); - } -} - -TEST_CASE("meta/registry/merge") { - namespace meta = meta_hpp; - using namespace std::string_literals; - - auto registry = meta::registry{}; - - SUBCASE("class") { - registry( - meta::class_("ivec2")( - meta::field_("x", &ivec2::x) - )); - - registry( - meta::class_("ivec2")( - meta::field_("y", &ivec2::y) - )); - - CHECK(registry.resolve()); - CHECK(registry.resolve()->get_field("x")); - CHECK(registry.resolve()->get_field("y")); - - CHECK(registry.resolve(ivec2{})); - CHECK(registry.resolve(ivec2{})->get_field("x")); - CHECK(registry.resolve(ivec2{})->get_field("y")); - - CHECK(registry.get_class_by_name("ivec2")); - CHECK(registry.get_class_by_name("ivec2")->get_field("x")); - CHECK(registry.get_class_by_name("ivec2")->get_field("y")); - } - - SUBCASE("namespace") { - registry( - meta::namespace_("vmath")( - meta::class_("ivec2"))); - - registry( - meta::namespace_("vmath")( - meta::class_("ivec3"))); - - CHECK(registry.get_namespace_by_name("vmath")); - CHECK(registry.get_namespace_by_name("vmath")->get_class("ivec2")); - CHECK(registry.get_namespace_by_name("vmath")->get_class("ivec3")); - } -} diff --git a/untests/meta_tests.cpp b/untests/meta_tests.cpp new file mode 100644 index 0000000..5e45309 --- /dev/null +++ b/untests/meta_tests.cpp @@ -0,0 +1,15 @@ +/******************************************************************************* + * 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 +#include "doctest/doctest.hpp" + +namespace +{ +} + +TEST_CASE("meta") { +} diff --git a/untests/meta_type_tests.cpp b/untests/meta_type_tests.cpp deleted file mode 100644 index 13953f5..0000000 --- a/untests/meta_type_tests.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/******************************************************************************* - * 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 - -#include -#include -#include -#include -#include -#include - -#include "doctest/doctest.hpp" - -namespace -{ - struct clazz { - int field{42}; - static int variable; - int method() const { return 42; } - static int function() { return 42; } - }; - - int clazz::variable{42}; -} - -TEST_CASE("meta/type") { - namespace meta = meta_hpp; - using namespace std::string_literals; - - meta::type class_type = meta::class_("clazz").make_info(); - CHECK(class_type.is_class()); - CHECK(class_type.get_class()->id() == "clazz"); - - meta::type field_type = meta::field_("field", &clazz::field).make_info(); - CHECK(field_type.is_field()); - CHECK(field_type.get_field()->id() == "field"); - - meta::type function_type = meta::function_("function", &clazz::function).make_info(); - CHECK(function_type.is_function()); - CHECK(function_type.get_function()->id() == "function"); - - meta::type method_type = meta::method_("method", &clazz::method).make_info(); - CHECK(method_type.is_method()); - CHECK(method_type.get_method()->id() == "method"); - - meta::type namespace_type = meta::namespace_("ns").make_info(); - CHECK(namespace_type.is_namespace()); - CHECK(namespace_type.get_namespace()->id() == "ns"); - - meta::type variable_type = meta::variable_("variable", &clazz::variable).make_info(); - CHECK(variable_type.is_variable()); - CHECK(variable_type.get_variable()->id() == "variable"); -} - -TEST_CASE("meta/type/merge") { - namespace meta = meta_hpp; - using namespace std::string_literals; - - { - meta::type clazz_type = meta::class_("clazz")( - meta::field_("field", &clazz::field) - ).make_info(); - - clazz_type.merge(meta::class_("clazz")( - meta::function_("function", &clazz::function) - ).make_info()); - - REQUIRE(clazz_type.is_class()); - CHECK(clazz_type.get_class()->get_field("field")); - CHECK(clazz_type.get_class()->get_function("function")); - } -} diff --git a/untests/meta_value_tests.cpp b/untests/meta_value_tests.cpp deleted file mode 100644 index bb06099..0000000 --- a/untests/meta_value_tests.cpp +++ /dev/null @@ -1,200 +0,0 @@ -/******************************************************************************* - * 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 -#include "doctest/doctest.hpp" - -#include -#include - -namespace -{ - class clazz {}; - class clazz2 {}; - - void func() {} -} - -TEST_CASE("meta/value") { - namespace meta = meta_hpp; - using namespace std::string_literals; - - CHECK(meta::value{true}.to_bool() == true); - CHECK(meta::value{1}.to_int() == 1); - CHECK(meta::value{1u}.to_uint() == 1u); - CHECK(meta::value{1.f}.to_float() == 1.f); - CHECK(meta::value{1.0}.to_double() == 1.0); - CHECK(meta::value{"meta"s}.to_string() == "meta"); - - CHECK(meta::value{true}.is_bool()); - CHECK_FALSE(meta::value{true}.is_int()); - CHECK(meta::value{1}.is_int()); - CHECK_FALSE(meta::value{1}.is_uint()); - CHECK(meta::value{1u}.is_uint()); - CHECK_FALSE(meta::value{1u}.is_float()); - CHECK(meta::value{1.f}.is_float()); - CHECK_FALSE(meta::value{1.f}.is_double()); - CHECK(meta::value{1.0}.is_double()); - CHECK_FALSE(meta::value{1.0}.is_string()); - CHECK(meta::value{"meta"s}.is_string()); - CHECK_FALSE(meta::value{"meta"s}.is_bool()); - - CHECK(meta::value{std::in_place_type, std::int8_t{1}}.to_int8() == 1); - CHECK(meta::value{std::in_place_type, std::int16_t{1}}.to_int16() == 1); - CHECK(meta::value{std::in_place_type, std::int32_t{1}}.to_int32() == 1); - CHECK(meta::value{std::in_place_type, std::int64_t{1}}.to_int64() == 1); - CHECK(meta::value{std::in_place_type, std::ptrdiff_t{1}}.to_ptrdiff_t() == 1); - CHECK(meta::value{std::in_place_type, std::intptr_t{1}}.to_intptr_t() == 1); - - CHECK(meta::value{std::in_place_type, std::uint8_t{1}}.to_uint8() == 1u); - CHECK(meta::value{std::in_place_type, std::uint16_t{1}}.to_uint16() == 1u); - CHECK(meta::value{std::in_place_type, std::uint32_t{1}}.to_uint32() == 1u); - CHECK(meta::value{std::in_place_type, std::uint64_t{1}}.to_uint64() == 1u); - CHECK(meta::value{std::in_place_type, std::size_t{1}}.to_size_t() == 1u); - CHECK(meta::value{std::in_place_type, std::uintptr_t{1}}.to_uintptr_t() == 1u); - - CHECK(meta::value{std::in_place_type, std::int8_t{1}}.is_int8()); - CHECK(meta::value{std::in_place_type, std::int16_t{1}}.is_int16()); - CHECK(meta::value{std::in_place_type, std::int32_t{1}}.is_int32()); - CHECK(meta::value{std::in_place_type, std::int64_t{1}}.is_int64()); - CHECK(meta::value{std::in_place_type, std::ptrdiff_t{1}}.is_ptrdiff_t()); - CHECK(meta::value{std::in_place_type, std::intptr_t{1}}.is_intptr_t()); - - CHECK(meta::value{std::in_place_type, std::uint8_t{1}}.is_uint8()); - CHECK(meta::value{std::in_place_type, std::uint16_t{1}}.is_uint16()); - CHECK(meta::value{std::in_place_type, std::uint32_t{1}}.is_uint32()); - CHECK(meta::value{std::in_place_type, std::uint64_t{1}}.is_uint64()); - CHECK(meta::value{std::in_place_type, std::size_t{1}}.is_size_t()); - CHECK(meta::value{std::in_place_type, std::uintptr_t{1}}.is_uintptr_t()); - - SUBCASE("in_place") { - CHECK(meta::value{std::in_place_type, std::uint8_t{1}}.is_uint8()); - CHECK(meta::value{std::in_place_type, std::uint8_t{1}}.is_uint8()); - CHECK(meta::value{std::in_place_type, std::uint8_t{1}}.is_uint8()); - CHECK(meta::value{std::in_place_type, std::uint8_t{1}}.is_uint8()); - } -} - -TEST_CASE("meta/value/fid") { - namespace meta = meta_hpp; - using namespace std::string_literals; - - CHECK(meta::value{clazz{}}.has_type()); - CHECK(meta::value{clazz{}}.fid() == meta::get_family_id()); - - CHECK(meta::value{clazz2{}}.has_type()); - CHECK(meta::value{clazz2{}}.fid() == meta::get_family_id()); - - CHECK(meta::value{clazz{}}.fid() != meta::value{clazz2{}}.fid()); - - { - meta::value v = clazz{}; - CHECK(v.fid() == meta::get_family_id()); - v = clazz2{}; - CHECK(v.fid() == meta::get_family_id()); - } - - CHECK(meta::value{std::in_place_type, 1}.fid() == meta::get_family_id()); - CHECK(meta::value{std::in_place_type>, {1,2,3,4}}.fid() == meta::get_family_id>()); -} - -TEST_CASE("meta/value/data") { - namespace meta = meta_hpp; - using namespace std::string_literals; - - meta::value v{1}; - CHECK(*static_cast(v.data()) == 1); - *static_cast(v.data()) = 2; - CHECK(v.to_int() == 2); - CHECK(*static_cast(std::as_const(v).data()) == 2); -} - -TEST_CASE("meta/value/equal") { - namespace meta = meta_hpp; - using namespace std::string_literals; - - { - CHECK(meta::value{1}.equals(1)); - CHECK_FALSE(meta::value{1}.equals(0)); - CHECK_FALSE(meta::value{1}.equals("hello"s)); - } - - { - int i = 1; - - CHECK(meta::value{1}.equals(i)); - CHECK(meta::value{1}.equals(std::as_const(i))); - CHECK_FALSE(meta::value{2}.equals(i)); - CHECK_FALSE(meta::value{2}.equals(std::as_const(i))); - } - - { - CHECK(meta::value{1}.equals(meta::value{1})); - CHECK_FALSE(meta::value{1}.equals(meta::value{0})); - CHECK_FALSE(meta::value{1}.equals(meta::value{"hello"s})); - - CHECK(meta::value{1}.equals(meta::value{1})); - CHECK_FALSE(meta::value{0}.equals(meta::value{1})); - CHECK_FALSE(meta::value{"hello"s}.equals(meta::value{1})); - } - - { - CHECK(meta::value{std::in_place_type, 1}.equals(meta::value{1})); - CHECK(meta::value{1}.equals(meta::value{std::in_place_type, 1})); - - using vi = std::vector; - CHECK(meta::value{std::in_place_type, {1,2,3}}.equals(meta::value{vi{1,2,3}})); - CHECK(meta::value{vi{1,2,3}}.equals(meta::value{std::in_place_type, {1,2,3}})); - CHECK_FALSE(meta::value{std::in_place_type, {1,2,3}}.equals(meta::value{vi{1,2,4}})); - CHECK_FALSE(meta::value{vi{1,2,4}}.equals(meta::value{std::in_place_type, {1,2,3}})); - } - - { - meta::value v1{&func}; - meta::value v2{&func}; - - CHECK(v1.equals(v1)); - CHECK(v1.equals(v2)); - } - - { - meta::value v1{clazz{}}; - meta::value v2{clazz{}}; - - CHECK(v1.equals(v1)); - CHECK_FALSE(v1.equals(v2)); - } - - { - const int rv = 1; - - meta::value v1{&rv}; - meta::value v2{&rv}; - - CHECK(v1.equals(v1)); - } - - { - meta::value v1{"hello"s}; - meta::value{1}.swap(v1); - CHECK(v1.equals(meta::value{1})); - } -} - -TEST_CASE("meta/value/swap") { - namespace meta = meta_hpp; - using namespace std::string_literals; - - meta::value v1{"hello"s}; - meta::value v2{42}; - meta::swap(v1, v2); - - CHECK(v1.fid() == meta::get_family_id()); - CHECK(v1.to_int() == 42); - - CHECK(v2.fid() == meta::get_family_id()); - CHECK(v2.to_string() == "hello"); -} diff --git a/untests/meta_variable_tests.cpp b/untests/meta_variable_tests.cpp deleted file mode 100644 index 0acc5b8..0000000 --- a/untests/meta_variable_tests.cpp +++ /dev/null @@ -1,129 +0,0 @@ -/******************************************************************************* - * 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 -#include "doctest/doctest.hpp" - -namespace -{ - int variable{1}; - const int cvariable{2}; - - class clazz { - public: - static int variable; - static const int cvariable; - }; - - int clazz::variable{1}; - const int clazz::cvariable{2}; -} - -TEST_CASE("meta/variable") { - namespace meta = meta_hpp; - - SUBCASE("in_namespace") { - meta::variable_ variable_{"variable", &variable}; - meta::variable_ cvariable_{"cvariable", &cvariable}; - - const meta::variable_info& variable_info = variable_.make_info(); - const meta::variable_info& cvariable_info = cvariable_.make_info(); - - { - CHECK(variable_info.value_type() == meta::get_family_id()); - CHECK(cvariable_info.value_type() == meta::get_family_id()); - } - - { - CHECK(variable == 1); - CHECK(variable_info().cast() == 1); - CHECK(variable_info.get().cast() == 1); - CHECK(variable_info.get_r() == 1); - - CHECK_NOTHROW(variable_info(3)); - CHECK_NOTHROW(variable_info.set(3)); - CHECK_THROWS_AS(variable_info(4.f), std::logic_error); - CHECK_THROWS_AS(variable_info.set(4.f), std::logic_error); - - CHECK(variable == 3); - CHECK(variable_info().cast() == 3); - CHECK(variable_info.get().cast() == 3); - CHECK(variable_info.get_r() == 3); - } - - { - CHECK(cvariable == 2); - CHECK(cvariable_info().cast() == 2); - CHECK(cvariable_info.get().cast() == 2); - CHECK(cvariable_info.get_r() == 2); - - CHECK_THROWS_AS(cvariable_info(4), std::logic_error); - CHECK_THROWS_AS(cvariable_info.set(4), std::logic_error); - - CHECK(cvariable == 2); - CHECK(cvariable_info().cast() == 2); - CHECK(cvariable_info.get().cast() == 2); - CHECK(cvariable_info.get_r() == 2); - } - - { - variable = 5; - CHECK(variable_info().cast() == 5); - CHECK(variable_info.get().cast() == 5); - CHECK(variable_info.get_r() == 5); - } - } - - SUBCASE("in_class") { - meta::variable_ variable_{"variable", &clazz::variable}; - meta::variable_ cvariable_{"cvariable", &clazz::cvariable}; - - const meta::variable_info& variable_info = variable_.make_info(); - const meta::variable_info& cvariable_info = cvariable_.make_info(); - - { - CHECK(variable_info.value_type() == meta::get_family_id()); - CHECK(cvariable_info.value_type() == meta::get_family_id()); - } - - { - CHECK(clazz::variable == 1); - CHECK(variable_info().cast() == 1); - CHECK(variable_info.get().cast() == 1); - CHECK(variable_info.get_r() == 1); - - CHECK_NOTHROW(variable_info(3)); - CHECK_NOTHROW(variable_info.set(3)); - - CHECK(clazz::variable == 3); - CHECK(variable_info().cast() == 3); - CHECK(variable_info.get().cast() == 3); - CHECK(variable_info.get_r() == 3); - } - - { - CHECK(clazz::cvariable == 2); - CHECK(cvariable_info().cast() == 2); - CHECK(cvariable_info.get().cast() == 2); - CHECK(cvariable_info.get_r() == 2); - - CHECK_THROWS_AS(cvariable_info(4), std::logic_error); - CHECK_THROWS_AS(cvariable_info.set(4), std::logic_error); - - CHECK(clazz::cvariable == 2); - CHECK(cvariable_info().cast() == 2); - CHECK(cvariable_info.get().cast() == 2); - CHECK(cvariable_info.get_r() == 2); - } - - { - clazz::variable = 5; - CHECK(variable_info().cast() == 5); - CHECK(variable_info.get().cast() == 5); - CHECK(variable_info.get_r() == 5); - } - } -} From 77d018264a71f37c5153a6df2ca4250962def078 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Mon, 2 Aug 2021 20:22:59 +0700 Subject: [PATCH 063/233] dummy test files --- untests/features/infos/_infos_fwd.hpp | 9 +++++++++ untests/features/infos/class_tests.cpp | 14 ++++++++++++++ untests/features/infos/ctor_tests.cpp | 14 ++++++++++++++ untests/features/infos/enum_tests.cpp | 14 ++++++++++++++ untests/features/infos/function_tests.cpp | 14 ++++++++++++++ untests/features/infos/member_tests.cpp | 14 ++++++++++++++ untests/features/infos/method_tests.cpp | 14 ++++++++++++++ untests/features/infos/namespace_tests.cpp | 14 ++++++++++++++ untests/features/traits/_traits_fwd.hpp | 9 +++++++++ untests/features/traits/arithmetic_tests.cpp | 14 ++++++++++++++ untests/features/traits/array_tests.cpp | 14 ++++++++++++++ untests/features/traits/class_tests.cpp | 14 ++++++++++++++ untests/features/traits/ctor_tests.cpp | 14 ++++++++++++++ untests/features/traits/enum_tests.cpp | 14 ++++++++++++++ untests/features/traits/function_tests.cpp | 14 ++++++++++++++ untests/features/traits/member_tests.cpp | 14 ++++++++++++++ untests/features/traits/method_tests.cpp | 14 ++++++++++++++ untests/features/traits/pointer_tests.cpp | 14 ++++++++++++++ untests/features/traits/reference_tests.cpp | 14 ++++++++++++++ untests/features/traits/void_tests.cpp | 14 ++++++++++++++ untests/features/types/_types_fwd.hpp | 9 +++++++++ untests/features/types/arithmetic_tests.cpp | 14 ++++++++++++++ untests/features/types/array_tests.cpp | 14 ++++++++++++++ untests/features/types/class_tests.cpp | 14 ++++++++++++++ untests/features/types/ctor_tests.cpp | 14 ++++++++++++++ untests/features/types/enum_tests.cpp | 14 ++++++++++++++ untests/features/types/function_tests.cpp | 14 ++++++++++++++ untests/features/types/member_tests.cpp | 14 ++++++++++++++ untests/features/types/method_tests.cpp | 14 ++++++++++++++ untests/features/types/pointer_tests.cpp | 14 ++++++++++++++ untests/features/types/reference_tests.cpp | 14 ++++++++++++++ untests/features/types/void_tests.cpp | 14 ++++++++++++++ untests/meta_tests.cpp | 3 +-- untests/meta_tests.hpp | 10 ++++++++++ 34 files changed, 444 insertions(+), 2 deletions(-) create mode 100644 untests/features/infos/_infos_fwd.hpp create mode 100644 untests/features/infos/class_tests.cpp create mode 100644 untests/features/infos/ctor_tests.cpp create mode 100644 untests/features/infos/enum_tests.cpp create mode 100644 untests/features/infos/function_tests.cpp create mode 100644 untests/features/infos/member_tests.cpp create mode 100644 untests/features/infos/method_tests.cpp create mode 100644 untests/features/infos/namespace_tests.cpp create mode 100644 untests/features/traits/_traits_fwd.hpp create mode 100644 untests/features/traits/arithmetic_tests.cpp create mode 100644 untests/features/traits/array_tests.cpp create mode 100644 untests/features/traits/class_tests.cpp create mode 100644 untests/features/traits/ctor_tests.cpp create mode 100644 untests/features/traits/enum_tests.cpp create mode 100644 untests/features/traits/function_tests.cpp create mode 100644 untests/features/traits/member_tests.cpp create mode 100644 untests/features/traits/method_tests.cpp create mode 100644 untests/features/traits/pointer_tests.cpp create mode 100644 untests/features/traits/reference_tests.cpp create mode 100644 untests/features/traits/void_tests.cpp create mode 100644 untests/features/types/_types_fwd.hpp create mode 100644 untests/features/types/arithmetic_tests.cpp create mode 100644 untests/features/types/array_tests.cpp create mode 100644 untests/features/types/class_tests.cpp create mode 100644 untests/features/types/ctor_tests.cpp create mode 100644 untests/features/types/enum_tests.cpp create mode 100644 untests/features/types/function_tests.cpp create mode 100644 untests/features/types/member_tests.cpp create mode 100644 untests/features/types/method_tests.cpp create mode 100644 untests/features/types/pointer_tests.cpp create mode 100644 untests/features/types/reference_tests.cpp create mode 100644 untests/features/types/void_tests.cpp create mode 100644 untests/meta_tests.hpp diff --git a/untests/features/infos/_infos_fwd.hpp b/untests/features/infos/_infos_fwd.hpp new file mode 100644 index 0000000..b826cce --- /dev/null +++ b/untests/features/infos/_infos_fwd.hpp @@ -0,0 +1,9 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../../meta_tests.hpp" diff --git a/untests/features/infos/class_tests.cpp b/untests/features/infos/class_tests.cpp new file mode 100644 index 0000000..de7996a --- /dev/null +++ b/untests/features/infos/class_tests.cpp @@ -0,0 +1,14 @@ +/******************************************************************************* + * 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 "_infos_fwd.hpp" + +namespace +{ +} + +TEST_CASE("features/infos/class") { +} diff --git a/untests/features/infos/ctor_tests.cpp b/untests/features/infos/ctor_tests.cpp new file mode 100644 index 0000000..57fe560 --- /dev/null +++ b/untests/features/infos/ctor_tests.cpp @@ -0,0 +1,14 @@ +/******************************************************************************* + * 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 "_infos_fwd.hpp" + +namespace +{ +} + +TEST_CASE("features/infos/ctor") { +} diff --git a/untests/features/infos/enum_tests.cpp b/untests/features/infos/enum_tests.cpp new file mode 100644 index 0000000..497af93 --- /dev/null +++ b/untests/features/infos/enum_tests.cpp @@ -0,0 +1,14 @@ +/******************************************************************************* + * 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 "_infos_fwd.hpp" + +namespace +{ +} + +TEST_CASE("features/infos/enum") { +} diff --git a/untests/features/infos/function_tests.cpp b/untests/features/infos/function_tests.cpp new file mode 100644 index 0000000..83baf40 --- /dev/null +++ b/untests/features/infos/function_tests.cpp @@ -0,0 +1,14 @@ +/******************************************************************************* + * 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 "_infos_fwd.hpp" + +namespace +{ +} + +TEST_CASE("features/infos/function") { +} diff --git a/untests/features/infos/member_tests.cpp b/untests/features/infos/member_tests.cpp new file mode 100644 index 0000000..31db3d2 --- /dev/null +++ b/untests/features/infos/member_tests.cpp @@ -0,0 +1,14 @@ +/******************************************************************************* + * 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 "_infos_fwd.hpp" + +namespace +{ +} + +TEST_CASE("features/infos/member") { +} diff --git a/untests/features/infos/method_tests.cpp b/untests/features/infos/method_tests.cpp new file mode 100644 index 0000000..21bcea4 --- /dev/null +++ b/untests/features/infos/method_tests.cpp @@ -0,0 +1,14 @@ +/******************************************************************************* + * 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 "_infos_fwd.hpp" + +namespace +{ +} + +TEST_CASE("features/infos/method") { +} diff --git a/untests/features/infos/namespace_tests.cpp b/untests/features/infos/namespace_tests.cpp new file mode 100644 index 0000000..bd029d5 --- /dev/null +++ b/untests/features/infos/namespace_tests.cpp @@ -0,0 +1,14 @@ +/******************************************************************************* + * 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 "_infos_fwd.hpp" + +namespace +{ +} + +TEST_CASE("features/infos/namespace") { +} diff --git a/untests/features/traits/_traits_fwd.hpp b/untests/features/traits/_traits_fwd.hpp new file mode 100644 index 0000000..b826cce --- /dev/null +++ b/untests/features/traits/_traits_fwd.hpp @@ -0,0 +1,9 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../../meta_tests.hpp" diff --git a/untests/features/traits/arithmetic_tests.cpp b/untests/features/traits/arithmetic_tests.cpp new file mode 100644 index 0000000..af82e77 --- /dev/null +++ b/untests/features/traits/arithmetic_tests.cpp @@ -0,0 +1,14 @@ +/******************************************************************************* + * 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 "_traits_fwd.hpp" + +namespace +{ +} + +TEST_CASE("features/traits/arithmetic") { +} diff --git a/untests/features/traits/array_tests.cpp b/untests/features/traits/array_tests.cpp new file mode 100644 index 0000000..3b5446b --- /dev/null +++ b/untests/features/traits/array_tests.cpp @@ -0,0 +1,14 @@ +/******************************************************************************* + * 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 "_traits_fwd.hpp" + +namespace +{ +} + +TEST_CASE("features/traits/array") { +} diff --git a/untests/features/traits/class_tests.cpp b/untests/features/traits/class_tests.cpp new file mode 100644 index 0000000..cacd905 --- /dev/null +++ b/untests/features/traits/class_tests.cpp @@ -0,0 +1,14 @@ +/******************************************************************************* + * 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 "_traits_fwd.hpp" + +namespace +{ +} + +TEST_CASE("features/traits/class") { +} diff --git a/untests/features/traits/ctor_tests.cpp b/untests/features/traits/ctor_tests.cpp new file mode 100644 index 0000000..7480901 --- /dev/null +++ b/untests/features/traits/ctor_tests.cpp @@ -0,0 +1,14 @@ +/******************************************************************************* + * 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 "_traits_fwd.hpp" + +namespace +{ +} + +TEST_CASE("features/traits/ctor") { +} diff --git a/untests/features/traits/enum_tests.cpp b/untests/features/traits/enum_tests.cpp new file mode 100644 index 0000000..deba0df --- /dev/null +++ b/untests/features/traits/enum_tests.cpp @@ -0,0 +1,14 @@ +/******************************************************************************* + * 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 "_traits_fwd.hpp" + +namespace +{ +} + +TEST_CASE("features/traits/enum") { +} diff --git a/untests/features/traits/function_tests.cpp b/untests/features/traits/function_tests.cpp new file mode 100644 index 0000000..60be950 --- /dev/null +++ b/untests/features/traits/function_tests.cpp @@ -0,0 +1,14 @@ +/******************************************************************************* + * 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 "_traits_fwd.hpp" + +namespace +{ +} + +TEST_CASE("features/traits/function") { +} diff --git a/untests/features/traits/member_tests.cpp b/untests/features/traits/member_tests.cpp new file mode 100644 index 0000000..5e225db --- /dev/null +++ b/untests/features/traits/member_tests.cpp @@ -0,0 +1,14 @@ +/******************************************************************************* + * 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 "_traits_fwd.hpp" + +namespace +{ +} + +TEST_CASE("features/traits/member") { +} diff --git a/untests/features/traits/method_tests.cpp b/untests/features/traits/method_tests.cpp new file mode 100644 index 0000000..d1e47df --- /dev/null +++ b/untests/features/traits/method_tests.cpp @@ -0,0 +1,14 @@ +/******************************************************************************* + * 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 "_traits_fwd.hpp" + +namespace +{ +} + +TEST_CASE("features/traits/method") { +} diff --git a/untests/features/traits/pointer_tests.cpp b/untests/features/traits/pointer_tests.cpp new file mode 100644 index 0000000..6ab744f --- /dev/null +++ b/untests/features/traits/pointer_tests.cpp @@ -0,0 +1,14 @@ +/******************************************************************************* + * 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 "_traits_fwd.hpp" + +namespace +{ +} + +TEST_CASE("features/traits/pointer") { +} diff --git a/untests/features/traits/reference_tests.cpp b/untests/features/traits/reference_tests.cpp new file mode 100644 index 0000000..a214604 --- /dev/null +++ b/untests/features/traits/reference_tests.cpp @@ -0,0 +1,14 @@ +/******************************************************************************* + * 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 "_traits_fwd.hpp" + +namespace +{ +} + +TEST_CASE("features/traits/reference") { +} diff --git a/untests/features/traits/void_tests.cpp b/untests/features/traits/void_tests.cpp new file mode 100644 index 0000000..d1c5a6e --- /dev/null +++ b/untests/features/traits/void_tests.cpp @@ -0,0 +1,14 @@ +/******************************************************************************* + * 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 "_traits_fwd.hpp" + +namespace +{ +} + +TEST_CASE("features/traits/void") { +} diff --git a/untests/features/types/_types_fwd.hpp b/untests/features/types/_types_fwd.hpp new file mode 100644 index 0000000..b826cce --- /dev/null +++ b/untests/features/types/_types_fwd.hpp @@ -0,0 +1,9 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../../meta_tests.hpp" diff --git a/untests/features/types/arithmetic_tests.cpp b/untests/features/types/arithmetic_tests.cpp new file mode 100644 index 0000000..96c5a0c --- /dev/null +++ b/untests/features/types/arithmetic_tests.cpp @@ -0,0 +1,14 @@ +/******************************************************************************* + * 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 "_types_fwd.hpp" + +namespace +{ +} + +TEST_CASE("features/types/arithmetic") { +} diff --git a/untests/features/types/array_tests.cpp b/untests/features/types/array_tests.cpp new file mode 100644 index 0000000..a373834 --- /dev/null +++ b/untests/features/types/array_tests.cpp @@ -0,0 +1,14 @@ +/******************************************************************************* + * 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 "_types_fwd.hpp" + +namespace +{ +} + +TEST_CASE("features/types/array") { +} diff --git a/untests/features/types/class_tests.cpp b/untests/features/types/class_tests.cpp new file mode 100644 index 0000000..3e39f73 --- /dev/null +++ b/untests/features/types/class_tests.cpp @@ -0,0 +1,14 @@ +/******************************************************************************* + * 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 "_types_fwd.hpp" + +namespace +{ +} + +TEST_CASE("features/types/class") { +} diff --git a/untests/features/types/ctor_tests.cpp b/untests/features/types/ctor_tests.cpp new file mode 100644 index 0000000..41e8df7 --- /dev/null +++ b/untests/features/types/ctor_tests.cpp @@ -0,0 +1,14 @@ +/******************************************************************************* + * 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 "_types_fwd.hpp" + +namespace +{ +} + +TEST_CASE("features/types/ctor") { +} diff --git a/untests/features/types/enum_tests.cpp b/untests/features/types/enum_tests.cpp new file mode 100644 index 0000000..cc6da38 --- /dev/null +++ b/untests/features/types/enum_tests.cpp @@ -0,0 +1,14 @@ +/******************************************************************************* + * 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 "_types_fwd.hpp" + +namespace +{ +} + +TEST_CASE("features/types/enum") { +} diff --git a/untests/features/types/function_tests.cpp b/untests/features/types/function_tests.cpp new file mode 100644 index 0000000..ab64d7d --- /dev/null +++ b/untests/features/types/function_tests.cpp @@ -0,0 +1,14 @@ +/******************************************************************************* + * 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 "_types_fwd.hpp" + +namespace +{ +} + +TEST_CASE("features/types/function") { +} diff --git a/untests/features/types/member_tests.cpp b/untests/features/types/member_tests.cpp new file mode 100644 index 0000000..1bc8d60 --- /dev/null +++ b/untests/features/types/member_tests.cpp @@ -0,0 +1,14 @@ +/******************************************************************************* + * 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 "_types_fwd.hpp" + +namespace +{ +} + +TEST_CASE("features/types/member") { +} diff --git a/untests/features/types/method_tests.cpp b/untests/features/types/method_tests.cpp new file mode 100644 index 0000000..18607d9 --- /dev/null +++ b/untests/features/types/method_tests.cpp @@ -0,0 +1,14 @@ +/******************************************************************************* + * 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 "_types_fwd.hpp" + +namespace +{ +} + +TEST_CASE("features/types/method") { +} diff --git a/untests/features/types/pointer_tests.cpp b/untests/features/types/pointer_tests.cpp new file mode 100644 index 0000000..133bc47 --- /dev/null +++ b/untests/features/types/pointer_tests.cpp @@ -0,0 +1,14 @@ +/******************************************************************************* + * 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 "_types_fwd.hpp" + +namespace +{ +} + +TEST_CASE("features/types/pointer") { +} diff --git a/untests/features/types/reference_tests.cpp b/untests/features/types/reference_tests.cpp new file mode 100644 index 0000000..21019ac --- /dev/null +++ b/untests/features/types/reference_tests.cpp @@ -0,0 +1,14 @@ +/******************************************************************************* + * 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 "_types_fwd.hpp" + +namespace +{ +} + +TEST_CASE("features/types/reference") { +} diff --git a/untests/features/types/void_tests.cpp b/untests/features/types/void_tests.cpp new file mode 100644 index 0000000..5e29b35 --- /dev/null +++ b/untests/features/types/void_tests.cpp @@ -0,0 +1,14 @@ +/******************************************************************************* + * 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 "_types_fwd.hpp" + +namespace +{ +} + +TEST_CASE("features/types/void") { +} diff --git a/untests/meta_tests.cpp b/untests/meta_tests.cpp index 5e45309..cbb5826 100644 --- a/untests/meta_tests.cpp +++ b/untests/meta_tests.cpp @@ -4,8 +4,7 @@ * Copyright (C) 2021, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ -#include -#include "doctest/doctest.hpp" +#include "meta_tests.hpp" namespace { diff --git a/untests/meta_tests.hpp b/untests/meta_tests.hpp new file mode 100644 index 0000000..e699cda --- /dev/null +++ b/untests/meta_tests.hpp @@ -0,0 +1,10 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include +#include "doctest/doctest.hpp" From 9ffdb5989494c03c7ef56d3d77eb4ba44da7797e Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Mon, 2 Aug 2021 21:19:52 +0700 Subject: [PATCH 064/233] dummy info and registry files --- headers/meta.hpp/meta_all.hpp | 11 ++++ headers/meta.hpp/meta_fwd.hpp | 54 +++++++++++++++++++ headers/meta.hpp/meta_infos.hpp | 19 +++++++ headers/meta.hpp/meta_infos/class_info.hpp | 13 +++++ headers/meta.hpp/meta_infos/ctor_info.hpp | 13 +++++ headers/meta.hpp/meta_infos/data_info.hpp | 13 +++++ headers/meta.hpp/meta_infos/enum_info.hpp | 13 +++++ headers/meta.hpp/meta_infos/evalue_info.hpp | 13 +++++ headers/meta.hpp/meta_infos/function_info.hpp | 13 +++++ headers/meta.hpp/meta_infos/member_info.hpp | 13 +++++ headers/meta.hpp/meta_infos/method_info.hpp | 13 +++++ .../meta.hpp/meta_infos/namespace_info.hpp | 13 +++++ headers/meta.hpp/meta_registry.hpp | 37 +++++++++++++ headers/meta.hpp/meta_registry/class_.hpp | 14 +++++ headers/meta.hpp/meta_registry/ctor_.hpp | 14 +++++ .../{meta.hpp => meta_registry/data_.hpp} | 6 +++ headers/meta.hpp/meta_registry/enum_.hpp | 14 +++++ headers/meta.hpp/meta_registry/evalue_.hpp | 14 +++++ headers/meta.hpp/meta_registry/function_.hpp | 14 +++++ headers/meta.hpp/meta_registry/member_.hpp | 14 +++++ headers/meta.hpp/meta_registry/method_.hpp | 14 +++++ headers/meta.hpp/meta_registry/namespace_.hpp | 13 +++++ untests/features/infos/data_tests.cpp | 14 +++++ untests/features/infos/evalue_tests.cpp | 14 +++++ untests/meta_tests.hpp | 2 +- 25 files changed, 384 insertions(+), 1 deletion(-) create mode 100644 headers/meta.hpp/meta_all.hpp create mode 100644 headers/meta.hpp/meta_fwd.hpp create mode 100644 headers/meta.hpp/meta_infos.hpp create mode 100644 headers/meta.hpp/meta_infos/class_info.hpp create mode 100644 headers/meta.hpp/meta_infos/ctor_info.hpp create mode 100644 headers/meta.hpp/meta_infos/data_info.hpp create mode 100644 headers/meta.hpp/meta_infos/enum_info.hpp create mode 100644 headers/meta.hpp/meta_infos/evalue_info.hpp create mode 100644 headers/meta.hpp/meta_infos/function_info.hpp create mode 100644 headers/meta.hpp/meta_infos/member_info.hpp create mode 100644 headers/meta.hpp/meta_infos/method_info.hpp create mode 100644 headers/meta.hpp/meta_infos/namespace_info.hpp create mode 100644 headers/meta.hpp/meta_registry.hpp create mode 100644 headers/meta.hpp/meta_registry/class_.hpp create mode 100644 headers/meta.hpp/meta_registry/ctor_.hpp rename headers/meta.hpp/{meta.hpp => meta_registry/data_.hpp} (87%) create mode 100644 headers/meta.hpp/meta_registry/enum_.hpp create mode 100644 headers/meta.hpp/meta_registry/evalue_.hpp create mode 100644 headers/meta.hpp/meta_registry/function_.hpp create mode 100644 headers/meta.hpp/meta_registry/member_.hpp create mode 100644 headers/meta.hpp/meta_registry/method_.hpp create mode 100644 headers/meta.hpp/meta_registry/namespace_.hpp create mode 100644 untests/features/infos/data_tests.cpp create mode 100644 untests/features/infos/evalue_tests.cpp diff --git a/headers/meta.hpp/meta_all.hpp b/headers/meta.hpp/meta_all.hpp new file mode 100644 index 0000000..fb0bc4e --- /dev/null +++ b/headers/meta.hpp/meta_all.hpp @@ -0,0 +1,11 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "meta_fwd.hpp" +#include "meta_infos.hpp" +#include "meta_registry.hpp" diff --git a/headers/meta.hpp/meta_fwd.hpp b/headers/meta.hpp/meta_fwd.hpp new file mode 100644 index 0000000..cc8e0c7 --- /dev/null +++ b/headers/meta.hpp/meta_fwd.hpp @@ -0,0 +1,54 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace meta_hpp +{ + class class_info; + class ctor_info; + class data_info; + class enum_info; + class evalue_info; + class function_info; + class member_info; + class method_info; + class namespace_info; +} + +namespace meta_hpp +{ + template < typename Class > class class_; + template < typename... Args > class ctor_; + class data_; + template < typename Enum > class enum_; + template < typename Enum > class evalue_; + template < typename Function > class function_; + template < typename Member > class member_; + template < typename Method > class method_; + class namespace_; +} diff --git a/headers/meta.hpp/meta_infos.hpp b/headers/meta.hpp/meta_infos.hpp new file mode 100644 index 0000000..9ac7f25 --- /dev/null +++ b/headers/meta.hpp/meta_infos.hpp @@ -0,0 +1,19 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "meta_fwd.hpp" + +#include "meta_infos/class_info.hpp" +#include "meta_infos/ctor_info.hpp" +#include "meta_infos/data_info.hpp" +#include "meta_infos/enum_info.hpp" +#include "meta_infos/evalue_info.hpp" +#include "meta_infos/function_info.hpp" +#include "meta_infos/member_info.hpp" +#include "meta_infos/method_info.hpp" +#include "meta_infos/namespace_info.hpp" diff --git a/headers/meta.hpp/meta_infos/class_info.hpp b/headers/meta.hpp/meta_infos/class_info.hpp new file mode 100644 index 0000000..20d7bc7 --- /dev/null +++ b/headers/meta.hpp/meta_infos/class_info.hpp @@ -0,0 +1,13 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +namespace meta_hpp +{ + class class_info final { + }; +} diff --git a/headers/meta.hpp/meta_infos/ctor_info.hpp b/headers/meta.hpp/meta_infos/ctor_info.hpp new file mode 100644 index 0000000..770d0a6 --- /dev/null +++ b/headers/meta.hpp/meta_infos/ctor_info.hpp @@ -0,0 +1,13 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +namespace meta_hpp +{ + class ctor_info final { + }; +} diff --git a/headers/meta.hpp/meta_infos/data_info.hpp b/headers/meta.hpp/meta_infos/data_info.hpp new file mode 100644 index 0000000..faf7811 --- /dev/null +++ b/headers/meta.hpp/meta_infos/data_info.hpp @@ -0,0 +1,13 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +namespace meta_hpp +{ + class data_info final { + }; +} diff --git a/headers/meta.hpp/meta_infos/enum_info.hpp b/headers/meta.hpp/meta_infos/enum_info.hpp new file mode 100644 index 0000000..b21b7f4 --- /dev/null +++ b/headers/meta.hpp/meta_infos/enum_info.hpp @@ -0,0 +1,13 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +namespace meta_hpp +{ + class enum_info final { + }; +} diff --git a/headers/meta.hpp/meta_infos/evalue_info.hpp b/headers/meta.hpp/meta_infos/evalue_info.hpp new file mode 100644 index 0000000..c19ca79 --- /dev/null +++ b/headers/meta.hpp/meta_infos/evalue_info.hpp @@ -0,0 +1,13 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +namespace meta_hpp +{ + class evalue_info final { + }; +} diff --git a/headers/meta.hpp/meta_infos/function_info.hpp b/headers/meta.hpp/meta_infos/function_info.hpp new file mode 100644 index 0000000..74f911c --- /dev/null +++ b/headers/meta.hpp/meta_infos/function_info.hpp @@ -0,0 +1,13 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +namespace meta_hpp +{ + class function_info final { + }; +} diff --git a/headers/meta.hpp/meta_infos/member_info.hpp b/headers/meta.hpp/meta_infos/member_info.hpp new file mode 100644 index 0000000..8fd680e --- /dev/null +++ b/headers/meta.hpp/meta_infos/member_info.hpp @@ -0,0 +1,13 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +namespace meta_hpp +{ + class member_info final { + }; +} diff --git a/headers/meta.hpp/meta_infos/method_info.hpp b/headers/meta.hpp/meta_infos/method_info.hpp new file mode 100644 index 0000000..591fabf --- /dev/null +++ b/headers/meta.hpp/meta_infos/method_info.hpp @@ -0,0 +1,13 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +namespace meta_hpp +{ + class method_info final { + }; +} diff --git a/headers/meta.hpp/meta_infos/namespace_info.hpp b/headers/meta.hpp/meta_infos/namespace_info.hpp new file mode 100644 index 0000000..5f17f32 --- /dev/null +++ b/headers/meta.hpp/meta_infos/namespace_info.hpp @@ -0,0 +1,13 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +namespace meta_hpp +{ + class namespace_info final { + }; +} diff --git a/headers/meta.hpp/meta_registry.hpp b/headers/meta.hpp/meta_registry.hpp new file mode 100644 index 0000000..bbbccd8 --- /dev/null +++ b/headers/meta.hpp/meta_registry.hpp @@ -0,0 +1,37 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "meta_fwd.hpp" +#include "meta_infos.hpp" + +#include "meta_registry/class_.hpp" +#include "meta_registry/ctor_.hpp" +#include "meta_registry/data_.hpp" +#include "meta_registry/enum_.hpp" +#include "meta_registry/evalue_.hpp" +#include "meta_registry/function_.hpp" +#include "meta_registry/member_.hpp" +#include "meta_registry/method_.hpp" +#include "meta_registry/namespace_.hpp" + +namespace meta_hpp +{ + class registry final { + public: + registry() = default; + + class_info get_class_by_name(std::string_view name) const noexcept; + data_info get_data_by_name(std::string_view name) const noexcept; + enum_info get_enum_by_name(std::string_view name) const noexcept; + evalue_info get_evalue_by_name(std::string_view name) const noexcept; + function_info get_function_by_name(std::string_view name) const noexcept; + member_info get_member_by_name(std::string_view name) const noexcept; + method_info get_method_by_name(std::string_view name) const noexcept; + namespace_info get_namespace_by_name(std::string_view name) const noexcept; + }; +} diff --git a/headers/meta.hpp/meta_registry/class_.hpp b/headers/meta.hpp/meta_registry/class_.hpp new file mode 100644 index 0000000..525931e --- /dev/null +++ b/headers/meta.hpp/meta_registry/class_.hpp @@ -0,0 +1,14 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +namespace meta_hpp +{ + template < typename Class > + class class_ final { + }; +} diff --git a/headers/meta.hpp/meta_registry/ctor_.hpp b/headers/meta.hpp/meta_registry/ctor_.hpp new file mode 100644 index 0000000..fd15a22 --- /dev/null +++ b/headers/meta.hpp/meta_registry/ctor_.hpp @@ -0,0 +1,14 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +namespace meta_hpp +{ + template < typename... Args > + class ctor_ final { + }; +} diff --git a/headers/meta.hpp/meta.hpp b/headers/meta.hpp/meta_registry/data_.hpp similarity index 87% rename from headers/meta.hpp/meta.hpp rename to headers/meta.hpp/meta_registry/data_.hpp index 1c5f3b4..0c6d281 100644 --- a/headers/meta.hpp/meta.hpp +++ b/headers/meta.hpp/meta_registry/data_.hpp @@ -5,3 +5,9 @@ ******************************************************************************/ #pragma once + +namespace meta_hpp +{ + class data_ final { + }; +} diff --git a/headers/meta.hpp/meta_registry/enum_.hpp b/headers/meta.hpp/meta_registry/enum_.hpp new file mode 100644 index 0000000..d046015 --- /dev/null +++ b/headers/meta.hpp/meta_registry/enum_.hpp @@ -0,0 +1,14 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +namespace meta_hpp +{ + template < typename Enum > + class enum_ final { + }; +} diff --git a/headers/meta.hpp/meta_registry/evalue_.hpp b/headers/meta.hpp/meta_registry/evalue_.hpp new file mode 100644 index 0000000..397fe7a --- /dev/null +++ b/headers/meta.hpp/meta_registry/evalue_.hpp @@ -0,0 +1,14 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +namespace meta_hpp +{ + template < typename Enum > + class evalue_ final { + }; +} diff --git a/headers/meta.hpp/meta_registry/function_.hpp b/headers/meta.hpp/meta_registry/function_.hpp new file mode 100644 index 0000000..12a04ab --- /dev/null +++ b/headers/meta.hpp/meta_registry/function_.hpp @@ -0,0 +1,14 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +namespace meta_hpp +{ + template < typename Function > + class function_ final { + }; +} diff --git a/headers/meta.hpp/meta_registry/member_.hpp b/headers/meta.hpp/meta_registry/member_.hpp new file mode 100644 index 0000000..a93eb31 --- /dev/null +++ b/headers/meta.hpp/meta_registry/member_.hpp @@ -0,0 +1,14 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +namespace meta_hpp +{ + template < typename Member > + class member_ final { + }; +} diff --git a/headers/meta.hpp/meta_registry/method_.hpp b/headers/meta.hpp/meta_registry/method_.hpp new file mode 100644 index 0000000..2cb0530 --- /dev/null +++ b/headers/meta.hpp/meta_registry/method_.hpp @@ -0,0 +1,14 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +namespace meta_hpp +{ + template < typename Method > + class method_ final { + }; +} diff --git a/headers/meta.hpp/meta_registry/namespace_.hpp b/headers/meta.hpp/meta_registry/namespace_.hpp new file mode 100644 index 0000000..cd21b26 --- /dev/null +++ b/headers/meta.hpp/meta_registry/namespace_.hpp @@ -0,0 +1,13 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +namespace meta_hpp +{ + class namespace_ final { + }; +} diff --git a/untests/features/infos/data_tests.cpp b/untests/features/infos/data_tests.cpp new file mode 100644 index 0000000..1bc3e47 --- /dev/null +++ b/untests/features/infos/data_tests.cpp @@ -0,0 +1,14 @@ +/******************************************************************************* + * 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 "_infos_fwd.hpp" + +namespace +{ +} + +TEST_CASE("features/infos/data") { +} diff --git a/untests/features/infos/evalue_tests.cpp b/untests/features/infos/evalue_tests.cpp new file mode 100644 index 0000000..75e3355 --- /dev/null +++ b/untests/features/infos/evalue_tests.cpp @@ -0,0 +1,14 @@ +/******************************************************************************* + * 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 "_infos_fwd.hpp" + +namespace +{ +} + +TEST_CASE("features/infos/evalue") { +} diff --git a/untests/meta_tests.hpp b/untests/meta_tests.hpp index e699cda..150e971 100644 --- a/untests/meta_tests.hpp +++ b/untests/meta_tests.hpp @@ -6,5 +6,5 @@ #pragma once -#include +#include #include "doctest/doctest.hpp" From 071cc952b23e513d1eb63e4dfe157091a10a8d40 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Mon, 2 Aug 2021 23:48:12 +0700 Subject: [PATCH 065/233] dummy info registration --- headers/meta.hpp/meta_all.hpp | 1 + headers/meta.hpp/meta_fwd.hpp | 16 +++ headers/meta.hpp/meta_infos/class_info.hpp | 3 + headers/meta.hpp/meta_infos/ctor_info.hpp | 3 + headers/meta.hpp/meta_infos/data_info.hpp | 3 + headers/meta.hpp/meta_infos/enum_info.hpp | 3 + headers/meta.hpp/meta_infos/evalue_info.hpp | 3 + headers/meta.hpp/meta_infos/function_info.hpp | 3 + headers/meta.hpp/meta_infos/member_info.hpp | 3 + headers/meta.hpp/meta_infos/method_info.hpp | 3 + .../meta.hpp/meta_infos/namespace_info.hpp | 3 + headers/meta.hpp/meta_registry.hpp | 129 ++++++++++++++++++ headers/meta.hpp/meta_registry/class_.hpp | 23 ++++ headers/meta.hpp/meta_registry/ctor_.hpp | 20 +++ headers/meta.hpp/meta_registry/data_.hpp | 23 ++++ headers/meta.hpp/meta_registry/enum_.hpp | 23 ++++ headers/meta.hpp/meta_registry/evalue_.hpp | 25 ++++ headers/meta.hpp/meta_registry/function_.hpp | 25 ++++ headers/meta.hpp/meta_registry/member_.hpp | 25 ++++ headers/meta.hpp/meta_registry/method_.hpp | 25 ++++ headers/meta.hpp/meta_registry/namespace_.hpp | 21 +++ headers/meta.hpp/meta_utilities.hpp | 11 ++ headers/meta.hpp/meta_utilities/value.hpp | 23 ++++ 23 files changed, 417 insertions(+) create mode 100644 headers/meta.hpp/meta_utilities.hpp create mode 100644 headers/meta.hpp/meta_utilities/value.hpp diff --git a/headers/meta.hpp/meta_all.hpp b/headers/meta.hpp/meta_all.hpp index fb0bc4e..1037a7a 100644 --- a/headers/meta.hpp/meta_all.hpp +++ b/headers/meta.hpp/meta_all.hpp @@ -9,3 +9,4 @@ #include "meta_fwd.hpp" #include "meta_infos.hpp" #include "meta_registry.hpp" +#include "meta_utilities.hpp" diff --git a/headers/meta.hpp/meta_fwd.hpp b/headers/meta.hpp/meta_fwd.hpp index cc8e0c7..19ff1ac 100644 --- a/headers/meta.hpp/meta_fwd.hpp +++ b/headers/meta.hpp/meta_fwd.hpp @@ -52,3 +52,19 @@ namespace meta_hpp template < typename Method > class method_; class namespace_; } + +namespace meta_hpp +{ + template < typename K, typename V > + using info_map = std::map>; + + using class_info_map = info_map; + using ctor_info_map = info_map; + using data_info_map = info_map; + using enum_info_map = info_map; + using evalue_info_map = info_map; + using function_info_map = info_map; + using member_info_map = info_map; + using method_info_map = info_map; + using namespace_info_map = info_map; +} diff --git a/headers/meta.hpp/meta_infos/class_info.hpp b/headers/meta.hpp/meta_infos/class_info.hpp index 20d7bc7..64971b6 100644 --- a/headers/meta.hpp/meta_infos/class_info.hpp +++ b/headers/meta.hpp/meta_infos/class_info.hpp @@ -6,6 +6,9 @@ #pragma once +#include "../meta_fwd.hpp" +#include "../meta_utilities.hpp" + namespace meta_hpp { class class_info final { diff --git a/headers/meta.hpp/meta_infos/ctor_info.hpp b/headers/meta.hpp/meta_infos/ctor_info.hpp index 770d0a6..3012a5c 100644 --- a/headers/meta.hpp/meta_infos/ctor_info.hpp +++ b/headers/meta.hpp/meta_infos/ctor_info.hpp @@ -6,6 +6,9 @@ #pragma once +#include "../meta_fwd.hpp" +#include "../meta_utilities.hpp" + namespace meta_hpp { class ctor_info final { diff --git a/headers/meta.hpp/meta_infos/data_info.hpp b/headers/meta.hpp/meta_infos/data_info.hpp index faf7811..1f5dd9e 100644 --- a/headers/meta.hpp/meta_infos/data_info.hpp +++ b/headers/meta.hpp/meta_infos/data_info.hpp @@ -6,6 +6,9 @@ #pragma once +#include "../meta_fwd.hpp" +#include "../meta_utilities.hpp" + namespace meta_hpp { class data_info final { diff --git a/headers/meta.hpp/meta_infos/enum_info.hpp b/headers/meta.hpp/meta_infos/enum_info.hpp index b21b7f4..6430153 100644 --- a/headers/meta.hpp/meta_infos/enum_info.hpp +++ b/headers/meta.hpp/meta_infos/enum_info.hpp @@ -6,6 +6,9 @@ #pragma once +#include "../meta_fwd.hpp" +#include "../meta_utilities.hpp" + namespace meta_hpp { class enum_info final { diff --git a/headers/meta.hpp/meta_infos/evalue_info.hpp b/headers/meta.hpp/meta_infos/evalue_info.hpp index c19ca79..13db9d5 100644 --- a/headers/meta.hpp/meta_infos/evalue_info.hpp +++ b/headers/meta.hpp/meta_infos/evalue_info.hpp @@ -6,6 +6,9 @@ #pragma once +#include "../meta_fwd.hpp" +#include "../meta_utilities.hpp" + namespace meta_hpp { class evalue_info final { diff --git a/headers/meta.hpp/meta_infos/function_info.hpp b/headers/meta.hpp/meta_infos/function_info.hpp index 74f911c..f84237c 100644 --- a/headers/meta.hpp/meta_infos/function_info.hpp +++ b/headers/meta.hpp/meta_infos/function_info.hpp @@ -6,6 +6,9 @@ #pragma once +#include "../meta_fwd.hpp" +#include "../meta_utilities.hpp" + namespace meta_hpp { class function_info final { diff --git a/headers/meta.hpp/meta_infos/member_info.hpp b/headers/meta.hpp/meta_infos/member_info.hpp index 8fd680e..d1bb8d3 100644 --- a/headers/meta.hpp/meta_infos/member_info.hpp +++ b/headers/meta.hpp/meta_infos/member_info.hpp @@ -6,6 +6,9 @@ #pragma once +#include "../meta_fwd.hpp" +#include "../meta_utilities.hpp" + namespace meta_hpp { class member_info final { diff --git a/headers/meta.hpp/meta_infos/method_info.hpp b/headers/meta.hpp/meta_infos/method_info.hpp index 591fabf..97483b0 100644 --- a/headers/meta.hpp/meta_infos/method_info.hpp +++ b/headers/meta.hpp/meta_infos/method_info.hpp @@ -6,6 +6,9 @@ #pragma once +#include "../meta_fwd.hpp" +#include "../meta_utilities.hpp" + namespace meta_hpp { class method_info final { diff --git a/headers/meta.hpp/meta_infos/namespace_info.hpp b/headers/meta.hpp/meta_infos/namespace_info.hpp index 5f17f32..855765f 100644 --- a/headers/meta.hpp/meta_infos/namespace_info.hpp +++ b/headers/meta.hpp/meta_infos/namespace_info.hpp @@ -6,6 +6,9 @@ #pragma once +#include "../meta_fwd.hpp" +#include "../meta_utilities.hpp" + namespace meta_hpp { class namespace_info final { diff --git a/headers/meta.hpp/meta_registry.hpp b/headers/meta.hpp/meta_registry.hpp index bbbccd8..dbc2616 100644 --- a/headers/meta.hpp/meta_registry.hpp +++ b/headers/meta.hpp/meta_registry.hpp @@ -33,5 +33,134 @@ namespace meta_hpp member_info get_member_by_name(std::string_view name) const noexcept; method_info get_method_by_name(std::string_view name) const noexcept; namespace_info get_namespace_by_name(std::string_view name) const noexcept; + public: + template < typename... Internals > + registry& operator()(Internals&&... internals); + private: + template < typename Class > + void add_(const std::string& prefix, const class_& internal); + void add_(const std::string& prefix, const data_& internal); + template < typename Enum > + void add_(const std::string& prefix, const enum_& internal); + template < typename Function > + void add_(const std::string& prefix, const function_& internal); + template < typename Member > + void add_(const std::string& prefix, const member_& internal); + template < typename Method > + void add_(const std::string& prefix, const method_& internal); + void add_(const std::string& prefix, const namespace_& internal); + void add_(const std::string& prefix, ...) = delete; + private: + void add_info_(const std::string& prefix, const class_info& info); + void add_info_(const std::string& prefix, const ctor_info& info); + void add_info_(const std::string& prefix, const data_info& info); + void add_info_(const std::string& prefix, const enum_info& info); + void add_info_(const std::string& prefix, const evalue_info& info); + void add_info_(const std::string& prefix, const function_info& info); + void add_info_(const std::string& prefix, const member_info& info); + void add_info_(const std::string& prefix, const method_info& info); + void add_info_(const std::string& prefix, const namespace_info& info); + private: + class_info_map classes_; + data_info_map datas_; + enum_info_map enums_; + evalue_info_map evalues_; + function_info_map functions_; + member_info_map members_; + method_info_map methods_; + namespace_info_map namespaces_; }; } + +namespace meta_hpp +{ + template < typename... Internals > + inline registry& registry::operator()(Internals&&... internals) { + (add_(std::string{}, std::forward(internals)), ...); + return *this; + } +} + +namespace meta_hpp +{ + template < typename Class > + inline void registry::add_(const std::string& prefix, const class_& internal) { + add_info_(prefix, internal.make_info()); + } + + inline void registry::add_(const std::string& prefix, const data_& internal) { + add_info_(prefix, internal.make_info()); + } + + template < typename Enum > + inline void registry::add_(const std::string& prefix, const enum_& internal) { + add_info_(prefix, internal.make_info()); + } + + template < typename Function > + inline void registry::add_(const std::string& prefix, const function_& internal) { + add_info_(prefix, internal.make_info()); + } + + template < typename Member > + inline void registry::add_(const std::string& prefix, const member_& internal) { + add_info_(prefix, internal.make_info()); + } + + template < typename Method > + inline void registry::add_(const std::string& prefix, const method_& internal) { + add_info_(prefix, internal.make_info()); + } + + inline void registry::add_(const std::string& prefix, const namespace_& internal) { + add_info_(prefix, internal.make_info()); + } +} + +namespace meta_hpp +{ + inline void registry::add_info_(const std::string& prefix, const class_info& info) { + (void)prefix; + (void)info; + } + + inline void registry::add_info_(const std::string& prefix, const ctor_info& info) { + (void)prefix; + (void)info; + } + + inline void registry::add_info_(const std::string& prefix, const data_info& info) { + (void)prefix; + (void)info; + } + + inline void registry::add_info_(const std::string& prefix, const enum_info& info) { + (void)prefix; + (void)info; + } + + inline void registry::add_info_(const std::string& prefix, const evalue_info& info) { + (void)prefix; + (void)info; + } + + inline void registry::add_info_(const std::string& prefix, const function_info& info) { + (void)prefix; + (void)info; + } + + inline void registry::add_info_(const std::string& prefix, const member_info& info) { + (void)prefix; + (void)info; + } + + inline void registry::add_info_(const std::string& prefix, const method_info& info) { + (void)prefix; + (void)info; + } + + inline void registry::add_info_(const std::string& prefix, const namespace_info& info) { + (void)prefix; + (void)info; + } +} diff --git a/headers/meta.hpp/meta_registry/class_.hpp b/headers/meta.hpp/meta_registry/class_.hpp index 525931e..c6de986 100644 --- a/headers/meta.hpp/meta_registry/class_.hpp +++ b/headers/meta.hpp/meta_registry/class_.hpp @@ -6,9 +6,32 @@ #pragma once +#include "../meta_fwd.hpp" +#include "../meta_utilities.hpp" + +#include "../meta_infos/class_info.hpp" + namespace meta_hpp { template < typename Class > class class_ final { + public: + explicit class_(std::string name); + + class_info make_info() const; + private: + std::string name_; }; } + +namespace meta_hpp +{ + template < typename Class > + inline class_::class_(std::string name) + : name_{std::move(name)} {} + + template < typename Class > + inline class_info class_::make_info() const { + return class_info{}; + } +} diff --git a/headers/meta.hpp/meta_registry/ctor_.hpp b/headers/meta.hpp/meta_registry/ctor_.hpp index fd15a22..03d628d 100644 --- a/headers/meta.hpp/meta_registry/ctor_.hpp +++ b/headers/meta.hpp/meta_registry/ctor_.hpp @@ -6,9 +6,29 @@ #pragma once +#include "../meta_fwd.hpp" +#include "../meta_utilities.hpp" + +#include "../meta_infos/ctor_info.hpp" + namespace meta_hpp { template < typename... Args > class ctor_ final { + public: + explicit ctor_() = default; + + template < typename Class > + ctor_info make_info() const; + private: }; } + +namespace meta_hpp +{ + template < typename... Args > + template < typename Class > + inline ctor_info ctor_::make_info() const { + return ctor_info{}; + } +} diff --git a/headers/meta.hpp/meta_registry/data_.hpp b/headers/meta.hpp/meta_registry/data_.hpp index 0c6d281..ccbf5a0 100644 --- a/headers/meta.hpp/meta_registry/data_.hpp +++ b/headers/meta.hpp/meta_registry/data_.hpp @@ -6,8 +6,31 @@ #pragma once +#include "../meta_fwd.hpp" +#include "../meta_utilities.hpp" + +#include "../meta_infos/data_info.hpp" + namespace meta_hpp { class data_ final { + public: + explicit data_(std::string name, class value value); + + data_info make_info() const; + private: + std::string name_; + class value value_; }; } + +namespace meta_hpp +{ + inline data_::data_(std::string name, class value value) + : name_{std::move(name)} + , value_{std::move(value)} {} + + inline data_info data_::make_info() const { + return data_info{}; + } +} diff --git a/headers/meta.hpp/meta_registry/enum_.hpp b/headers/meta.hpp/meta_registry/enum_.hpp index d046015..3910210 100644 --- a/headers/meta.hpp/meta_registry/enum_.hpp +++ b/headers/meta.hpp/meta_registry/enum_.hpp @@ -6,9 +6,32 @@ #pragma once +#include "../meta_fwd.hpp" +#include "../meta_utilities.hpp" + +#include "../meta_infos/enum_info.hpp" + namespace meta_hpp { template < typename Enum > class enum_ final { + public: + explicit enum_(std::string name); + + enum_info make_info() const; + private: + std::string name_; }; } + +namespace meta_hpp +{ + template < typename Enum > + inline enum_::enum_(std::string name) + : name_{std::move(name)} {} + + template < typename Enum > + inline enum_info enum_::make_info() const { + return enum_info{}; + } +} diff --git a/headers/meta.hpp/meta_registry/evalue_.hpp b/headers/meta.hpp/meta_registry/evalue_.hpp index 397fe7a..a338fee 100644 --- a/headers/meta.hpp/meta_registry/evalue_.hpp +++ b/headers/meta.hpp/meta_registry/evalue_.hpp @@ -6,9 +6,34 @@ #pragma once +#include "../meta_fwd.hpp" +#include "../meta_utilities.hpp" + +#include "../meta_infos/evalue_info.hpp" + namespace meta_hpp { template < typename Enum > class evalue_ final { + public: + explicit evalue_(std::string name, Enum value); + + evalue_info make_info() const; + private: + std::string name_; + Enum value_; }; } + +namespace meta_hpp +{ + template < typename Enum > + inline evalue_::evalue_(std::string name, Enum value) + : name_{std::move(name)} + , value_{std::move(value)} {} + + template < typename Enum > + inline evalue_info evalue_::make_info() const { + return evalue_info{}; + } +} diff --git a/headers/meta.hpp/meta_registry/function_.hpp b/headers/meta.hpp/meta_registry/function_.hpp index 12a04ab..72273d2 100644 --- a/headers/meta.hpp/meta_registry/function_.hpp +++ b/headers/meta.hpp/meta_registry/function_.hpp @@ -6,9 +6,34 @@ #pragma once +#include "../meta_fwd.hpp" +#include "../meta_utilities.hpp" + +#include "../meta_infos/function_info.hpp" + namespace meta_hpp { template < typename Function > class function_ final { + public: + explicit function_(std::string name, Function instance); + + function_info make_info() const; + private: + std::string name_; + Function instance_; }; } + +namespace meta_hpp +{ + template < typename Function > + inline function_::function_(std::string name, Function instance) + : name_{std::move(name)} + , instance_{std::move(instance)} {} + + template < typename Function > + inline function_info function_::make_info() const { + return function_info{}; + } +} diff --git a/headers/meta.hpp/meta_registry/member_.hpp b/headers/meta.hpp/meta_registry/member_.hpp index a93eb31..0630d49 100644 --- a/headers/meta.hpp/meta_registry/member_.hpp +++ b/headers/meta.hpp/meta_registry/member_.hpp @@ -6,9 +6,34 @@ #pragma once +#include "../meta_fwd.hpp" +#include "../meta_utilities.hpp" + +#include "../meta_infos/member_info.hpp" + namespace meta_hpp { template < typename Member > class member_ final { + public: + explicit member_(std::string name, Member instance); + + member_info make_info() const; + private: + std::string name_; + Member instance_; }; } + +namespace meta_hpp +{ + template < typename Member > + inline member_::member_(std::string name, Member instance) + : name_{std::move(name)} + , instance_{std::move(instance)} {} + + template < typename Member > + inline member_info member_::make_info() const { + return member_info{}; + } +} diff --git a/headers/meta.hpp/meta_registry/method_.hpp b/headers/meta.hpp/meta_registry/method_.hpp index 2cb0530..7aa9aa1 100644 --- a/headers/meta.hpp/meta_registry/method_.hpp +++ b/headers/meta.hpp/meta_registry/method_.hpp @@ -6,9 +6,34 @@ #pragma once +#include "../meta_fwd.hpp" +#include "../meta_utilities.hpp" + +#include "../meta_infos/method_info.hpp" + namespace meta_hpp { template < typename Method > class method_ final { + public: + explicit method_(std::string name, Method instance); + + method_info make_info() const; + private: + std::string name_; + Method instance_; }; } + +namespace meta_hpp +{ + template < typename Method > + inline method_::method_(std::string name, Method instance) + : name_{std::move(name)} + , instance_{std::move(instance)} {} + + template < typename Method > + inline method_info method_::make_info() const { + return method_info{}; + } +} diff --git a/headers/meta.hpp/meta_registry/namespace_.hpp b/headers/meta.hpp/meta_registry/namespace_.hpp index cd21b26..bc4f16e 100644 --- a/headers/meta.hpp/meta_registry/namespace_.hpp +++ b/headers/meta.hpp/meta_registry/namespace_.hpp @@ -6,8 +6,29 @@ #pragma once +#include "../meta_fwd.hpp" +#include "../meta_utilities.hpp" + +#include "../meta_infos/namespace_info.hpp" + namespace meta_hpp { class namespace_ final { + public: + explicit namespace_(std::string name); + + namespace_info make_info() const; + private: + std::string name_; }; } + +namespace meta_hpp +{ + inline namespace_::namespace_(std::string name) + : name_{std::move(name)} {} + + inline namespace_info namespace_::make_info() const { + return namespace_info{}; + } +} diff --git a/headers/meta.hpp/meta_utilities.hpp b/headers/meta.hpp/meta_utilities.hpp new file mode 100644 index 0000000..8658506 --- /dev/null +++ b/headers/meta.hpp/meta_utilities.hpp @@ -0,0 +1,11 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "meta_fwd.hpp" + +#include "meta_utilities/value.hpp" diff --git a/headers/meta.hpp/meta_utilities/value.hpp b/headers/meta.hpp/meta_utilities/value.hpp new file mode 100644 index 0000000..461fa3f --- /dev/null +++ b/headers/meta.hpp/meta_utilities/value.hpp @@ -0,0 +1,23 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_fwd.hpp" + +namespace meta_hpp +{ + class value final { + public: + value() = delete; + + value(value&&) = default; + value& operator=(value&&) = default; + + value(const value&) = default; + value& operator=(const value&) = default; + }; +} From 929a173c09eed06b8cbd866f9ad8b28acfe9474f Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Tue, 3 Aug 2021 01:52:12 +0700 Subject: [PATCH 066/233] simple info registration in registry --- headers/meta.hpp/meta_fwd.hpp | 34 +++++++++ headers/meta.hpp/meta_infos/class_info.hpp | 43 +++++++++++ headers/meta.hpp/meta_infos/ctor_info.hpp | 36 +++++++++ headers/meta.hpp/meta_infos/data_info.hpp | 51 +++++++++++++ headers/meta.hpp/meta_infos/enum_info.hpp | 43 +++++++++++ headers/meta.hpp/meta_infos/evalue_info.hpp | 53 ++++++++++++++ headers/meta.hpp/meta_infos/function_info.hpp | 47 ++++++++++++ headers/meta.hpp/meta_infos/member_info.hpp | 47 ++++++++++++ headers/meta.hpp/meta_infos/method_info.hpp | 47 ++++++++++++ .../meta.hpp/meta_infos/namespace_info.hpp | 43 +++++++++++ headers/meta.hpp/meta_registry.hpp | 73 +++++++++++++------ headers/meta.hpp/meta_registry/class_.hpp | 2 +- headers/meta.hpp/meta_registry/ctor_.hpp | 2 +- headers/meta.hpp/meta_registry/data_.hpp | 2 +- headers/meta.hpp/meta_registry/enum_.hpp | 2 +- headers/meta.hpp/meta_registry/evalue_.hpp | 2 +- headers/meta.hpp/meta_registry/function_.hpp | 2 +- headers/meta.hpp/meta_registry/member_.hpp | 2 +- headers/meta.hpp/meta_registry/method_.hpp | 2 +- headers/meta.hpp/meta_registry/namespace_.hpp | 2 +- untests/features/infos/function_tests.cpp | 39 ++++++++++ 21 files changed, 543 insertions(+), 31 deletions(-) diff --git a/headers/meta.hpp/meta_fwd.hpp b/headers/meta.hpp/meta_fwd.hpp index 19ff1ac..aab63a5 100644 --- a/headers/meta.hpp/meta_fwd.hpp +++ b/headers/meta.hpp/meta_fwd.hpp @@ -68,3 +68,37 @@ namespace meta_hpp using method_info_map = info_map; using namespace_info_map = info_map; } + +namespace meta_hpp +{ + template < typename... Args > + struct typename_arg_t {}; + + template < typename... Args > + inline typename_arg_t typename_arg; +} + +namespace meta_hpp::detail +{ + template < typename K, typename V, typename C, typename A, typename K2, typename U > + V find_or(const std::map& src, K2&& key, U&& def) { + if ( auto iter = src.find(std::forward(key)); iter != src.end() ) { + return iter->second; + } + return std::forward(def); + } + + template < typename K, typename V, typename C, typename A, typename K2 > + V find_or_default(const std::map& src, K2&& key) { + return find_or(src, std::forward(key), V{}); + } + + template < typename K, typename V, typename C, typename A, typename K2, typename V2, typename F > + void merge_with(std::map& dst, K2&& key, V2&& value, F&& f) { + if ( auto iter = dst.find(key); iter != dst.end() ) { + std::invoke(std::forward(f), iter->second, std::forward(value)); + } else { + dst.emplace(std::forward(key), std::forward(value)); + } + } +} diff --git a/headers/meta.hpp/meta_infos/class_info.hpp b/headers/meta.hpp/meta_infos/class_info.hpp index 64971b6..f95bff5 100644 --- a/headers/meta.hpp/meta_infos/class_info.hpp +++ b/headers/meta.hpp/meta_infos/class_info.hpp @@ -12,5 +12,48 @@ namespace meta_hpp { class class_info final { + public: + class_info() = default; + + void merge(const class_info& other); + explicit operator bool() const noexcept; + + const std::string& name() const noexcept; + private: + template < typename Class > friend class class_; + + explicit class_info(std::string name); + private: + struct state; + std::shared_ptr state_; }; } + +namespace meta_hpp +{ + struct class_info::state final { + std::string name; + }; +} + +namespace meta_hpp +{ + inline void class_info::merge(const class_info& other) { + (void)other; + ///TODO: implme + } + + inline class_info::operator bool() const noexcept { + return !!state_; + } + + inline const std::string& class_info::name() const noexcept { + assert(state_); + return state_->name; + } + + inline class_info::class_info(std::string name) + : state_{std::make_shared(state{ + std::move(name) + })} {} +} diff --git a/headers/meta.hpp/meta_infos/ctor_info.hpp b/headers/meta.hpp/meta_infos/ctor_info.hpp index 3012a5c..8be221c 100644 --- a/headers/meta.hpp/meta_infos/ctor_info.hpp +++ b/headers/meta.hpp/meta_infos/ctor_info.hpp @@ -12,5 +12,41 @@ namespace meta_hpp { class ctor_info final { + public: + ctor_info() = default; + + void merge(const ctor_info& other); + explicit operator bool() const noexcept; + private: + template < typename... Args > friend class ctor_; + + template < typename Class, typename... Args > + explicit ctor_info(typename_arg_t, typename_arg_t); + private: + struct state; + std::shared_ptr state_; }; } + +namespace meta_hpp +{ + struct ctor_info::state final { + }; +} + +namespace meta_hpp +{ + inline void ctor_info::merge(const ctor_info& other) { + (void)other; + ///TODO: implme + } + + inline ctor_info::operator bool() const noexcept { + return !!state_; + } + + template < typename Class, typename... Args > + inline ctor_info::ctor_info(typename_arg_t, typename_arg_t) + : state_{std::make_shared(state{ + })} {} +} diff --git a/headers/meta.hpp/meta_infos/data_info.hpp b/headers/meta.hpp/meta_infos/data_info.hpp index 1f5dd9e..89419b4 100644 --- a/headers/meta.hpp/meta_infos/data_info.hpp +++ b/headers/meta.hpp/meta_infos/data_info.hpp @@ -12,5 +12,56 @@ namespace meta_hpp { class data_info final { + public: + data_info() = default; + + void merge(const data_info& other); + explicit operator bool() const noexcept; + + const std::string& name() const noexcept; + const class value& value() const noexcept; + private: + friend class data_; + + explicit data_info(std::string name, class value value); + private: + struct state; + std::shared_ptr state_; }; } + +namespace meta_hpp +{ + struct data_info::state final { + std::string name; + class value value; + }; +} + +namespace meta_hpp +{ + inline void data_info::merge(const data_info& other) { + (void)other; + ///TODO: implme + } + + inline data_info::operator bool() const noexcept { + return !!state_; + } + + inline const std::string& data_info::name() const noexcept { + assert(state_); + return state_->name; + } + + inline const class value& data_info::value() const noexcept { + assert(state_); + return state_->value; + } + + inline data_info::data_info(std::string name, class value value) + : state_{std::make_shared(state{ + std::move(name), + std::move(value) + })} {} +} diff --git a/headers/meta.hpp/meta_infos/enum_info.hpp b/headers/meta.hpp/meta_infos/enum_info.hpp index 6430153..ae9f8c5 100644 --- a/headers/meta.hpp/meta_infos/enum_info.hpp +++ b/headers/meta.hpp/meta_infos/enum_info.hpp @@ -12,5 +12,48 @@ namespace meta_hpp { class enum_info final { + public: + enum_info() = default; + + void merge(const enum_info& other); + explicit operator bool() const noexcept; + + const std::string& name() const noexcept; + private: + template < typename Enum > friend class enum_; + + explicit enum_info(std::string name); + private: + struct state; + std::shared_ptr state_; }; } + +namespace meta_hpp +{ + struct enum_info::state final { + std::string name; + }; +} + +namespace meta_hpp +{ + inline void enum_info::merge(const enum_info& other) { + (void)other; + ///TODO: implme + } + + inline enum_info::operator bool() const noexcept { + return !!state_; + } + + inline const std::string& enum_info::name() const noexcept { + assert(state_); + return state_->name; + } + + inline enum_info::enum_info(std::string name) + : state_{std::make_shared(state{ + std::move(name) + })} {} +} diff --git a/headers/meta.hpp/meta_infos/evalue_info.hpp b/headers/meta.hpp/meta_infos/evalue_info.hpp index 13db9d5..2a86fbd 100644 --- a/headers/meta.hpp/meta_infos/evalue_info.hpp +++ b/headers/meta.hpp/meta_infos/evalue_info.hpp @@ -12,5 +12,58 @@ namespace meta_hpp { class evalue_info final { + public: + evalue_info() = default; + + void merge(const evalue_info& other); + explicit operator bool() const noexcept; + + const std::string& name() const noexcept; + const class value& value() const noexcept; + private: + template < typename Enum > friend class evalue_; + + template < typename Enum > + explicit evalue_info(std::string name, Enum value); + private: + struct state; + std::shared_ptr state_; }; } + +namespace meta_hpp +{ + struct evalue_info::state final { + std::string name; + class value value; + }; +} + +namespace meta_hpp +{ + inline void evalue_info::merge(const evalue_info& other) { + (void)other; + ///TODO: implme + } + + inline evalue_info::operator bool() const noexcept { + return !!state_; + } + + inline const std::string& evalue_info::name() const noexcept { + assert(state_); + return state_->name; + } + + inline const class value& evalue_info::value() const noexcept { + assert(state_); + return state_->value; + } + + template < typename Enum > + inline evalue_info::evalue_info(std::string name, Enum value) + : state_{std::make_shared(state{ + std::move(name), + std::move(value) + })} {} +} diff --git a/headers/meta.hpp/meta_infos/function_info.hpp b/headers/meta.hpp/meta_infos/function_info.hpp index f84237c..ffe4dc2 100644 --- a/headers/meta.hpp/meta_infos/function_info.hpp +++ b/headers/meta.hpp/meta_infos/function_info.hpp @@ -12,5 +12,52 @@ namespace meta_hpp { class function_info final { + public: + function_info() = default; + + void merge(const function_info& other); + explicit operator bool() const noexcept; + + const std::string& name() const noexcept; + private: + template < typename Function > friend class function_; + + template < typename Function > + explicit function_info(std::string name, Function instance); + private: + struct state; + std::shared_ptr state_; }; } + +namespace meta_hpp +{ + struct function_info::state final { + std::string name; + }; +} + +namespace meta_hpp +{ + inline void function_info::merge(const function_info& other) { + (void)other; + ///TODO: implme + } + + inline function_info::operator bool() const noexcept { + return !!state_; + } + + inline const std::string& function_info::name() const noexcept { + assert(state_); + return state_->name; + } + + template < typename Function > + inline function_info::function_info(std::string name, Function instance) + : state_{std::make_shared(state{ + std::move(name) + })} { + (void)instance; + } +} diff --git a/headers/meta.hpp/meta_infos/member_info.hpp b/headers/meta.hpp/meta_infos/member_info.hpp index d1bb8d3..68fb921 100644 --- a/headers/meta.hpp/meta_infos/member_info.hpp +++ b/headers/meta.hpp/meta_infos/member_info.hpp @@ -12,5 +12,52 @@ namespace meta_hpp { class member_info final { + public: + member_info() = default; + + void merge(const member_info& other); + explicit operator bool() const noexcept; + + const std::string& name() const noexcept; + private: + template < typename Member > friend class member_; + + template < typename Member > + explicit member_info(std::string name, Member instance); + private: + struct state; + std::shared_ptr state_; }; } + +namespace meta_hpp +{ + struct member_info::state final { + std::string name; + }; +} + +namespace meta_hpp +{ + inline void member_info::merge(const member_info& other) { + (void)other; + ///TODO: implme + } + + inline member_info::operator bool() const noexcept { + return !!state_; + } + + inline const std::string& member_info::name() const noexcept { + assert(state_); + return state_->name; + } + + template < typename Member > + inline member_info::member_info(std::string name, Member instance) + : state_{std::make_shared(state{ + std::move(name) + })} { + (void)instance; + } +} diff --git a/headers/meta.hpp/meta_infos/method_info.hpp b/headers/meta.hpp/meta_infos/method_info.hpp index 97483b0..c1ba03b 100644 --- a/headers/meta.hpp/meta_infos/method_info.hpp +++ b/headers/meta.hpp/meta_infos/method_info.hpp @@ -12,5 +12,52 @@ namespace meta_hpp { class method_info final { + public: + method_info() = default; + + void merge(const method_info& other); + explicit operator bool() const noexcept; + + const std::string& name() const noexcept; + private: + template < typename Method > friend class method_; + + template < typename Method > + explicit method_info(std::string name, Method instance); + private: + struct state; + std::shared_ptr state_; }; } + +namespace meta_hpp +{ + struct method_info::state final { + std::string name; + }; +} + +namespace meta_hpp +{ + inline void method_info::merge(const method_info& other) { + (void)other; + ///TODO: implme + } + + inline method_info::operator bool() const noexcept { + return !!state_; + } + + inline const std::string& method_info::name() const noexcept { + assert(state_); + return state_->name; + } + + template < typename Method > + inline method_info::method_info(std::string name, Method instance) + : state_{std::make_shared(state{ + std::move(name) + })} { + (void)instance; + } +} diff --git a/headers/meta.hpp/meta_infos/namespace_info.hpp b/headers/meta.hpp/meta_infos/namespace_info.hpp index 855765f..a6e6a4f 100644 --- a/headers/meta.hpp/meta_infos/namespace_info.hpp +++ b/headers/meta.hpp/meta_infos/namespace_info.hpp @@ -12,5 +12,48 @@ namespace meta_hpp { class namespace_info final { + public: + namespace_info() = default; + + void merge(const namespace_info& other); + explicit operator bool() const noexcept; + + const std::string& name() const noexcept; + private: + friend class namespace_; + + explicit namespace_info(std::string name); + private: + struct state; + std::shared_ptr state_; }; } + +namespace meta_hpp +{ + struct namespace_info::state final { + std::string name; + }; +} + +namespace meta_hpp +{ + inline void namespace_info::merge(const namespace_info& other) { + (void)other; + ///TODO: implme + } + + inline namespace_info::operator bool() const noexcept { + return !!state_; + } + + inline const std::string& namespace_info::name() const noexcept { + assert(state_); + return state_->name; + } + + inline namespace_info::namespace_info(std::string name) + : state_{std::make_shared(state{ + std::move(name) + })} {} +} diff --git a/headers/meta.hpp/meta_registry.hpp b/headers/meta.hpp/meta_registry.hpp index dbc2616..62dc2cc 100644 --- a/headers/meta.hpp/meta_registry.hpp +++ b/headers/meta.hpp/meta_registry.hpp @@ -52,7 +52,6 @@ namespace meta_hpp void add_(const std::string& prefix, ...) = delete; private: void add_info_(const std::string& prefix, const class_info& info); - void add_info_(const std::string& prefix, const ctor_info& info); void add_info_(const std::string& prefix, const data_info& info); void add_info_(const std::string& prefix, const enum_info& info); void add_info_(const std::string& prefix, const evalue_info& info); @@ -72,6 +71,41 @@ namespace meta_hpp }; } +namespace meta_hpp +{ + inline class_info registry::get_class_by_name(std::string_view name) const noexcept { + return detail::find_or_default(classes_, name); + } + + inline data_info registry::get_data_by_name(std::string_view name) const noexcept { + return detail::find_or_default(datas_, name); + } + + inline enum_info registry::get_enum_by_name(std::string_view name) const noexcept { + return detail::find_or_default(enums_, name); + } + + inline evalue_info registry::get_evalue_by_name(std::string_view name) const noexcept { + return detail::find_or_default(evalues_, name); + } + + inline function_info registry::get_function_by_name(std::string_view name) const noexcept { + return detail::find_or_default(functions_, name); + } + + inline member_info registry::get_member_by_name(std::string_view name) const noexcept { + return detail::find_or_default(members_, name); + } + + inline method_info registry::get_method_by_name(std::string_view name) const noexcept { + return detail::find_or_default(methods_, name); + } + + inline namespace_info registry::get_namespace_by_name(std::string_view name) const noexcept { + return detail::find_or_default(namespaces_, name); + } +} + namespace meta_hpp { template < typename... Internals > @@ -120,47 +154,42 @@ namespace meta_hpp namespace meta_hpp { inline void registry::add_info_(const std::string& prefix, const class_info& info) { - (void)prefix; - (void)info; - } - - inline void registry::add_info_(const std::string& prefix, const ctor_info& info) { - (void)prefix; - (void)info; + std::string name = prefix.empty() ? info.name() : prefix + "::" + info.name(); + detail::merge_with(classes_, name, info, &class_info::merge); } inline void registry::add_info_(const std::string& prefix, const data_info& info) { - (void)prefix; - (void)info; + std::string name = prefix.empty() ? info.name() : prefix + "::" + info.name(); + detail::merge_with(datas_, name, info, &data_info::merge); } inline void registry::add_info_(const std::string& prefix, const enum_info& info) { - (void)prefix; - (void)info; + std::string name = prefix.empty() ? info.name() : prefix + "::" + info.name(); + detail::merge_with(enums_, name, info, &enum_info::merge); } inline void registry::add_info_(const std::string& prefix, const evalue_info& info) { - (void)prefix; - (void)info; + std::string name = prefix.empty() ? info.name() : prefix + "::" + info.name(); + detail::merge_with(evalues_, name, info, &evalue_info::merge); } inline void registry::add_info_(const std::string& prefix, const function_info& info) { - (void)prefix; - (void)info; + std::string name = prefix.empty() ? info.name() : prefix + "::" + info.name(); + detail::merge_with(functions_, name, info, &function_info::merge); } inline void registry::add_info_(const std::string& prefix, const member_info& info) { - (void)prefix; - (void)info; + std::string name = prefix.empty() ? info.name() : prefix + "::" + info.name(); + detail::merge_with(members_, name, info, &member_info::merge); } inline void registry::add_info_(const std::string& prefix, const method_info& info) { - (void)prefix; - (void)info; + std::string name = prefix.empty() ? info.name() : prefix + "::" + info.name(); + detail::merge_with(methods_, name, info, &method_info::merge); } inline void registry::add_info_(const std::string& prefix, const namespace_info& info) { - (void)prefix; - (void)info; + std::string name = prefix.empty() ? info.name() : prefix + "::" + info.name(); + detail::merge_with(namespaces_, name, info, &namespace_info::merge); } } diff --git a/headers/meta.hpp/meta_registry/class_.hpp b/headers/meta.hpp/meta_registry/class_.hpp index c6de986..d012492 100644 --- a/headers/meta.hpp/meta_registry/class_.hpp +++ b/headers/meta.hpp/meta_registry/class_.hpp @@ -32,6 +32,6 @@ namespace meta_hpp template < typename Class > inline class_info class_::make_info() const { - return class_info{}; + return class_info{name_}; } } diff --git a/headers/meta.hpp/meta_registry/ctor_.hpp b/headers/meta.hpp/meta_registry/ctor_.hpp index 03d628d..61cd8f2 100644 --- a/headers/meta.hpp/meta_registry/ctor_.hpp +++ b/headers/meta.hpp/meta_registry/ctor_.hpp @@ -29,6 +29,6 @@ namespace meta_hpp template < typename... Args > template < typename Class > inline ctor_info ctor_::make_info() const { - return ctor_info{}; + return ctor_info{typename_arg, typename_arg}; } } diff --git a/headers/meta.hpp/meta_registry/data_.hpp b/headers/meta.hpp/meta_registry/data_.hpp index ccbf5a0..f1d8a1e 100644 --- a/headers/meta.hpp/meta_registry/data_.hpp +++ b/headers/meta.hpp/meta_registry/data_.hpp @@ -31,6 +31,6 @@ namespace meta_hpp , value_{std::move(value)} {} inline data_info data_::make_info() const { - return data_info{}; + return data_info{name_, value_}; } } diff --git a/headers/meta.hpp/meta_registry/enum_.hpp b/headers/meta.hpp/meta_registry/enum_.hpp index 3910210..263cbaf 100644 --- a/headers/meta.hpp/meta_registry/enum_.hpp +++ b/headers/meta.hpp/meta_registry/enum_.hpp @@ -32,6 +32,6 @@ namespace meta_hpp template < typename Enum > inline enum_info enum_::make_info() const { - return enum_info{}; + return enum_info{name_}; } } diff --git a/headers/meta.hpp/meta_registry/evalue_.hpp b/headers/meta.hpp/meta_registry/evalue_.hpp index a338fee..c94afad 100644 --- a/headers/meta.hpp/meta_registry/evalue_.hpp +++ b/headers/meta.hpp/meta_registry/evalue_.hpp @@ -34,6 +34,6 @@ namespace meta_hpp template < typename Enum > inline evalue_info evalue_::make_info() const { - return evalue_info{}; + return evalue_info{name_, value_}; } } diff --git a/headers/meta.hpp/meta_registry/function_.hpp b/headers/meta.hpp/meta_registry/function_.hpp index 72273d2..af64730 100644 --- a/headers/meta.hpp/meta_registry/function_.hpp +++ b/headers/meta.hpp/meta_registry/function_.hpp @@ -34,6 +34,6 @@ namespace meta_hpp template < typename Function > inline function_info function_::make_info() const { - return function_info{}; + return function_info{name_, instance_}; } } diff --git a/headers/meta.hpp/meta_registry/member_.hpp b/headers/meta.hpp/meta_registry/member_.hpp index 0630d49..348bdd2 100644 --- a/headers/meta.hpp/meta_registry/member_.hpp +++ b/headers/meta.hpp/meta_registry/member_.hpp @@ -34,6 +34,6 @@ namespace meta_hpp template < typename Member > inline member_info member_::make_info() const { - return member_info{}; + return member_info{name_, instance_}; } } diff --git a/headers/meta.hpp/meta_registry/method_.hpp b/headers/meta.hpp/meta_registry/method_.hpp index 7aa9aa1..c0f2079 100644 --- a/headers/meta.hpp/meta_registry/method_.hpp +++ b/headers/meta.hpp/meta_registry/method_.hpp @@ -34,6 +34,6 @@ namespace meta_hpp template < typename Method > inline method_info method_::make_info() const { - return method_info{}; + return method_info{name_, instance_}; } } diff --git a/headers/meta.hpp/meta_registry/namespace_.hpp b/headers/meta.hpp/meta_registry/namespace_.hpp index bc4f16e..15020ad 100644 --- a/headers/meta.hpp/meta_registry/namespace_.hpp +++ b/headers/meta.hpp/meta_registry/namespace_.hpp @@ -29,6 +29,6 @@ namespace meta_hpp : name_{std::move(name)} {} inline namespace_info namespace_::make_info() const { - return namespace_info{}; + return namespace_info{name_}; } } diff --git a/untests/features/infos/function_tests.cpp b/untests/features/infos/function_tests.cpp index 83baf40..c7af985 100644 --- a/untests/features/infos/function_tests.cpp +++ b/untests/features/infos/function_tests.cpp @@ -8,7 +8,46 @@ namespace { + using namespace meta_hpp; + using namespace std::string_literals; +} + +namespace +{ + struct ivec2 { + int x{}; + int y{}; + }; + + void arg_copy(ivec2) {} + + void arg_ref(ivec2&) {} + void arg_cref(const ivec2&) {} + + void arg_rref(ivec2&&) {} + void arg_crref(const ivec2&&) {} } TEST_CASE("features/infos/function") { + auto db = registry{}( + function_{"arg_copy", &arg_copy}, + function_{"arg_ref", &arg_ref}, + function_{"arg_cref", &arg_cref}, + function_{"arg_rref", &arg_rref}, + function_{"arg_crref", &arg_crref} + ); + + const function_info arg_copy_info = db.get_function_by_name("arg_copy"); + const function_info arg_ref_info = db.get_function_by_name("arg_ref"); + const function_info arg_cref_info = db.get_function_by_name("arg_cref"); + const function_info arg_rref_info = db.get_function_by_name("arg_rref"); + const function_info arg_crref_info = db.get_function_by_name("arg_crref"); + const function_info arg_not_exist_info = db.get_function_by_name("arg_not_exist"); + + REQUIRE(arg_copy_info); + REQUIRE(arg_ref_info); + REQUIRE(arg_cref_info); + REQUIRE(arg_rref_info); + REQUIRE(arg_crref_info); + REQUIRE_FALSE(arg_not_exist_info); } From 4880d953a0a72a4fb95d76f12731afe6737b2c9c Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Tue, 3 Aug 2021 06:47:16 +0700 Subject: [PATCH 067/233] visit info functions --- headers/meta.hpp/meta_infos/class_info.hpp | 108 +++++++++++++++++- headers/meta.hpp/meta_infos/ctor_info.hpp | 28 +++++ headers/meta.hpp/meta_infos/data_info.hpp | 30 ++++- headers/meta.hpp/meta_infos/enum_info.hpp | 44 ++++++- headers/meta.hpp/meta_infos/evalue_info.hpp | 32 +++++- headers/meta.hpp/meta_infos/function_info.hpp | 31 ++++- headers/meta.hpp/meta_infos/member_info.hpp | 31 ++++- headers/meta.hpp/meta_infos/method_info.hpp | 31 ++++- .../meta.hpp/meta_infos/namespace_info.hpp | 82 ++++++++++++- 9 files changed, 399 insertions(+), 18 deletions(-) diff --git a/headers/meta.hpp/meta_infos/class_info.hpp b/headers/meta.hpp/meta_infos/class_info.hpp index f95bff5..3b8e2c5 100644 --- a/headers/meta.hpp/meta_infos/class_info.hpp +++ b/headers/meta.hpp/meta_infos/class_info.hpp @@ -9,6 +9,13 @@ #include "../meta_fwd.hpp" #include "../meta_utilities.hpp" +#include "ctor_info.hpp" +#include "data_info.hpp" +#include "enum_info.hpp" +#include "function_info.hpp" +#include "member_info.hpp" +#include "method_info.hpp" + namespace meta_hpp { class class_info final { @@ -19,6 +26,30 @@ namespace meta_hpp explicit operator bool() const noexcept; const std::string& name() const noexcept; + public: + template < typename F > + void visit(F&& f) const; + + template < typename F > + void each_class(F&& f) const; + + template < typename F > + void each_ctor(F&& f) const; + + template < typename F > + void each_data(F&& f) const; + + template < typename F > + void each_enum(F&& f) const; + + template < typename F > + void each_function(F&& f) const; + + template < typename F > + void each_member(F&& f) const; + + template < typename F > + void each_method(F&& f) const; private: template < typename Class > friend class class_; @@ -33,6 +64,13 @@ namespace meta_hpp { struct class_info::state final { std::string name; + class_info_map classes; + ctor_info_map ctors; + data_info_map datas; + enum_info_map enums; + function_info_map functions; + member_info_map members; + method_info_map methods; }; } @@ -48,12 +86,78 @@ namespace meta_hpp } inline const std::string& class_info::name() const noexcept { - assert(state_); return state_->name; } +} +namespace meta_hpp +{ + template < typename F > + void class_info::visit(F&& f) const { + each_class(f); + each_ctor(f); + each_data(f); + each_enum(f); + each_function(f); + each_member(f); + each_method(f); + } + + template < typename F > + void class_info::each_class(F&& f) const { + for ( auto&& name_info : state_->classes ) { + std::invoke(f, name_info.second); + } + } + + template < typename F > + void class_info::each_ctor(F&& f) const { + for ( auto&& id_info : state_->ctors ) { + std::invoke(f, id_info.second); + } + } + + template < typename F > + void class_info::each_data(F&& f) const { + for ( auto&& name_info : state_->datas ) { + std::invoke(f, name_info.second); + } + } + + template < typename F > + void class_info::each_enum(F&& f) const { + for ( auto&& name_info : state_->enums ) { + std::invoke(f, name_info.second); + } + } + + template < typename F > + void class_info::each_function(F&& f) const { + for ( auto&& name_info : state_->functions ) { + std::invoke(f, name_info.second); + } + } + + template < typename F > + void class_info::each_member(F&& f) const { + for ( auto&& name_info : state_->members ) { + std::invoke(f, name_info.second); + } + } + + template < typename F > + void class_info::each_method(F&& f) const { + for ( auto&& name_info : state_->methods ) { + std::invoke(f, name_info.second); + } + } +} + +namespace meta_hpp +{ inline class_info::class_info(std::string name) : state_{std::make_shared(state{ - std::move(name) + std::move(name), + {}, {}, {}, {}, {}, {}, {} })} {} } diff --git a/headers/meta.hpp/meta_infos/ctor_info.hpp b/headers/meta.hpp/meta_infos/ctor_info.hpp index 8be221c..e2bbdc1 100644 --- a/headers/meta.hpp/meta_infos/ctor_info.hpp +++ b/headers/meta.hpp/meta_infos/ctor_info.hpp @@ -9,6 +9,8 @@ #include "../meta_fwd.hpp" #include "../meta_utilities.hpp" +#include "data_info.hpp" + namespace meta_hpp { class ctor_info final { @@ -17,6 +19,12 @@ namespace meta_hpp void merge(const ctor_info& other); explicit operator bool() const noexcept; + public: + template < typename F > + void visit(F&& f) const; + + template < typename F > + void each_data(F&& f) const; private: template < typename... Args > friend class ctor_; @@ -31,6 +39,7 @@ namespace meta_hpp namespace meta_hpp { struct ctor_info::state final { + data_info_map datas; }; } @@ -44,9 +53,28 @@ namespace meta_hpp inline ctor_info::operator bool() const noexcept { return !!state_; } +} +namespace meta_hpp +{ + template < typename F > + void ctor_info::visit(F&& f) const { + each_data(f); + } + + template < typename F > + void ctor_info::each_data(F&& f) const { + for ( auto&& name_info : state_->datas ) { + std::invoke(f, name_info.second); + } + } +} + +namespace meta_hpp +{ template < typename Class, typename... Args > inline ctor_info::ctor_info(typename_arg_t, typename_arg_t) : state_{std::make_shared(state{ + {} })} {} } diff --git a/headers/meta.hpp/meta_infos/data_info.hpp b/headers/meta.hpp/meta_infos/data_info.hpp index 89419b4..810f46d 100644 --- a/headers/meta.hpp/meta_infos/data_info.hpp +++ b/headers/meta.hpp/meta_infos/data_info.hpp @@ -20,6 +20,12 @@ namespace meta_hpp const std::string& name() const noexcept; const class value& value() const noexcept; + public: + template < typename F > + void visit(F&& f) const; + + template < typename F > + void each_data(F&& f) const; private: friend class data_; @@ -35,6 +41,7 @@ namespace meta_hpp struct data_info::state final { std::string name; class value value; + data_info_map datas; }; } @@ -50,18 +57,35 @@ namespace meta_hpp } inline const std::string& data_info::name() const noexcept { - assert(state_); return state_->name; } inline const class value& data_info::value() const noexcept { - assert(state_); return state_->value; } +} +namespace meta_hpp +{ + template < typename F > + void data_info::visit(F&& f) const { + each_data(f); + } + + template < typename F > + void data_info::each_data(F&& f) const { + for ( auto&& name_info : state_->datas ) { + std::invoke(f, name_info.second); + } + } +} + +namespace meta_hpp +{ inline data_info::data_info(std::string name, class value value) : state_{std::make_shared(state{ std::move(name), - std::move(value) + std::move(value), + {} })} {} } diff --git a/headers/meta.hpp/meta_infos/enum_info.hpp b/headers/meta.hpp/meta_infos/enum_info.hpp index ae9f8c5..96cc666 100644 --- a/headers/meta.hpp/meta_infos/enum_info.hpp +++ b/headers/meta.hpp/meta_infos/enum_info.hpp @@ -9,6 +9,9 @@ #include "../meta_fwd.hpp" #include "../meta_utilities.hpp" +#include "data_info.hpp" +#include "evalue_info.hpp" + namespace meta_hpp { class enum_info final { @@ -19,6 +22,15 @@ namespace meta_hpp explicit operator bool() const noexcept; const std::string& name() const noexcept; + public: + template < typename F > + void visit(F&& f) const; + + template < typename F > + void each_data(F&& f) const; + + template < typename F > + void each_evalue(F&& f) const; private: template < typename Enum > friend class enum_; @@ -33,6 +45,8 @@ namespace meta_hpp { struct enum_info::state final { std::string name; + data_info_map datas; + evalue_info_map evalues; }; } @@ -48,12 +62,38 @@ namespace meta_hpp } inline const std::string& enum_info::name() const noexcept { - assert(state_); return state_->name; } +} +namespace meta_hpp +{ + template < typename F > + void enum_info::visit(F&& f) const { + each_data(f); + each_evalue(f); + } + + template < typename F > + void enum_info::each_data(F&& f) const { + for ( auto&& name_info : state_->datas ) { + std::invoke(f, name_info.second); + } + } + + template < typename F > + void enum_info::each_evalue(F&& f) const { + for ( auto&& name_info : state_->evalues ) { + std::invoke(f, name_info.second); + } + } +} + +namespace meta_hpp +{ inline enum_info::enum_info(std::string name) : state_{std::make_shared(state{ - std::move(name) + std::move(name), + {}, {} })} {} } diff --git a/headers/meta.hpp/meta_infos/evalue_info.hpp b/headers/meta.hpp/meta_infos/evalue_info.hpp index 2a86fbd..9d0adee 100644 --- a/headers/meta.hpp/meta_infos/evalue_info.hpp +++ b/headers/meta.hpp/meta_infos/evalue_info.hpp @@ -9,6 +9,8 @@ #include "../meta_fwd.hpp" #include "../meta_utilities.hpp" +#include "data_info.hpp" + namespace meta_hpp { class evalue_info final { @@ -20,6 +22,12 @@ namespace meta_hpp const std::string& name() const noexcept; const class value& value() const noexcept; + public: + template < typename F > + void visit(F&& f) const; + + template < typename F > + void each_data(F&& f) const; private: template < typename Enum > friend class evalue_; @@ -36,6 +44,7 @@ namespace meta_hpp struct evalue_info::state final { std::string name; class value value; + data_info_map datas; }; } @@ -51,19 +60,36 @@ namespace meta_hpp } inline const std::string& evalue_info::name() const noexcept { - assert(state_); return state_->name; } inline const class value& evalue_info::value() const noexcept { - assert(state_); return state_->value; } +} +namespace meta_hpp +{ + template < typename F > + void evalue_info::visit(F&& f) const { + each_data(f); + } + + template < typename F > + void evalue_info::each_data(F&& f) const { + for ( auto&& name_info : state_->datas ) { + std::invoke(f, name_info.second); + } + } +} + +namespace meta_hpp +{ template < typename Enum > inline evalue_info::evalue_info(std::string name, Enum value) : state_{std::make_shared(state{ std::move(name), - std::move(value) + std::move(value), + {} })} {} } diff --git a/headers/meta.hpp/meta_infos/function_info.hpp b/headers/meta.hpp/meta_infos/function_info.hpp index ffe4dc2..e979464 100644 --- a/headers/meta.hpp/meta_infos/function_info.hpp +++ b/headers/meta.hpp/meta_infos/function_info.hpp @@ -9,6 +9,8 @@ #include "../meta_fwd.hpp" #include "../meta_utilities.hpp" +#include "data_info.hpp" + namespace meta_hpp { class function_info final { @@ -19,6 +21,12 @@ namespace meta_hpp explicit operator bool() const noexcept; const std::string& name() const noexcept; + public: + template < typename F > + void visit(F&& f) const; + + template < typename F > + void each_data(F&& f) const; private: template < typename Function > friend class function_; @@ -34,6 +42,7 @@ namespace meta_hpp { struct function_info::state final { std::string name; + data_info_map datas; }; } @@ -49,14 +58,32 @@ namespace meta_hpp } inline const std::string& function_info::name() const noexcept { - assert(state_); return state_->name; } +} +namespace meta_hpp +{ + template < typename F > + void function_info::visit(F&& f) const { + each_data(f); + } + + template < typename F > + void function_info::each_data(F&& f) const { + for ( auto&& name_info : state_->datas ) { + std::invoke(f, name_info.second); + } + } +} + +namespace meta_hpp +{ template < typename Function > inline function_info::function_info(std::string name, Function instance) : state_{std::make_shared(state{ - std::move(name) + std::move(name), + {} })} { (void)instance; } diff --git a/headers/meta.hpp/meta_infos/member_info.hpp b/headers/meta.hpp/meta_infos/member_info.hpp index 68fb921..443705f 100644 --- a/headers/meta.hpp/meta_infos/member_info.hpp +++ b/headers/meta.hpp/meta_infos/member_info.hpp @@ -9,6 +9,8 @@ #include "../meta_fwd.hpp" #include "../meta_utilities.hpp" +#include "data_info.hpp" + namespace meta_hpp { class member_info final { @@ -19,6 +21,12 @@ namespace meta_hpp explicit operator bool() const noexcept; const std::string& name() const noexcept; + public: + template < typename F > + void visit(F&& f) const; + + template < typename F > + void each_data(F&& f) const; private: template < typename Member > friend class member_; @@ -34,6 +42,7 @@ namespace meta_hpp { struct member_info::state final { std::string name; + data_info_map datas; }; } @@ -49,14 +58,32 @@ namespace meta_hpp } inline const std::string& member_info::name() const noexcept { - assert(state_); return state_->name; } +} +namespace meta_hpp +{ + template < typename F > + void member_info::visit(F&& f) const { + each_data(f); + } + + template < typename F > + void member_info::each_data(F&& f) const { + for ( auto&& name_info : state_->datas ) { + std::invoke(f, name_info.second); + } + } +} + +namespace meta_hpp +{ template < typename Member > inline member_info::member_info(std::string name, Member instance) : state_{std::make_shared(state{ - std::move(name) + std::move(name), + {} })} { (void)instance; } diff --git a/headers/meta.hpp/meta_infos/method_info.hpp b/headers/meta.hpp/meta_infos/method_info.hpp index c1ba03b..335643d 100644 --- a/headers/meta.hpp/meta_infos/method_info.hpp +++ b/headers/meta.hpp/meta_infos/method_info.hpp @@ -9,6 +9,8 @@ #include "../meta_fwd.hpp" #include "../meta_utilities.hpp" +#include "data_info.hpp" + namespace meta_hpp { class method_info final { @@ -19,6 +21,12 @@ namespace meta_hpp explicit operator bool() const noexcept; const std::string& name() const noexcept; + public: + template < typename F > + void visit(F&& f) const; + + template < typename F > + void each_data(F&& f) const; private: template < typename Method > friend class method_; @@ -34,6 +42,7 @@ namespace meta_hpp { struct method_info::state final { std::string name; + data_info_map datas; }; } @@ -49,14 +58,32 @@ namespace meta_hpp } inline const std::string& method_info::name() const noexcept { - assert(state_); return state_->name; } +} +namespace meta_hpp +{ + template < typename F > + void method_info::visit(F&& f) const { + each_data(f); + } + + template < typename F > + void method_info::each_data(F&& f) const { + for ( auto&& name_info : state_->datas ) { + std::invoke(f, name_info.second); + } + } +} + +namespace meta_hpp +{ template < typename Method > inline method_info::method_info(std::string name, Method instance) : state_{std::make_shared(state{ - std::move(name) + std::move(name), + {} })} { (void)instance; } diff --git a/headers/meta.hpp/meta_infos/namespace_info.hpp b/headers/meta.hpp/meta_infos/namespace_info.hpp index a6e6a4f..73e8d33 100644 --- a/headers/meta.hpp/meta_infos/namespace_info.hpp +++ b/headers/meta.hpp/meta_infos/namespace_info.hpp @@ -9,6 +9,11 @@ #include "../meta_fwd.hpp" #include "../meta_utilities.hpp" +#include "class_info.hpp" +#include "data_info.hpp" +#include "enum_info.hpp" +#include "function_info.hpp" + namespace meta_hpp { class namespace_info final { @@ -19,6 +24,24 @@ namespace meta_hpp explicit operator bool() const noexcept; const std::string& name() const noexcept; + public: + template < typename F > + void visit(F&& f) const; + + template < typename F > + void each_class(F&& f) const; + + template < typename F > + void each_data(F&& f) const; + + template < typename F > + void each_enum(F&& f) const; + + template < typename F > + void each_function(F&& f) const; + + template < typename F > + void each_namespace(F&& f) const; private: friend class namespace_; @@ -33,6 +56,11 @@ namespace meta_hpp { struct namespace_info::state final { std::string name; + class_info_map classes; + data_info_map datas; + enum_info_map enums; + function_info_map functions; + namespace_info_map namespaces; }; } @@ -48,12 +76,62 @@ namespace meta_hpp } inline const std::string& namespace_info::name() const noexcept { - assert(state_); return state_->name; } +} +namespace meta_hpp +{ + template < typename F > + void namespace_info::visit(F&& f) const { + each_class(f); + each_data(f); + each_enum(f); + each_function(f); + each_namespace(f); + } + + template < typename F > + void namespace_info::each_class(F&& f) const { + for ( auto&& name_info : state_->classes ) { + std::invoke(f, name_info.second); + } + } + + template < typename F > + void namespace_info::each_data(F&& f) const { + for ( auto&& name_info : state_->datas ) { + std::invoke(f, name_info.second); + } + } + + template < typename F > + void namespace_info::each_enum(F&& f) const { + for ( auto&& name_info : state_->enums ) { + std::invoke(f, name_info.second); + } + } + + template < typename F > + void namespace_info::each_function(F&& f) const { + for ( auto&& name_info : state_->functions ) { + std::invoke(f, name_info.second); + } + } + + template < typename F > + void namespace_info::each_namespace(F&& f) const { + for ( auto&& name_info : state_->namespaces ) { + std::invoke(f, name_info.second); + } + } +} + +namespace meta_hpp +{ inline namespace_info::namespace_info(std::string name) : state_{std::make_shared(state{ - std::move(name) + std::move(name), + {}, {}, {}, {}, {} })} {} } From 505eff00d4250aeb74ef7e6f4a944c7576585dd4 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Tue, 3 Aug 2021 07:50:57 +0700 Subject: [PATCH 068/233] add curry impl from kari.hpp library --- headers/meta.hpp/meta_utilities.hpp | 1 + headers/meta.hpp/meta_utilities/curry.hpp | 104 ++++++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 headers/meta.hpp/meta_utilities/curry.hpp diff --git a/headers/meta.hpp/meta_utilities.hpp b/headers/meta.hpp/meta_utilities.hpp index 8658506..3ceab77 100644 --- a/headers/meta.hpp/meta_utilities.hpp +++ b/headers/meta.hpp/meta_utilities.hpp @@ -8,4 +8,5 @@ #include "meta_fwd.hpp" +#include "meta_utilities/curry.hpp" #include "meta_utilities/value.hpp" diff --git a/headers/meta.hpp/meta_utilities/curry.hpp b/headers/meta.hpp/meta_utilities/curry.hpp new file mode 100644 index 0000000..bcf3780 --- /dev/null +++ b/headers/meta.hpp/meta_utilities/curry.hpp @@ -0,0 +1,104 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_fwd.hpp" + +namespace meta_hpp +{ + template < typename F, typename... As > + class curry_t; + + namespace impl + { + template < typename F > + struct is_curried_impl + : std::false_type {}; + + template < typename F, typename... As > + struct is_curried_impl> + : std::true_type {}; + } + + template < typename F > + struct is_curried + : impl::is_curried_impl> {}; + + template < typename F > + inline constexpr bool is_curried_v = is_curried::value; +} + +namespace meta_hpp::detail +{ + template < typename F, typename... Args > + constexpr auto curry_or_apply(F&& f, std::tuple&& args) { + if constexpr ( std::is_invocable_v, Args...> ) { + return std::apply(std::forward(f), std::move(args)); + } else { + return curry_t(std::forward(f), std::move(args)); + } + } +} + +namespace meta_hpp +{ + template < typename F, typename... Args > + class curry_t final { + public: + constexpr curry_t(F f) + : f_(std::move(f)) {} + + constexpr curry_t(F f, std::tuple args) + : f_(std::move(f)) + , args_(std::move(args)) {} + + constexpr auto operator()() && { + return detail::curry_or_apply( + std::move(f_), + std::move(args_)); + } + + template < typename A > + constexpr auto operator()(A&& a) && { + return detail::curry_or_apply( + std::move(f_), + std::tuple_cat( + std::move(args_), + std::make_tuple(std::forward(a)))); + } + + template < typename A, typename... As > + constexpr auto operator()(A&& a, As&&... as) && { + return std::move(*this)(std::forward(a))(std::forward(as)...); + } + + template < typename... As > + constexpr auto operator()(As&&... as) const & { + return std::move(curry_t(*this))(std::forward(as)...); + } + private: + F f_; + std::tuple args_; + }; +} + +namespace meta_hpp +{ + template < typename F > + constexpr auto curry(F&& f) { + if constexpr ( is_curried_v> ) { + return std::forward(f); + } else { + return detail::curry_or_apply(std::forward(f), {}); + } + } + + template < typename F, typename A, typename... As > + constexpr auto curry(F&& f, A&& a, As&&... as) { + return curry(std::forward(f))(std::forward(a), std::forward(as)...); + } +} From d45c31c0b0583957a2480a499104b38dd8a30f8b Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Tue, 3 Aug 2021 07:52:24 +0700 Subject: [PATCH 069/233] recursive registry filling --- headers/meta.hpp/meta_registry.hpp | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/headers/meta.hpp/meta_registry.hpp b/headers/meta.hpp/meta_registry.hpp index 62dc2cc..c865fb1 100644 --- a/headers/meta.hpp/meta_registry.hpp +++ b/headers/meta.hpp/meta_registry.hpp @@ -10,7 +10,6 @@ #include "meta_infos.hpp" #include "meta_registry/class_.hpp" -#include "meta_registry/ctor_.hpp" #include "meta_registry/data_.hpp" #include "meta_registry/enum_.hpp" #include "meta_registry/evalue_.hpp" @@ -51,6 +50,7 @@ namespace meta_hpp void add_(const std::string& prefix, const namespace_& internal); void add_(const std::string& prefix, ...) = delete; private: + struct add_info_f; void add_info_(const std::string& prefix, const class_info& info); void add_info_(const std::string& prefix, const data_info& info); void add_info_(const std::string& prefix, const enum_info& info); @@ -153,43 +153,58 @@ namespace meta_hpp namespace meta_hpp { + struct registry::add_info_f final { + template < typename Info > + void operator()(registry& self, const std::string& prefix, Info&& info) { + self.add_info_(prefix, std::forward(info)); + } + }; + inline void registry::add_info_(const std::string& prefix, const class_info& info) { std::string name = prefix.empty() ? info.name() : prefix + "::" + info.name(); + info.visit(curry(add_info_f{}, *this, name)); detail::merge_with(classes_, name, info, &class_info::merge); } inline void registry::add_info_(const std::string& prefix, const data_info& info) { std::string name = prefix.empty() ? info.name() : prefix + "::" + info.name(); + info.visit(curry(add_info_f{}, *this, name)); detail::merge_with(datas_, name, info, &data_info::merge); } inline void registry::add_info_(const std::string& prefix, const enum_info& info) { std::string name = prefix.empty() ? info.name() : prefix + "::" + info.name(); + info.visit(curry(add_info_f{}, *this, name)); detail::merge_with(enums_, name, info, &enum_info::merge); } inline void registry::add_info_(const std::string& prefix, const evalue_info& info) { std::string name = prefix.empty() ? info.name() : prefix + "::" + info.name(); + info.visit(curry(add_info_f{}, *this, name)); detail::merge_with(evalues_, name, info, &evalue_info::merge); } inline void registry::add_info_(const std::string& prefix, const function_info& info) { std::string name = prefix.empty() ? info.name() : prefix + "::" + info.name(); + info.visit(curry(add_info_f{}, *this, name)); detail::merge_with(functions_, name, info, &function_info::merge); } inline void registry::add_info_(const std::string& prefix, const member_info& info) { std::string name = prefix.empty() ? info.name() : prefix + "::" + info.name(); + info.visit(curry(add_info_f{}, *this, name)); detail::merge_with(members_, name, info, &member_info::merge); } inline void registry::add_info_(const std::string& prefix, const method_info& info) { std::string name = prefix.empty() ? info.name() : prefix + "::" + info.name(); + info.visit(curry(add_info_f{}, *this, name)); detail::merge_with(methods_, name, info, &method_info::merge); } inline void registry::add_info_(const std::string& prefix, const namespace_info& info) { std::string name = prefix.empty() ? info.name() : prefix + "::" + info.name(); + info.visit(curry(add_info_f{}, *this, name)); detail::merge_with(namespaces_, name, info, &namespace_info::merge); } } From 481a5d5531f6c0e0adc736e6222e0e471e5eea79 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Tue, 3 Aug 2021 09:13:53 +0700 Subject: [PATCH 070/233] dummy type files --- headers/meta.hpp/meta_all.hpp | 1 + headers/meta.hpp/meta_fwd.hpp | 15 +++++++++++++ headers/meta.hpp/meta_types.hpp | 21 +++++++++++++++++++ .../meta.hpp/meta_types/arithmetic_type.hpp | 15 +++++++++++++ headers/meta.hpp/meta_types/array_type.hpp | 15 +++++++++++++ headers/meta.hpp/meta_types/class_type.hpp | 15 +++++++++++++ headers/meta.hpp/meta_types/ctor_type.hpp | 15 +++++++++++++ headers/meta.hpp/meta_types/enum_type.hpp | 15 +++++++++++++ headers/meta.hpp/meta_types/function_type.hpp | 15 +++++++++++++ headers/meta.hpp/meta_types/member_type.hpp | 15 +++++++++++++ headers/meta.hpp/meta_types/method_type.hpp | 15 +++++++++++++ headers/meta.hpp/meta_types/pointer_type.hpp | 15 +++++++++++++ .../meta.hpp/meta_types/reference_type.hpp | 15 +++++++++++++ headers/meta.hpp/meta_types/void_type.hpp | 15 +++++++++++++ 14 files changed, 202 insertions(+) create mode 100644 headers/meta.hpp/meta_types.hpp create mode 100644 headers/meta.hpp/meta_types/arithmetic_type.hpp create mode 100644 headers/meta.hpp/meta_types/array_type.hpp create mode 100644 headers/meta.hpp/meta_types/class_type.hpp create mode 100644 headers/meta.hpp/meta_types/ctor_type.hpp create mode 100644 headers/meta.hpp/meta_types/enum_type.hpp create mode 100644 headers/meta.hpp/meta_types/function_type.hpp create mode 100644 headers/meta.hpp/meta_types/member_type.hpp create mode 100644 headers/meta.hpp/meta_types/method_type.hpp create mode 100644 headers/meta.hpp/meta_types/pointer_type.hpp create mode 100644 headers/meta.hpp/meta_types/reference_type.hpp create mode 100644 headers/meta.hpp/meta_types/void_type.hpp diff --git a/headers/meta.hpp/meta_all.hpp b/headers/meta.hpp/meta_all.hpp index 1037a7a..d31c920 100644 --- a/headers/meta.hpp/meta_all.hpp +++ b/headers/meta.hpp/meta_all.hpp @@ -9,4 +9,5 @@ #include "meta_fwd.hpp" #include "meta_infos.hpp" #include "meta_registry.hpp" +#include "meta_types.hpp" #include "meta_utilities.hpp" diff --git a/headers/meta.hpp/meta_fwd.hpp b/headers/meta.hpp/meta_fwd.hpp index aab63a5..411d2c8 100644 --- a/headers/meta.hpp/meta_fwd.hpp +++ b/headers/meta.hpp/meta_fwd.hpp @@ -53,6 +53,21 @@ namespace meta_hpp class namespace_; } +namespace meta_hpp +{ + class arithmetic_type; + class array_type; + class class_type; + class ctor_type; + class enum_type; + class function_type; + class member_type; + class method_type; + class pointer_type; + class reference_type; + class void_type; +} + namespace meta_hpp { template < typename K, typename V > diff --git a/headers/meta.hpp/meta_types.hpp b/headers/meta.hpp/meta_types.hpp new file mode 100644 index 0000000..e64eb51 --- /dev/null +++ b/headers/meta.hpp/meta_types.hpp @@ -0,0 +1,21 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "meta_fwd.hpp" + +#include "meta_types/arithmetic_type.hpp" +#include "meta_types/array_type.hpp" +#include "meta_types/class_type.hpp" +#include "meta_types/ctor_type.hpp" +#include "meta_types/enum_type.hpp" +#include "meta_types/function_type.hpp" +#include "meta_types/member_type.hpp" +#include "meta_types/method_type.hpp" +#include "meta_types/pointer_type.hpp" +#include "meta_types/reference_type.hpp" +#include "meta_types/void_type.hpp" diff --git a/headers/meta.hpp/meta_types/arithmetic_type.hpp b/headers/meta.hpp/meta_types/arithmetic_type.hpp new file mode 100644 index 0000000..a76a968 --- /dev/null +++ b/headers/meta.hpp/meta_types/arithmetic_type.hpp @@ -0,0 +1,15 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_fwd.hpp" + +namespace meta_hpp +{ + class arithmetic_type final { + }; +} diff --git a/headers/meta.hpp/meta_types/array_type.hpp b/headers/meta.hpp/meta_types/array_type.hpp new file mode 100644 index 0000000..11e8940 --- /dev/null +++ b/headers/meta.hpp/meta_types/array_type.hpp @@ -0,0 +1,15 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_fwd.hpp" + +namespace meta_hpp +{ + class array_type final { + }; +} diff --git a/headers/meta.hpp/meta_types/class_type.hpp b/headers/meta.hpp/meta_types/class_type.hpp new file mode 100644 index 0000000..5a1fd2a --- /dev/null +++ b/headers/meta.hpp/meta_types/class_type.hpp @@ -0,0 +1,15 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_fwd.hpp" + +namespace meta_hpp +{ + class class_type final { + }; +} diff --git a/headers/meta.hpp/meta_types/ctor_type.hpp b/headers/meta.hpp/meta_types/ctor_type.hpp new file mode 100644 index 0000000..50d9d05 --- /dev/null +++ b/headers/meta.hpp/meta_types/ctor_type.hpp @@ -0,0 +1,15 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_fwd.hpp" + +namespace meta_hpp +{ + class ctor_type final { + }; +} diff --git a/headers/meta.hpp/meta_types/enum_type.hpp b/headers/meta.hpp/meta_types/enum_type.hpp new file mode 100644 index 0000000..a9a5970 --- /dev/null +++ b/headers/meta.hpp/meta_types/enum_type.hpp @@ -0,0 +1,15 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_fwd.hpp" + +namespace meta_hpp +{ + class enum_type final { + }; +} diff --git a/headers/meta.hpp/meta_types/function_type.hpp b/headers/meta.hpp/meta_types/function_type.hpp new file mode 100644 index 0000000..a99fab2 --- /dev/null +++ b/headers/meta.hpp/meta_types/function_type.hpp @@ -0,0 +1,15 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_fwd.hpp" + +namespace meta_hpp +{ + class function_type final { + }; +} diff --git a/headers/meta.hpp/meta_types/member_type.hpp b/headers/meta.hpp/meta_types/member_type.hpp new file mode 100644 index 0000000..864c896 --- /dev/null +++ b/headers/meta.hpp/meta_types/member_type.hpp @@ -0,0 +1,15 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_fwd.hpp" + +namespace meta_hpp +{ + class member_type final { + }; +} diff --git a/headers/meta.hpp/meta_types/method_type.hpp b/headers/meta.hpp/meta_types/method_type.hpp new file mode 100644 index 0000000..2910d22 --- /dev/null +++ b/headers/meta.hpp/meta_types/method_type.hpp @@ -0,0 +1,15 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_fwd.hpp" + +namespace meta_hpp +{ + class method_type final { + }; +} diff --git a/headers/meta.hpp/meta_types/pointer_type.hpp b/headers/meta.hpp/meta_types/pointer_type.hpp new file mode 100644 index 0000000..19389bf --- /dev/null +++ b/headers/meta.hpp/meta_types/pointer_type.hpp @@ -0,0 +1,15 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_fwd.hpp" + +namespace meta_hpp +{ + class pointer_type final { + }; +} diff --git a/headers/meta.hpp/meta_types/reference_type.hpp b/headers/meta.hpp/meta_types/reference_type.hpp new file mode 100644 index 0000000..060d6b0 --- /dev/null +++ b/headers/meta.hpp/meta_types/reference_type.hpp @@ -0,0 +1,15 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_fwd.hpp" + +namespace meta_hpp +{ + class reference_type final { + }; +} diff --git a/headers/meta.hpp/meta_types/void_type.hpp b/headers/meta.hpp/meta_types/void_type.hpp new file mode 100644 index 0000000..5b212d8 --- /dev/null +++ b/headers/meta.hpp/meta_types/void_type.hpp @@ -0,0 +1,15 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_fwd.hpp" + +namespace meta_hpp +{ + class void_type final { + }; +} From adb8141d14cf04887b1f4630217ee713ce797661 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Tue, 3 Aug 2021 10:56:32 +0700 Subject: [PATCH 071/233] basic type_id --- headers/meta.hpp/meta_fwd.hpp | 5 +- headers/meta.hpp/meta_types/_types_fwd.hpp | 89 +++++++++++++++++++ .../meta.hpp/meta_types/arithmetic_type.hpp | 8 +- headers/meta.hpp/meta_types/array_type.hpp | 8 +- headers/meta.hpp/meta_types/class_type.hpp | 8 +- headers/meta.hpp/meta_types/ctor_type.hpp | 8 +- headers/meta.hpp/meta_types/enum_type.hpp | 8 +- headers/meta.hpp/meta_types/function_type.hpp | 8 +- headers/meta.hpp/meta_types/member_type.hpp | 8 +- headers/meta.hpp/meta_types/method_type.hpp | 8 +- headers/meta.hpp/meta_types/pointer_type.hpp | 8 +- .../meta.hpp/meta_types/reference_type.hpp | 8 +- headers/meta.hpp/meta_types/void_type.hpp | 8 +- 13 files changed, 159 insertions(+), 23 deletions(-) create mode 100644 headers/meta.hpp/meta_types/_types_fwd.hpp diff --git a/headers/meta.hpp/meta_fwd.hpp b/headers/meta.hpp/meta_fwd.hpp index 411d2c8..4e57006 100644 --- a/headers/meta.hpp/meta_fwd.hpp +++ b/headers/meta.hpp/meta_fwd.hpp @@ -55,6 +55,9 @@ namespace meta_hpp namespace meta_hpp { + class type_id; + class base_type; + class arithmetic_type; class array_type; class class_type; @@ -74,7 +77,7 @@ namespace meta_hpp using info_map = std::map>; using class_info_map = info_map; - using ctor_info_map = info_map; + using ctor_info_map = info_map; using data_info_map = info_map; using enum_info_map = info_map; using evalue_info_map = info_map; diff --git a/headers/meta.hpp/meta_types/_types_fwd.hpp b/headers/meta.hpp/meta_types/_types_fwd.hpp new file mode 100644 index 0000000..dbbc9b8 --- /dev/null +++ b/headers/meta.hpp/meta_types/_types_fwd.hpp @@ -0,0 +1,89 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_fwd.hpp" + +namespace meta_hpp +{ + class type_id final { + public: + type_id() = delete; + + type_id(type_id&&) = default; + type_id& operator=(type_id&&) = default; + + type_id(const type_id&) = default; + type_id& operator=(const type_id&) = default; + + std::size_t hash() const noexcept { + return std::hash{}(id_); + } + + friend bool operator<(type_id l, type_id r) noexcept { + return l.id_ < r.id_; + } + + friend bool operator==(type_id l, type_id r) noexcept { + return l.id_ == r.id_; + } + + friend bool operator!=(type_id l, type_id r) noexcept { + return l.id_ != r.id_; + } + private: + using underlying_type = std::size_t; + underlying_type id_{0u}; + private: + template < typename T > + friend type_id make_type_id() noexcept; + + template < typename T > + explicit type_id(typename_arg_t) noexcept + : id_{next()} {} + + static underlying_type next() noexcept { + static std::atomic id{}; + return ++id; + } + }; + + template < typename T > + type_id make_type_id() noexcept { + static const type_id id = type_id{typename_arg}; + return id; + } +} + +namespace std +{ + template <> + struct hash { + size_t operator()(meta_hpp::type_id id) const noexcept { + return id.hash(); + } + }; +} + +namespace meta_hpp +{ + class base_type { + public: + template < typename... Ts > + struct tag {}; + public: + template < typename... Ts > + explicit base_type(typename_arg_t) + : id_{make_type_id>()} {} + + type_id id() const noexcept { + return id_; + } + private: + type_id id_; + }; +} diff --git a/headers/meta.hpp/meta_types/arithmetic_type.hpp b/headers/meta.hpp/meta_types/arithmetic_type.hpp index a76a968..cf7fb6d 100644 --- a/headers/meta.hpp/meta_types/arithmetic_type.hpp +++ b/headers/meta.hpp/meta_types/arithmetic_type.hpp @@ -6,10 +6,14 @@ #pragma once -#include "../meta_fwd.hpp" +#include "_types_fwd.hpp" namespace meta_hpp { - class arithmetic_type final { + class arithmetic_type final : public base_type { + public: + template < typename T > + explicit arithmetic_type(typename_arg_t) + : base_type{typename_arg} {} }; } diff --git a/headers/meta.hpp/meta_types/array_type.hpp b/headers/meta.hpp/meta_types/array_type.hpp index 11e8940..9b30ebc 100644 --- a/headers/meta.hpp/meta_types/array_type.hpp +++ b/headers/meta.hpp/meta_types/array_type.hpp @@ -6,10 +6,14 @@ #pragma once -#include "../meta_fwd.hpp" +#include "_types_fwd.hpp" namespace meta_hpp { - class array_type final { + class array_type final : public base_type { + public: + template < typename T > + explicit array_type(typename_arg_t) + : base_type{typename_arg} {} }; } diff --git a/headers/meta.hpp/meta_types/class_type.hpp b/headers/meta.hpp/meta_types/class_type.hpp index 5a1fd2a..1d97540 100644 --- a/headers/meta.hpp/meta_types/class_type.hpp +++ b/headers/meta.hpp/meta_types/class_type.hpp @@ -6,10 +6,14 @@ #pragma once -#include "../meta_fwd.hpp" +#include "_types_fwd.hpp" namespace meta_hpp { - class class_type final { + class class_type final : public base_type { + public: + template < typename T > + explicit class_type(typename_arg_t) + : base_type{typename_arg} {} }; } diff --git a/headers/meta.hpp/meta_types/ctor_type.hpp b/headers/meta.hpp/meta_types/ctor_type.hpp index 50d9d05..5d17ca9 100644 --- a/headers/meta.hpp/meta_types/ctor_type.hpp +++ b/headers/meta.hpp/meta_types/ctor_type.hpp @@ -6,10 +6,14 @@ #pragma once -#include "../meta_fwd.hpp" +#include "_types_fwd.hpp" namespace meta_hpp { - class ctor_type final { + class ctor_type final : public base_type { + public: + template < typename Class, typename... Args > + explicit ctor_type(typename_arg_t, typename_arg_t) + : base_type{typename_arg} {} }; } diff --git a/headers/meta.hpp/meta_types/enum_type.hpp b/headers/meta.hpp/meta_types/enum_type.hpp index a9a5970..158bd3a 100644 --- a/headers/meta.hpp/meta_types/enum_type.hpp +++ b/headers/meta.hpp/meta_types/enum_type.hpp @@ -6,10 +6,14 @@ #pragma once -#include "../meta_fwd.hpp" +#include "_types_fwd.hpp" namespace meta_hpp { - class enum_type final { + class enum_type final : public base_type { + public: + template < typename T > + explicit enum_type(typename_arg_t) + : base_type{typename_arg} {} }; } diff --git a/headers/meta.hpp/meta_types/function_type.hpp b/headers/meta.hpp/meta_types/function_type.hpp index a99fab2..59a4868 100644 --- a/headers/meta.hpp/meta_types/function_type.hpp +++ b/headers/meta.hpp/meta_types/function_type.hpp @@ -6,10 +6,14 @@ #pragma once -#include "../meta_fwd.hpp" +#include "_types_fwd.hpp" namespace meta_hpp { - class function_type final { + class function_type final : public base_type { + public: + template < typename T > + explicit function_type(typename_arg_t) + : base_type{typename_arg} {} }; } diff --git a/headers/meta.hpp/meta_types/member_type.hpp b/headers/meta.hpp/meta_types/member_type.hpp index 864c896..5186541 100644 --- a/headers/meta.hpp/meta_types/member_type.hpp +++ b/headers/meta.hpp/meta_types/member_type.hpp @@ -6,10 +6,14 @@ #pragma once -#include "../meta_fwd.hpp" +#include "_types_fwd.hpp" namespace meta_hpp { - class member_type final { + class member_type final : public base_type { + public: + template < typename T > + explicit member_type(typename_arg_t) + : base_type{typename_arg} {} }; } diff --git a/headers/meta.hpp/meta_types/method_type.hpp b/headers/meta.hpp/meta_types/method_type.hpp index 2910d22..89bb9d5 100644 --- a/headers/meta.hpp/meta_types/method_type.hpp +++ b/headers/meta.hpp/meta_types/method_type.hpp @@ -6,10 +6,14 @@ #pragma once -#include "../meta_fwd.hpp" +#include "_types_fwd.hpp" namespace meta_hpp { - class method_type final { + class method_type final : public base_type { + public: + template < typename T > + explicit method_type(typename_arg_t) + : base_type{typename_arg} {} }; } diff --git a/headers/meta.hpp/meta_types/pointer_type.hpp b/headers/meta.hpp/meta_types/pointer_type.hpp index 19389bf..3c3ca0d 100644 --- a/headers/meta.hpp/meta_types/pointer_type.hpp +++ b/headers/meta.hpp/meta_types/pointer_type.hpp @@ -6,10 +6,14 @@ #pragma once -#include "../meta_fwd.hpp" +#include "_types_fwd.hpp" namespace meta_hpp { - class pointer_type final { + class pointer_type final : public base_type { + public: + template < typename T > + explicit pointer_type(typename_arg_t) + : base_type{typename_arg} {} }; } diff --git a/headers/meta.hpp/meta_types/reference_type.hpp b/headers/meta.hpp/meta_types/reference_type.hpp index 060d6b0..267b9a9 100644 --- a/headers/meta.hpp/meta_types/reference_type.hpp +++ b/headers/meta.hpp/meta_types/reference_type.hpp @@ -6,10 +6,14 @@ #pragma once -#include "../meta_fwd.hpp" +#include "_types_fwd.hpp" namespace meta_hpp { - class reference_type final { + class reference_type final : public base_type { + public: + template < typename T > + explicit reference_type(typename_arg_t) + : base_type{typename_arg} {} }; } diff --git a/headers/meta.hpp/meta_types/void_type.hpp b/headers/meta.hpp/meta_types/void_type.hpp index 5b212d8..e87b794 100644 --- a/headers/meta.hpp/meta_types/void_type.hpp +++ b/headers/meta.hpp/meta_types/void_type.hpp @@ -6,10 +6,14 @@ #pragma once -#include "../meta_fwd.hpp" +#include "_types_fwd.hpp" namespace meta_hpp { - class void_type final { + class void_type final : public base_type { + public: + template < typename T > + explicit void_type(typename_arg_t) + : base_type{typename_arg} {} }; } From 0601285e9c6c02fea8ee2ed97fa294c7fe9ccd0f Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Tue, 3 Aug 2021 10:57:55 +0700 Subject: [PATCH 072/233] type for infos --- headers/meta.hpp/meta_infos/_infos_fwd.hpp | 11 +++++++++++ headers/meta.hpp/meta_infos/class_info.hpp | 16 ++++++++++++---- headers/meta.hpp/meta_infos/ctor_info.hpp | 11 +++++++++-- headers/meta.hpp/meta_infos/data_info.hpp | 3 +-- headers/meta.hpp/meta_infos/enum_info.hpp | 16 ++++++++++++---- headers/meta.hpp/meta_infos/evalue_info.hpp | 3 +-- headers/meta.hpp/meta_infos/function_info.hpp | 10 ++++++++-- headers/meta.hpp/meta_infos/member_info.hpp | 10 ++++++++-- headers/meta.hpp/meta_infos/method_info.hpp | 10 ++++++++-- headers/meta.hpp/meta_infos/namespace_info.hpp | 3 +-- 10 files changed, 71 insertions(+), 22 deletions(-) create mode 100644 headers/meta.hpp/meta_infos/_infos_fwd.hpp diff --git a/headers/meta.hpp/meta_infos/_infos_fwd.hpp b/headers/meta.hpp/meta_infos/_infos_fwd.hpp new file mode 100644 index 0000000..62999e5 --- /dev/null +++ b/headers/meta.hpp/meta_infos/_infos_fwd.hpp @@ -0,0 +1,11 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_fwd.hpp" +#include "../meta_types.hpp" +#include "../meta_utilities.hpp" diff --git a/headers/meta.hpp/meta_infos/class_info.hpp b/headers/meta.hpp/meta_infos/class_info.hpp index 3b8e2c5..2095cf7 100644 --- a/headers/meta.hpp/meta_infos/class_info.hpp +++ b/headers/meta.hpp/meta_infos/class_info.hpp @@ -6,8 +6,7 @@ #pragma once -#include "../meta_fwd.hpp" -#include "../meta_utilities.hpp" +#include "_infos_fwd.hpp" #include "ctor_info.hpp" #include "data_info.hpp" @@ -26,6 +25,7 @@ namespace meta_hpp explicit operator bool() const noexcept; const std::string& name() const noexcept; + const class_type& type() const noexcept; public: template < typename F > void visit(F&& f) const; @@ -53,7 +53,8 @@ namespace meta_hpp private: template < typename Class > friend class class_; - explicit class_info(std::string name); + template < typename Class > + explicit class_info(typename_arg_t, std::string name); private: struct state; std::shared_ptr state_; @@ -64,6 +65,7 @@ namespace meta_hpp { struct class_info::state final { std::string name; + class_type type; class_info_map classes; ctor_info_map ctors; data_info_map datas; @@ -88,6 +90,10 @@ namespace meta_hpp inline const std::string& class_info::name() const noexcept { return state_->name; } + + inline const class_type& class_info::type() const noexcept { + return state_->type; + } } namespace meta_hpp @@ -155,9 +161,11 @@ namespace meta_hpp namespace meta_hpp { - inline class_info::class_info(std::string name) + template < typename Class > + inline class_info::class_info(typename_arg_t, std::string name) : state_{std::make_shared(state{ std::move(name), + class_type{typename_arg}, {}, {}, {}, {}, {}, {}, {} })} {} } diff --git a/headers/meta.hpp/meta_infos/ctor_info.hpp b/headers/meta.hpp/meta_infos/ctor_info.hpp index e2bbdc1..464d28c 100644 --- a/headers/meta.hpp/meta_infos/ctor_info.hpp +++ b/headers/meta.hpp/meta_infos/ctor_info.hpp @@ -6,8 +6,7 @@ #pragma once -#include "../meta_fwd.hpp" -#include "../meta_utilities.hpp" +#include "_infos_fwd.hpp" #include "data_info.hpp" @@ -19,6 +18,8 @@ namespace meta_hpp void merge(const ctor_info& other); explicit operator bool() const noexcept; + + const ctor_type& type() const noexcept; public: template < typename F > void visit(F&& f) const; @@ -39,6 +40,7 @@ namespace meta_hpp namespace meta_hpp { struct ctor_info::state final { + ctor_type type; data_info_map datas; }; } @@ -53,6 +55,10 @@ namespace meta_hpp inline ctor_info::operator bool() const noexcept { return !!state_; } + + inline const ctor_type& ctor_info::type() const noexcept { + return state_->type; + } } namespace meta_hpp @@ -75,6 +81,7 @@ namespace meta_hpp template < typename Class, typename... Args > inline ctor_info::ctor_info(typename_arg_t, typename_arg_t) : state_{std::make_shared(state{ + ctor_type{typename_arg, typename_arg}, {} })} {} } diff --git a/headers/meta.hpp/meta_infos/data_info.hpp b/headers/meta.hpp/meta_infos/data_info.hpp index 810f46d..560d31c 100644 --- a/headers/meta.hpp/meta_infos/data_info.hpp +++ b/headers/meta.hpp/meta_infos/data_info.hpp @@ -6,8 +6,7 @@ #pragma once -#include "../meta_fwd.hpp" -#include "../meta_utilities.hpp" +#include "_infos_fwd.hpp" namespace meta_hpp { diff --git a/headers/meta.hpp/meta_infos/enum_info.hpp b/headers/meta.hpp/meta_infos/enum_info.hpp index 96cc666..9b13e68 100644 --- a/headers/meta.hpp/meta_infos/enum_info.hpp +++ b/headers/meta.hpp/meta_infos/enum_info.hpp @@ -6,8 +6,7 @@ #pragma once -#include "../meta_fwd.hpp" -#include "../meta_utilities.hpp" +#include "_infos_fwd.hpp" #include "data_info.hpp" #include "evalue_info.hpp" @@ -22,6 +21,7 @@ namespace meta_hpp explicit operator bool() const noexcept; const std::string& name() const noexcept; + const enum_type& type() const noexcept; public: template < typename F > void visit(F&& f) const; @@ -34,7 +34,8 @@ namespace meta_hpp private: template < typename Enum > friend class enum_; - explicit enum_info(std::string name); + template < typename Enum > + explicit enum_info(typename_arg_t, std::string name); private: struct state; std::shared_ptr state_; @@ -45,6 +46,7 @@ namespace meta_hpp { struct enum_info::state final { std::string name; + enum_type type; data_info_map datas; evalue_info_map evalues; }; @@ -64,6 +66,10 @@ namespace meta_hpp inline const std::string& enum_info::name() const noexcept { return state_->name; } + + inline const enum_type& enum_info::type() const noexcept { + return state_->type; + } } namespace meta_hpp @@ -91,9 +97,11 @@ namespace meta_hpp namespace meta_hpp { - inline enum_info::enum_info(std::string name) + template < typename Enum > + inline enum_info::enum_info(typename_arg_t, std::string name) : state_{std::make_shared(state{ std::move(name), + enum_type{typename_arg}, {}, {} })} {} } diff --git a/headers/meta.hpp/meta_infos/evalue_info.hpp b/headers/meta.hpp/meta_infos/evalue_info.hpp index 9d0adee..a1c988b 100644 --- a/headers/meta.hpp/meta_infos/evalue_info.hpp +++ b/headers/meta.hpp/meta_infos/evalue_info.hpp @@ -6,8 +6,7 @@ #pragma once -#include "../meta_fwd.hpp" -#include "../meta_utilities.hpp" +#include "_infos_fwd.hpp" #include "data_info.hpp" diff --git a/headers/meta.hpp/meta_infos/function_info.hpp b/headers/meta.hpp/meta_infos/function_info.hpp index e979464..d4efcb7 100644 --- a/headers/meta.hpp/meta_infos/function_info.hpp +++ b/headers/meta.hpp/meta_infos/function_info.hpp @@ -6,8 +6,7 @@ #pragma once -#include "../meta_fwd.hpp" -#include "../meta_utilities.hpp" +#include "_infos_fwd.hpp" #include "data_info.hpp" @@ -21,6 +20,7 @@ namespace meta_hpp explicit operator bool() const noexcept; const std::string& name() const noexcept; + const function_type& type() const noexcept; public: template < typename F > void visit(F&& f) const; @@ -42,6 +42,7 @@ namespace meta_hpp { struct function_info::state final { std::string name; + function_type type; data_info_map datas; }; } @@ -60,6 +61,10 @@ namespace meta_hpp inline const std::string& function_info::name() const noexcept { return state_->name; } + + inline const function_type& function_info::type() const noexcept { + return state_->type; + } } namespace meta_hpp @@ -83,6 +88,7 @@ namespace meta_hpp inline function_info::function_info(std::string name, Function instance) : state_{std::make_shared(state{ std::move(name), + function_type{typename_arg}, {} })} { (void)instance; diff --git a/headers/meta.hpp/meta_infos/member_info.hpp b/headers/meta.hpp/meta_infos/member_info.hpp index 443705f..ab5b147 100644 --- a/headers/meta.hpp/meta_infos/member_info.hpp +++ b/headers/meta.hpp/meta_infos/member_info.hpp @@ -6,8 +6,7 @@ #pragma once -#include "../meta_fwd.hpp" -#include "../meta_utilities.hpp" +#include "_infos_fwd.hpp" #include "data_info.hpp" @@ -21,6 +20,7 @@ namespace meta_hpp explicit operator bool() const noexcept; const std::string& name() const noexcept; + const member_type& type() const noexcept; public: template < typename F > void visit(F&& f) const; @@ -42,6 +42,7 @@ namespace meta_hpp { struct member_info::state final { std::string name; + member_type type; data_info_map datas; }; } @@ -60,6 +61,10 @@ namespace meta_hpp inline const std::string& member_info::name() const noexcept { return state_->name; } + + inline const member_type& member_info::type() const noexcept { + return state_->type; + } } namespace meta_hpp @@ -83,6 +88,7 @@ namespace meta_hpp inline member_info::member_info(std::string name, Member instance) : state_{std::make_shared(state{ std::move(name), + member_type{typename_arg}, {} })} { (void)instance; diff --git a/headers/meta.hpp/meta_infos/method_info.hpp b/headers/meta.hpp/meta_infos/method_info.hpp index 335643d..0d99b9d 100644 --- a/headers/meta.hpp/meta_infos/method_info.hpp +++ b/headers/meta.hpp/meta_infos/method_info.hpp @@ -6,8 +6,7 @@ #pragma once -#include "../meta_fwd.hpp" -#include "../meta_utilities.hpp" +#include "_infos_fwd.hpp" #include "data_info.hpp" @@ -21,6 +20,7 @@ namespace meta_hpp explicit operator bool() const noexcept; const std::string& name() const noexcept; + const method_type& type() const noexcept; public: template < typename F > void visit(F&& f) const; @@ -42,6 +42,7 @@ namespace meta_hpp { struct method_info::state final { std::string name; + method_type type; data_info_map datas; }; } @@ -60,6 +61,10 @@ namespace meta_hpp inline const std::string& method_info::name() const noexcept { return state_->name; } + + inline const method_type& method_info::type() const noexcept { + return state_->type; + } } namespace meta_hpp @@ -83,6 +88,7 @@ namespace meta_hpp inline method_info::method_info(std::string name, Method instance) : state_{std::make_shared(state{ std::move(name), + method_type{typename_arg}, {} })} { (void)instance; diff --git a/headers/meta.hpp/meta_infos/namespace_info.hpp b/headers/meta.hpp/meta_infos/namespace_info.hpp index 73e8d33..6f7638f 100644 --- a/headers/meta.hpp/meta_infos/namespace_info.hpp +++ b/headers/meta.hpp/meta_infos/namespace_info.hpp @@ -6,8 +6,7 @@ #pragma once -#include "../meta_fwd.hpp" -#include "../meta_utilities.hpp" +#include "_infos_fwd.hpp" #include "class_info.hpp" #include "data_info.hpp" From 5dde35baef4c7a71162f3cda6bf5dc62105f51d8 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Tue, 3 Aug 2021 11:16:27 +0700 Subject: [PATCH 073/233] info internals registration --- headers/meta.hpp/meta_registry.hpp | 25 +++-- .../meta.hpp/meta_registry/_registry_fwd.hpp | 12 ++ headers/meta.hpp/meta_registry/class_.hpp | 103 +++++++++++++++++- headers/meta.hpp/meta_registry/ctor_.hpp | 32 +++++- headers/meta.hpp/meta_registry/data_.hpp | 30 ++++- headers/meta.hpp/meta_registry/enum_.hpp | 32 +++++- headers/meta.hpp/meta_registry/evalue_.hpp | 32 +++++- headers/meta.hpp/meta_registry/function_.hpp | 32 +++++- headers/meta.hpp/meta_registry/member_.hpp | 32 +++++- headers/meta.hpp/meta_registry/method_.hpp | 32 +++++- headers/meta.hpp/meta_registry/namespace_.hpp | 71 +++++++++++- .../meta.hpp/meta_types/arithmetic_type.hpp | 4 +- headers/meta.hpp/meta_types/array_type.hpp | 4 +- headers/meta.hpp/meta_types/class_type.hpp | 4 +- headers/meta.hpp/meta_types/ctor_type.hpp | 5 +- headers/meta.hpp/meta_types/enum_type.hpp | 4 +- headers/meta.hpp/meta_types/function_type.hpp | 5 +- headers/meta.hpp/meta_types/member_type.hpp | 4 +- headers/meta.hpp/meta_types/method_type.hpp | 4 +- headers/meta.hpp/meta_types/pointer_type.hpp | 4 +- .../meta.hpp/meta_types/reference_type.hpp | 4 +- headers/meta.hpp/meta_types/void_type.hpp | 4 +- 22 files changed, 422 insertions(+), 57 deletions(-) create mode 100644 headers/meta.hpp/meta_registry/_registry_fwd.hpp diff --git a/headers/meta.hpp/meta_registry.hpp b/headers/meta.hpp/meta_registry.hpp index c865fb1..4d32ec6 100644 --- a/headers/meta.hpp/meta_registry.hpp +++ b/headers/meta.hpp/meta_registry.hpp @@ -52,6 +52,7 @@ namespace meta_hpp private: struct add_info_f; void add_info_(const std::string& prefix, const class_info& info); + void add_info_(const std::string& prefix, const ctor_info& info); void add_info_(const std::string& prefix, const data_info& info); void add_info_(const std::string& prefix, const enum_info& info); void add_info_(const std::string& prefix, const evalue_info& info); @@ -59,6 +60,7 @@ namespace meta_hpp void add_info_(const std::string& prefix, const member_info& info); void add_info_(const std::string& prefix, const method_info& info); void add_info_(const std::string& prefix, const namespace_info& info); + void add_info_(const std::string& prefix, ...) = delete; private: class_info_map classes_; data_info_map datas_; @@ -155,56 +157,61 @@ namespace meta_hpp { struct registry::add_info_f final { template < typename Info > - void operator()(registry& self, const std::string& prefix, Info&& info) { + void operator()(registry& self, const std::string& prefix, Info&& info) const { self.add_info_(prefix, std::forward(info)); } }; inline void registry::add_info_(const std::string& prefix, const class_info& info) { std::string name = prefix.empty() ? info.name() : prefix + "::" + info.name(); - info.visit(curry(add_info_f{}, *this, name)); + info.visit(curry(add_info_f{}, std::ref(*this), name)); detail::merge_with(classes_, name, info, &class_info::merge); } + inline void registry::add_info_(const std::string& prefix, const ctor_info& info) { + (void)prefix; + (void)info; + } + inline void registry::add_info_(const std::string& prefix, const data_info& info) { std::string name = prefix.empty() ? info.name() : prefix + "::" + info.name(); - info.visit(curry(add_info_f{}, *this, name)); + info.visit(curry(add_info_f{}, std::ref(*this), name)); detail::merge_with(datas_, name, info, &data_info::merge); } inline void registry::add_info_(const std::string& prefix, const enum_info& info) { std::string name = prefix.empty() ? info.name() : prefix + "::" + info.name(); - info.visit(curry(add_info_f{}, *this, name)); + info.visit(curry(add_info_f{}, std::ref(*this), name)); detail::merge_with(enums_, name, info, &enum_info::merge); } inline void registry::add_info_(const std::string& prefix, const evalue_info& info) { std::string name = prefix.empty() ? info.name() : prefix + "::" + info.name(); - info.visit(curry(add_info_f{}, *this, name)); + info.visit(curry(add_info_f{}, std::ref(*this), name)); detail::merge_with(evalues_, name, info, &evalue_info::merge); } inline void registry::add_info_(const std::string& prefix, const function_info& info) { std::string name = prefix.empty() ? info.name() : prefix + "::" + info.name(); - info.visit(curry(add_info_f{}, *this, name)); + info.visit(curry(add_info_f{}, std::ref(*this), name)); detail::merge_with(functions_, name, info, &function_info::merge); } inline void registry::add_info_(const std::string& prefix, const member_info& info) { std::string name = prefix.empty() ? info.name() : prefix + "::" + info.name(); - info.visit(curry(add_info_f{}, *this, name)); + info.visit(curry(add_info_f{}, std::ref(*this), name)); detail::merge_with(members_, name, info, &member_info::merge); } inline void registry::add_info_(const std::string& prefix, const method_info& info) { std::string name = prefix.empty() ? info.name() : prefix + "::" + info.name(); - info.visit(curry(add_info_f{}, *this, name)); + info.visit(curry(add_info_f{}, std::ref(*this), name)); detail::merge_with(methods_, name, info, &method_info::merge); } inline void registry::add_info_(const std::string& prefix, const namespace_info& info) { std::string name = prefix.empty() ? info.name() : prefix + "::" + info.name(); - info.visit(curry(add_info_f{}, *this, name)); + info.visit(curry(add_info_f{}, std::ref(*this), name)); detail::merge_with(namespaces_, name, info, &namespace_info::merge); } } diff --git a/headers/meta.hpp/meta_registry/_registry_fwd.hpp b/headers/meta.hpp/meta_registry/_registry_fwd.hpp new file mode 100644 index 0000000..9cfa643 --- /dev/null +++ b/headers/meta.hpp/meta_registry/_registry_fwd.hpp @@ -0,0 +1,12 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_fwd.hpp" +#include "../meta_infos.hpp" +#include "../meta_utilities.hpp" + diff --git a/headers/meta.hpp/meta_registry/class_.hpp b/headers/meta.hpp/meta_registry/class_.hpp index d012492..8207e89 100644 --- a/headers/meta.hpp/meta_registry/class_.hpp +++ b/headers/meta.hpp/meta_registry/class_.hpp @@ -6,10 +6,14 @@ #pragma once -#include "../meta_fwd.hpp" -#include "../meta_utilities.hpp" +#include "_registry_fwd.hpp" -#include "../meta_infos/class_info.hpp" +#include "ctor_.hpp" +#include "data_.hpp" +#include "enum_.hpp" +#include "function_.hpp" +#include "member_.hpp" +#include "method_.hpp" namespace meta_hpp { @@ -19,8 +23,33 @@ namespace meta_hpp explicit class_(std::string name); class_info make_info() const; + public: + template < typename... Internals > + class_& operator()(Internals&&...internals); + private: + template < typename Class2 > + void add_(const class_& internal); + template < typename... Args > + void add_(const ctor_& internal); + void add_(const data_& internal); + template < typename Enum > + void add_(const enum_& internal); + template < typename Function > + void add_(const function_& internal); + template < typename Member > + void add_(const member_& internal); + template < typename Method > + void add_(const method_& internal); + void add_(...) = delete; private: std::string name_; + class_info_map classes_; + ctor_info_map ctors_; + data_info_map datas_; + enum_info_map enums_; + function_info_map functions_; + member_info_map members_; + method_info_map methods_; }; } @@ -32,6 +61,72 @@ namespace meta_hpp template < typename Class > inline class_info class_::make_info() const { - return class_info{name_}; + class_info info{typename_arg, name_}; + info.state_->classes.insert(classes_.begin(), classes_.end()); + info.state_->ctors.insert(ctors_.begin(), ctors_.end()); + info.state_->datas.insert(datas_.begin(), datas_.end()); + info.state_->enums.insert(enums_.begin(), enums_.end()); + info.state_->functions.insert(functions_.begin(), functions_.end()); + info.state_->members.insert(members_.begin(), members_.end()); + info.state_->methods.insert(methods_.begin(), methods_.end()); + return info; + } + + template < typename Class > + template < typename... Internals > + inline class_& class_::operator()(Internals&&...internals) { + (add_(std::forward(internals)), ...); + return *this; + } +} + +namespace meta_hpp +{ + template < typename Class > + template < typename Class2 > + inline void class_::add_(const class_& internal) { + auto info = internal.make_info(); + detail::merge_with(classes_, info.name(), info, &class_info::merge); + } + + template < typename Class > + template < typename... Args > + inline void class_::add_(const ctor_& internal) { + auto info = internal.template make_info(); + detail::merge_with(ctors_, info.type().id(), info, &ctor_info::merge); + } + + template < typename Class > + inline void class_::add_(const data_& internal) { + auto info = internal.make_info(); + detail::merge_with(datas_, info.name(), info, &data_info::merge); + } + + template < typename Class > + template < typename Enum > + inline void class_::add_(const enum_& internal) { + auto info = internal.make_info(); + detail::merge_with(enums_, info.name(), info, &enum_info::merge); + } + + template < typename Class > + template < typename Function > + inline void class_::add_(const function_& internal) { + auto info = internal.make_info(); + detail::merge_with(functions_, info.name(), info, &function_info::merge); + } + + template < typename Class > + template < typename Member > + inline void class_::add_(const member_& internal) { + auto info = internal.make_info(); + detail::merge_with(members_, info.name(), info, &member_info::merge); + } + + template < typename Class > + template < typename Method > + inline void class_::add_(const method_& internal) { + auto info = internal.make_info(); + detail::merge_with(methods_, info.name(), info, &method_info::merge); } } diff --git a/headers/meta.hpp/meta_registry/ctor_.hpp b/headers/meta.hpp/meta_registry/ctor_.hpp index 61cd8f2..7a32c38 100644 --- a/headers/meta.hpp/meta_registry/ctor_.hpp +++ b/headers/meta.hpp/meta_registry/ctor_.hpp @@ -6,10 +6,9 @@ #pragma once -#include "../meta_fwd.hpp" -#include "../meta_utilities.hpp" +#include "_registry_fwd.hpp" -#include "../meta_infos/ctor_info.hpp" +#include "data_.hpp" namespace meta_hpp { @@ -20,7 +19,14 @@ namespace meta_hpp template < typename Class > ctor_info make_info() const; + public: + template < typename... Internals > + ctor_& operator()(Internals&&...internals); private: + void add_(const data_& internal); + void add_(...) = delete; + private: + data_info_map datas_; }; } @@ -29,6 +35,24 @@ namespace meta_hpp template < typename... Args > template < typename Class > inline ctor_info ctor_::make_info() const { - return ctor_info{typename_arg, typename_arg}; + ctor_info info{typename_arg, typename_arg}; + info.state_->datas.insert(datas_.begin(), datas_.end()); + return info; + } + + template < typename... Args > + template < typename... Internals > + inline ctor_& ctor_::operator()(Internals&&...internals) { + (add_(std::forward(internals)), ...); + return *this; + } +} + +namespace meta_hpp +{ + template < typename... Args > + inline void ctor_::add_(const data_& internal) { + auto info = internal.make_info(); + detail::merge_with(datas_, info.name(), info, &data_info::merge); } } diff --git a/headers/meta.hpp/meta_registry/data_.hpp b/headers/meta.hpp/meta_registry/data_.hpp index f1d8a1e..5b6a9d3 100644 --- a/headers/meta.hpp/meta_registry/data_.hpp +++ b/headers/meta.hpp/meta_registry/data_.hpp @@ -6,10 +6,7 @@ #pragma once -#include "../meta_fwd.hpp" -#include "../meta_utilities.hpp" - -#include "../meta_infos/data_info.hpp" +#include "_registry_fwd.hpp" namespace meta_hpp { @@ -18,9 +15,16 @@ namespace meta_hpp explicit data_(std::string name, class value value); data_info make_info() const; + public: + template < typename... Internals > + data_& operator()(Internals&&...internals); + private: + void add_(const data_& internal); + void add_(...) = delete; private: std::string name_; class value value_; + data_info_map datas_; }; } @@ -31,6 +35,22 @@ namespace meta_hpp , value_{std::move(value)} {} inline data_info data_::make_info() const { - return data_info{name_, value_}; + data_info info{name_, value_}; + info.state_->datas.insert(datas_.begin(), datas_.end()); + return info; + } + + template < typename... Internals > + inline data_& data_::operator()(Internals&&...internals) { + (add_(std::forward(internals)), ...); + return *this; + } +} + +namespace meta_hpp +{ + inline void data_::add_(const data_& internal) { + auto info = internal.make_info(); + detail::merge_with(datas_, info.name(), info, &data_info::merge); } } diff --git a/headers/meta.hpp/meta_registry/enum_.hpp b/headers/meta.hpp/meta_registry/enum_.hpp index 263cbaf..9a9c80f 100644 --- a/headers/meta.hpp/meta_registry/enum_.hpp +++ b/headers/meta.hpp/meta_registry/enum_.hpp @@ -6,10 +6,9 @@ #pragma once -#include "../meta_fwd.hpp" -#include "../meta_utilities.hpp" +#include "_registry_fwd.hpp" -#include "../meta_infos/enum_info.hpp" +#include "data_.hpp" namespace meta_hpp { @@ -19,8 +18,15 @@ namespace meta_hpp explicit enum_(std::string name); enum_info make_info() const; + public: + template < typename... Internals > + enum_& operator()(Internals&&...internals); + private: + void add_(const data_& internal); + void add_(...) = delete; private: std::string name_; + data_info_map datas_; }; } @@ -32,6 +38,24 @@ namespace meta_hpp template < typename Enum > inline enum_info enum_::make_info() const { - return enum_info{name_}; + enum_info info{typename_arg, name_}; + info.state_->datas.insert(datas_.begin(), datas_.end()); + return info; + } + + template < typename Enum > + template < typename... Internals > + inline enum_& enum_::operator()(Internals&&...internals) { + (add_(std::forward(internals)), ...); + return *this; + } +} + +namespace meta_hpp +{ + template < typename Enum > + inline void enum_::add_(const data_& internal) { + auto info = internal.make_info(); + detail::merge_with(datas_, info.name(), info, &data_info::merge); } } diff --git a/headers/meta.hpp/meta_registry/evalue_.hpp b/headers/meta.hpp/meta_registry/evalue_.hpp index c94afad..a8705e1 100644 --- a/headers/meta.hpp/meta_registry/evalue_.hpp +++ b/headers/meta.hpp/meta_registry/evalue_.hpp @@ -6,10 +6,9 @@ #pragma once -#include "../meta_fwd.hpp" -#include "../meta_utilities.hpp" +#include "_registry_fwd.hpp" -#include "../meta_infos/evalue_info.hpp" +#include "data_.hpp" namespace meta_hpp { @@ -19,9 +18,16 @@ namespace meta_hpp explicit evalue_(std::string name, Enum value); evalue_info make_info() const; + public: + template < typename... Internals > + evalue_& operator()(Internals&&...internals); + private: + void add_(const data_& internal); + void add_(...) = delete; private: std::string name_; Enum value_; + data_info_map datas_; }; } @@ -34,6 +40,24 @@ namespace meta_hpp template < typename Enum > inline evalue_info evalue_::make_info() const { - return evalue_info{name_, value_}; + evalue_info info{name_, value_}; + info.state_->datas.insert(datas_.begin(), datas_.end()); + return info; + } + + template < typename Enum > + template < typename... Internals > + inline evalue_& evalue_::operator()(Internals&&...internals) { + (add_(std::forward(internals)), ...); + return *this; + } +} + +namespace meta_hpp +{ + template < typename Enum > + inline void evalue_::add_(const data_& internal) { + auto info = internal.make_info(); + detail::merge_with(datas_, info.name(), info, &data_info::merge); } } diff --git a/headers/meta.hpp/meta_registry/function_.hpp b/headers/meta.hpp/meta_registry/function_.hpp index af64730..924516d 100644 --- a/headers/meta.hpp/meta_registry/function_.hpp +++ b/headers/meta.hpp/meta_registry/function_.hpp @@ -6,10 +6,9 @@ #pragma once -#include "../meta_fwd.hpp" -#include "../meta_utilities.hpp" +#include "_registry_fwd.hpp" -#include "../meta_infos/function_info.hpp" +#include "data_.hpp" namespace meta_hpp { @@ -19,9 +18,16 @@ namespace meta_hpp explicit function_(std::string name, Function instance); function_info make_info() const; + public: + template < typename... Internals > + function_& operator()(Internals&&...internals); + private: + void add_(const data_& internal); + void add_(...) = delete; private: std::string name_; Function instance_; + data_info_map datas_; }; } @@ -34,6 +40,24 @@ namespace meta_hpp template < typename Function > inline function_info function_::make_info() const { - return function_info{name_, instance_}; + function_info info{name_, instance_}; + info.state_->datas.insert(datas_.begin(), datas_.end()); + return info; + } + + template < typename Function > + template < typename... Internals > + inline function_& function_::operator()(Internals&&...internals) { + (add_(std::forward(internals)), ...); + return *this; + } +} + +namespace meta_hpp +{ + template < typename Function > + inline void function_::add_(const data_& internal) { + auto info = internal.make_info(); + detail::merge_with(datas_, info.name(), info, &data_info::merge); } } diff --git a/headers/meta.hpp/meta_registry/member_.hpp b/headers/meta.hpp/meta_registry/member_.hpp index 348bdd2..44073cb 100644 --- a/headers/meta.hpp/meta_registry/member_.hpp +++ b/headers/meta.hpp/meta_registry/member_.hpp @@ -6,10 +6,9 @@ #pragma once -#include "../meta_fwd.hpp" -#include "../meta_utilities.hpp" +#include "_registry_fwd.hpp" -#include "../meta_infos/member_info.hpp" +#include "data_.hpp" namespace meta_hpp { @@ -19,9 +18,16 @@ namespace meta_hpp explicit member_(std::string name, Member instance); member_info make_info() const; + public: + template < typename... Internals > + member_& operator()(Internals&&...internals); + private: + void add_(const data_& internal); + void add_(...) = delete; private: std::string name_; Member instance_; + data_info_map datas_; }; } @@ -34,6 +40,24 @@ namespace meta_hpp template < typename Member > inline member_info member_::make_info() const { - return member_info{name_, instance_}; + member_info info{name_, instance_}; + info.state_->datas.insert(datas_.begin(), datas_.end()); + return info; + } + + template < typename Member > + template < typename... Internals > + inline member_& member_::operator()(Internals&&...internals) { + (add_(std::forward(internals)), ...); + return *this; + } +} + +namespace meta_hpp +{ + template < typename Member > + inline void member_::add_(const data_& internal) { + auto info = internal.make_info(); + detail::merge_with(datas_, info.name(), info, &data_info::merge); } } diff --git a/headers/meta.hpp/meta_registry/method_.hpp b/headers/meta.hpp/meta_registry/method_.hpp index c0f2079..911ffe6 100644 --- a/headers/meta.hpp/meta_registry/method_.hpp +++ b/headers/meta.hpp/meta_registry/method_.hpp @@ -6,10 +6,9 @@ #pragma once -#include "../meta_fwd.hpp" -#include "../meta_utilities.hpp" +#include "_registry_fwd.hpp" -#include "../meta_infos/method_info.hpp" +#include "data_.hpp" namespace meta_hpp { @@ -19,9 +18,16 @@ namespace meta_hpp explicit method_(std::string name, Method instance); method_info make_info() const; + public: + template < typename... Internals > + method_& operator()(Internals&&...internals); + private: + void add_(const data_& internal); + void add_(...) = delete; private: std::string name_; Method instance_; + data_info_map datas_; }; } @@ -34,6 +40,24 @@ namespace meta_hpp template < typename Method > inline method_info method_::make_info() const { - return method_info{name_, instance_}; + method_info info{name_, instance_}; + info.state_->datas.insert(datas_.begin(), datas_.end()); + return info; + } + + template < typename Method > + template < typename... Internals > + inline method_& method_::operator()(Internals&&...internals) { + (add_(std::forward(internals)), ...); + return *this; + } +} + +namespace meta_hpp +{ + template < typename Method > + inline void method_::add_(const data_& internal) { + auto info = internal.make_info(); + detail::merge_with(datas_, info.name(), info, &data_info::merge); } } diff --git a/headers/meta.hpp/meta_registry/namespace_.hpp b/headers/meta.hpp/meta_registry/namespace_.hpp index 15020ad..bd15745 100644 --- a/headers/meta.hpp/meta_registry/namespace_.hpp +++ b/headers/meta.hpp/meta_registry/namespace_.hpp @@ -6,10 +6,12 @@ #pragma once -#include "../meta_fwd.hpp" -#include "../meta_utilities.hpp" +#include "_registry_fwd.hpp" -#include "../meta_infos/namespace_info.hpp" +#include "class_.hpp" +#include "data_.hpp" +#include "enum_.hpp" +#include "function_.hpp" namespace meta_hpp { @@ -18,8 +20,26 @@ namespace meta_hpp explicit namespace_(std::string name); namespace_info make_info() const; + public: + template < typename... Internals > + namespace_& operator()(Internals&&...internals); + private: + template < typename Class > + void add_(const class_& internal); + void add_(const data_& internal); + template < typename Enum > + void add_(const enum_& internal); + template < typename Function > + void add_(const function_& internal); + void add_(const namespace_& internal); + void add_(...) = delete; private: std::string name_; + class_info_map classes_; + data_info_map datas_; + enum_info_map enums_; + function_info_map functions_; + namespace_info_map namespaces_; }; } @@ -29,6 +49,49 @@ namespace meta_hpp : name_{std::move(name)} {} inline namespace_info namespace_::make_info() const { - return namespace_info{name_}; + namespace_info info{name_}; + info.state_->classes.insert(classes_.begin(), classes_.end()); + info.state_->datas.insert(datas_.begin(), datas_.end()); + info.state_->enums.insert(enums_.begin(), enums_.end()); + info.state_->functions.insert(functions_.begin(), functions_.end()); + info.state_->namespaces.insert(namespaces_.begin(), namespaces_.end()); + return info; + } + + template < typename... Internals > + inline namespace_& namespace_::operator()(Internals&&...internals) { + (add_(std::forward(internals)), ...); + return *this; + } +} + +namespace meta_hpp +{ + template < typename Class > + inline void namespace_::add_(const class_& internal) { + auto info = internal.make_info(); + detail::merge_with(classes_, info.name(), info, &class_info::merge); + } + + inline void namespace_::add_(const data_& internal) { + auto info = internal.make_info(); + detail::merge_with(datas_, info.name(), info, &data_info::merge); + } + + template < typename Enum > + inline void namespace_::add_(const enum_& internal) { + auto info = internal.make_info(); + detail::merge_with(enums_, info.name(), info, &enum_info::merge); + } + + template < typename Function > + inline void namespace_::add_(const function_& internal) { + auto info = internal.make_info(); + detail::merge_with(functions_, info.name(), info, &function_info::merge); + } + + inline void namespace_::add_(const namespace_& internal) { + auto info = internal.make_info(); + detail::merge_with(namespaces_, info.name(), info, &namespace_info::merge); } } diff --git a/headers/meta.hpp/meta_types/arithmetic_type.hpp b/headers/meta.hpp/meta_types/arithmetic_type.hpp index cf7fb6d..0cf4d27 100644 --- a/headers/meta.hpp/meta_types/arithmetic_type.hpp +++ b/headers/meta.hpp/meta_types/arithmetic_type.hpp @@ -14,6 +14,8 @@ namespace meta_hpp public: template < typename T > explicit arithmetic_type(typename_arg_t) - : base_type{typename_arg} {} + : base_type{typename_arg} { + static_assert(std::is_arithmetic_v); + } }; } diff --git a/headers/meta.hpp/meta_types/array_type.hpp b/headers/meta.hpp/meta_types/array_type.hpp index 9b30ebc..f00083b 100644 --- a/headers/meta.hpp/meta_types/array_type.hpp +++ b/headers/meta.hpp/meta_types/array_type.hpp @@ -14,6 +14,8 @@ namespace meta_hpp public: template < typename T > explicit array_type(typename_arg_t) - : base_type{typename_arg} {} + : base_type{typename_arg} { + static_assert(std::is_array_v); + } }; } diff --git a/headers/meta.hpp/meta_types/class_type.hpp b/headers/meta.hpp/meta_types/class_type.hpp index 1d97540..e66dca1 100644 --- a/headers/meta.hpp/meta_types/class_type.hpp +++ b/headers/meta.hpp/meta_types/class_type.hpp @@ -14,6 +14,8 @@ namespace meta_hpp public: template < typename T > explicit class_type(typename_arg_t) - : base_type{typename_arg} {} + : base_type{typename_arg} { + static_assert(std::is_class_v); + } }; } diff --git a/headers/meta.hpp/meta_types/ctor_type.hpp b/headers/meta.hpp/meta_types/ctor_type.hpp index 5d17ca9..0c3df1a 100644 --- a/headers/meta.hpp/meta_types/ctor_type.hpp +++ b/headers/meta.hpp/meta_types/ctor_type.hpp @@ -14,6 +14,9 @@ namespace meta_hpp public: template < typename Class, typename... Args > explicit ctor_type(typename_arg_t, typename_arg_t) - : base_type{typename_arg} {} + : base_type{typename_arg} { + static_assert(std::is_class_v); + static_assert(std::is_constructible_v); + } }; } diff --git a/headers/meta.hpp/meta_types/enum_type.hpp b/headers/meta.hpp/meta_types/enum_type.hpp index 158bd3a..9bfc3b7 100644 --- a/headers/meta.hpp/meta_types/enum_type.hpp +++ b/headers/meta.hpp/meta_types/enum_type.hpp @@ -14,6 +14,8 @@ namespace meta_hpp public: template < typename T > explicit enum_type(typename_arg_t) - : base_type{typename_arg} {} + : base_type{typename_arg} { + static_assert(std::is_enum_v); + } }; } diff --git a/headers/meta.hpp/meta_types/function_type.hpp b/headers/meta.hpp/meta_types/function_type.hpp index 59a4868..13bc58c 100644 --- a/headers/meta.hpp/meta_types/function_type.hpp +++ b/headers/meta.hpp/meta_types/function_type.hpp @@ -14,6 +14,9 @@ namespace meta_hpp public: template < typename T > explicit function_type(typename_arg_t) - : base_type{typename_arg} {} + : base_type{typename_arg} { + static_assert(std::is_pointer_v); + static_assert(std::is_function_v>); + } }; } diff --git a/headers/meta.hpp/meta_types/member_type.hpp b/headers/meta.hpp/meta_types/member_type.hpp index 5186541..3cd3b50 100644 --- a/headers/meta.hpp/meta_types/member_type.hpp +++ b/headers/meta.hpp/meta_types/member_type.hpp @@ -14,6 +14,8 @@ namespace meta_hpp public: template < typename T > explicit member_type(typename_arg_t) - : base_type{typename_arg} {} + : base_type{typename_arg} { + static_assert(std::is_member_object_pointer_v); + } }; } diff --git a/headers/meta.hpp/meta_types/method_type.hpp b/headers/meta.hpp/meta_types/method_type.hpp index 89bb9d5..2a16b72 100644 --- a/headers/meta.hpp/meta_types/method_type.hpp +++ b/headers/meta.hpp/meta_types/method_type.hpp @@ -14,6 +14,8 @@ namespace meta_hpp public: template < typename T > explicit method_type(typename_arg_t) - : base_type{typename_arg} {} + : base_type{typename_arg} { + static_assert(std::is_member_function_pointer_v); + } }; } diff --git a/headers/meta.hpp/meta_types/pointer_type.hpp b/headers/meta.hpp/meta_types/pointer_type.hpp index 3c3ca0d..81d0734 100644 --- a/headers/meta.hpp/meta_types/pointer_type.hpp +++ b/headers/meta.hpp/meta_types/pointer_type.hpp @@ -14,6 +14,8 @@ namespace meta_hpp public: template < typename T > explicit pointer_type(typename_arg_t) - : base_type{typename_arg} {} + : base_type{typename_arg} { + static_assert(std::is_pointer_v); + } }; } diff --git a/headers/meta.hpp/meta_types/reference_type.hpp b/headers/meta.hpp/meta_types/reference_type.hpp index 267b9a9..cc9324b 100644 --- a/headers/meta.hpp/meta_types/reference_type.hpp +++ b/headers/meta.hpp/meta_types/reference_type.hpp @@ -14,6 +14,8 @@ namespace meta_hpp public: template < typename T > explicit reference_type(typename_arg_t) - : base_type{typename_arg} {} + : base_type{typename_arg} { + static_assert(std::is_reference_v); + } }; } diff --git a/headers/meta.hpp/meta_types/void_type.hpp b/headers/meta.hpp/meta_types/void_type.hpp index e87b794..e8b352c 100644 --- a/headers/meta.hpp/meta_types/void_type.hpp +++ b/headers/meta.hpp/meta_types/void_type.hpp @@ -14,6 +14,8 @@ namespace meta_hpp public: template < typename T > explicit void_type(typename_arg_t) - : base_type{typename_arg} {} + : base_type{typename_arg} { + static_assert(std::is_void_v); + } }; } From 952bd4b214882f9acc75c7d23c7f26401eb35495 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Tue, 3 Aug 2021 12:01:07 +0700 Subject: [PATCH 074/233] get internals from info --- headers/meta.hpp/meta_infos/class_info.hpp | 31 ++++++++ headers/meta.hpp/meta_infos/ctor_info.hpp | 6 ++ headers/meta.hpp/meta_infos/data_info.hpp | 6 ++ headers/meta.hpp/meta_infos/enum_info.hpp | 11 +++ headers/meta.hpp/meta_infos/evalue_info.hpp | 6 ++ headers/meta.hpp/meta_infos/function_info.hpp | 6 ++ headers/meta.hpp/meta_infos/member_info.hpp | 6 ++ headers/meta.hpp/meta_infos/method_info.hpp | 6 ++ .../meta.hpp/meta_infos/namespace_info.hpp | 26 +++++++ headers/meta.hpp/meta_registry.hpp | 48 ++++++------- headers/meta.hpp/meta_utilities/value.hpp | 23 ++++++ untests/features/infos/function_tests.cpp | 12 ++-- untests/features/registry/_registry_fwd.hpp | 9 +++ untests/features/registry/registry_tests.cpp | 70 +++++++++++++++++++ 14 files changed, 236 insertions(+), 30 deletions(-) create mode 100644 untests/features/registry/_registry_fwd.hpp create mode 100644 untests/features/registry/registry_tests.cpp diff --git a/headers/meta.hpp/meta_infos/class_info.hpp b/headers/meta.hpp/meta_infos/class_info.hpp index 2095cf7..6ffc3a2 100644 --- a/headers/meta.hpp/meta_infos/class_info.hpp +++ b/headers/meta.hpp/meta_infos/class_info.hpp @@ -50,6 +50,13 @@ namespace meta_hpp template < typename F > void each_method(F&& f) const; + + class_info get_class_by_name(std::string_view name) const noexcept; + data_info get_data_by_name(std::string_view name) const noexcept; + enum_info get_enum_by_name(std::string_view name) const noexcept; + function_info get_function_by_name(std::string_view name) const noexcept; + member_info get_member_by_name(std::string_view name) const noexcept; + method_info get_method_by_name(std::string_view name) const noexcept; private: template < typename Class > friend class class_; @@ -157,6 +164,30 @@ namespace meta_hpp std::invoke(f, name_info.second); } } + + inline class_info class_info::get_class_by_name(std::string_view name) const noexcept { + return detail::find_or_default(state_->classes, name); + } + + inline data_info class_info::get_data_by_name(std::string_view name) const noexcept { + return detail::find_or_default(state_->datas, name); + } + + inline enum_info class_info::get_enum_by_name(std::string_view name) const noexcept { + return detail::find_or_default(state_->enums, name); + } + + inline function_info class_info::get_function_by_name(std::string_view name) const noexcept { + return detail::find_or_default(state_->functions, name); + } + + inline member_info class_info::get_member_by_name(std::string_view name) const noexcept { + return detail::find_or_default(state_->members, name); + } + + inline method_info class_info::get_method_by_name(std::string_view name) const noexcept { + return detail::find_or_default(state_->methods, name); + } } namespace meta_hpp diff --git a/headers/meta.hpp/meta_infos/ctor_info.hpp b/headers/meta.hpp/meta_infos/ctor_info.hpp index 464d28c..970840c 100644 --- a/headers/meta.hpp/meta_infos/ctor_info.hpp +++ b/headers/meta.hpp/meta_infos/ctor_info.hpp @@ -26,6 +26,8 @@ namespace meta_hpp template < typename F > void each_data(F&& f) const; + + data_info get_data_by_name(std::string_view name) const noexcept; private: template < typename... Args > friend class ctor_; @@ -74,6 +76,10 @@ namespace meta_hpp std::invoke(f, name_info.second); } } + + inline data_info ctor_info::get_data_by_name(std::string_view name) const noexcept { + return detail::find_or_default(state_->datas, name); + } } namespace meta_hpp diff --git a/headers/meta.hpp/meta_infos/data_info.hpp b/headers/meta.hpp/meta_infos/data_info.hpp index 560d31c..e6554c8 100644 --- a/headers/meta.hpp/meta_infos/data_info.hpp +++ b/headers/meta.hpp/meta_infos/data_info.hpp @@ -25,6 +25,8 @@ namespace meta_hpp template < typename F > void each_data(F&& f) const; + + data_info get_data_by_name(std::string_view name) const noexcept; private: friend class data_; @@ -77,6 +79,10 @@ namespace meta_hpp std::invoke(f, name_info.second); } } + + inline data_info data_info::get_data_by_name(std::string_view name) const noexcept { + return detail::find_or_default(state_->datas, name); + } } namespace meta_hpp diff --git a/headers/meta.hpp/meta_infos/enum_info.hpp b/headers/meta.hpp/meta_infos/enum_info.hpp index 9b13e68..450f4ee 100644 --- a/headers/meta.hpp/meta_infos/enum_info.hpp +++ b/headers/meta.hpp/meta_infos/enum_info.hpp @@ -31,6 +31,9 @@ namespace meta_hpp template < typename F > void each_evalue(F&& f) const; + + data_info get_data_by_name(std::string_view name) const noexcept; + evalue_info get_evalue_by_name(std::string_view name) const noexcept; private: template < typename Enum > friend class enum_; @@ -93,6 +96,14 @@ namespace meta_hpp std::invoke(f, name_info.second); } } + + inline data_info enum_info::get_data_by_name(std::string_view name) const noexcept { + return detail::find_or_default(state_->datas, name); + } + + inline evalue_info enum_info::get_evalue_by_name(std::string_view name) const noexcept { + return detail::find_or_default(state_->evalues, name); + } } namespace meta_hpp diff --git a/headers/meta.hpp/meta_infos/evalue_info.hpp b/headers/meta.hpp/meta_infos/evalue_info.hpp index a1c988b..7bb90a8 100644 --- a/headers/meta.hpp/meta_infos/evalue_info.hpp +++ b/headers/meta.hpp/meta_infos/evalue_info.hpp @@ -27,6 +27,8 @@ namespace meta_hpp template < typename F > void each_data(F&& f) const; + + data_info get_data_by_name(std::string_view name) const noexcept; private: template < typename Enum > friend class evalue_; @@ -80,6 +82,10 @@ namespace meta_hpp std::invoke(f, name_info.second); } } + + inline data_info evalue_info::get_data_by_name(std::string_view name) const noexcept { + return detail::find_or_default(state_->datas, name); + } } namespace meta_hpp diff --git a/headers/meta.hpp/meta_infos/function_info.hpp b/headers/meta.hpp/meta_infos/function_info.hpp index d4efcb7..ebfb2c5 100644 --- a/headers/meta.hpp/meta_infos/function_info.hpp +++ b/headers/meta.hpp/meta_infos/function_info.hpp @@ -27,6 +27,8 @@ namespace meta_hpp template < typename F > void each_data(F&& f) const; + + data_info get_data_by_name(std::string_view name) const noexcept; private: template < typename Function > friend class function_; @@ -80,6 +82,10 @@ namespace meta_hpp std::invoke(f, name_info.second); } } + + inline data_info function_info::get_data_by_name(std::string_view name) const noexcept { + return detail::find_or_default(state_->datas, name); + } } namespace meta_hpp diff --git a/headers/meta.hpp/meta_infos/member_info.hpp b/headers/meta.hpp/meta_infos/member_info.hpp index ab5b147..f23841e 100644 --- a/headers/meta.hpp/meta_infos/member_info.hpp +++ b/headers/meta.hpp/meta_infos/member_info.hpp @@ -27,6 +27,8 @@ namespace meta_hpp template < typename F > void each_data(F&& f) const; + + data_info get_data_by_name(std::string_view name) const noexcept; private: template < typename Member > friend class member_; @@ -80,6 +82,10 @@ namespace meta_hpp std::invoke(f, name_info.second); } } + + inline data_info member_info::get_data_by_name(std::string_view name) const noexcept { + return detail::find_or_default(state_->datas, name); + } } namespace meta_hpp diff --git a/headers/meta.hpp/meta_infos/method_info.hpp b/headers/meta.hpp/meta_infos/method_info.hpp index 0d99b9d..50d14b5 100644 --- a/headers/meta.hpp/meta_infos/method_info.hpp +++ b/headers/meta.hpp/meta_infos/method_info.hpp @@ -27,6 +27,8 @@ namespace meta_hpp template < typename F > void each_data(F&& f) const; + + data_info get_data_by_name(std::string_view name) const noexcept; private: template < typename Method > friend class method_; @@ -80,6 +82,10 @@ namespace meta_hpp std::invoke(f, name_info.second); } } + + inline data_info method_info::get_data_by_name(std::string_view name) const noexcept { + return detail::find_or_default(state_->datas, name); + } } namespace meta_hpp diff --git a/headers/meta.hpp/meta_infos/namespace_info.hpp b/headers/meta.hpp/meta_infos/namespace_info.hpp index 6f7638f..0cb2ef5 100644 --- a/headers/meta.hpp/meta_infos/namespace_info.hpp +++ b/headers/meta.hpp/meta_infos/namespace_info.hpp @@ -41,6 +41,12 @@ namespace meta_hpp template < typename F > void each_namespace(F&& f) const; + + class_info get_class_by_name(std::string_view name) const noexcept; + data_info get_data_by_name(std::string_view name) const noexcept; + enum_info get_enum_by_name(std::string_view name) const noexcept; + function_info get_function_by_name(std::string_view name) const noexcept; + namespace_info get_namespace_by_name(std::string_view name) const noexcept; private: friend class namespace_; @@ -124,6 +130,26 @@ namespace meta_hpp std::invoke(f, name_info.second); } } + + inline class_info namespace_info::get_class_by_name(std::string_view name) const noexcept { + return detail::find_or_default(state_->classes, name); + } + + inline data_info namespace_info::get_data_by_name(std::string_view name) const noexcept { + return detail::find_or_default(state_->datas, name); + } + + inline enum_info namespace_info::get_enum_by_name(std::string_view name) const noexcept { + return detail::find_or_default(state_->enums, name); + } + + inline function_info namespace_info::get_function_by_name(std::string_view name) const noexcept { + return detail::find_or_default(state_->functions, name); + } + + inline namespace_info namespace_info::get_namespace_by_name(std::string_view name) const noexcept { + return detail::find_or_default(state_->namespaces, name); + } } namespace meta_hpp diff --git a/headers/meta.hpp/meta_registry.hpp b/headers/meta.hpp/meta_registry.hpp index 4d32ec6..dafe434 100644 --- a/headers/meta.hpp/meta_registry.hpp +++ b/headers/meta.hpp/meta_registry.hpp @@ -24,14 +24,14 @@ namespace meta_hpp public: registry() = default; - class_info get_class_by_name(std::string_view name) const noexcept; - data_info get_data_by_name(std::string_view name) const noexcept; - enum_info get_enum_by_name(std::string_view name) const noexcept; - evalue_info get_evalue_by_name(std::string_view name) const noexcept; - function_info get_function_by_name(std::string_view name) const noexcept; - member_info get_member_by_name(std::string_view name) const noexcept; - method_info get_method_by_name(std::string_view name) const noexcept; - namespace_info get_namespace_by_name(std::string_view name) const noexcept; + class_info get_class_by_path(std::string_view path) const noexcept; + data_info get_data_by_path(std::string_view path) const noexcept; + enum_info get_enum_by_path(std::string_view path) const noexcept; + evalue_info get_evalue_by_path(std::string_view path) const noexcept; + function_info get_function_by_path(std::string_view path) const noexcept; + member_info get_member_by_path(std::string_view path) const noexcept; + method_info get_method_by_path(std::string_view path) const noexcept; + namespace_info get_namespace_by_path(std::string_view path) const noexcept; public: template < typename... Internals > registry& operator()(Internals&&... internals); @@ -75,36 +75,36 @@ namespace meta_hpp namespace meta_hpp { - inline class_info registry::get_class_by_name(std::string_view name) const noexcept { - return detail::find_or_default(classes_, name); + inline class_info registry::get_class_by_path(std::string_view path) const noexcept { + return detail::find_or_default(classes_, path); } - inline data_info registry::get_data_by_name(std::string_view name) const noexcept { - return detail::find_or_default(datas_, name); + inline data_info registry::get_data_by_path(std::string_view path) const noexcept { + return detail::find_or_default(datas_, path); } - inline enum_info registry::get_enum_by_name(std::string_view name) const noexcept { - return detail::find_or_default(enums_, name); + inline enum_info registry::get_enum_by_path(std::string_view path) const noexcept { + return detail::find_or_default(enums_, path); } - inline evalue_info registry::get_evalue_by_name(std::string_view name) const noexcept { - return detail::find_or_default(evalues_, name); + inline evalue_info registry::get_evalue_by_path(std::string_view path) const noexcept { + return detail::find_or_default(evalues_, path); } - inline function_info registry::get_function_by_name(std::string_view name) const noexcept { - return detail::find_or_default(functions_, name); + inline function_info registry::get_function_by_path(std::string_view path) const noexcept { + return detail::find_or_default(functions_, path); } - inline member_info registry::get_member_by_name(std::string_view name) const noexcept { - return detail::find_or_default(members_, name); + inline member_info registry::get_member_by_path(std::string_view path) const noexcept { + return detail::find_or_default(members_, path); } - inline method_info registry::get_method_by_name(std::string_view name) const noexcept { - return detail::find_or_default(methods_, name); + inline method_info registry::get_method_by_path(std::string_view path) const noexcept { + return detail::find_or_default(methods_, path); } - inline namespace_info registry::get_namespace_by_name(std::string_view name) const noexcept { - return detail::find_or_default(namespaces_, name); + inline namespace_info registry::get_namespace_by_path(std::string_view path) const noexcept { + return detail::find_or_default(namespaces_, path); } } diff --git a/headers/meta.hpp/meta_utilities/value.hpp b/headers/meta.hpp/meta_utilities/value.hpp index 461fa3f..1926e55 100644 --- a/headers/meta.hpp/meta_utilities/value.hpp +++ b/headers/meta.hpp/meta_utilities/value.hpp @@ -19,5 +19,28 @@ namespace meta_hpp value(const value&) = default; value& operator=(const value&) = default; + + template < typename T, typename Tp = std::decay_t + , std::enable_if_t, int> = 0 > + value(T&& val) + : raw_{std::forward(val)} {} + + template < typename T, typename Tp = std::decay_t + , std::enable_if_t, int> = 0 > + value& operator=(T&& val) { + value{std::forward(val)}.swap(*this); + return *this; + } + + void swap(value& other) noexcept { + using std::swap; + swap(raw_, other.raw_); + } + private: + std::any raw_{}; }; + + inline void swap(value& l, value& r) noexcept { + l.swap(r); + } } diff --git a/untests/features/infos/function_tests.cpp b/untests/features/infos/function_tests.cpp index c7af985..6b67cb2 100644 --- a/untests/features/infos/function_tests.cpp +++ b/untests/features/infos/function_tests.cpp @@ -37,12 +37,12 @@ TEST_CASE("features/infos/function") { function_{"arg_crref", &arg_crref} ); - const function_info arg_copy_info = db.get_function_by_name("arg_copy"); - const function_info arg_ref_info = db.get_function_by_name("arg_ref"); - const function_info arg_cref_info = db.get_function_by_name("arg_cref"); - const function_info arg_rref_info = db.get_function_by_name("arg_rref"); - const function_info arg_crref_info = db.get_function_by_name("arg_crref"); - const function_info arg_not_exist_info = db.get_function_by_name("arg_not_exist"); + const function_info arg_copy_info = db.get_function_by_path("arg_copy"); + const function_info arg_ref_info = db.get_function_by_path("arg_ref"); + const function_info arg_cref_info = db.get_function_by_path("arg_cref"); + const function_info arg_rref_info = db.get_function_by_path("arg_rref"); + const function_info arg_crref_info = db.get_function_by_path("arg_crref"); + const function_info arg_not_exist_info = db.get_function_by_path("arg_not_exist"); REQUIRE(arg_copy_info); REQUIRE(arg_ref_info); diff --git a/untests/features/registry/_registry_fwd.hpp b/untests/features/registry/_registry_fwd.hpp new file mode 100644 index 0000000..b826cce --- /dev/null +++ b/untests/features/registry/_registry_fwd.hpp @@ -0,0 +1,9 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../../meta_tests.hpp" diff --git a/untests/features/registry/registry_tests.cpp b/untests/features/registry/registry_tests.cpp new file mode 100644 index 0000000..c72b2e1 --- /dev/null +++ b/untests/features/registry/registry_tests.cpp @@ -0,0 +1,70 @@ +/******************************************************************************* + * 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 "_registry_fwd.hpp" + +namespace +{ + using namespace meta_hpp; + using namespace std::string_literals; +} + +namespace +{ + struct ivec2 { + int x{}; + int y{}; + + [[maybe_unused]] ivec2() = default; + [[maybe_unused]] explicit ivec2(int v): x{v}, y{v} {} + [[maybe_unused]] ivec2(int x, int y): x{x}, y{y} {} + }; +} + +TEST_CASE("features/registry/registry") { + auto db = registry{}( + namespace_{"vmath"}(data_{"info", "vmath namespace"}, + class_{"ivec2"}(data_{"info", "ivec2 class"}, + ctor_<>{}, + ctor_{}, + ctor_{}, + member_{"x", &ivec2::x}(data_{"info", "x-coord"}), + member_{"y", &ivec2::y}(data_{"info", "y-coord"}) + ) + ) + ); + + { + const namespace_info vmath_info = db.get_namespace_by_path("vmath"); + REQUIRE(vmath_info); + CHECK(vmath_info.name() == "vmath"); + CHECK(vmath_info.get_data_by_name("info")); + + const class_info ivec2_info = vmath_info.get_class_by_name("ivec2"); + REQUIRE(ivec2_info); + CHECK(ivec2_info.name() == "ivec2"); + CHECK(ivec2_info.get_data_by_name("info")); + + const member_info ivec2_x_info = ivec2_info.get_member_by_name("x"); + REQUIRE(ivec2_x_info); + CHECK(ivec2_x_info.name() == "x"); + CHECK(ivec2_x_info.get_data_by_name("info")); + } + + { + const class_info ivec2_info = db.get_class_by_path("vmath::ivec2"); + REQUIRE(ivec2_info); + CHECK(ivec2_info.name() == "ivec2"); + + const member_info ivec2_x_info = db.get_member_by_path("vmath::ivec2::x"); + REQUIRE(ivec2_x_info); + CHECK(ivec2_x_info.name() == "x"); + + const data_info ivec2_x_data_info = db.get_data_by_path("vmath::ivec2::x::info"); + REQUIRE(ivec2_x_data_info); + CHECK(ivec2_x_data_info.name() == "info"); + } +} From 2adf5154db56040f11d62a072e3f2ad93116778b Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Tue, 3 Aug 2021 22:03:12 +0700 Subject: [PATCH 075/233] dummy arg file --- headers/meta.hpp/meta_fwd.hpp | 6 +++++ .../meta_utilities/_utilities_fwd.hpp | 9 ++++++++ headers/meta.hpp/meta_utilities/arg.hpp | 23 +++++++++++++++++++ untests/features/utilities/_utilities_fwd.hpp | 9 ++++++++ untests/features/utilities/arg_tests.cpp | 14 +++++++++++ untests/features/utilities/value_tests.cpp | 14 +++++++++++ 6 files changed, 75 insertions(+) create mode 100644 headers/meta.hpp/meta_utilities/_utilities_fwd.hpp create mode 100644 headers/meta.hpp/meta_utilities/arg.hpp create mode 100644 untests/features/utilities/_utilities_fwd.hpp create mode 100644 untests/features/utilities/arg_tests.cpp create mode 100644 untests/features/utilities/value_tests.cpp diff --git a/headers/meta.hpp/meta_fwd.hpp b/headers/meta.hpp/meta_fwd.hpp index 4e57006..26e9973 100644 --- a/headers/meta.hpp/meta_fwd.hpp +++ b/headers/meta.hpp/meta_fwd.hpp @@ -71,6 +71,12 @@ namespace meta_hpp class void_type; } +namespace meta_hpp +{ + class arg; + class value; +} + namespace meta_hpp { template < typename K, typename V > diff --git a/headers/meta.hpp/meta_utilities/_utilities_fwd.hpp b/headers/meta.hpp/meta_utilities/_utilities_fwd.hpp new file mode 100644 index 0000000..c4f416c --- /dev/null +++ b/headers/meta.hpp/meta_utilities/_utilities_fwd.hpp @@ -0,0 +1,9 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_fwd.hpp" diff --git a/headers/meta.hpp/meta_utilities/arg.hpp b/headers/meta.hpp/meta_utilities/arg.hpp new file mode 100644 index 0000000..a581f49 --- /dev/null +++ b/headers/meta.hpp/meta_utilities/arg.hpp @@ -0,0 +1,23 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_fwd.hpp" + +namespace meta_hpp +{ + class arg final { + public: + arg() = delete; + + arg(arg&&) = delete; + arg& operator=(arg&&) = delete; + + arg(const arg&) = delete; + arg& operator=(const arg&) = delete; + }; +} diff --git a/untests/features/utilities/_utilities_fwd.hpp b/untests/features/utilities/_utilities_fwd.hpp new file mode 100644 index 0000000..b826cce --- /dev/null +++ b/untests/features/utilities/_utilities_fwd.hpp @@ -0,0 +1,9 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../../meta_tests.hpp" diff --git a/untests/features/utilities/arg_tests.cpp b/untests/features/utilities/arg_tests.cpp new file mode 100644 index 0000000..ed05cf2 --- /dev/null +++ b/untests/features/utilities/arg_tests.cpp @@ -0,0 +1,14 @@ +/******************************************************************************* + * 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 "_utilities_fwd.hpp" + +namespace +{ +} + +TEST_CASE("features/utilities/arg") { +} diff --git a/untests/features/utilities/value_tests.cpp b/untests/features/utilities/value_tests.cpp new file mode 100644 index 0000000..6613699 --- /dev/null +++ b/untests/features/utilities/value_tests.cpp @@ -0,0 +1,14 @@ +/******************************************************************************* + * 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 "_utilities_fwd.hpp" + +namespace +{ +} + +TEST_CASE("features/utilities/value") { +} From 5eb8e4aed34e895a5dd5f658a00043aad207469c Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Wed, 4 Aug 2021 22:13:38 +0700 Subject: [PATCH 076/233] rename test files --- .../{class_tests.cpp => class_info_tests.cpp} | 0 .../{ctor_tests.cpp => ctor_info_tests.cpp} | 0 .../{data_tests.cpp => data_info_tests.cpp} | 0 .../{enum_tests.cpp => enum_info_tests.cpp} | 0 ...evalue_tests.cpp => evalue_info_tests.cpp} | 0 .../features/infos/function_info_tests.cpp | 14 +++++ untests/features/infos/function_tests.cpp | 53 ------------------- ...member_tests.cpp => member_info_tests.cpp} | 0 ...method_tests.cpp => method_info_tests.cpp} | 0 ...ace_tests.cpp => namespace_info_tests.cpp} | 0 ..._tests.cpp => arithmetic_traits_tests.cpp} | 0 ...array_tests.cpp => array_traits_tests.cpp} | 0 ...class_tests.cpp => class_traits_tests.cpp} | 0 .../{ctor_tests.cpp => ctor_traits_tests.cpp} | 0 .../{enum_tests.cpp => enum_traits_tests.cpp} | 0 ...on_tests.cpp => function_traits_tests.cpp} | 0 ...mber_tests.cpp => member_traits_tests.cpp} | 0 ...thod_tests.cpp => method_traits_tests.cpp} | 0 ...ter_tests.cpp => pointer_traits_tests.cpp} | 0 ...e_tests.cpp => reference_traits_tests.cpp} | 0 .../{void_tests.cpp => void_traits_tests.cpp} | 0 ...ic_tests.cpp => arithmetic_type_tests.cpp} | 0 .../{array_tests.cpp => array_type_tests.cpp} | 0 .../{class_tests.cpp => class_type_tests.cpp} | 0 .../{ctor_tests.cpp => ctor_type_tests.cpp} | 0 .../{enum_tests.cpp => enum_type_tests.cpp} | 0 ...tion_tests.cpp => function_type_tests.cpp} | 0 ...member_tests.cpp => member_type_tests.cpp} | 0 ...method_tests.cpp => method_type_tests.cpp} | 0 ...inter_tests.cpp => pointer_type_tests.cpp} | 0 ...nce_tests.cpp => reference_type_tests.cpp} | 0 .../{void_tests.cpp => void_type_tests.cpp} | 0 32 files changed, 14 insertions(+), 53 deletions(-) rename untests/features/infos/{class_tests.cpp => class_info_tests.cpp} (100%) rename untests/features/infos/{ctor_tests.cpp => ctor_info_tests.cpp} (100%) rename untests/features/infos/{data_tests.cpp => data_info_tests.cpp} (100%) rename untests/features/infos/{enum_tests.cpp => enum_info_tests.cpp} (100%) rename untests/features/infos/{evalue_tests.cpp => evalue_info_tests.cpp} (100%) create mode 100644 untests/features/infos/function_info_tests.cpp delete mode 100644 untests/features/infos/function_tests.cpp rename untests/features/infos/{member_tests.cpp => member_info_tests.cpp} (100%) rename untests/features/infos/{method_tests.cpp => method_info_tests.cpp} (100%) rename untests/features/infos/{namespace_tests.cpp => namespace_info_tests.cpp} (100%) rename untests/features/traits/{arithmetic_tests.cpp => arithmetic_traits_tests.cpp} (100%) rename untests/features/traits/{array_tests.cpp => array_traits_tests.cpp} (100%) rename untests/features/traits/{class_tests.cpp => class_traits_tests.cpp} (100%) rename untests/features/traits/{ctor_tests.cpp => ctor_traits_tests.cpp} (100%) rename untests/features/traits/{enum_tests.cpp => enum_traits_tests.cpp} (100%) rename untests/features/traits/{function_tests.cpp => function_traits_tests.cpp} (100%) rename untests/features/traits/{member_tests.cpp => member_traits_tests.cpp} (100%) rename untests/features/traits/{method_tests.cpp => method_traits_tests.cpp} (100%) rename untests/features/traits/{pointer_tests.cpp => pointer_traits_tests.cpp} (100%) rename untests/features/traits/{reference_tests.cpp => reference_traits_tests.cpp} (100%) rename untests/features/traits/{void_tests.cpp => void_traits_tests.cpp} (100%) rename untests/features/types/{arithmetic_tests.cpp => arithmetic_type_tests.cpp} (100%) rename untests/features/types/{array_tests.cpp => array_type_tests.cpp} (100%) rename untests/features/types/{class_tests.cpp => class_type_tests.cpp} (100%) rename untests/features/types/{ctor_tests.cpp => ctor_type_tests.cpp} (100%) rename untests/features/types/{enum_tests.cpp => enum_type_tests.cpp} (100%) rename untests/features/types/{function_tests.cpp => function_type_tests.cpp} (100%) rename untests/features/types/{member_tests.cpp => member_type_tests.cpp} (100%) rename untests/features/types/{method_tests.cpp => method_type_tests.cpp} (100%) rename untests/features/types/{pointer_tests.cpp => pointer_type_tests.cpp} (100%) rename untests/features/types/{reference_tests.cpp => reference_type_tests.cpp} (100%) rename untests/features/types/{void_tests.cpp => void_type_tests.cpp} (100%) diff --git a/untests/features/infos/class_tests.cpp b/untests/features/infos/class_info_tests.cpp similarity index 100% rename from untests/features/infos/class_tests.cpp rename to untests/features/infos/class_info_tests.cpp diff --git a/untests/features/infos/ctor_tests.cpp b/untests/features/infos/ctor_info_tests.cpp similarity index 100% rename from untests/features/infos/ctor_tests.cpp rename to untests/features/infos/ctor_info_tests.cpp diff --git a/untests/features/infos/data_tests.cpp b/untests/features/infos/data_info_tests.cpp similarity index 100% rename from untests/features/infos/data_tests.cpp rename to untests/features/infos/data_info_tests.cpp diff --git a/untests/features/infos/enum_tests.cpp b/untests/features/infos/enum_info_tests.cpp similarity index 100% rename from untests/features/infos/enum_tests.cpp rename to untests/features/infos/enum_info_tests.cpp diff --git a/untests/features/infos/evalue_tests.cpp b/untests/features/infos/evalue_info_tests.cpp similarity index 100% rename from untests/features/infos/evalue_tests.cpp rename to untests/features/infos/evalue_info_tests.cpp diff --git a/untests/features/infos/function_info_tests.cpp b/untests/features/infos/function_info_tests.cpp new file mode 100644 index 0000000..83baf40 --- /dev/null +++ b/untests/features/infos/function_info_tests.cpp @@ -0,0 +1,14 @@ +/******************************************************************************* + * 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 "_infos_fwd.hpp" + +namespace +{ +} + +TEST_CASE("features/infos/function") { +} diff --git a/untests/features/infos/function_tests.cpp b/untests/features/infos/function_tests.cpp deleted file mode 100644 index 6b67cb2..0000000 --- a/untests/features/infos/function_tests.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/******************************************************************************* - * 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 "_infos_fwd.hpp" - -namespace -{ - using namespace meta_hpp; - using namespace std::string_literals; -} - -namespace -{ - struct ivec2 { - int x{}; - int y{}; - }; - - void arg_copy(ivec2) {} - - void arg_ref(ivec2&) {} - void arg_cref(const ivec2&) {} - - void arg_rref(ivec2&&) {} - void arg_crref(const ivec2&&) {} -} - -TEST_CASE("features/infos/function") { - auto db = registry{}( - function_{"arg_copy", &arg_copy}, - function_{"arg_ref", &arg_ref}, - function_{"arg_cref", &arg_cref}, - function_{"arg_rref", &arg_rref}, - function_{"arg_crref", &arg_crref} - ); - - const function_info arg_copy_info = db.get_function_by_path("arg_copy"); - const function_info arg_ref_info = db.get_function_by_path("arg_ref"); - const function_info arg_cref_info = db.get_function_by_path("arg_cref"); - const function_info arg_rref_info = db.get_function_by_path("arg_rref"); - const function_info arg_crref_info = db.get_function_by_path("arg_crref"); - const function_info arg_not_exist_info = db.get_function_by_path("arg_not_exist"); - - REQUIRE(arg_copy_info); - REQUIRE(arg_ref_info); - REQUIRE(arg_cref_info); - REQUIRE(arg_rref_info); - REQUIRE(arg_crref_info); - REQUIRE_FALSE(arg_not_exist_info); -} diff --git a/untests/features/infos/member_tests.cpp b/untests/features/infos/member_info_tests.cpp similarity index 100% rename from untests/features/infos/member_tests.cpp rename to untests/features/infos/member_info_tests.cpp diff --git a/untests/features/infos/method_tests.cpp b/untests/features/infos/method_info_tests.cpp similarity index 100% rename from untests/features/infos/method_tests.cpp rename to untests/features/infos/method_info_tests.cpp diff --git a/untests/features/infos/namespace_tests.cpp b/untests/features/infos/namespace_info_tests.cpp similarity index 100% rename from untests/features/infos/namespace_tests.cpp rename to untests/features/infos/namespace_info_tests.cpp diff --git a/untests/features/traits/arithmetic_tests.cpp b/untests/features/traits/arithmetic_traits_tests.cpp similarity index 100% rename from untests/features/traits/arithmetic_tests.cpp rename to untests/features/traits/arithmetic_traits_tests.cpp diff --git a/untests/features/traits/array_tests.cpp b/untests/features/traits/array_traits_tests.cpp similarity index 100% rename from untests/features/traits/array_tests.cpp rename to untests/features/traits/array_traits_tests.cpp diff --git a/untests/features/traits/class_tests.cpp b/untests/features/traits/class_traits_tests.cpp similarity index 100% rename from untests/features/traits/class_tests.cpp rename to untests/features/traits/class_traits_tests.cpp diff --git a/untests/features/traits/ctor_tests.cpp b/untests/features/traits/ctor_traits_tests.cpp similarity index 100% rename from untests/features/traits/ctor_tests.cpp rename to untests/features/traits/ctor_traits_tests.cpp diff --git a/untests/features/traits/enum_tests.cpp b/untests/features/traits/enum_traits_tests.cpp similarity index 100% rename from untests/features/traits/enum_tests.cpp rename to untests/features/traits/enum_traits_tests.cpp diff --git a/untests/features/traits/function_tests.cpp b/untests/features/traits/function_traits_tests.cpp similarity index 100% rename from untests/features/traits/function_tests.cpp rename to untests/features/traits/function_traits_tests.cpp diff --git a/untests/features/traits/member_tests.cpp b/untests/features/traits/member_traits_tests.cpp similarity index 100% rename from untests/features/traits/member_tests.cpp rename to untests/features/traits/member_traits_tests.cpp diff --git a/untests/features/traits/method_tests.cpp b/untests/features/traits/method_traits_tests.cpp similarity index 100% rename from untests/features/traits/method_tests.cpp rename to untests/features/traits/method_traits_tests.cpp diff --git a/untests/features/traits/pointer_tests.cpp b/untests/features/traits/pointer_traits_tests.cpp similarity index 100% rename from untests/features/traits/pointer_tests.cpp rename to untests/features/traits/pointer_traits_tests.cpp diff --git a/untests/features/traits/reference_tests.cpp b/untests/features/traits/reference_traits_tests.cpp similarity index 100% rename from untests/features/traits/reference_tests.cpp rename to untests/features/traits/reference_traits_tests.cpp diff --git a/untests/features/traits/void_tests.cpp b/untests/features/traits/void_traits_tests.cpp similarity index 100% rename from untests/features/traits/void_tests.cpp rename to untests/features/traits/void_traits_tests.cpp diff --git a/untests/features/types/arithmetic_tests.cpp b/untests/features/types/arithmetic_type_tests.cpp similarity index 100% rename from untests/features/types/arithmetic_tests.cpp rename to untests/features/types/arithmetic_type_tests.cpp diff --git a/untests/features/types/array_tests.cpp b/untests/features/types/array_type_tests.cpp similarity index 100% rename from untests/features/types/array_tests.cpp rename to untests/features/types/array_type_tests.cpp diff --git a/untests/features/types/class_tests.cpp b/untests/features/types/class_type_tests.cpp similarity index 100% rename from untests/features/types/class_tests.cpp rename to untests/features/types/class_type_tests.cpp diff --git a/untests/features/types/ctor_tests.cpp b/untests/features/types/ctor_type_tests.cpp similarity index 100% rename from untests/features/types/ctor_tests.cpp rename to untests/features/types/ctor_type_tests.cpp diff --git a/untests/features/types/enum_tests.cpp b/untests/features/types/enum_type_tests.cpp similarity index 100% rename from untests/features/types/enum_tests.cpp rename to untests/features/types/enum_type_tests.cpp diff --git a/untests/features/types/function_tests.cpp b/untests/features/types/function_type_tests.cpp similarity index 100% rename from untests/features/types/function_tests.cpp rename to untests/features/types/function_type_tests.cpp diff --git a/untests/features/types/member_tests.cpp b/untests/features/types/member_type_tests.cpp similarity index 100% rename from untests/features/types/member_tests.cpp rename to untests/features/types/member_type_tests.cpp diff --git a/untests/features/types/method_tests.cpp b/untests/features/types/method_type_tests.cpp similarity index 100% rename from untests/features/types/method_tests.cpp rename to untests/features/types/method_type_tests.cpp diff --git a/untests/features/types/pointer_tests.cpp b/untests/features/types/pointer_type_tests.cpp similarity index 100% rename from untests/features/types/pointer_tests.cpp rename to untests/features/types/pointer_type_tests.cpp diff --git a/untests/features/types/reference_tests.cpp b/untests/features/types/reference_type_tests.cpp similarity index 100% rename from untests/features/types/reference_tests.cpp rename to untests/features/types/reference_type_tests.cpp diff --git a/untests/features/types/void_tests.cpp b/untests/features/types/void_type_tests.cpp similarity index 100% rename from untests/features/types/void_tests.cpp rename to untests/features/types/void_type_tests.cpp From 4526cdd4e906b88223d67f91f1707ef88534f5c1 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Thu, 5 Aug 2021 00:38:49 +0700 Subject: [PATCH 077/233] add kari.hpp and enum.hpp as submodules --- .gitmodules | 6 ++ CMakeLists.txt | 14 ++- headers/meta.hpp/meta_fwd.hpp | 5 ++ headers/meta.hpp/meta_registry.hpp | 17 ++-- headers/meta.hpp/meta_utilities.hpp | 2 +- headers/meta.hpp/meta_utilities/curry.hpp | 104 ---------------------- untests/CMakeLists.txt | 8 +- vendors/enum.hpp | 1 + vendors/kari.hpp | 1 + 9 files changed, 39 insertions(+), 119 deletions(-) create mode 100644 .gitmodules delete mode 100644 headers/meta.hpp/meta_utilities/curry.hpp create mode 160000 vendors/enum.hpp create mode 160000 vendors/kari.hpp diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..e9f4823 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "vendors/enum.hpp"] + path = vendors/enum.hpp + url = https://github.com/BlackMATov/enum.hpp +[submodule "vendors/kari.hpp"] + path = vendors/kari.hpp + url = https://github.com/BlackMATov/kari.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index da1b980..ed72031 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,9 +7,19 @@ endif() project(meta.hpp) +add_subdirectory(vendors/enum.hpp) +add_subdirectory(vendors/kari.hpp) + add_library(${PROJECT_NAME} INTERFACE) -target_compile_features(${PROJECT_NAME} INTERFACE cxx_std_17) -target_include_directories(${PROJECT_NAME} INTERFACE headers) + +target_link_libraries(${PROJECT_NAME} + INTERFACE enum.hpp kari.hpp) + +target_compile_features(${PROJECT_NAME} + INTERFACE cxx_std_17) + +target_include_directories(${PROJECT_NAME} + INTERFACE headers) if(BUILD_AS_STANDALONE) option(BUILD_WITH_UNTESTS "Build with unit tests" ON) diff --git a/headers/meta.hpp/meta_fwd.hpp b/headers/meta.hpp/meta_fwd.hpp index 26e9973..8276d6a 100644 --- a/headers/meta.hpp/meta_fwd.hpp +++ b/headers/meta.hpp/meta_fwd.hpp @@ -27,6 +27,11 @@ #include #include +#include +#include + +#include + namespace meta_hpp { class class_info; diff --git a/headers/meta.hpp/meta_registry.hpp b/headers/meta.hpp/meta_registry.hpp index dafe434..0175acf 100644 --- a/headers/meta.hpp/meta_registry.hpp +++ b/headers/meta.hpp/meta_registry.hpp @@ -10,6 +10,7 @@ #include "meta_infos.hpp" #include "meta_registry/class_.hpp" +#include "meta_registry/ctor_.hpp" #include "meta_registry/data_.hpp" #include "meta_registry/enum_.hpp" #include "meta_registry/evalue_.hpp" @@ -164,7 +165,7 @@ namespace meta_hpp inline void registry::add_info_(const std::string& prefix, const class_info& info) { std::string name = prefix.empty() ? info.name() : prefix + "::" + info.name(); - info.visit(curry(add_info_f{}, std::ref(*this), name)); + info.visit(kari_hpp::curry(add_info_f{}, std::ref(*this), name)); detail::merge_with(classes_, name, info, &class_info::merge); } @@ -175,43 +176,43 @@ namespace meta_hpp inline void registry::add_info_(const std::string& prefix, const data_info& info) { std::string name = prefix.empty() ? info.name() : prefix + "::" + info.name(); - info.visit(curry(add_info_f{}, std::ref(*this), name)); + info.visit(kari_hpp::curry(add_info_f{}, std::ref(*this), name)); detail::merge_with(datas_, name, info, &data_info::merge); } inline void registry::add_info_(const std::string& prefix, const enum_info& info) { std::string name = prefix.empty() ? info.name() : prefix + "::" + info.name(); - info.visit(curry(add_info_f{}, std::ref(*this), name)); + info.visit(kari_hpp::curry(add_info_f{}, std::ref(*this), name)); detail::merge_with(enums_, name, info, &enum_info::merge); } inline void registry::add_info_(const std::string& prefix, const evalue_info& info) { std::string name = prefix.empty() ? info.name() : prefix + "::" + info.name(); - info.visit(curry(add_info_f{}, std::ref(*this), name)); + info.visit(kari_hpp::curry(add_info_f{}, std::ref(*this), name)); detail::merge_with(evalues_, name, info, &evalue_info::merge); } inline void registry::add_info_(const std::string& prefix, const function_info& info) { std::string name = prefix.empty() ? info.name() : prefix + "::" + info.name(); - info.visit(curry(add_info_f{}, std::ref(*this), name)); + info.visit(kari_hpp::curry(add_info_f{}, std::ref(*this), name)); detail::merge_with(functions_, name, info, &function_info::merge); } inline void registry::add_info_(const std::string& prefix, const member_info& info) { std::string name = prefix.empty() ? info.name() : prefix + "::" + info.name(); - info.visit(curry(add_info_f{}, std::ref(*this), name)); + info.visit(kari_hpp::curry(add_info_f{}, std::ref(*this), name)); detail::merge_with(members_, name, info, &member_info::merge); } inline void registry::add_info_(const std::string& prefix, const method_info& info) { std::string name = prefix.empty() ? info.name() : prefix + "::" + info.name(); - info.visit(curry(add_info_f{}, std::ref(*this), name)); + info.visit(kari_hpp::curry(add_info_f{}, std::ref(*this), name)); detail::merge_with(methods_, name, info, &method_info::merge); } inline void registry::add_info_(const std::string& prefix, const namespace_info& info) { std::string name = prefix.empty() ? info.name() : prefix + "::" + info.name(); - info.visit(curry(add_info_f{}, std::ref(*this), name)); + info.visit(kari_hpp::curry(add_info_f{}, std::ref(*this), name)); detail::merge_with(namespaces_, name, info, &namespace_info::merge); } } diff --git a/headers/meta.hpp/meta_utilities.hpp b/headers/meta.hpp/meta_utilities.hpp index 3ceab77..be54873 100644 --- a/headers/meta.hpp/meta_utilities.hpp +++ b/headers/meta.hpp/meta_utilities.hpp @@ -8,5 +8,5 @@ #include "meta_fwd.hpp" -#include "meta_utilities/curry.hpp" +#include "meta_utilities/arg.hpp" #include "meta_utilities/value.hpp" diff --git a/headers/meta.hpp/meta_utilities/curry.hpp b/headers/meta.hpp/meta_utilities/curry.hpp deleted file mode 100644 index bcf3780..0000000 --- a/headers/meta.hpp/meta_utilities/curry.hpp +++ /dev/null @@ -1,104 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "../meta_fwd.hpp" - -namespace meta_hpp -{ - template < typename F, typename... As > - class curry_t; - - namespace impl - { - template < typename F > - struct is_curried_impl - : std::false_type {}; - - template < typename F, typename... As > - struct is_curried_impl> - : std::true_type {}; - } - - template < typename F > - struct is_curried - : impl::is_curried_impl> {}; - - template < typename F > - inline constexpr bool is_curried_v = is_curried::value; -} - -namespace meta_hpp::detail -{ - template < typename F, typename... Args > - constexpr auto curry_or_apply(F&& f, std::tuple&& args) { - if constexpr ( std::is_invocable_v, Args...> ) { - return std::apply(std::forward(f), std::move(args)); - } else { - return curry_t(std::forward(f), std::move(args)); - } - } -} - -namespace meta_hpp -{ - template < typename F, typename... Args > - class curry_t final { - public: - constexpr curry_t(F f) - : f_(std::move(f)) {} - - constexpr curry_t(F f, std::tuple args) - : f_(std::move(f)) - , args_(std::move(args)) {} - - constexpr auto operator()() && { - return detail::curry_or_apply( - std::move(f_), - std::move(args_)); - } - - template < typename A > - constexpr auto operator()(A&& a) && { - return detail::curry_or_apply( - std::move(f_), - std::tuple_cat( - std::move(args_), - std::make_tuple(std::forward(a)))); - } - - template < typename A, typename... As > - constexpr auto operator()(A&& a, As&&... as) && { - return std::move(*this)(std::forward(a))(std::forward(as)...); - } - - template < typename... As > - constexpr auto operator()(As&&... as) const & { - return std::move(curry_t(*this))(std::forward(as)...); - } - private: - F f_; - std::tuple args_; - }; -} - -namespace meta_hpp -{ - template < typename F > - constexpr auto curry(F&& f) { - if constexpr ( is_curried_v> ) { - return std::forward(f); - } else { - return detail::curry_or_apply(std::forward(f), {}); - } - } - - template < typename F, typename A, typename... As > - constexpr auto curry(F&& f, A&& a, As&&... as) { - return curry(std::forward(f))(std::forward(a), std::forward(as)...); - } -} diff --git a/untests/CMakeLists.txt b/untests/CMakeLists.txt index 524f30f..8e18fd3 100644 --- a/untests/CMakeLists.txt +++ b/untests/CMakeLists.txt @@ -29,9 +29,9 @@ target_compile_options(${PROJECT_NAME} -Werror -Wall -Wextra -Wpedantic> PRIVATE $<$,$>: - -Werror -Weverything -Wno-unknown-warning-option - -Wconversion -Wimplicit-int-float-conversion - -Wno-c++98-compat-pedantic -Wno-ctad-maybe-unsupported -Wno-padded - -Wno-float-equal -Wno-double-promotion -Wno-shadow-field-in-constructor>) + -Werror -Weverything -Wconversion -Wno-unknown-warning-option + -Wno-padded + -Wno-c++98-compat-pedantic + -Wno-shadow-field-in-constructor>) add_test(${PROJECT_NAME} ${PROJECT_NAME}) diff --git a/vendors/enum.hpp b/vendors/enum.hpp new file mode 160000 index 0000000..0a549d3 --- /dev/null +++ b/vendors/enum.hpp @@ -0,0 +1 @@ +Subproject commit 0a549d3341e8f6d9efd8e6cea343f2d3ab4e7633 diff --git a/vendors/kari.hpp b/vendors/kari.hpp new file mode 160000 index 0000000..c52226f --- /dev/null +++ b/vendors/kari.hpp @@ -0,0 +1 @@ +Subproject commit c52226f8556a0a439389514143f336fe4979b480 From 9a6b06d25aef9b045c46f619761df6f1bc94a14b Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 6 Aug 2021 00:55:02 +0700 Subject: [PATCH 078/233] remove dummy trait tests --- untests/features/traits/_traits_fwd.hpp | 9 --------- .../features/traits/arithmetic_traits_tests.cpp | 14 -------------- untests/features/traits/array_traits_tests.cpp | 14 -------------- untests/features/traits/class_traits_tests.cpp | 14 -------------- untests/features/traits/ctor_traits_tests.cpp | 14 -------------- untests/features/traits/enum_traits_tests.cpp | 14 -------------- untests/features/traits/function_traits_tests.cpp | 14 -------------- untests/features/traits/member_traits_tests.cpp | 14 -------------- untests/features/traits/method_traits_tests.cpp | 14 -------------- untests/features/traits/pointer_traits_tests.cpp | 14 -------------- untests/features/traits/reference_traits_tests.cpp | 14 -------------- untests/features/traits/void_traits_tests.cpp | 14 -------------- 12 files changed, 163 deletions(-) delete mode 100644 untests/features/traits/_traits_fwd.hpp delete mode 100644 untests/features/traits/arithmetic_traits_tests.cpp delete mode 100644 untests/features/traits/array_traits_tests.cpp delete mode 100644 untests/features/traits/class_traits_tests.cpp delete mode 100644 untests/features/traits/ctor_traits_tests.cpp delete mode 100644 untests/features/traits/enum_traits_tests.cpp delete mode 100644 untests/features/traits/function_traits_tests.cpp delete mode 100644 untests/features/traits/member_traits_tests.cpp delete mode 100644 untests/features/traits/method_traits_tests.cpp delete mode 100644 untests/features/traits/pointer_traits_tests.cpp delete mode 100644 untests/features/traits/reference_traits_tests.cpp delete mode 100644 untests/features/traits/void_traits_tests.cpp diff --git a/untests/features/traits/_traits_fwd.hpp b/untests/features/traits/_traits_fwd.hpp deleted file mode 100644 index b826cce..0000000 --- a/untests/features/traits/_traits_fwd.hpp +++ /dev/null @@ -1,9 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "../../meta_tests.hpp" diff --git a/untests/features/traits/arithmetic_traits_tests.cpp b/untests/features/traits/arithmetic_traits_tests.cpp deleted file mode 100644 index af82e77..0000000 --- a/untests/features/traits/arithmetic_traits_tests.cpp +++ /dev/null @@ -1,14 +0,0 @@ -/******************************************************************************* - * 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 "_traits_fwd.hpp" - -namespace -{ -} - -TEST_CASE("features/traits/arithmetic") { -} diff --git a/untests/features/traits/array_traits_tests.cpp b/untests/features/traits/array_traits_tests.cpp deleted file mode 100644 index 3b5446b..0000000 --- a/untests/features/traits/array_traits_tests.cpp +++ /dev/null @@ -1,14 +0,0 @@ -/******************************************************************************* - * 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 "_traits_fwd.hpp" - -namespace -{ -} - -TEST_CASE("features/traits/array") { -} diff --git a/untests/features/traits/class_traits_tests.cpp b/untests/features/traits/class_traits_tests.cpp deleted file mode 100644 index cacd905..0000000 --- a/untests/features/traits/class_traits_tests.cpp +++ /dev/null @@ -1,14 +0,0 @@ -/******************************************************************************* - * 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 "_traits_fwd.hpp" - -namespace -{ -} - -TEST_CASE("features/traits/class") { -} diff --git a/untests/features/traits/ctor_traits_tests.cpp b/untests/features/traits/ctor_traits_tests.cpp deleted file mode 100644 index 7480901..0000000 --- a/untests/features/traits/ctor_traits_tests.cpp +++ /dev/null @@ -1,14 +0,0 @@ -/******************************************************************************* - * 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 "_traits_fwd.hpp" - -namespace -{ -} - -TEST_CASE("features/traits/ctor") { -} diff --git a/untests/features/traits/enum_traits_tests.cpp b/untests/features/traits/enum_traits_tests.cpp deleted file mode 100644 index deba0df..0000000 --- a/untests/features/traits/enum_traits_tests.cpp +++ /dev/null @@ -1,14 +0,0 @@ -/******************************************************************************* - * 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 "_traits_fwd.hpp" - -namespace -{ -} - -TEST_CASE("features/traits/enum") { -} diff --git a/untests/features/traits/function_traits_tests.cpp b/untests/features/traits/function_traits_tests.cpp deleted file mode 100644 index 60be950..0000000 --- a/untests/features/traits/function_traits_tests.cpp +++ /dev/null @@ -1,14 +0,0 @@ -/******************************************************************************* - * 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 "_traits_fwd.hpp" - -namespace -{ -} - -TEST_CASE("features/traits/function") { -} diff --git a/untests/features/traits/member_traits_tests.cpp b/untests/features/traits/member_traits_tests.cpp deleted file mode 100644 index 5e225db..0000000 --- a/untests/features/traits/member_traits_tests.cpp +++ /dev/null @@ -1,14 +0,0 @@ -/******************************************************************************* - * 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 "_traits_fwd.hpp" - -namespace -{ -} - -TEST_CASE("features/traits/member") { -} diff --git a/untests/features/traits/method_traits_tests.cpp b/untests/features/traits/method_traits_tests.cpp deleted file mode 100644 index d1e47df..0000000 --- a/untests/features/traits/method_traits_tests.cpp +++ /dev/null @@ -1,14 +0,0 @@ -/******************************************************************************* - * 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 "_traits_fwd.hpp" - -namespace -{ -} - -TEST_CASE("features/traits/method") { -} diff --git a/untests/features/traits/pointer_traits_tests.cpp b/untests/features/traits/pointer_traits_tests.cpp deleted file mode 100644 index 6ab744f..0000000 --- a/untests/features/traits/pointer_traits_tests.cpp +++ /dev/null @@ -1,14 +0,0 @@ -/******************************************************************************* - * 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 "_traits_fwd.hpp" - -namespace -{ -} - -TEST_CASE("features/traits/pointer") { -} diff --git a/untests/features/traits/reference_traits_tests.cpp b/untests/features/traits/reference_traits_tests.cpp deleted file mode 100644 index a214604..0000000 --- a/untests/features/traits/reference_traits_tests.cpp +++ /dev/null @@ -1,14 +0,0 @@ -/******************************************************************************* - * 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 "_traits_fwd.hpp" - -namespace -{ -} - -TEST_CASE("features/traits/reference") { -} diff --git a/untests/features/traits/void_traits_tests.cpp b/untests/features/traits/void_traits_tests.cpp deleted file mode 100644 index d1c5a6e..0000000 --- a/untests/features/traits/void_traits_tests.cpp +++ /dev/null @@ -1,14 +0,0 @@ -/******************************************************************************* - * 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 "_traits_fwd.hpp" - -namespace -{ -} - -TEST_CASE("features/traits/void") { -} From 481dbd3339b5a6264da64395cf2fc6ff15951fbc Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 6 Aug 2021 01:03:12 +0700 Subject: [PATCH 079/233] fill static types --- headers/meta.hpp/meta_fwd.hpp | 1 - headers/meta.hpp/meta_infos/class_info.hpp | 2 +- headers/meta.hpp/meta_infos/enum_info.hpp | 2 +- headers/meta.hpp/meta_infos/function_info.hpp | 2 +- headers/meta.hpp/meta_infos/member_info.hpp | 2 +- headers/meta.hpp/meta_infos/method_info.hpp | 2 +- headers/meta.hpp/meta_registry/enum_.hpp | 10 ++ headers/meta.hpp/meta_types.hpp | 61 ++++++++++ headers/meta.hpp/meta_types/_types_fwd.hpp | 111 ++++++++++++++--- .../meta.hpp/meta_types/arithmetic_type.hpp | 102 +++++++++++++++- headers/meta.hpp/meta_types/array_type.hpp | 84 ++++++++++++- headers/meta.hpp/meta_types/class_type.hpp | 102 +++++++++++++++- headers/meta.hpp/meta_types/ctor_type.hpp | 83 ++++++++++++- headers/meta.hpp/meta_types/enum_type.hpp | 70 ++++++++++- headers/meta.hpp/meta_types/function_type.hpp | 90 +++++++++++++- headers/meta.hpp/meta_types/member_type.hpp | 60 ++++++++- headers/meta.hpp/meta_types/method_type.hpp | 115 +++++++++++++++++- headers/meta.hpp/meta_types/pointer_type.hpp | 67 +++++++++- .../meta.hpp/meta_types/reference_type.hpp | 75 +++++++++++- headers/meta.hpp/meta_types/void_type.hpp | 62 +++++++++- .../features/types/arithmetic_type_tests.cpp | 58 +++++++++ untests/features/types/array_type_tests.cpp | 31 +++++ untests/features/types/class_type_tests.cpp | 114 +++++++++++++++++ untests/features/types/ctor_type_tests.cpp | 70 +++++++++++ untests/features/types/enum_type_tests.cpp | 38 ++++++ .../features/types/function_type_tests.cpp | 82 +++++++++++++ untests/features/types/member_type_tests.cpp | 31 +++++ untests/features/types/method_type_tests.cpp | 65 ++++++++++ untests/features/types/pointer_type_tests.cpp | 61 ++++++++++ .../features/types/reference_type_tests.cpp | 33 +++++ untests/features/types/void_type_tests.cpp | 27 ++++ 31 files changed, 1646 insertions(+), 67 deletions(-) diff --git a/headers/meta.hpp/meta_fwd.hpp b/headers/meta.hpp/meta_fwd.hpp index 8276d6a..f405320 100644 --- a/headers/meta.hpp/meta_fwd.hpp +++ b/headers/meta.hpp/meta_fwd.hpp @@ -61,7 +61,6 @@ namespace meta_hpp namespace meta_hpp { class type_id; - class base_type; class arithmetic_type; class array_type; diff --git a/headers/meta.hpp/meta_infos/class_info.hpp b/headers/meta.hpp/meta_infos/class_info.hpp index 6ffc3a2..00d9e49 100644 --- a/headers/meta.hpp/meta_infos/class_info.hpp +++ b/headers/meta.hpp/meta_infos/class_info.hpp @@ -196,7 +196,7 @@ namespace meta_hpp inline class_info::class_info(typename_arg_t, std::string name) : state_{std::make_shared(state{ std::move(name), - class_type{typename_arg}, + type_db::get().template as(), {}, {}, {}, {}, {}, {}, {} })} {} } diff --git a/headers/meta.hpp/meta_infos/enum_info.hpp b/headers/meta.hpp/meta_infos/enum_info.hpp index 450f4ee..1e37ba6 100644 --- a/headers/meta.hpp/meta_infos/enum_info.hpp +++ b/headers/meta.hpp/meta_infos/enum_info.hpp @@ -112,7 +112,7 @@ namespace meta_hpp inline enum_info::enum_info(typename_arg_t, std::string name) : state_{std::make_shared(state{ std::move(name), - enum_type{typename_arg}, + type_db::get().template as(), {}, {} })} {} } diff --git a/headers/meta.hpp/meta_infos/function_info.hpp b/headers/meta.hpp/meta_infos/function_info.hpp index ebfb2c5..b25c453 100644 --- a/headers/meta.hpp/meta_infos/function_info.hpp +++ b/headers/meta.hpp/meta_infos/function_info.hpp @@ -94,7 +94,7 @@ namespace meta_hpp inline function_info::function_info(std::string name, Function instance) : state_{std::make_shared(state{ std::move(name), - function_type{typename_arg}, + type_db::get().template as(), {} })} { (void)instance; diff --git a/headers/meta.hpp/meta_infos/member_info.hpp b/headers/meta.hpp/meta_infos/member_info.hpp index f23841e..3945fc0 100644 --- a/headers/meta.hpp/meta_infos/member_info.hpp +++ b/headers/meta.hpp/meta_infos/member_info.hpp @@ -94,7 +94,7 @@ namespace meta_hpp inline member_info::member_info(std::string name, Member instance) : state_{std::make_shared(state{ std::move(name), - member_type{typename_arg}, + type_db::get().template as(), {} })} { (void)instance; diff --git a/headers/meta.hpp/meta_infos/method_info.hpp b/headers/meta.hpp/meta_infos/method_info.hpp index 50d14b5..82c670d 100644 --- a/headers/meta.hpp/meta_infos/method_info.hpp +++ b/headers/meta.hpp/meta_infos/method_info.hpp @@ -94,7 +94,7 @@ namespace meta_hpp inline method_info::method_info(std::string name, Method instance) : state_{std::make_shared(state{ std::move(name), - method_type{typename_arg}, + type_db::get().template as(), {} })} { (void)instance; diff --git a/headers/meta.hpp/meta_registry/enum_.hpp b/headers/meta.hpp/meta_registry/enum_.hpp index 9a9c80f..5734f85 100644 --- a/headers/meta.hpp/meta_registry/enum_.hpp +++ b/headers/meta.hpp/meta_registry/enum_.hpp @@ -9,6 +9,7 @@ #include "_registry_fwd.hpp" #include "data_.hpp" +#include "evalue_.hpp" namespace meta_hpp { @@ -23,10 +24,12 @@ namespace meta_hpp enum_& operator()(Internals&&...internals); private: void add_(const data_& internal); + void add_(const evalue_& internal); void add_(...) = delete; private: std::string name_; data_info_map datas_; + evalue_info_map evalues_; }; } @@ -40,6 +43,7 @@ namespace meta_hpp inline enum_info enum_::make_info() const { enum_info info{typename_arg, name_}; info.state_->datas.insert(datas_.begin(), datas_.end()); + info.state_->evalues.insert(evalues_.begin(), evalues_.end()); return info; } @@ -58,4 +62,10 @@ namespace meta_hpp auto info = internal.make_info(); detail::merge_with(datas_, info.name(), info, &data_info::merge); } + + template < typename Enum > + inline void enum_::add_(const evalue_& internal) { + auto info = internal.make_info(); + detail::merge_with(evalues_, info.name(), info, &evalue_info::merge); + } } diff --git a/headers/meta.hpp/meta_types.hpp b/headers/meta.hpp/meta_types.hpp index e64eb51..39d7152 100644 --- a/headers/meta.hpp/meta_types.hpp +++ b/headers/meta.hpp/meta_types.hpp @@ -19,3 +19,64 @@ #include "meta_types/pointer_type.hpp" #include "meta_types/reference_type.hpp" #include "meta_types/void_type.hpp" + +namespace meta_hpp +{ + namespace detail + { + template < typename Tuple > + struct multi_get_impl; + + template < typename... Ts > + struct multi_get_impl> { + static std::vector get() { + return { type_db::get()... }; + } + }; + + template < typename T > + auto make_any_type() { + if constexpr ( std::is_arithmetic_v ) { + return arithmetic_type{typename_arg}; + } + if constexpr ( std::is_array_v ) { + return array_type{typename_arg}; + } + if constexpr ( std::is_class_v ) { + return class_type{typename_arg}; + } + if constexpr ( std::is_enum_v ) { + return enum_type{typename_arg}; + } + if constexpr ( std::is_pointer_v && std::is_function_v> ) { + return function_type{typename_arg}; + } + if constexpr ( std::is_member_object_pointer_v ) { + return member_type{typename_arg}; + } + if constexpr ( std::is_member_function_pointer_v ) { + return method_type{typename_arg}; + } + if constexpr ( std::is_pointer_v && !std::is_function_v> ) { + return pointer_type{typename_arg}; + } + if constexpr ( std::is_reference_v ) { + return reference_type{typename_arg}; + } + if constexpr ( std::is_void_v ) { + return void_type{typename_arg}; + } + } + } + + template < typename T > + inline any_type type_db::get() { + static const auto raw_type = detail::make_any_type(); + return raw_type; + } + + template < typename Tuple > + inline std::vector type_db::multi_get() { + return detail::multi_get_impl::get(); + } +} diff --git a/headers/meta.hpp/meta_types/_types_fwd.hpp b/headers/meta.hpp/meta_types/_types_fwd.hpp index dbbc9b8..b160c9f 100644 --- a/headers/meta.hpp/meta_types/_types_fwd.hpp +++ b/headers/meta.hpp/meta_types/_types_fwd.hpp @@ -12,7 +12,7 @@ namespace meta_hpp { class type_id final { public: - type_id() = delete; + type_id() = default; type_id(type_id&&) = default; type_id& operator=(type_id&&) = default; @@ -20,6 +20,14 @@ namespace meta_hpp type_id(const type_id&) = default; type_id& operator=(const type_id&) = default; + template < typename T > + explicit type_id(typename_arg_t) noexcept + : id_{type_to_id()} {} + + explicit operator bool() const noexcept { + return !!id_; + } + std::size_t hash() const noexcept { return std::hash{}(id_); } @@ -39,24 +47,17 @@ namespace meta_hpp using underlying_type = std::size_t; underlying_type id_{0u}; private: - template < typename T > - friend type_id make_type_id() noexcept; - - template < typename T > - explicit type_id(typename_arg_t) noexcept - : id_{next()} {} - static underlying_type next() noexcept { static std::atomic id{}; return ++id; } - }; - template < typename T > - type_id make_type_id() noexcept { - static const type_id id = type_id{typename_arg}; - return id; - } + template < typename T > + static underlying_type type_to_id() noexcept { + static const underlying_type id{next()}; + return id; + } + }; } namespace std @@ -76,14 +77,94 @@ namespace meta_hpp template < typename... Ts > struct tag {}; public: + base_type() = default; + virtual ~base_type() = default; + + base_type(base_type&&) = default; + base_type& operator=(base_type&&) = default; + + base_type(const base_type&) = default; + base_type& operator=(const base_type&) = default; + template < typename... Ts > explicit base_type(typename_arg_t) - : id_{make_type_id>()} {} + : id_{typename_arg>} {} type_id id() const noexcept { return id_; } + + explicit operator bool() const noexcept { + return !!id_; + } private: type_id id_; }; } + +namespace meta_hpp +{ + class any_type final { + public: + any_type() = default; + + any_type(any_type&&) = default; + any_type& operator=(any_type&&) = default; + + any_type(const any_type&) = default; + any_type& operator=(const any_type&) = default; + + template < typename T, std::enable_if_t, int> = 0 > + any_type(const T& type) + : id_{type.id()} + , type_{std::addressof(type)} {} + + type_id id() const noexcept { + return id_; + } + + explicit operator bool() const noexcept { + return !!id_; + } + + template < typename T > + std::enable_if_t, T> as() const noexcept { + using Tptr = std::add_pointer_t>; + return is() ? *std::get(type_) : T{}; + } + + template < typename T > + std::enable_if_t, bool> is() const noexcept { + using Tptr = std::add_pointer_t>; + return std::holds_alternative(type_); + } + private: + type_id id_; + std::variant< + const arithmetic_type*, + const array_type*, + const class_type*, + const ctor_type*, + const enum_type*, + const function_type*, + const member_type*, + const method_type*, + const pointer_type*, + const reference_type*, + const void_type*> type_; + }; +} + +namespace meta_hpp +{ + class type_db final { + public: + type_db() = delete; + + template < typename T > + static any_type get(); + + template < typename Tuple > + static std::vector multi_get(); + }; +} diff --git a/headers/meta.hpp/meta_types/arithmetic_type.hpp b/headers/meta.hpp/meta_types/arithmetic_type.hpp index 0cf4d27..089678a 100644 --- a/headers/meta.hpp/meta_types/arithmetic_type.hpp +++ b/headers/meta.hpp/meta_types/arithmetic_type.hpp @@ -12,10 +12,104 @@ namespace meta_hpp { class arithmetic_type final : public base_type { public: + arithmetic_type() = default; + + arithmetic_type(arithmetic_type&&) = default; + arithmetic_type& operator=(arithmetic_type&&) = default; + + arithmetic_type(const arithmetic_type&) = default; + arithmetic_type& operator=(const arithmetic_type&) = default; + template < typename T > - explicit arithmetic_type(typename_arg_t) - : base_type{typename_arg} { - static_assert(std::is_arithmetic_v); - } + explicit arithmetic_type(typename_arg_t); + + any_type raw_type() const noexcept; + std::size_t size() const noexcept; + bool is_const() const noexcept; + bool is_signed() const noexcept; + bool is_unsigned() const noexcept; + bool is_integral() const noexcept; + bool is_floating_point() const noexcept; + private: + struct state; + std::shared_ptr state_; }; } + +namespace meta_hpp +{ + struct arithmetic_type::state final { + const any_type raw_type; + const std::size_t size; + const bool is_const; + const bool is_signed; + const bool is_unsigned; + const bool is_integral; + const bool is_floating_point; + }; +} + +namespace meta_hpp::detail +{ + template < typename T, typename = void > + struct arithmetic_traits; + + template < typename T > + struct arithmetic_traits>> { + using raw_type = std::remove_const_t; + static constexpr std::size_t size{sizeof(T)}; + static constexpr bool is_const{std::is_const_v}; + static constexpr bool is_signed{std::is_signed_v}; + static constexpr bool is_unsigned{std::is_unsigned_v}; + static constexpr bool is_integral{std::is_integral_v}; + static constexpr bool is_floating_point{std::is_floating_point_v}; + }; +} + +namespace meta_hpp +{ + template < typename T > + inline arithmetic_type::arithmetic_type(typename_arg_t) + : base_type{typename_arg} + , state_{std::make_shared(state{ + std::is_same_v::raw_type> + ? any_type{*this} + : type_db::get::raw_type>(), + detail::arithmetic_traits::size, + detail::arithmetic_traits::is_const, + detail::arithmetic_traits::is_signed, + detail::arithmetic_traits::is_unsigned, + detail::arithmetic_traits::is_integral, + detail::arithmetic_traits::is_floating_point, + })} { + static_assert(std::is_arithmetic_v); + } + + inline any_type arithmetic_type::raw_type() const noexcept { + return state_->raw_type; + } + + inline std::size_t arithmetic_type::size() const noexcept { + return state_->size; + } + + inline bool arithmetic_type::is_const() const noexcept { + return state_->is_const; + } + + inline bool arithmetic_type::is_signed() const noexcept { + return state_->is_signed; + } + + inline bool arithmetic_type::is_unsigned() const noexcept { + return state_->is_unsigned; + } + + inline bool arithmetic_type::is_integral() const noexcept { + return state_->is_integral; + } + + inline bool arithmetic_type::is_floating_point() const noexcept { + return state_->is_floating_point; + } +} diff --git a/headers/meta.hpp/meta_types/array_type.hpp b/headers/meta.hpp/meta_types/array_type.hpp index f00083b..1d9ea78 100644 --- a/headers/meta.hpp/meta_types/array_type.hpp +++ b/headers/meta.hpp/meta_types/array_type.hpp @@ -12,10 +12,86 @@ namespace meta_hpp { class array_type final : public base_type { public: + array_type() = default; + + array_type(array_type&&) = default; + array_type& operator=(array_type&&) = default; + + array_type(const array_type&) = default; + array_type& operator=(const array_type&) = default; + template < typename T > - explicit array_type(typename_arg_t) - : base_type{typename_arg} { - static_assert(std::is_array_v); - } + explicit array_type(typename_arg_t); + + any_type data_type() const noexcept; + std::size_t extent() const noexcept; + bool is_bounded() const noexcept; + bool is_unbounded() const noexcept; + private: + struct state; + std::shared_ptr state_; }; } + +namespace meta_hpp +{ + struct array_type::state final { + const any_type data_type; + const std::size_t extent; + const bool is_bounded; + const bool is_unbounded; + }; +} + +namespace meta_hpp::detail +{ + template < typename T > + struct array_traits; + + template < typename T > + struct array_traits { + using data_type = T; + static constexpr std::size_t extent{0}; + static constexpr bool is_bounded{false}; + static constexpr bool is_unbounded{true}; + }; + + template < typename T, std::size_t N > + struct array_traits { + using data_type = T; + static constexpr std::size_t extent{N}; + static constexpr bool is_bounded{true}; + static constexpr bool is_unbounded{false}; + }; +} + +namespace meta_hpp +{ + template < typename T > + inline array_type::array_type(typename_arg_t) + : base_type{typename_arg} + , state_{std::make_shared(state{ + type_db::get::data_type>(), + detail::array_traits::extent, + detail::array_traits::is_bounded, + detail::array_traits::is_unbounded, + })} { + static_assert(std::is_array_v); + } + + inline any_type array_type::data_type() const noexcept { + return state_->data_type; + } + + inline std::size_t array_type::extent() const noexcept { + return state_->extent; + } + + inline bool array_type::is_bounded() const noexcept { + return state_->is_bounded; + } + + inline bool array_type::is_unbounded() const noexcept { + return state_->is_unbounded; + } +} diff --git a/headers/meta.hpp/meta_types/class_type.hpp b/headers/meta.hpp/meta_types/class_type.hpp index e66dca1..3bf64cf 100644 --- a/headers/meta.hpp/meta_types/class_type.hpp +++ b/headers/meta.hpp/meta_types/class_type.hpp @@ -12,10 +12,104 @@ namespace meta_hpp { class class_type final : public base_type { public: + class_type() = default; + + class_type(class_type&&) = default; + class_type& operator=(class_type&&) = default; + + class_type(const class_type&) = default; + class_type& operator=(const class_type&) = default; + template < typename T > - explicit class_type(typename_arg_t) - : base_type{typename_arg} { - static_assert(std::is_class_v); - } + explicit class_type(typename_arg_t); + + any_type raw_type() const noexcept; + std::size_t size() const noexcept; + bool is_const() const noexcept; + bool is_empty() const noexcept; + bool is_final() const noexcept; + bool is_abstract() const noexcept; + bool is_polymorphic() const noexcept; + private: + struct state; + std::shared_ptr state_; }; } + +namespace meta_hpp +{ + struct class_type::state final { + const any_type raw_type; + const std::size_t size; + const bool is_const; + const bool is_empty; + const bool is_final; + const bool is_abstract; + const bool is_polymorphic; + }; +} + +namespace meta_hpp::detail +{ + template < typename T, typename = void > + struct class_traits; + + template < typename T > + struct class_traits>> { + using raw_type = std::remove_const_t; + static constexpr std::size_t size{sizeof(T)}; + static constexpr bool is_const{std::is_const_v}; + static constexpr bool is_empty{std::is_empty_v}; + static constexpr bool is_final{std::is_final_v}; + static constexpr bool is_abstract{std::is_abstract_v}; + static constexpr bool is_polymorphic{std::is_polymorphic_v}; + }; +} + +namespace meta_hpp +{ + template < typename T > + inline class_type::class_type(typename_arg_t) + : base_type{typename_arg} + , state_{std::make_shared(state{ + std::is_same_v::raw_type> + ? any_type{*this} + : type_db::get::raw_type>(), + detail::class_traits::size, + detail::class_traits::is_const, + detail::class_traits::is_empty, + detail::class_traits::is_final, + detail::class_traits::is_abstract, + detail::class_traits::is_polymorphic, + })} { + static_assert(std::is_class_v); + } + + inline any_type class_type::raw_type() const noexcept { + return state_->raw_type; + } + + inline std::size_t class_type::size() const noexcept { + return state_->size; + } + + inline bool class_type::is_const() const noexcept { + return state_->is_const; + } + + inline bool class_type::is_empty() const noexcept { + return state_->is_empty; + } + + inline bool class_type::is_final() const noexcept { + return state_->is_final; + } + + inline bool class_type::is_abstract() const noexcept { + return state_->is_abstract; + } + + inline bool class_type::is_polymorphic() const noexcept { + return state_->is_polymorphic; + } +} diff --git a/headers/meta.hpp/meta_types/ctor_type.hpp b/headers/meta.hpp/meta_types/ctor_type.hpp index 0c3df1a..aa7ea57 100644 --- a/headers/meta.hpp/meta_types/ctor_type.hpp +++ b/headers/meta.hpp/meta_types/ctor_type.hpp @@ -12,11 +12,84 @@ namespace meta_hpp { class ctor_type final : public base_type { public: + ctor_type() = default; + + ctor_type(ctor_type&&) = default; + ctor_type& operator=(ctor_type&&) = default; + + ctor_type(const ctor_type&) = default; + ctor_type& operator=(const ctor_type&) = default; + template < typename Class, typename... Args > - explicit ctor_type(typename_arg_t, typename_arg_t) - : base_type{typename_arg} { - static_assert(std::is_class_v); - static_assert(std::is_constructible_v); - } + explicit ctor_type(typename_arg_t, typename_arg_t); + + any_type class_type() const noexcept; + any_type argument_type(std::size_t i) const noexcept; + const std::vector& argument_types() const noexcept; + std::size_t arity() const noexcept; + bool is_noexcept() const noexcept; + private: + struct state; + std::shared_ptr state_; }; } + +namespace meta_hpp +{ + struct ctor_type::state final { + const any_type class_type; + const std::vector argument_types; + const std::size_t arity; + const bool is_noexcept; + }; +} + +namespace meta_hpp::detail +{ + template < typename C, typename... Args > + struct ctor_traits { + static_assert(std::is_constructible_v); + using class_type = C; + using argument_types = std::tuple; + static constexpr std::size_t arity{sizeof...(Args)}; + static constexpr bool is_noexcept{std::is_nothrow_constructible_v}; + }; +} + +namespace meta_hpp +{ + template < typename Class, typename... Args > + inline ctor_type::ctor_type(typename_arg_t, typename_arg_t) + : base_type{typename_arg} + , state_{std::make_shared(state{ + type_db::get::class_type>(), + type_db::multi_get::argument_types>(), + detail::ctor_traits::arity, + detail::ctor_traits::is_noexcept, + })} { + static_assert(std::is_class_v); + static_assert(std::is_constructible_v); + } + + inline any_type ctor_type::class_type() const noexcept { + return state_->class_type; + } + + inline any_type ctor_type::argument_type(std::size_t i) const noexcept { + return i < state_->argument_types.size() + ? state_->argument_types[i] + : any_type{}; + } + + inline const std::vector& ctor_type::argument_types() const noexcept { + return state_->argument_types; + } + + inline std::size_t ctor_type::arity() const noexcept { + return state_->arity; + } + + inline bool ctor_type::is_noexcept() const noexcept { + return state_->is_noexcept; + } +} diff --git a/headers/meta.hpp/meta_types/enum_type.hpp b/headers/meta.hpp/meta_types/enum_type.hpp index 9bfc3b7..6feaaef 100644 --- a/headers/meta.hpp/meta_types/enum_type.hpp +++ b/headers/meta.hpp/meta_types/enum_type.hpp @@ -12,10 +12,72 @@ namespace meta_hpp { class enum_type final : public base_type { public: + enum_type() = default; + + enum_type(enum_type&&) = default; + enum_type& operator=(enum_type&&) = default; + + enum_type(const enum_type&) = default; + enum_type& operator=(const enum_type&) = default; + template < typename T > - explicit enum_type(typename_arg_t) - : base_type{typename_arg} { - static_assert(std::is_enum_v); - } + explicit enum_type(typename_arg_t); + + any_type raw_type() const noexcept; + any_type underlying_type() const noexcept; + bool is_const() const noexcept; + private: + struct state; + std::shared_ptr state_; }; } + +namespace meta_hpp +{ + struct enum_type::state final { + const any_type raw_type; + const any_type underlying_type; + const bool is_const; + }; +} + +namespace meta_hpp::detail +{ + template < typename T, typename = void > + struct enum_traits; + + template < typename T > + struct enum_traits>> { + using raw_type = std::remove_const_t; + using underlying_type = std::underlying_type_t; + static constexpr bool is_const{std::is_const_v}; + }; +} + +namespace meta_hpp +{ + template < typename T > + inline enum_type::enum_type(typename_arg_t) + : base_type{typename_arg} + , state_{std::make_shared(state{ + std::is_same_v::raw_type> + ? any_type{*this} + : type_db::get::raw_type>(), + type_db::get::underlying_type>(), + detail::enum_traits::is_const, + })} { + static_assert(std::is_enum_v); + } + + inline any_type enum_type::raw_type() const noexcept { + return state_->raw_type; + } + + inline any_type enum_type::underlying_type() const noexcept { + return state_->underlying_type; + } + + inline bool enum_type::is_const() const noexcept { + return state_->is_const; + } +} diff --git a/headers/meta.hpp/meta_types/function_type.hpp b/headers/meta.hpp/meta_types/function_type.hpp index 13bc58c..b4f4b4a 100644 --- a/headers/meta.hpp/meta_types/function_type.hpp +++ b/headers/meta.hpp/meta_types/function_type.hpp @@ -12,11 +12,91 @@ namespace meta_hpp { class function_type final : public base_type { public: + function_type() = default; + + function_type(function_type&&) = default; + function_type& operator=(function_type&&) = default; + + function_type(const function_type&) = default; + function_type& operator=(const function_type&) = default; + template < typename T > - explicit function_type(typename_arg_t) - : base_type{typename_arg} { - static_assert(std::is_pointer_v); - static_assert(std::is_function_v>); - } + explicit function_type(typename_arg_t); + + any_type return_type() const noexcept; + any_type argument_type(std::size_t i) const noexcept; + const std::vector& argument_types() const noexcept; + std::size_t arity() const noexcept; + bool is_noexcept() const noexcept; + private: + struct state; + std::shared_ptr state_; }; } + +namespace meta_hpp +{ + struct function_type::state final { + const any_type return_type; + const std::vector argument_types; + const std::size_t arity; + const bool is_noexcept; + }; +} + +namespace meta_hpp::detail +{ + template < typename T > + struct function_pointer_traits; + + template < typename R, typename... Args > + struct function_pointer_traits { + using return_type = R; + using argument_types = std::tuple; + static constexpr std::size_t arity{sizeof...(Args)}; + static constexpr bool is_noexcept{false}; + }; + + template < typename R, typename... Args > + struct function_pointer_traits : function_pointer_traits { + static constexpr bool is_noexcept{true}; + }; +} + +namespace meta_hpp +{ + template < typename T > + inline function_type::function_type(typename_arg_t) + : base_type{typename_arg} + , state_{std::make_shared(state{ + type_db::get::return_type>(), + type_db::multi_get::argument_types>(), + detail::function_pointer_traits::arity, + detail::function_pointer_traits::is_noexcept, + })} { + static_assert(std::is_pointer_v); + static_assert(std::is_function_v>); + } + + inline any_type function_type::return_type() const noexcept { + return state_->return_type; + } + + inline any_type function_type::argument_type(std::size_t i) const noexcept { + return i < state_->argument_types.size() + ? state_->argument_types[i] + : any_type{}; + } + + inline const std::vector& function_type::argument_types() const noexcept { + return state_->argument_types; + } + + inline std::size_t function_type::arity() const noexcept { + return state_->arity; + } + + inline bool function_type::is_noexcept() const noexcept { + return state_->is_noexcept; + } +} diff --git a/headers/meta.hpp/meta_types/member_type.hpp b/headers/meta.hpp/meta_types/member_type.hpp index 3cd3b50..93a4ed7 100644 --- a/headers/meta.hpp/meta_types/member_type.hpp +++ b/headers/meta.hpp/meta_types/member_type.hpp @@ -12,10 +12,62 @@ namespace meta_hpp { class member_type final : public base_type { public: + member_type() = default; + + member_type(member_type&&) = default; + member_type& operator=(member_type&&) = default; + + member_type(const member_type&) = default; + member_type& operator=(const member_type&) = default; + template < typename T > - explicit member_type(typename_arg_t) - : base_type{typename_arg} { - static_assert(std::is_member_object_pointer_v); - } + explicit member_type(typename_arg_t); + + any_type class_type() const noexcept; + any_type value_type() const noexcept; + private: + struct state; + std::shared_ptr state_; }; } + +namespace meta_hpp +{ + struct member_type::state final { + const any_type class_type; + const any_type value_type; + }; +} + +namespace meta_hpp::detail +{ + template < typename T > + struct method_pointer_traits; + + template < typename V, typename C > + struct method_pointer_traits { + using class_type = C; + using value_type = V; + }; +} + +namespace meta_hpp +{ + template < typename T > + inline member_type::member_type(typename_arg_t) + : base_type{typename_arg} + , state_{std::make_shared(state{ + type_db::get::class_type>(), + type_db::get::value_type>(), + })} { + static_assert(std::is_member_object_pointer_v); + } + + inline any_type member_type::class_type() const noexcept { + return state_->class_type; + } + + inline any_type member_type::value_type() const noexcept { + return state_->value_type; + } +} diff --git a/headers/meta.hpp/meta_types/method_type.hpp b/headers/meta.hpp/meta_types/method_type.hpp index 2a16b72..1be2a77 100644 --- a/headers/meta.hpp/meta_types/method_type.hpp +++ b/headers/meta.hpp/meta_types/method_type.hpp @@ -12,10 +12,117 @@ namespace meta_hpp { class method_type final : public base_type { public: + method_type() = default; + + method_type(method_type&&) = default; + method_type& operator=(method_type&&) = default; + + method_type(const method_type&) = default; + method_type& operator=(const method_type&) = default; + template < typename T > - explicit method_type(typename_arg_t) - : base_type{typename_arg} { - static_assert(std::is_member_function_pointer_v); - } + explicit method_type(typename_arg_t); + + any_type class_type() const noexcept; + any_type return_type() const noexcept; + any_type argument_type(std::size_t i) const noexcept; + const std::vector& argument_types() const noexcept; + std::size_t arity() const noexcept; + bool is_const() const noexcept; + bool is_noexcept() const noexcept; + private: + struct state; + std::shared_ptr state_; }; } + +namespace meta_hpp +{ + struct method_type::state final { + const any_type class_type; + const any_type return_type; + const std::vector argument_types; + const std::size_t arity; + const bool is_const; + const bool is_noexcept; + }; +} + +namespace meta_hpp::detail +{ + template < typename T > + struct method_pointer_traits; + + template < typename R, typename C, typename... Args > + struct method_pointer_traits { + using class_type = C; + using return_type = R; + using argument_types = std::tuple; + static constexpr std::size_t arity{sizeof...(Args)}; + static constexpr bool is_const{false}; + static constexpr bool is_noexcept{false}; + }; + + template < typename R, typename C, typename... Args > + struct method_pointer_traits : method_pointer_traits { + static constexpr bool is_const{true}; + }; + + template < typename R, typename C, typename... Args > + struct method_pointer_traits : method_pointer_traits { + static constexpr bool is_noexcept{true}; + }; + + template < typename R, typename C, typename... Args > + struct method_pointer_traits : method_pointer_traits { + static constexpr bool is_const{true}; + static constexpr bool is_noexcept{true}; + }; +} + +namespace meta_hpp +{ + template < typename T > + inline method_type::method_type(typename_arg_t) + : base_type{typename_arg} + , state_{std::make_shared(state{ + type_db::get::class_type>(), + type_db::get::return_type>(), + type_db::multi_get::argument_types>(), + detail::method_pointer_traits::arity, + detail::method_pointer_traits::is_const, + detail::method_pointer_traits::is_noexcept, + })} { + static_assert(std::is_member_function_pointer_v); + } + + inline any_type method_type::class_type() const noexcept { + return state_->class_type; + } + + inline any_type method_type::return_type() const noexcept { + return state_->return_type; + } + + inline any_type method_type::argument_type(std::size_t i) const noexcept { + return i < state_->argument_types.size() + ? state_->argument_types[i] + : any_type{}; + } + + inline const std::vector& method_type::argument_types() const noexcept { + return state_->argument_types; + } + + inline std::size_t method_type::arity() const noexcept { + return state_->arity; + } + + inline bool method_type::is_const() const noexcept { + return state_->is_const; + } + + inline bool method_type::is_noexcept() const noexcept { + return state_->is_noexcept; + } +} diff --git a/headers/meta.hpp/meta_types/pointer_type.hpp b/headers/meta.hpp/meta_types/pointer_type.hpp index 81d0734..5038f30 100644 --- a/headers/meta.hpp/meta_types/pointer_type.hpp +++ b/headers/meta.hpp/meta_types/pointer_type.hpp @@ -12,10 +12,69 @@ namespace meta_hpp { class pointer_type final : public base_type { public: + pointer_type() = default; + + pointer_type(pointer_type&&) = default; + pointer_type& operator=(pointer_type&&) = default; + + pointer_type(const pointer_type&) = default; + pointer_type& operator=(const pointer_type&) = default; + template < typename T > - explicit pointer_type(typename_arg_t) - : base_type{typename_arg} { - static_assert(std::is_pointer_v); - } + explicit pointer_type(typename_arg_t); + + any_type data_type() const noexcept; + bool is_const() const noexcept; + private: + struct state; + std::shared_ptr state_; }; } + +namespace meta_hpp +{ + struct pointer_type::state final { + const any_type data_type; + const bool is_const; + }; +} + +namespace meta_hpp::detail +{ + template < typename T > + struct pointer_traits; + + template < typename T > + struct pointer_traits { + using data_type = T; + static constexpr bool is_const{false}; + }; + + template < typename T > + struct pointer_traits { + using data_type = T; + static constexpr bool is_const{true}; + }; +} + +namespace meta_hpp +{ + template < typename T > + inline pointer_type::pointer_type(typename_arg_t) + : base_type{typename_arg} + , state_{std::make_shared(state{ + type_db::get::data_type>(), + detail::pointer_traits::is_const, + })} { + static_assert(std::is_pointer_v); + static_assert(!std::is_function_v>); + } + + inline any_type pointer_type::data_type() const noexcept { + return state_->data_type; + } + + inline bool pointer_type::is_const() const noexcept { + return state_->is_const; + } +} diff --git a/headers/meta.hpp/meta_types/reference_type.hpp b/headers/meta.hpp/meta_types/reference_type.hpp index cc9324b..3821359 100644 --- a/headers/meta.hpp/meta_types/reference_type.hpp +++ b/headers/meta.hpp/meta_types/reference_type.hpp @@ -12,10 +12,77 @@ namespace meta_hpp { class reference_type final : public base_type { public: + reference_type() = default; + + reference_type(reference_type&&) = default; + reference_type& operator=(reference_type&&) = default; + + reference_type(const reference_type&) = default; + reference_type& operator=(const reference_type&) = default; + template < typename T > - explicit reference_type(typename_arg_t) - : base_type{typename_arg} { - static_assert(std::is_reference_v); - } + explicit reference_type(typename_arg_t); + + any_type data_type() const noexcept; + bool is_lvalue() const noexcept; + bool is_rvalue() const noexcept; + private: + struct state; + std::shared_ptr state_; }; } + +namespace meta_hpp +{ + struct reference_type::state final { + const any_type data_type; + const bool is_lvalue; + const bool is_rvalue; + }; +} + +namespace meta_hpp::detail +{ + template < typename T > + struct reference_traits; + + template < typename T > + struct reference_traits { + using data_type = T; + static constexpr bool is_lvalue{true}; + static constexpr bool is_rvalue{false}; + }; + + template < typename T > + struct reference_traits { + using data_type = T; + static constexpr bool is_lvalue{false}; + static constexpr bool is_rvalue{true}; + }; +} + +namespace meta_hpp +{ + template < typename T > + inline reference_type::reference_type(typename_arg_t) + : base_type{typename_arg} + , state_{std::make_shared(state{ + type_db::get::data_type>(), + detail::reference_traits::is_lvalue, + detail::reference_traits::is_rvalue, + })} { + static_assert(std::is_reference_v); + } + + inline any_type reference_type::data_type() const noexcept { + return state_->data_type; + } + + inline bool reference_type::is_lvalue() const noexcept { + return state_->is_lvalue; + } + + inline bool reference_type::is_rvalue() const noexcept { + return state_->is_rvalue; + } +} diff --git a/headers/meta.hpp/meta_types/void_type.hpp b/headers/meta.hpp/meta_types/void_type.hpp index e8b352c..2e7a962 100644 --- a/headers/meta.hpp/meta_types/void_type.hpp +++ b/headers/meta.hpp/meta_types/void_type.hpp @@ -12,10 +12,64 @@ namespace meta_hpp { class void_type final : public base_type { public: + void_type() = default; + + void_type(void_type&&) = default; + void_type& operator=(void_type&&) = default; + + void_type(const void_type&) = default; + void_type& operator=(const void_type&) = default; + template < typename T > - explicit void_type(typename_arg_t) - : base_type{typename_arg} { - static_assert(std::is_void_v); - } + explicit void_type(typename_arg_t); + + any_type raw_type() const noexcept; + bool is_const() const noexcept; + private: + struct state; + std::shared_ptr state_; }; } + +namespace meta_hpp +{ + struct void_type::state final { + const any_type raw_type; + const bool is_const; + }; +} + +namespace meta_hpp::detail +{ + template < typename T, typename = void > + struct void_traits; + + template < typename T > + struct void_traits>> { + using raw_type = std::remove_const_t; + static constexpr bool is_const{std::is_const_v}; + }; +} + +namespace meta_hpp +{ + template < typename T > + inline void_type::void_type(typename_arg_t) + : base_type{typename_arg} + , state_{std::make_shared(state{ + std::is_same_v::raw_type> + ? any_type{*this} + : type_db::get::raw_type>(), + detail::void_traits::is_const, + })} { + static_assert(std::is_void_v); + } + + inline any_type void_type::raw_type() const noexcept { + return state_->raw_type; + } + + inline bool void_type::is_const() const noexcept { + return state_->is_const; + } +} diff --git a/untests/features/types/arithmetic_type_tests.cpp b/untests/features/types/arithmetic_type_tests.cpp index 96c5a0c..a120637 100644 --- a/untests/features/types/arithmetic_type_tests.cpp +++ b/untests/features/types/arithmetic_type_tests.cpp @@ -8,7 +8,65 @@ namespace { + using namespace meta_hpp; + using namespace std::string_literals; } TEST_CASE("features/types/arithmetic") { + SUBCASE("int") { + using type = int; + + REQUIRE(type_db::get()); + REQUIRE(type_db::get().is()); + + const arithmetic_type at = type_db::get().as(); + CHECK(at.id() == type_id{typename_arg>}); + + CHECK(at.raw_type().id() == type_db::get().id()); + CHECK(at.size() == sizeof(type)); + + CHECK_FALSE(at.is_const()); + CHECK(at.is_signed()); + CHECK_FALSE(at.is_unsigned()); + CHECK(at.is_integral()); + CHECK_FALSE(at.is_floating_point()); + } + + SUBCASE("const float") { + using type = const float; + + REQUIRE(type_db::get()); + REQUIRE(type_db::get().is()); + + const arithmetic_type at = type_db::get().as(); + CHECK(at.id() == type_id{typename_arg>}); + + CHECK(at.raw_type().id() == type_db::get().id()); + CHECK(at.size() == sizeof(type)); + + CHECK(at.is_const()); + CHECK(at.is_signed()); + CHECK_FALSE(at.is_unsigned()); + CHECK_FALSE(at.is_integral()); + CHECK(at.is_floating_point()); + } + + SUBCASE("const unsigned") { + using type = const unsigned; + + REQUIRE(type_db::get()); + REQUIRE(type_db::get().is()); + + const arithmetic_type at = type_db::get().as(); + CHECK(at.id() == type_id{typename_arg>}); + + CHECK(at.raw_type().id() == type_db::get().id()); + CHECK(at.size() == sizeof(type)); + + CHECK(at.is_const()); + CHECK_FALSE(at.is_signed()); + CHECK(at.is_unsigned()); + CHECK(at.is_integral()); + CHECK_FALSE(at.is_floating_point()); + } } diff --git a/untests/features/types/array_type_tests.cpp b/untests/features/types/array_type_tests.cpp index a373834..8ad653e 100644 --- a/untests/features/types/array_type_tests.cpp +++ b/untests/features/types/array_type_tests.cpp @@ -8,7 +8,38 @@ namespace { + using namespace meta_hpp; + using namespace std::string_literals; } TEST_CASE("features/types/array") { + SUBCASE("int[]") { + using type = int[]; + + REQUIRE(type_db::get()); + REQUIRE(type_db::get().is()); + + const array_type at = type_db::get().as(); + CHECK(at.id() == type_id{typename_arg>}); + + CHECK(at.data_type().id() == type_db::get().id()); + CHECK(at.extent() == 0); + CHECK_FALSE(at.is_bounded()); + CHECK(at.is_unbounded()); + } + + SUBCASE("const unsigned[42]") { + using type = const unsigned[42]; + + REQUIRE(type_db::get()); + REQUIRE(type_db::get().is()); + + const array_type at = type_db::get().as(); + CHECK(at.id() == type_id{typename_arg>}); + + CHECK(at.data_type().id() == type_db::get().id()); + CHECK(at.extent() == 42); + CHECK(at.is_bounded()); + CHECK_FALSE(at.is_unbounded()); + } } diff --git a/untests/features/types/class_type_tests.cpp b/untests/features/types/class_type_tests.cpp index 3e39f73..99b5b37 100644 --- a/untests/features/types/class_type_tests.cpp +++ b/untests/features/types/class_type_tests.cpp @@ -8,7 +8,121 @@ namespace { + using namespace meta_hpp; + using namespace std::string_literals; +} + +namespace +{ + struct base { + virtual ~base() = 0; + }; + + struct derived final : base { + }; + + struct empty final { + }; + + struct ivec2 final { + int x{}; + int y{}; + }; } TEST_CASE("features/types/class") { + SUBCASE("base") { + using type = base; + + REQUIRE(type_db::get()); + REQUIRE(type_db::get().is()); + + const class_type ct = type_db::get().as(); + CHECK(ct.id() == type_id{typename_arg>}); + + CHECK(ct.raw_type().id() == type_db::get().id()); + CHECK(ct.size() == sizeof(type)); + + CHECK_FALSE(ct.is_const()); + CHECK_FALSE(ct.is_empty()); + CHECK_FALSE(ct.is_final()); + CHECK(ct.is_abstract()); + CHECK(ct.is_polymorphic()); + } + + SUBCASE("derived") { + using type = derived; + + REQUIRE(type_db::get()); + REQUIRE(type_db::get().is()); + + const class_type ct = type_db::get().as(); + CHECK(ct.id() == type_id{typename_arg>}); + + CHECK(ct.raw_type().id() == type_db::get().id()); + CHECK(ct.size() == sizeof(type)); + + CHECK_FALSE(ct.is_const()); + CHECK_FALSE(ct.is_empty()); + CHECK(ct.is_final()); + CHECK_FALSE(ct.is_abstract()); + CHECK(ct.is_polymorphic()); + } + + SUBCASE("empty") { + using type = empty; + + REQUIRE(type_db::get()); + REQUIRE(type_db::get().is()); + + const class_type ct = type_db::get().as(); + CHECK(ct.id() == type_id{typename_arg>}); + + CHECK(ct.raw_type().id() == type_db::get().id()); + CHECK(ct.size() == sizeof(type)); + + CHECK_FALSE(ct.is_const()); + CHECK(ct.is_empty()); + CHECK(ct.is_final()); + CHECK_FALSE(ct.is_abstract()); + CHECK_FALSE(ct.is_polymorphic()); + } + + SUBCASE("ivec2") { + using type = ivec2; + + REQUIRE(type_db::get()); + REQUIRE(type_db::get().is()); + + const class_type ct = type_db::get().as(); + CHECK(ct.id() == type_id{typename_arg>}); + + CHECK(ct.raw_type().id() == type_db::get().id()); + CHECK(ct.size() == sizeof(type)); + + CHECK_FALSE(ct.is_const()); + CHECK_FALSE(ct.is_empty()); + CHECK(ct.is_final()); + CHECK_FALSE(ct.is_abstract()); + CHECK_FALSE(ct.is_polymorphic()); + } + + SUBCASE("const ivec2") { + using type = const ivec2; + + REQUIRE(type_db::get()); + REQUIRE(type_db::get().is()); + + const class_type ct = type_db::get().as(); + CHECK(ct.id() == type_id{typename_arg>}); + + CHECK(ct.raw_type().id() == type_db::get().id()); + CHECK(ct.size() == sizeof(type)); + + CHECK(ct.is_const()); + CHECK_FALSE(ct.is_empty()); + CHECK(ct.is_final()); + CHECK_FALSE(ct.is_abstract()); + CHECK_FALSE(ct.is_polymorphic()); + } } diff --git a/untests/features/types/ctor_type_tests.cpp b/untests/features/types/ctor_type_tests.cpp index 41e8df7..3fa34d9 100644 --- a/untests/features/types/ctor_type_tests.cpp +++ b/untests/features/types/ctor_type_tests.cpp @@ -8,7 +8,77 @@ namespace { + using namespace meta_hpp; + using namespace std::string_literals; +} + +namespace +{ + struct ivec2 final { + int x{}; + int y{}; + + ivec2() = default; + explicit ivec2(int v): x{v}, y{v} {} + ivec2(int x, int y): x{x}, y{y} {} + }; } TEST_CASE("features/types/ctor") { + SUBCASE("ivec2_void") { + ctor_type ct{typename_arg, typename_arg<>}; + + CHECK(ct.class_type().id() == type_db::get().id()); + CHECK(ct.argument_types().size() == 0); + CHECK(ct.arity() == 0); + CHECK(ct.is_noexcept()); + + { + CHECK_FALSE(ct.argument_type(0)); + } + } + + SUBCASE("ivec2_int") { + ctor_type ct{typename_arg, typename_arg}; + + CHECK_FALSE(ct.is_noexcept()); + CHECK(ct.arity() == 1); + CHECK(ct.class_type().id() == type_db::get().id()); + CHECK(ct.argument_types().size() == 1); + + { + REQUIRE(ct.argument_type(0)); + const any_type arg0 = ct.argument_type(0); + CHECK(arg0.id() == type_db::get().id()); + } + + { + CHECK_FALSE(ct.argument_type(1)); + } + } + + SUBCASE("ivec2_int_int") { + ctor_type ct{typename_arg, typename_arg}; + + CHECK(ct.class_type().id() == type_db::get().id()); + CHECK(ct.argument_types().size() == 2); + CHECK(ct.arity() == 2); + CHECK_FALSE(ct.is_noexcept()); + + { + REQUIRE(ct.argument_type(0)); + const any_type arg0 = ct.argument_type(0); + CHECK(arg0.id() == type_db::get().id()); + } + + { + REQUIRE(ct.argument_type(1)); + const any_type arg1 = ct.argument_type(1); + CHECK(arg1.id() == type_db::get().id()); + } + + { + CHECK_FALSE(ct.argument_type(2)); + } + } } diff --git a/untests/features/types/enum_type_tests.cpp b/untests/features/types/enum_type_tests.cpp index cc6da38..8ba737e 100644 --- a/untests/features/types/enum_type_tests.cpp +++ b/untests/features/types/enum_type_tests.cpp @@ -8,7 +8,45 @@ namespace { + using namespace meta_hpp; + using namespace std::string_literals; +} + +namespace +{ + enum class ecolor : unsigned { + red = 0xFF0000, + green = 0x00FF00, + blue = 0x0000FF, + }; } TEST_CASE("features/types/enum") { + SUBCASE("ecolor") { + using type = ecolor; + + REQUIRE(type_db::get()); + REQUIRE(type_db::get().is()); + + const enum_type et = type_db::get().as(); + CHECK(et.id() == type_id{typename_arg>}); + + CHECK(et.raw_type().id() == type_db::get().id()); + CHECK(et.underlying_type().id() == type_db::get().id()); + CHECK_FALSE(et.is_const()); + } + + SUBCASE("const ecolor") { + using type = const ecolor; + + REQUIRE(type_db::get()); + REQUIRE(type_db::get().is()); + + const enum_type et = type_db::get().as(); + CHECK(et.id() == type_id{typename_arg>}); + + CHECK(et.raw_type().id() == type_db::get().id()); + CHECK(et.underlying_type().id() == type_db::get().id()); + CHECK(et.is_const()); + } } diff --git a/untests/features/types/function_type_tests.cpp b/untests/features/types/function_type_tests.cpp index ab64d7d..7459767 100644 --- a/untests/features/types/function_type_tests.cpp +++ b/untests/features/types/function_type_tests.cpp @@ -8,7 +8,89 @@ namespace { + using namespace meta_hpp; + using namespace std::string_literals; +} + +namespace +{ + struct ivec2 { + int x{}; + int y{}; + }; + + void arg_copy(ivec2) {} + void arg_ref_noexcept(ivec2&) noexcept {} + void arg_cref_noexcept(const ivec2&) noexcept {} } TEST_CASE("features/types/function") { + SUBCASE("arg_copy") { + using type = decltype(&arg_copy); + + REQUIRE(type_db::get()); + REQUIRE(type_db::get().is()); + + const function_type ft = type_db::get().as(); + CHECK(ft.return_type().id() == type_db::get().id()); + CHECK(ft.argument_types().size() == 1); + CHECK(ft.arity() == 1); + CHECK_FALSE(ft.is_noexcept()); + + { + REQUIRE(ft.argument_type(0)); + const any_type arg0 = ft.argument_type(0); + CHECK(arg0.id() == type_db::get().id()); + } + + { + CHECK_FALSE(ft.argument_type(1)); + } + } + + SUBCASE("arg_ref_noexcept") { + using type = decltype(&arg_ref_noexcept); + + REQUIRE(type_db::get()); + REQUIRE(type_db::get().is()); + + const function_type ft = type_db::get().as(); + CHECK(ft.return_type().id() == type_db::get().id()); + CHECK(ft.argument_types().size() == 1); + CHECK(ft.arity() == 1); + CHECK(ft.is_noexcept()); + + { + REQUIRE(ft.argument_type(0)); + const any_type arg0 = ft.argument_type(0); + CHECK(arg0.id() == type_db::get().id()); + } + + { + CHECK_FALSE(ft.argument_type(1)); + } + } + + SUBCASE("arg_cref_noexcept") { + using type = decltype(&arg_cref_noexcept); + + REQUIRE(type_db::get()); + REQUIRE(type_db::get().is()); + + const function_type ft = type_db::get().as(); + CHECK(ft.return_type().id() == type_db::get().id()); + CHECK(ft.argument_types().size() == 1); + CHECK(ft.arity() == 1); + CHECK(ft.is_noexcept()); + + { + REQUIRE(ft.argument_type(0)); + const any_type arg0 = ft.argument_type(0); + CHECK(arg0.id() == type_db::get().id()); + } + + { + CHECK_FALSE(ft.argument_type(1)); + } + } } diff --git a/untests/features/types/member_type_tests.cpp b/untests/features/types/member_type_tests.cpp index 1bc8d60..3115124 100644 --- a/untests/features/types/member_type_tests.cpp +++ b/untests/features/types/member_type_tests.cpp @@ -8,7 +8,38 @@ namespace { + using namespace meta_hpp; + using namespace std::string_literals; +} + +namespace +{ + struct clazz { + int int_member{}; + const int const_int_member{10}; + }; } TEST_CASE("features/types/member") { + SUBCASE("clazz::int_member") { + using type = decltype(&clazz::int_member); + + REQUIRE(type_db::get()); + REQUIRE(type_db::get().is()); + + const member_type mt = type_db::get().as(); + CHECK(mt.class_type().id() == type_db::get().id()); + CHECK(mt.value_type().id() == type_db::get().id()); + } + + SUBCASE("clazz::const_int_member") { + using type = decltype(&clazz::const_int_member); + + REQUIRE(type_db::get()); + REQUIRE(type_db::get().is()); + + const member_type mt = type_db::get().as(); + CHECK(mt.class_type().id() == type_db::get().id()); + CHECK(mt.value_type().id() == type_db::get().id()); + } } diff --git a/untests/features/types/method_type_tests.cpp b/untests/features/types/method_type_tests.cpp index 18607d9..3a44321 100644 --- a/untests/features/types/method_type_tests.cpp +++ b/untests/features/types/method_type_tests.cpp @@ -8,7 +8,72 @@ namespace { + using namespace meta_hpp; + using namespace std::string_literals; +} + +namespace +{ + struct ivec2 { + int x{}; + int y{}; + + int& at(std::size_t i) { + switch ( i ) { + case 0: return x; + case 1: return y; + default: throw std::out_of_range("ivec2::at"); + } + } + + int length2() const noexcept { + return x * x + y * y; + } + }; } TEST_CASE("features/types/method") { + SUBCASE("ivec2::at") { + using type = decltype(&ivec2::at); + + REQUIRE(type_db::get()); + REQUIRE(type_db::get().is()); + + const method_type mt = type_db::get().as(); + CHECK(mt.class_type().id() == type_db::get().id()); + CHECK(mt.return_type().id() == type_db::get().id()); + CHECK(mt.argument_types().size() == 1); + CHECK(mt.arity() == 1); + CHECK_FALSE(mt.is_const()); + CHECK_FALSE(mt.is_noexcept()); + + { + REQUIRE(mt.argument_type(0)); + const any_type arg0 = mt.argument_type(0); + CHECK(arg0.id() == type_db::get().id()); + } + + { + CHECK_FALSE(mt.argument_type(1)); + } + } + + SUBCASE("ivec2::length2") { + using type = decltype(&ivec2::length2); + + REQUIRE(type_db::get()); + REQUIRE(type_db::get().is()); + + const method_type mt = type_db::get().as(); + CHECK(mt.class_type().id() == type_db::get().id()); + CHECK(mt.return_type().id() == type_db::get().id()); + CHECK(mt.argument_types().size() == 0); + CHECK(mt.arity() == 0); + CHECK(mt.is_const()); + CHECK(mt.is_noexcept()); + + { + CHECK_FALSE(mt.argument_type(0)); + } + } } diff --git a/untests/features/types/pointer_type_tests.cpp b/untests/features/types/pointer_type_tests.cpp index 133bc47..ef67ec0 100644 --- a/untests/features/types/pointer_type_tests.cpp +++ b/untests/features/types/pointer_type_tests.cpp @@ -8,7 +8,68 @@ namespace { + using namespace meta_hpp; + using namespace std::string_literals; +} + +namespace +{ + struct ivec2 { + int x{}; + int y{}; + }; } TEST_CASE("features/types/pointer") { + SUBCASE("ivec2*") { + using type = ivec2*; + + REQUIRE(type_db::get()); + REQUIRE(type_db::get().is()); + + const pointer_type pt = type_db::get().as(); + CHECK(pt.id() == type_id{typename_arg>}); + + CHECK(pt.data_type().id() == type_db::get().id()); + CHECK_FALSE(pt.is_const()); + } + + SUBCASE("const ivec2*") { + using type = const ivec2*; + + REQUIRE(type_db::get()); + REQUIRE(type_db::get().is()); + + const pointer_type pt = type_db::get().as(); + CHECK(pt.id() == type_id{typename_arg>}); + + CHECK(pt.data_type().id() == type_db::get().id()); + CHECK_FALSE(pt.is_const()); + } + + SUBCASE("ivec2* const") { + using type = ivec2* const; + + REQUIRE(type_db::get()); + REQUIRE(type_db::get().is()); + + const pointer_type pt = type_db::get().as(); + CHECK(pt.id() == type_id{typename_arg>}); + + CHECK(pt.data_type().id() == type_db::get().id()); + CHECK(pt.is_const()); + } + + SUBCASE("const ivec2* const") { + using type = const ivec2* const; + + REQUIRE(type_db::get()); + REQUIRE(type_db::get().is()); + + const pointer_type pt = type_db::get().as(); + CHECK(pt.id() == type_id{typename_arg>}); + + CHECK(pt.data_type().id() == type_db::get().id()); + CHECK(pt.is_const()); + } } diff --git a/untests/features/types/reference_type_tests.cpp b/untests/features/types/reference_type_tests.cpp index 21019ac..6c4617b 100644 --- a/untests/features/types/reference_type_tests.cpp +++ b/untests/features/types/reference_type_tests.cpp @@ -8,7 +8,40 @@ namespace { + using namespace meta_hpp; + using namespace std::string_literals; +} + +namespace +{ + struct ivec2 { + int x{}; + int y{}; + }; } TEST_CASE("features/types/reference") { + SUBCASE("ivec2&") { + REQUIRE(type_db::get()); + REQUIRE(type_db::get().is()); + + const reference_type rt = type_db::get().as(); + CHECK(rt.id() == type_id{typename_arg>}); + + CHECK(rt.data_type().id() == type_db::get().id()); + CHECK(rt.is_lvalue()); + CHECK_FALSE(rt.is_rvalue()); + } + + SUBCASE("const ivec2&&") { + REQUIRE(type_db::get()); + REQUIRE(type_db::get().is()); + + const reference_type rt = type_db::get().as(); + CHECK(rt.id() == type_id{typename_arg>}); + + CHECK(rt.data_type().id() == type_db::get().id()); + CHECK_FALSE(rt.is_lvalue()); + CHECK(rt.is_rvalue()); + } } diff --git a/untests/features/types/void_type_tests.cpp b/untests/features/types/void_type_tests.cpp index 5e29b35..f1d8103 100644 --- a/untests/features/types/void_type_tests.cpp +++ b/untests/features/types/void_type_tests.cpp @@ -8,7 +8,34 @@ namespace { + using namespace meta_hpp; + using namespace std::string_literals; } TEST_CASE("features/types/void") { + SUBCASE("void") { + using type = void; + + REQUIRE(type_db::get()); + REQUIRE(type_db::get().is()); + + const void_type vt = type_db::get().as(); + CHECK(vt.id() == type_id{typename_arg>}); + + CHECK(vt.raw_type().id() == type_db::get().id()); + CHECK_FALSE(vt.is_const()); + } + + SUBCASE("const void") { + using type = const void; + + REQUIRE(type_db::get()); + REQUIRE(type_db::get().is()); + + const void_type vt = type_db::get().as(); + CHECK(vt.id() == type_id{typename_arg>}); + + CHECK(vt.raw_type().id() == type_db::get().id()); + CHECK(vt.is_const()); + } } From 689740b858e18cfa059a665d297d85ff1db9c309 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 6 Aug 2021 02:38:51 +0700 Subject: [PATCH 080/233] update submodules --- CMakeLists.txt | 23 ++++++++++++------- untests/CMakeLists.txt | 5 +--- untests/features/types/ctor_type_tests.cpp | 6 ++--- .../features/types/function_type_tests.cpp | 6 ++--- untests/features/types/method_type_tests.cpp | 4 ++-- vendors/enum.hpp | 2 +- vendors/kari.hpp | 2 +- 7 files changed, 26 insertions(+), 22 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ed72031..78e0b6d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,15 +11,22 @@ add_subdirectory(vendors/enum.hpp) add_subdirectory(vendors/kari.hpp) add_library(${PROJECT_NAME} INTERFACE) +target_link_libraries(${PROJECT_NAME} INTERFACE enum.hpp kari.hpp) +target_compile_features(${PROJECT_NAME} INTERFACE cxx_std_17) +target_include_directories(${PROJECT_NAME} INTERFACE headers) -target_link_libraries(${PROJECT_NAME} - INTERFACE enum.hpp kari.hpp) - -target_compile_features(${PROJECT_NAME} - INTERFACE cxx_std_17) - -target_include_directories(${PROJECT_NAME} - INTERFACE headers) +target_compile_options(${PROJECT_NAME} + INTERFACE + $<$,$>: + -Wno-c++98-compat-pedantic + -Wno-covered-switch-default + -Wno-ctad-maybe-unsupported + -Wno-exit-time-destructors + -Wno-padded + -Wno-poison-system-directories + -Wno-shadow + -Wno-unknown-warning-option + -Wno-weak-vtables>) if(BUILD_AS_STANDALONE) option(BUILD_WITH_UNTESTS "Build with unit tests" ON) diff --git a/untests/CMakeLists.txt b/untests/CMakeLists.txt index 8e18fd3..1ce7207 100644 --- a/untests/CMakeLists.txt +++ b/untests/CMakeLists.txt @@ -29,9 +29,6 @@ target_compile_options(${PROJECT_NAME} -Werror -Wall -Wextra -Wpedantic> PRIVATE $<$,$>: - -Werror -Weverything -Wconversion -Wno-unknown-warning-option - -Wno-padded - -Wno-c++98-compat-pedantic - -Wno-shadow-field-in-constructor>) + -Werror -Weverything -Wconversion>) add_test(${PROJECT_NAME} ${PROJECT_NAME}) diff --git a/untests/features/types/ctor_type_tests.cpp b/untests/features/types/ctor_type_tests.cpp index 3fa34d9..61b8f53 100644 --- a/untests/features/types/ctor_type_tests.cpp +++ b/untests/features/types/ctor_type_tests.cpp @@ -18,9 +18,9 @@ namespace int x{}; int y{}; - ivec2() = default; - explicit ivec2(int v): x{v}, y{v} {} - ivec2(int x, int y): x{x}, y{y} {} + [[maybe_unused]] ivec2() = default; + [[maybe_unused]] explicit ivec2(int v): x{v}, y{v} {} + [[maybe_unused]] ivec2(int x, int y): x{x}, y{y} {} }; } diff --git a/untests/features/types/function_type_tests.cpp b/untests/features/types/function_type_tests.cpp index 7459767..b76a244 100644 --- a/untests/features/types/function_type_tests.cpp +++ b/untests/features/types/function_type_tests.cpp @@ -19,9 +19,9 @@ namespace int y{}; }; - void arg_copy(ivec2) {} - void arg_ref_noexcept(ivec2&) noexcept {} - void arg_cref_noexcept(const ivec2&) noexcept {} + [[maybe_unused]] void arg_copy(ivec2) {} + [[maybe_unused]] void arg_ref_noexcept(ivec2&) noexcept {} + [[maybe_unused]] void arg_cref_noexcept(const ivec2&) noexcept {} } TEST_CASE("features/types/function") { diff --git a/untests/features/types/method_type_tests.cpp b/untests/features/types/method_type_tests.cpp index 3a44321..952422e 100644 --- a/untests/features/types/method_type_tests.cpp +++ b/untests/features/types/method_type_tests.cpp @@ -18,7 +18,7 @@ namespace int x{}; int y{}; - int& at(std::size_t i) { + [[maybe_unused]] int& at(std::size_t i) { switch ( i ) { case 0: return x; case 1: return y; @@ -26,7 +26,7 @@ namespace } } - int length2() const noexcept { + [[maybe_unused]] int length2() const noexcept { return x * x + y * y; } }; diff --git a/vendors/enum.hpp b/vendors/enum.hpp index 0a549d3..ba3d7db 160000 --- a/vendors/enum.hpp +++ b/vendors/enum.hpp @@ -1 +1 @@ -Subproject commit 0a549d3341e8f6d9efd8e6cea343f2d3ab4e7633 +Subproject commit ba3d7db0ad3612358ffbbebdd9bc922e8c144189 diff --git a/vendors/kari.hpp b/vendors/kari.hpp index c52226f..c6f6a73 160000 --- a/vendors/kari.hpp +++ b/vendors/kari.hpp @@ -1 +1 @@ -Subproject commit c52226f8556a0a439389514143f336fe4979b480 +Subproject commit c6f6a73a4f7ed9d60677ae5376a218aea379be38 From 85ff0b31fd12571fcdee3282f8a91345c8796a06 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 6 Aug 2021 02:42:13 +0700 Subject: [PATCH 081/233] add doctest as submodule --- .gitmodules | 3 + CMakeLists.txt | 1 + untests/CMakeLists.txt | 2 +- untests/doctest/doctest.cpp | 2 - untests/doctest/doctest.h | 6580 ----------------------------------- untests/doctest/doctest.hpp | 14 - untests/meta_tests.hpp | 2 +- vendors/doctest | 1 + 8 files changed, 7 insertions(+), 6598 deletions(-) delete mode 100644 untests/doctest/doctest.cpp delete mode 100644 untests/doctest/doctest.h delete mode 100644 untests/doctest/doctest.hpp create mode 160000 vendors/doctest diff --git a/.gitmodules b/.gitmodules index e9f4823..a512f37 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "vendors/kari.hpp"] path = vendors/kari.hpp url = https://github.com/BlackMATov/kari.hpp +[submodule "vendors/doctest"] + path = vendors/doctest + url = https://github.com/onqtam/doctest diff --git a/CMakeLists.txt b/CMakeLists.txt index 78e0b6d..a007d89 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,6 +32,7 @@ if(BUILD_AS_STANDALONE) option(BUILD_WITH_UNTESTS "Build with unit tests" ON) if(BUILD_WITH_UNTESTS) enable_testing() + add_subdirectory(vendors/doctest) add_subdirectory(untests) endif() endif() diff --git a/untests/CMakeLists.txt b/untests/CMakeLists.txt index 1ce7207..2fc86fc 100644 --- a/untests/CMakeLists.txt +++ b/untests/CMakeLists.txt @@ -18,7 +18,7 @@ endif() file(GLOB_RECURSE UNTESTS_SOURCES "*.cpp" "*.hpp") add_executable(${PROJECT_NAME} ${UNTESTS_SOURCES}) -target_link_libraries(${PROJECT_NAME} meta.hpp) +target_link_libraries(${PROJECT_NAME} meta.hpp doctest_with_main) target_compile_options(${PROJECT_NAME} PRIVATE diff --git a/untests/doctest/doctest.cpp b/untests/doctest/doctest.cpp deleted file mode 100644 index a3f832e..0000000 --- a/untests/doctest/doctest.cpp +++ /dev/null @@ -1,2 +0,0 @@ -#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN -#include "doctest.h" diff --git a/untests/doctest/doctest.h b/untests/doctest/doctest.h deleted file mode 100644 index 42eb039..0000000 --- a/untests/doctest/doctest.h +++ /dev/null @@ -1,6580 +0,0 @@ -// ====================================================================== lgtm [cpp/missing-header-guard] -// == DO NOT MODIFY THIS FILE BY HAND - IT IS AUTO GENERATED BY CMAKE! == -// ====================================================================== -// -// doctest.h - the lightest feature-rich C++ single-header testing framework for unit tests and TDD -// -// Copyright (c) 2016-2021 Viktor Kirilov -// -// Distributed under the MIT Software License -// See accompanying file LICENSE.txt or copy at -// https://opensource.org/licenses/MIT -// -// The documentation can be found at the library's page: -// https://github.com/onqtam/doctest/blob/master/doc/markdown/readme.md -// -// ================================================================================================= -// ================================================================================================= -// ================================================================================================= -// -// The library is heavily influenced by Catch - https://github.com/catchorg/Catch2 -// which uses the Boost Software License - Version 1.0 -// see here - https://github.com/catchorg/Catch2/blob/master/LICENSE.txt -// -// The concept of subcases (sections in Catch) and expression decomposition are from there. -// Some parts of the code are taken directly: -// - stringification - the detection of "ostream& operator<<(ostream&, const T&)" and StringMaker<> -// - the Approx() helper class for floating point comparison -// - colors in the console -// - breaking into a debugger -// - signal / SEH handling -// - timer -// - XmlWriter class - thanks to Phil Nash for allowing the direct reuse (AKA copy/paste) -// -// The expression decomposing templates are taken from lest - https://github.com/martinmoene/lest -// which uses the Boost Software License - Version 1.0 -// see here - https://github.com/martinmoene/lest/blob/master/LICENSE.txt -// -// ================================================================================================= -// ================================================================================================= -// ================================================================================================= - -#ifndef DOCTEST_LIBRARY_INCLUDED -#define DOCTEST_LIBRARY_INCLUDED - -// ================================================================================================= -// == VERSION ====================================================================================== -// ================================================================================================= - -#define DOCTEST_VERSION_MAJOR 2 -#define DOCTEST_VERSION_MINOR 4 -#define DOCTEST_VERSION_PATCH 6 -#define DOCTEST_VERSION_STR "2.4.6" - -#define DOCTEST_VERSION \ - (DOCTEST_VERSION_MAJOR * 10000 + DOCTEST_VERSION_MINOR * 100 + DOCTEST_VERSION_PATCH) - -// ================================================================================================= -// == COMPILER VERSION ============================================================================= -// ================================================================================================= - -// ideas for the version stuff are taken from here: https://github.com/cxxstuff/cxx_detect - -#define DOCTEST_COMPILER(MAJOR, MINOR, PATCH) ((MAJOR)*10000000 + (MINOR)*100000 + (PATCH)) - -// GCC/Clang and GCC/MSVC are mutually exclusive, but Clang/MSVC are not because of clang-cl... -#if defined(_MSC_VER) && defined(_MSC_FULL_VER) -#if _MSC_VER == _MSC_FULL_VER / 10000 -#define DOCTEST_MSVC DOCTEST_COMPILER(_MSC_VER / 100, _MSC_VER % 100, _MSC_FULL_VER % 10000) -#else // MSVC -#define DOCTEST_MSVC \ - DOCTEST_COMPILER(_MSC_VER / 100, (_MSC_FULL_VER / 100000) % 100, _MSC_FULL_VER % 100000) -#endif // MSVC -#endif // MSVC -#if defined(__clang__) && defined(__clang_minor__) -#define DOCTEST_CLANG DOCTEST_COMPILER(__clang_major__, __clang_minor__, __clang_patchlevel__) -#elif defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) && \ - !defined(__INTEL_COMPILER) -#define DOCTEST_GCC DOCTEST_COMPILER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) -#endif // GCC - -#ifndef DOCTEST_MSVC -#define DOCTEST_MSVC 0 -#endif // DOCTEST_MSVC -#ifndef DOCTEST_CLANG -#define DOCTEST_CLANG 0 -#endif // DOCTEST_CLANG -#ifndef DOCTEST_GCC -#define DOCTEST_GCC 0 -#endif // DOCTEST_GCC - -// ================================================================================================= -// == COMPILER WARNINGS HELPERS ==================================================================== -// ================================================================================================= - -#if DOCTEST_CLANG -#define DOCTEST_PRAGMA_TO_STR(x) _Pragma(#x) -#define DOCTEST_CLANG_SUPPRESS_WARNING_PUSH _Pragma("clang diagnostic push") -#define DOCTEST_CLANG_SUPPRESS_WARNING(w) DOCTEST_PRAGMA_TO_STR(clang diagnostic ignored w) -#define DOCTEST_CLANG_SUPPRESS_WARNING_POP _Pragma("clang diagnostic pop") -#define DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH(w) \ - DOCTEST_CLANG_SUPPRESS_WARNING_PUSH DOCTEST_CLANG_SUPPRESS_WARNING(w) -#else // DOCTEST_CLANG -#define DOCTEST_CLANG_SUPPRESS_WARNING_PUSH -#define DOCTEST_CLANG_SUPPRESS_WARNING(w) -#define DOCTEST_CLANG_SUPPRESS_WARNING_POP -#define DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH(w) -#endif // DOCTEST_CLANG - -#if DOCTEST_GCC -#define DOCTEST_PRAGMA_TO_STR(x) _Pragma(#x) -#define DOCTEST_GCC_SUPPRESS_WARNING_PUSH _Pragma("GCC diagnostic push") -#define DOCTEST_GCC_SUPPRESS_WARNING(w) DOCTEST_PRAGMA_TO_STR(GCC diagnostic ignored w) -#define DOCTEST_GCC_SUPPRESS_WARNING_POP _Pragma("GCC diagnostic pop") -#define DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH(w) \ - DOCTEST_GCC_SUPPRESS_WARNING_PUSH DOCTEST_GCC_SUPPRESS_WARNING(w) -#else // DOCTEST_GCC -#define DOCTEST_GCC_SUPPRESS_WARNING_PUSH -#define DOCTEST_GCC_SUPPRESS_WARNING(w) -#define DOCTEST_GCC_SUPPRESS_WARNING_POP -#define DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH(w) -#endif // DOCTEST_GCC - -#if DOCTEST_MSVC -#define DOCTEST_MSVC_SUPPRESS_WARNING_PUSH __pragma(warning(push)) -#define DOCTEST_MSVC_SUPPRESS_WARNING(w) __pragma(warning(disable : w)) -#define DOCTEST_MSVC_SUPPRESS_WARNING_POP __pragma(warning(pop)) -#define DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(w) \ - DOCTEST_MSVC_SUPPRESS_WARNING_PUSH DOCTEST_MSVC_SUPPRESS_WARNING(w) -#else // DOCTEST_MSVC -#define DOCTEST_MSVC_SUPPRESS_WARNING_PUSH -#define DOCTEST_MSVC_SUPPRESS_WARNING(w) -#define DOCTEST_MSVC_SUPPRESS_WARNING_POP -#define DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(w) -#endif // DOCTEST_MSVC - -// ================================================================================================= -// == COMPILER WARNINGS ============================================================================ -// ================================================================================================= - -DOCTEST_CLANG_SUPPRESS_WARNING_PUSH -DOCTEST_CLANG_SUPPRESS_WARNING("-Wunknown-pragmas") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wnon-virtual-dtor") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wweak-vtables") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wpadded") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wdeprecated") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wmissing-prototypes") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wunused-local-typedef") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wc++98-compat") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wc++98-compat-pedantic") - -DOCTEST_GCC_SUPPRESS_WARNING_PUSH -DOCTEST_GCC_SUPPRESS_WARNING("-Wunknown-pragmas") -DOCTEST_GCC_SUPPRESS_WARNING("-Wpragmas") -DOCTEST_GCC_SUPPRESS_WARNING("-Weffc++") -DOCTEST_GCC_SUPPRESS_WARNING("-Wstrict-overflow") -DOCTEST_GCC_SUPPRESS_WARNING("-Wstrict-aliasing") -DOCTEST_GCC_SUPPRESS_WARNING("-Wctor-dtor-privacy") -DOCTEST_GCC_SUPPRESS_WARNING("-Wmissing-declarations") -DOCTEST_GCC_SUPPRESS_WARNING("-Wnon-virtual-dtor") -DOCTEST_GCC_SUPPRESS_WARNING("-Wunused-local-typedefs") -DOCTEST_GCC_SUPPRESS_WARNING("-Wuseless-cast") -DOCTEST_GCC_SUPPRESS_WARNING("-Wnoexcept") -DOCTEST_GCC_SUPPRESS_WARNING("-Wsign-promo") - -DOCTEST_MSVC_SUPPRESS_WARNING_PUSH -DOCTEST_MSVC_SUPPRESS_WARNING(4616) // invalid compiler warning -DOCTEST_MSVC_SUPPRESS_WARNING(4619) // invalid compiler warning -DOCTEST_MSVC_SUPPRESS_WARNING(4996) // The compiler encountered a deprecated declaration -DOCTEST_MSVC_SUPPRESS_WARNING(4706) // assignment within conditional expression -DOCTEST_MSVC_SUPPRESS_WARNING(4512) // 'class' : assignment operator could not be generated -DOCTEST_MSVC_SUPPRESS_WARNING(4127) // conditional expression is constant -DOCTEST_MSVC_SUPPRESS_WARNING(4820) // padding -DOCTEST_MSVC_SUPPRESS_WARNING(4625) // copy constructor was implicitly defined as deleted -DOCTEST_MSVC_SUPPRESS_WARNING(4626) // assignment operator was implicitly defined as deleted -DOCTEST_MSVC_SUPPRESS_WARNING(5027) // move assignment operator was implicitly defined as deleted -DOCTEST_MSVC_SUPPRESS_WARNING(5026) // move constructor was implicitly defined as deleted -DOCTEST_MSVC_SUPPRESS_WARNING(4623) // default constructor was implicitly defined as deleted -DOCTEST_MSVC_SUPPRESS_WARNING(4640) // construction of local static object is not thread-safe -// static analysis -DOCTEST_MSVC_SUPPRESS_WARNING(26439) // This kind of function may not throw. Declare it 'noexcept' -DOCTEST_MSVC_SUPPRESS_WARNING(26495) // Always initialize a member variable -DOCTEST_MSVC_SUPPRESS_WARNING(26451) // Arithmetic overflow ... -DOCTEST_MSVC_SUPPRESS_WARNING(26444) // Avoid unnamed objects with custom construction and dtr... -DOCTEST_MSVC_SUPPRESS_WARNING(26812) // Prefer 'enum class' over 'enum' - -// 4548 - expression before comma has no effect; expected expression with side - effect -// 4265 - class has virtual functions, but destructor is not virtual -// 4986 - exception specification does not match previous declaration -// 4350 - behavior change: 'member1' called instead of 'member2' -// 4668 - 'x' is not defined as a preprocessor macro, replacing with '0' for '#if/#elif' -// 4365 - conversion from 'int' to 'unsigned long', signed/unsigned mismatch -// 4774 - format string expected in argument 'x' is not a string literal -// 4820 - padding in structs - -// only 4 should be disabled globally: -// - 4514 # unreferenced inline function has been removed -// - 4571 # SEH related -// - 4710 # function not inlined -// - 4711 # function 'x' selected for automatic inline expansion - -#define DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_BEGIN \ - DOCTEST_MSVC_SUPPRESS_WARNING_PUSH \ - DOCTEST_MSVC_SUPPRESS_WARNING(4548) \ - DOCTEST_MSVC_SUPPRESS_WARNING(4265) \ - DOCTEST_MSVC_SUPPRESS_WARNING(4986) \ - DOCTEST_MSVC_SUPPRESS_WARNING(4350) \ - DOCTEST_MSVC_SUPPRESS_WARNING(4668) \ - DOCTEST_MSVC_SUPPRESS_WARNING(4365) \ - DOCTEST_MSVC_SUPPRESS_WARNING(4774) \ - DOCTEST_MSVC_SUPPRESS_WARNING(4820) \ - DOCTEST_MSVC_SUPPRESS_WARNING(4625) \ - DOCTEST_MSVC_SUPPRESS_WARNING(4626) \ - DOCTEST_MSVC_SUPPRESS_WARNING(5027) \ - DOCTEST_MSVC_SUPPRESS_WARNING(5026) \ - DOCTEST_MSVC_SUPPRESS_WARNING(4623) \ - DOCTEST_MSVC_SUPPRESS_WARNING(5039) \ - DOCTEST_MSVC_SUPPRESS_WARNING(5045) \ - DOCTEST_MSVC_SUPPRESS_WARNING(5105) - -#define DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_END DOCTEST_MSVC_SUPPRESS_WARNING_POP - -// ================================================================================================= -// == FEATURE DETECTION ============================================================================ -// ================================================================================================= - -// general compiler feature support table: https://en.cppreference.com/w/cpp/compiler_support -// MSVC C++11 feature support table: https://msdn.microsoft.com/en-us/library/hh567368.aspx -// GCC C++11 feature support table: https://gcc.gnu.org/projects/cxx-status.html -// MSVC version table: -// https://en.wikipedia.org/wiki/Microsoft_Visual_C%2B%2B#Internal_version_numbering -// MSVC++ 14.2 (16) _MSC_VER == 1920 (Visual Studio 2019) -// MSVC++ 14.1 (15) _MSC_VER == 1910 (Visual Studio 2017) -// MSVC++ 14.0 _MSC_VER == 1900 (Visual Studio 2015) -// MSVC++ 12.0 _MSC_VER == 1800 (Visual Studio 2013) -// MSVC++ 11.0 _MSC_VER == 1700 (Visual Studio 2012) -// MSVC++ 10.0 _MSC_VER == 1600 (Visual Studio 2010) -// MSVC++ 9.0 _MSC_VER == 1500 (Visual Studio 2008) -// MSVC++ 8.0 _MSC_VER == 1400 (Visual Studio 2005) - -#if DOCTEST_MSVC && !defined(DOCTEST_CONFIG_WINDOWS_SEH) -#define DOCTEST_CONFIG_WINDOWS_SEH -#endif // MSVC -#if defined(DOCTEST_CONFIG_NO_WINDOWS_SEH) && defined(DOCTEST_CONFIG_WINDOWS_SEH) -#undef DOCTEST_CONFIG_WINDOWS_SEH -#endif // DOCTEST_CONFIG_NO_WINDOWS_SEH - -#if !defined(_WIN32) && !defined(__QNX__) && !defined(DOCTEST_CONFIG_POSIX_SIGNALS) && \ - !defined(__EMSCRIPTEN__) -#define DOCTEST_CONFIG_POSIX_SIGNALS -#endif // _WIN32 -#if defined(DOCTEST_CONFIG_NO_POSIX_SIGNALS) && defined(DOCTEST_CONFIG_POSIX_SIGNALS) -#undef DOCTEST_CONFIG_POSIX_SIGNALS -#endif // DOCTEST_CONFIG_NO_POSIX_SIGNALS - -#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS -#if !defined(__cpp_exceptions) && !defined(__EXCEPTIONS) && !defined(_CPPUNWIND) -#define DOCTEST_CONFIG_NO_EXCEPTIONS -#endif // no exceptions -#endif // DOCTEST_CONFIG_NO_EXCEPTIONS - -#ifdef DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS -#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS -#define DOCTEST_CONFIG_NO_EXCEPTIONS -#endif // DOCTEST_CONFIG_NO_EXCEPTIONS -#endif // DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS - -#if defined(DOCTEST_CONFIG_NO_EXCEPTIONS) && !defined(DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS) -#define DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS -#endif // DOCTEST_CONFIG_NO_EXCEPTIONS && !DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS - -#if defined(DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN) && !defined(DOCTEST_CONFIG_IMPLEMENT) -#define DOCTEST_CONFIG_IMPLEMENT -#endif // DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN - -#if defined(_WIN32) || defined(__CYGWIN__) -#if DOCTEST_MSVC -#define DOCTEST_SYMBOL_EXPORT __declspec(dllexport) -#define DOCTEST_SYMBOL_IMPORT __declspec(dllimport) -#else // MSVC -#define DOCTEST_SYMBOL_EXPORT __attribute__((dllexport)) -#define DOCTEST_SYMBOL_IMPORT __attribute__((dllimport)) -#endif // MSVC -#else // _WIN32 -#define DOCTEST_SYMBOL_EXPORT __attribute__((visibility("default"))) -#define DOCTEST_SYMBOL_IMPORT -#endif // _WIN32 - -#ifdef DOCTEST_CONFIG_IMPLEMENTATION_IN_DLL -#ifdef DOCTEST_CONFIG_IMPLEMENT -#define DOCTEST_INTERFACE DOCTEST_SYMBOL_EXPORT -#else // DOCTEST_CONFIG_IMPLEMENT -#define DOCTEST_INTERFACE DOCTEST_SYMBOL_IMPORT -#endif // DOCTEST_CONFIG_IMPLEMENT -#else // DOCTEST_CONFIG_IMPLEMENTATION_IN_DLL -#define DOCTEST_INTERFACE -#endif // DOCTEST_CONFIG_IMPLEMENTATION_IN_DLL - -#define DOCTEST_EMPTY - -#if DOCTEST_MSVC -#define DOCTEST_NOINLINE __declspec(noinline) -#define DOCTEST_UNUSED -#define DOCTEST_ALIGNMENT(x) -#elif DOCTEST_CLANG && DOCTEST_CLANG < DOCTEST_COMPILER(3, 5, 0) -#define DOCTEST_NOINLINE -#define DOCTEST_UNUSED -#define DOCTEST_ALIGNMENT(x) -#else -#define DOCTEST_NOINLINE __attribute__((noinline)) -#define DOCTEST_UNUSED __attribute__((unused)) -#define DOCTEST_ALIGNMENT(x) __attribute__((aligned(x))) -#endif - -#ifndef DOCTEST_NORETURN -#define DOCTEST_NORETURN [[noreturn]] -#endif // DOCTEST_NORETURN - -#ifndef DOCTEST_NOEXCEPT -#define DOCTEST_NOEXCEPT noexcept -#endif // DOCTEST_NOEXCEPT - -// ================================================================================================= -// == FEATURE DETECTION END ======================================================================== -// ================================================================================================= - -// internal macros for string concatenation and anonymous variable name generation -#define DOCTEST_CAT_IMPL(s1, s2) s1##s2 -#define DOCTEST_CAT(s1, s2) DOCTEST_CAT_IMPL(s1, s2) -#ifdef __COUNTER__ // not standard and may be missing for some compilers -#define DOCTEST_ANONYMOUS(x) DOCTEST_CAT(x, __COUNTER__) -#else // __COUNTER__ -#define DOCTEST_ANONYMOUS(x) DOCTEST_CAT(x, __LINE__) -#endif // __COUNTER__ - -#define DOCTEST_TOSTR(x) #x - -#ifndef DOCTEST_CONFIG_ASSERTION_PARAMETERS_BY_VALUE -#define DOCTEST_REF_WRAP(x) x& -#else // DOCTEST_CONFIG_ASSERTION_PARAMETERS_BY_VALUE -#define DOCTEST_REF_WRAP(x) x -#endif // DOCTEST_CONFIG_ASSERTION_PARAMETERS_BY_VALUE - -// not using __APPLE__ because... this is how Catch does it -#ifdef __MAC_OS_X_VERSION_MIN_REQUIRED -#define DOCTEST_PLATFORM_MAC -#elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED) -#define DOCTEST_PLATFORM_IPHONE -#elif defined(_WIN32) -#define DOCTEST_PLATFORM_WINDOWS -#else // DOCTEST_PLATFORM -#define DOCTEST_PLATFORM_LINUX -#endif // DOCTEST_PLATFORM - -#define DOCTEST_GLOBAL_NO_WARNINGS(var) \ - DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wglobal-constructors") \ - DOCTEST_CLANG_SUPPRESS_WARNING("-Wunused-variable") \ - static const int var DOCTEST_UNUSED // NOLINT(fuchsia-statically-constructed-objects,cert-err58-cpp) -#define DOCTEST_GLOBAL_NO_WARNINGS_END() DOCTEST_CLANG_SUPPRESS_WARNING_POP - -#ifndef DOCTEST_BREAK_INTO_DEBUGGER -// should probably take a look at https://github.com/scottt/debugbreak -#ifdef DOCTEST_PLATFORM_LINUX -#if defined(__GNUC__) && (defined(__i386) || defined(__x86_64)) -// Break at the location of the failing check if possible -#define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("int $3\n" : :) // NOLINT (hicpp-no-assembler) -#else -#include -#define DOCTEST_BREAK_INTO_DEBUGGER() raise(SIGTRAP) -#endif -#elif defined(DOCTEST_PLATFORM_MAC) -#if defined(__x86_64) || defined(__x86_64__) || defined(__amd64__) || defined(__i386) -#define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("int $3\n" : :) // NOLINT (hicpp-no-assembler) -#else -#define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("brk #0"); // NOLINT (hicpp-no-assembler) -#endif -#elif DOCTEST_MSVC -#define DOCTEST_BREAK_INTO_DEBUGGER() __debugbreak() -#elif defined(__MINGW32__) -DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wredundant-decls") -extern "C" __declspec(dllimport) void __stdcall DebugBreak(); -DOCTEST_GCC_SUPPRESS_WARNING_POP -#define DOCTEST_BREAK_INTO_DEBUGGER() ::DebugBreak() -#else // linux -#define DOCTEST_BREAK_INTO_DEBUGGER() (static_cast(0)) -#endif // linux -#endif // DOCTEST_BREAK_INTO_DEBUGGER - -// this is kept here for backwards compatibility since the config option was changed -#ifdef DOCTEST_CONFIG_USE_IOSFWD -#define DOCTEST_CONFIG_USE_STD_HEADERS -#endif // DOCTEST_CONFIG_USE_IOSFWD - -#ifdef DOCTEST_CONFIG_USE_STD_HEADERS -#ifndef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS -#define DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS -#endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS -#include -#include -#include -#else // DOCTEST_CONFIG_USE_STD_HEADERS - -#if DOCTEST_CLANG -// to detect if libc++ is being used with clang (the _LIBCPP_VERSION identifier) -#include -#endif // clang - -#ifdef _LIBCPP_VERSION -#define DOCTEST_STD_NAMESPACE_BEGIN _LIBCPP_BEGIN_NAMESPACE_STD -#define DOCTEST_STD_NAMESPACE_END _LIBCPP_END_NAMESPACE_STD -#else // _LIBCPP_VERSION -#define DOCTEST_STD_NAMESPACE_BEGIN namespace std { -#define DOCTEST_STD_NAMESPACE_END } -#endif // _LIBCPP_VERSION - -// Forward declaring 'X' in namespace std is not permitted by the C++ Standard. -DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4643) - -DOCTEST_STD_NAMESPACE_BEGIN // NOLINT (cert-dcl58-cpp) -typedef decltype(nullptr) nullptr_t; -template -struct char_traits; -template <> -struct char_traits; -template -class basic_ostream; -typedef basic_ostream> ostream; -template -class tuple; -#if DOCTEST_MSVC >= DOCTEST_COMPILER(19, 20, 0) -// see this issue on why this is needed: https://github.com/onqtam/doctest/issues/183 -template -class allocator; -template -class basic_string; -using string = basic_string, allocator>; -#endif // VS 2019 -DOCTEST_STD_NAMESPACE_END - -DOCTEST_MSVC_SUPPRESS_WARNING_POP - -#endif // DOCTEST_CONFIG_USE_STD_HEADERS - -#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS -#include -#endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS - -namespace doctest { - -DOCTEST_INTERFACE extern bool is_running_in_test; - -// A 24 byte string class (can be as small as 17 for x64 and 13 for x86) that can hold strings with length -// of up to 23 chars on the stack before going on the heap - the last byte of the buffer is used for: -// - "is small" bit - the highest bit - if "0" then it is small - otherwise its "1" (128) -// - if small - capacity left before going on the heap - using the lowest 5 bits -// - if small - 2 bits are left unused - the second and third highest ones -// - if small - acts as a null terminator if strlen() is 23 (24 including the null terminator) -// and the "is small" bit remains "0" ("as well as the capacity left") so its OK -// Idea taken from this lecture about the string implementation of facebook/folly - fbstring -// https://www.youtube.com/watch?v=kPR8h4-qZdk -// TODO: -// - optimizations - like not deleting memory unnecessarily in operator= and etc. -// - resize/reserve/clear -// - substr -// - replace -// - back/front -// - iterator stuff -// - find & friends -// - push_back/pop_back -// - assign/insert/erase -// - relational operators as free functions - taking const char* as one of the params -class DOCTEST_INTERFACE String -{ - static const unsigned len = 24; //!OCLINT avoid private static members - static const unsigned last = len - 1; //!OCLINT avoid private static members - - struct view // len should be more than sizeof(view) - because of the final byte for flags - { - char* ptr; - unsigned size; - unsigned capacity; - }; - - union - { - char buf[len]; - view data; - }; - - bool isOnStack() const { return (buf[last] & 128) == 0; } - void setOnHeap(); - void setLast(unsigned in = last); - - void copy(const String& other); - -public: - String(); - ~String(); - - // cppcheck-suppress noExplicitConstructor - String(const char* in); - String(const char* in, unsigned in_size); - - String(const String& other); - String& operator=(const String& other); - - String& operator+=(const String& other); - String operator+(const String& other) const; - - String(String&& other); - String& operator=(String&& other); - - char operator[](unsigned i) const; - char& operator[](unsigned i); - - // the only functions I'm willing to leave in the interface - available for inlining - const char* c_str() const { return const_cast(this)->c_str(); } // NOLINT - char* c_str() { - if(isOnStack()) - return reinterpret_cast(buf); - return data.ptr; - } - - unsigned size() const; - unsigned capacity() const; - - int compare(const char* other, bool no_case = false) const; - int compare(const String& other, bool no_case = false) const; -}; - -DOCTEST_INTERFACE bool operator==(const String& lhs, const String& rhs); -DOCTEST_INTERFACE bool operator!=(const String& lhs, const String& rhs); -DOCTEST_INTERFACE bool operator<(const String& lhs, const String& rhs); -DOCTEST_INTERFACE bool operator>(const String& lhs, const String& rhs); -DOCTEST_INTERFACE bool operator<=(const String& lhs, const String& rhs); -DOCTEST_INTERFACE bool operator>=(const String& lhs, const String& rhs); - -DOCTEST_INTERFACE std::ostream& operator<<(std::ostream& s, const String& in); - -namespace Color { - enum Enum - { - None = 0, - White, - Red, - Green, - Blue, - Cyan, - Yellow, - Grey, - - Bright = 0x10, - - BrightRed = Bright | Red, - BrightGreen = Bright | Green, - LightGrey = Bright | Grey, - BrightWhite = Bright | White - }; - - DOCTEST_INTERFACE std::ostream& operator<<(std::ostream& s, Color::Enum code); -} // namespace Color - -namespace assertType { - enum Enum - { - // macro traits - - is_warn = 1, - is_check = 2 * is_warn, - is_require = 2 * is_check, - - is_normal = 2 * is_require, - is_throws = 2 * is_normal, - is_throws_as = 2 * is_throws, - is_throws_with = 2 * is_throws_as, - is_nothrow = 2 * is_throws_with, - - is_false = 2 * is_nothrow, - is_unary = 2 * is_false, // not checked anywhere - used just to distinguish the types - - is_eq = 2 * is_unary, - is_ne = 2 * is_eq, - - is_lt = 2 * is_ne, - is_gt = 2 * is_lt, - - is_ge = 2 * is_gt, - is_le = 2 * is_ge, - - // macro types - - DT_WARN = is_normal | is_warn, - DT_CHECK = is_normal | is_check, - DT_REQUIRE = is_normal | is_require, - - DT_WARN_FALSE = is_normal | is_false | is_warn, - DT_CHECK_FALSE = is_normal | is_false | is_check, - DT_REQUIRE_FALSE = is_normal | is_false | is_require, - - DT_WARN_THROWS = is_throws | is_warn, - DT_CHECK_THROWS = is_throws | is_check, - DT_REQUIRE_THROWS = is_throws | is_require, - - DT_WARN_THROWS_AS = is_throws_as | is_warn, - DT_CHECK_THROWS_AS = is_throws_as | is_check, - DT_REQUIRE_THROWS_AS = is_throws_as | is_require, - - DT_WARN_THROWS_WITH = is_throws_with | is_warn, - DT_CHECK_THROWS_WITH = is_throws_with | is_check, - DT_REQUIRE_THROWS_WITH = is_throws_with | is_require, - - DT_WARN_THROWS_WITH_AS = is_throws_with | is_throws_as | is_warn, - DT_CHECK_THROWS_WITH_AS = is_throws_with | is_throws_as | is_check, - DT_REQUIRE_THROWS_WITH_AS = is_throws_with | is_throws_as | is_require, - - DT_WARN_NOTHROW = is_nothrow | is_warn, - DT_CHECK_NOTHROW = is_nothrow | is_check, - DT_REQUIRE_NOTHROW = is_nothrow | is_require, - - DT_WARN_EQ = is_normal | is_eq | is_warn, - DT_CHECK_EQ = is_normal | is_eq | is_check, - DT_REQUIRE_EQ = is_normal | is_eq | is_require, - - DT_WARN_NE = is_normal | is_ne | is_warn, - DT_CHECK_NE = is_normal | is_ne | is_check, - DT_REQUIRE_NE = is_normal | is_ne | is_require, - - DT_WARN_GT = is_normal | is_gt | is_warn, - DT_CHECK_GT = is_normal | is_gt | is_check, - DT_REQUIRE_GT = is_normal | is_gt | is_require, - - DT_WARN_LT = is_normal | is_lt | is_warn, - DT_CHECK_LT = is_normal | is_lt | is_check, - DT_REQUIRE_LT = is_normal | is_lt | is_require, - - DT_WARN_GE = is_normal | is_ge | is_warn, - DT_CHECK_GE = is_normal | is_ge | is_check, - DT_REQUIRE_GE = is_normal | is_ge | is_require, - - DT_WARN_LE = is_normal | is_le | is_warn, - DT_CHECK_LE = is_normal | is_le | is_check, - DT_REQUIRE_LE = is_normal | is_le | is_require, - - DT_WARN_UNARY = is_normal | is_unary | is_warn, - DT_CHECK_UNARY = is_normal | is_unary | is_check, - DT_REQUIRE_UNARY = is_normal | is_unary | is_require, - - DT_WARN_UNARY_FALSE = is_normal | is_false | is_unary | is_warn, - DT_CHECK_UNARY_FALSE = is_normal | is_false | is_unary | is_check, - DT_REQUIRE_UNARY_FALSE = is_normal | is_false | is_unary | is_require, - }; -} // namespace assertType - -DOCTEST_INTERFACE const char* assertString(assertType::Enum at); -DOCTEST_INTERFACE const char* failureString(assertType::Enum at); -DOCTEST_INTERFACE const char* skipPathFromFilename(const char* file); - -struct DOCTEST_INTERFACE TestCaseData -{ - String m_file; // the file in which the test was registered (using String - see #350) - unsigned m_line; // the line where the test was registered - const char* m_name; // name of the test case - const char* m_test_suite; // the test suite in which the test was added - const char* m_description; - bool m_skip; - bool m_no_breaks; - bool m_no_output; - bool m_may_fail; - bool m_should_fail; - int m_expected_failures; - double m_timeout; -}; - -struct DOCTEST_INTERFACE AssertData -{ - // common - for all asserts - const TestCaseData* m_test_case; - assertType::Enum m_at; - const char* m_file; - int m_line; - const char* m_expr; - bool m_failed; - - // exception-related - for all asserts - bool m_threw; - String m_exception; - - // for normal asserts - String m_decomp; - - // for specific exception-related asserts - bool m_threw_as; - const char* m_exception_type; - const char* m_exception_string; -}; - -struct DOCTEST_INTERFACE MessageData -{ - String m_string; - const char* m_file; - int m_line; - assertType::Enum m_severity; -}; - -struct DOCTEST_INTERFACE SubcaseSignature -{ - String m_name; - const char* m_file; - int m_line; - - bool operator<(const SubcaseSignature& other) const; -}; - -struct DOCTEST_INTERFACE IContextScope -{ - IContextScope(); - virtual ~IContextScope(); - virtual void stringify(std::ostream*) const = 0; -}; - -namespace detail { - struct DOCTEST_INTERFACE TestCase; -} // namespace detail - -struct ContextOptions //!OCLINT too many fields -{ - std::ostream* cout; // stdout stream - std::cout by default - std::ostream* cerr; // stderr stream - std::cerr by default - String binary_name; // the test binary name - - const detail::TestCase* currentTest = nullptr; - - // == parameters from the command line - String out; // output filename - String order_by; // how tests should be ordered - unsigned rand_seed; // the seed for rand ordering - - unsigned first; // the first (matching) test to be executed - unsigned last; // the last (matching) test to be executed - - int abort_after; // stop tests after this many failed assertions - int subcase_filter_levels; // apply the subcase filters for the first N levels - - bool success; // include successful assertions in output - bool case_sensitive; // if filtering should be case sensitive - bool exit; // if the program should be exited after the tests are ran/whatever - bool duration; // print the time duration of each test case - bool no_throw; // to skip exceptions-related assertion macros - bool no_exitcode; // if the framework should return 0 as the exitcode - bool no_run; // to not run the tests at all (can be done with an "*" exclude) - bool no_version; // to not print the version of the framework - bool no_colors; // if output to the console should be colorized - bool force_colors; // forces the use of colors even when a tty cannot be detected - bool no_breaks; // to not break into the debugger - bool no_skip; // don't skip test cases which are marked to be skipped - bool gnu_file_line; // if line numbers should be surrounded with :x: and not (x): - bool no_path_in_filenames; // if the path to files should be removed from the output - bool no_line_numbers; // if source code line numbers should be omitted from the output - bool no_debug_output; // no output in the debug console when a debugger is attached - bool no_skipped_summary; // don't print "skipped" in the summary !!! UNDOCUMENTED !!! - bool no_time_in_output; // omit any time/timestamps from output !!! UNDOCUMENTED !!! - - bool help; // to print the help - bool version; // to print the version - bool count; // if only the count of matching tests is to be retrieved - bool list_test_cases; // to list all tests matching the filters - bool list_test_suites; // to list all suites matching the filters - bool list_reporters; // lists all registered reporters -}; - -namespace detail { - template - struct enable_if - {}; - - template - struct enable_if - { typedef TYPE type; }; - - // clang-format off - template struct remove_reference { typedef T type; }; - template struct remove_reference { typedef T type; }; - template struct remove_reference { typedef T type; }; - - template U declval(int); - - template T declval(long); - - template auto declval() DOCTEST_NOEXCEPT -> decltype(declval(0)) ; - - template struct is_lvalue_reference { const static bool value=false; }; - template struct is_lvalue_reference { const static bool value=true; }; - - template - inline T&& forward(typename remove_reference::type& t) DOCTEST_NOEXCEPT - { - return static_cast(t); - } - - template - inline T&& forward(typename remove_reference::type&& t) DOCTEST_NOEXCEPT - { - static_assert(!is_lvalue_reference::value, - "Can not forward an rvalue as an lvalue."); - return static_cast(t); - } - - template struct remove_const { typedef T type; }; - template struct remove_const { typedef T type; }; -#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS - template struct is_enum : public std::is_enum {}; - template struct underlying_type : public std::underlying_type {}; -#else - // Use compiler intrinsics - template struct is_enum { constexpr static bool value = __is_enum(T); }; - template struct underlying_type { typedef __underlying_type(T) type; }; -#endif - // clang-format on - - template - struct deferred_false - // cppcheck-suppress unusedStructMember - { static const bool value = false; }; - - namespace has_insertion_operator_impl { - std::ostream &os(); - template - DOCTEST_REF_WRAP(T) val(); - - template - struct check { - static constexpr bool value = false; - }; - - template - struct check(), void())> { - static constexpr bool value = true; - }; - } // namespace has_insertion_operator_impl - - template - using has_insertion_operator = has_insertion_operator_impl::check; - - DOCTEST_INTERFACE void my_memcpy(void* dest, const void* src, unsigned num); - - DOCTEST_INTERFACE std::ostream* getTlsOss(); // returns a thread-local ostringstream - DOCTEST_INTERFACE String getTlsOssResult(); - - template - struct StringMakerBase - { - template - static String convert(const DOCTEST_REF_WRAP(T)) { - return "{?}"; - } - }; - - template <> - struct StringMakerBase - { - template - static String convert(const DOCTEST_REF_WRAP(T) in) { - *getTlsOss() << in; - return getTlsOssResult(); - } - }; - - DOCTEST_INTERFACE String rawMemoryToString(const void* object, unsigned size); - - template - String rawMemoryToString(const DOCTEST_REF_WRAP(T) object) { - return rawMemoryToString(&object, sizeof(object)); - } - - template - const char* type_to_string() { - return "<>"; - } -} // namespace detail - -template -struct StringMaker : public detail::StringMakerBase::value> -{}; - -template -struct StringMaker -{ - template - static String convert(U* p) { - if(p) - return detail::rawMemoryToString(p); - return "NULL"; - } -}; - -template -struct StringMaker -{ - static String convert(R C::*p) { - if(p) - return detail::rawMemoryToString(p); - return "NULL"; - } -}; - -template ::value, bool>::type = true> -String toString(const DOCTEST_REF_WRAP(T) value) { - return StringMaker::convert(value); -} - -#ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING -DOCTEST_INTERFACE String toString(char* in); -DOCTEST_INTERFACE String toString(const char* in); -#endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING -DOCTEST_INTERFACE String toString(bool in); -DOCTEST_INTERFACE String toString(float in); -DOCTEST_INTERFACE String toString(double in); -DOCTEST_INTERFACE String toString(double long in); - -DOCTEST_INTERFACE String toString(char in); -DOCTEST_INTERFACE String toString(char signed in); -DOCTEST_INTERFACE String toString(char unsigned in); -DOCTEST_INTERFACE String toString(int short in); -DOCTEST_INTERFACE String toString(int short unsigned in); -DOCTEST_INTERFACE String toString(int in); -DOCTEST_INTERFACE String toString(int unsigned in); -DOCTEST_INTERFACE String toString(int long in); -DOCTEST_INTERFACE String toString(int long unsigned in); -DOCTEST_INTERFACE String toString(int long long in); -DOCTEST_INTERFACE String toString(int long long unsigned in); -DOCTEST_INTERFACE String toString(std::nullptr_t in); - -template ::value, bool>::type = true> -String toString(const DOCTEST_REF_WRAP(T) value) { - typedef typename detail::underlying_type::type UT; - return toString(static_cast(value)); -} - -#if DOCTEST_MSVC >= DOCTEST_COMPILER(19, 20, 0) -// see this issue on why this is needed: https://github.com/onqtam/doctest/issues/183 -DOCTEST_INTERFACE String toString(const std::string& in); -#endif // VS 2019 - -class DOCTEST_INTERFACE Approx -{ -public: - explicit Approx(double value); - - Approx operator()(double value) const; - -#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS - template - explicit Approx(const T& value, - typename detail::enable_if::value>::type* = - static_cast(nullptr)) { - *this = Approx(static_cast(value)); - } -#endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS - - Approx& epsilon(double newEpsilon); - -#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS - template - typename detail::enable_if::value, Approx&>::type epsilon( - const T& newEpsilon) { - m_epsilon = static_cast(newEpsilon); - return *this; - } -#endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS - - Approx& scale(double newScale); - -#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS - template - typename detail::enable_if::value, Approx&>::type scale( - const T& newScale) { - m_scale = static_cast(newScale); - return *this; - } -#endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS - - // clang-format off - DOCTEST_INTERFACE friend bool operator==(double lhs, const Approx & rhs); - DOCTEST_INTERFACE friend bool operator==(const Approx & lhs, double rhs); - DOCTEST_INTERFACE friend bool operator!=(double lhs, const Approx & rhs); - DOCTEST_INTERFACE friend bool operator!=(const Approx & lhs, double rhs); - DOCTEST_INTERFACE friend bool operator<=(double lhs, const Approx & rhs); - DOCTEST_INTERFACE friend bool operator<=(const Approx & lhs, double rhs); - DOCTEST_INTERFACE friend bool operator>=(double lhs, const Approx & rhs); - DOCTEST_INTERFACE friend bool operator>=(const Approx & lhs, double rhs); - DOCTEST_INTERFACE friend bool operator< (double lhs, const Approx & rhs); - DOCTEST_INTERFACE friend bool operator< (const Approx & lhs, double rhs); - DOCTEST_INTERFACE friend bool operator> (double lhs, const Approx & rhs); - DOCTEST_INTERFACE friend bool operator> (const Approx & lhs, double rhs); - - DOCTEST_INTERFACE friend String toString(const Approx& in); - -#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS -#define DOCTEST_APPROX_PREFIX \ - template friend typename detail::enable_if::value, bool>::type - - DOCTEST_APPROX_PREFIX operator==(const T& lhs, const Approx& rhs) { return operator==(double(lhs), rhs); } - DOCTEST_APPROX_PREFIX operator==(const Approx& lhs, const T& rhs) { return operator==(rhs, lhs); } - DOCTEST_APPROX_PREFIX operator!=(const T& lhs, const Approx& rhs) { return !operator==(lhs, rhs); } - DOCTEST_APPROX_PREFIX operator!=(const Approx& lhs, const T& rhs) { return !operator==(rhs, lhs); } - DOCTEST_APPROX_PREFIX operator<=(const T& lhs, const Approx& rhs) { return double(lhs) < rhs.m_value || lhs == rhs; } - DOCTEST_APPROX_PREFIX operator<=(const Approx& lhs, const T& rhs) { return lhs.m_value < double(rhs) || lhs == rhs; } - DOCTEST_APPROX_PREFIX operator>=(const T& lhs, const Approx& rhs) { return double(lhs) > rhs.m_value || lhs == rhs; } - DOCTEST_APPROX_PREFIX operator>=(const Approx& lhs, const T& rhs) { return lhs.m_value > double(rhs) || lhs == rhs; } - DOCTEST_APPROX_PREFIX operator< (const T& lhs, const Approx& rhs) { return double(lhs) < rhs.m_value && lhs != rhs; } - DOCTEST_APPROX_PREFIX operator< (const Approx& lhs, const T& rhs) { return lhs.m_value < double(rhs) && lhs != rhs; } - DOCTEST_APPROX_PREFIX operator> (const T& lhs, const Approx& rhs) { return double(lhs) > rhs.m_value && lhs != rhs; } - DOCTEST_APPROX_PREFIX operator> (const Approx& lhs, const T& rhs) { return lhs.m_value > double(rhs) && lhs != rhs; } -#undef DOCTEST_APPROX_PREFIX -#endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS - - // clang-format on - -private: - double m_epsilon; - double m_scale; - double m_value; -}; - -DOCTEST_INTERFACE String toString(const Approx& in); - -DOCTEST_INTERFACE const ContextOptions* getContextOptions(); - -#if !defined(DOCTEST_CONFIG_DISABLE) - -namespace detail { - // clang-format off -#ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING - template struct decay_array { typedef T type; }; - template struct decay_array { typedef T* type; }; - template struct decay_array { typedef T* type; }; - - template struct not_char_pointer { enum { value = 1 }; }; - template<> struct not_char_pointer { enum { value = 0 }; }; - template<> struct not_char_pointer { enum { value = 0 }; }; - - template struct can_use_op : public not_char_pointer::type> {}; -#endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING - // clang-format on - - struct DOCTEST_INTERFACE TestFailureException - { - }; - - DOCTEST_INTERFACE bool checkIfShouldThrow(assertType::Enum at); - -#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS - DOCTEST_NORETURN -#endif // DOCTEST_CONFIG_NO_EXCEPTIONS - DOCTEST_INTERFACE void throwException(); - - struct DOCTEST_INTERFACE Subcase - { - SubcaseSignature m_signature; - bool m_entered = false; - - Subcase(const String& name, const char* file, int line); - ~Subcase(); - - operator bool() const; - }; - - template - String stringifyBinaryExpr(const DOCTEST_REF_WRAP(L) lhs, const char* op, - const DOCTEST_REF_WRAP(R) rhs) { - // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) - return toString(lhs) + op + toString(rhs); - } - -#if DOCTEST_CLANG && DOCTEST_CLANG < DOCTEST_COMPILER(3, 6, 0) -DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wunused-comparison") -#endif - -// This will check if there is any way it could find a operator like member or friend and uses it. -// If not it doesn't find the operator or if the operator at global scope is defined after -// this template, the template won't be instantiated due to SFINAE. Once the template is not -// instantiated it can look for global operator using normal conversions. -#define SFINAE_OP(ret,op) decltype(doctest::detail::declval() op doctest::detail::declval(),static_cast(0)) - -#define DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(op, op_str, op_macro) \ - template \ - DOCTEST_NOINLINE SFINAE_OP(Result,op) operator op(R&& rhs) { \ - bool res = op_macro(doctest::detail::forward(lhs), doctest::detail::forward(rhs)); \ - if(m_at & assertType::is_false) \ - res = !res; \ - if(!res || doctest::getContextOptions()->success) \ - return Result(res, stringifyBinaryExpr(lhs, op_str, rhs)); \ - return Result(res); \ - } - - // more checks could be added - like in Catch: - // https://github.com/catchorg/Catch2/pull/1480/files - // https://github.com/catchorg/Catch2/pull/1481/files -#define DOCTEST_FORBIT_EXPRESSION(rt, op) \ - template \ - rt& operator op(const R&) { \ - static_assert(deferred_false::value, \ - "Expression Too Complex Please Rewrite As Binary Comparison!"); \ - return *this; \ - } - - struct DOCTEST_INTERFACE Result - { - bool m_passed; - String m_decomp; - - Result(bool passed, const String& decomposition = String()); - - // forbidding some expressions based on this table: https://en.cppreference.com/w/cpp/language/operator_precedence - DOCTEST_FORBIT_EXPRESSION(Result, &) - DOCTEST_FORBIT_EXPRESSION(Result, ^) - DOCTEST_FORBIT_EXPRESSION(Result, |) - DOCTEST_FORBIT_EXPRESSION(Result, &&) - DOCTEST_FORBIT_EXPRESSION(Result, ||) - DOCTEST_FORBIT_EXPRESSION(Result, ==) - DOCTEST_FORBIT_EXPRESSION(Result, !=) - DOCTEST_FORBIT_EXPRESSION(Result, <) - DOCTEST_FORBIT_EXPRESSION(Result, >) - DOCTEST_FORBIT_EXPRESSION(Result, <=) - DOCTEST_FORBIT_EXPRESSION(Result, >=) - DOCTEST_FORBIT_EXPRESSION(Result, =) - DOCTEST_FORBIT_EXPRESSION(Result, +=) - DOCTEST_FORBIT_EXPRESSION(Result, -=) - DOCTEST_FORBIT_EXPRESSION(Result, *=) - DOCTEST_FORBIT_EXPRESSION(Result, /=) - DOCTEST_FORBIT_EXPRESSION(Result, %=) - DOCTEST_FORBIT_EXPRESSION(Result, <<=) - DOCTEST_FORBIT_EXPRESSION(Result, >>=) - DOCTEST_FORBIT_EXPRESSION(Result, &=) - DOCTEST_FORBIT_EXPRESSION(Result, ^=) - DOCTEST_FORBIT_EXPRESSION(Result, |=) - }; - -#ifndef DOCTEST_CONFIG_NO_COMPARISON_WARNING_SUPPRESSION - - DOCTEST_CLANG_SUPPRESS_WARNING_PUSH - DOCTEST_CLANG_SUPPRESS_WARNING("-Wsign-conversion") - DOCTEST_CLANG_SUPPRESS_WARNING("-Wsign-compare") - //DOCTEST_CLANG_SUPPRESS_WARNING("-Wdouble-promotion") - //DOCTEST_CLANG_SUPPRESS_WARNING("-Wconversion") - //DOCTEST_CLANG_SUPPRESS_WARNING("-Wfloat-equal") - - DOCTEST_GCC_SUPPRESS_WARNING_PUSH - DOCTEST_GCC_SUPPRESS_WARNING("-Wsign-conversion") - DOCTEST_GCC_SUPPRESS_WARNING("-Wsign-compare") - //DOCTEST_GCC_SUPPRESS_WARNING("-Wdouble-promotion") - //DOCTEST_GCC_SUPPRESS_WARNING("-Wconversion") - //DOCTEST_GCC_SUPPRESS_WARNING("-Wfloat-equal") - - DOCTEST_MSVC_SUPPRESS_WARNING_PUSH - // https://stackoverflow.com/questions/39479163 what's the difference between 4018 and 4389 - DOCTEST_MSVC_SUPPRESS_WARNING(4388) // signed/unsigned mismatch - DOCTEST_MSVC_SUPPRESS_WARNING(4389) // 'operator' : signed/unsigned mismatch - DOCTEST_MSVC_SUPPRESS_WARNING(4018) // 'expression' : signed/unsigned mismatch - //DOCTEST_MSVC_SUPPRESS_WARNING(4805) // 'operation' : unsafe mix of type 'type' and type 'type' in operation - -#endif // DOCTEST_CONFIG_NO_COMPARISON_WARNING_SUPPRESSION - - // clang-format off -#ifndef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING -#define DOCTEST_COMPARISON_RETURN_TYPE bool -#else // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING -#define DOCTEST_COMPARISON_RETURN_TYPE typename enable_if::value || can_use_op::value, bool>::type - // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) - inline bool eq(const char* lhs, const char* rhs) { return String(lhs) == String(rhs); } - inline bool ne(const char* lhs, const char* rhs) { return String(lhs) != String(rhs); } - inline bool lt(const char* lhs, const char* rhs) { return String(lhs) < String(rhs); } - inline bool gt(const char* lhs, const char* rhs) { return String(lhs) > String(rhs); } - inline bool le(const char* lhs, const char* rhs) { return String(lhs) <= String(rhs); } - inline bool ge(const char* lhs, const char* rhs) { return String(lhs) >= String(rhs); } -#endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING - // clang-format on - -#define DOCTEST_RELATIONAL_OP(name, op) \ - template \ - DOCTEST_COMPARISON_RETURN_TYPE name(const DOCTEST_REF_WRAP(L) lhs, \ - const DOCTEST_REF_WRAP(R) rhs) { \ - return lhs op rhs; \ - } - - DOCTEST_RELATIONAL_OP(eq, ==) - DOCTEST_RELATIONAL_OP(ne, !=) - DOCTEST_RELATIONAL_OP(lt, <) - DOCTEST_RELATIONAL_OP(gt, >) - DOCTEST_RELATIONAL_OP(le, <=) - DOCTEST_RELATIONAL_OP(ge, >=) - -#ifndef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING -#define DOCTEST_CMP_EQ(l, r) l == r -#define DOCTEST_CMP_NE(l, r) l != r -#define DOCTEST_CMP_GT(l, r) l > r -#define DOCTEST_CMP_LT(l, r) l < r -#define DOCTEST_CMP_GE(l, r) l >= r -#define DOCTEST_CMP_LE(l, r) l <= r -#else // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING -#define DOCTEST_CMP_EQ(l, r) eq(l, r) -#define DOCTEST_CMP_NE(l, r) ne(l, r) -#define DOCTEST_CMP_GT(l, r) gt(l, r) -#define DOCTEST_CMP_LT(l, r) lt(l, r) -#define DOCTEST_CMP_GE(l, r) ge(l, r) -#define DOCTEST_CMP_LE(l, r) le(l, r) -#endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING - - template - // cppcheck-suppress copyCtorAndEqOperator - struct Expression_lhs - { - L lhs; - assertType::Enum m_at; - - explicit Expression_lhs(L&& in, assertType::Enum at) - : lhs(doctest::detail::forward(in)) - , m_at(at) {} - - DOCTEST_NOINLINE operator Result() { -// this is needed only foc MSVC 2015: -// https://ci.appveyor.com/project/onqtam/doctest/builds/38181202 -DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4800) // 'int': forcing value to bool - bool res = static_cast(lhs); -DOCTEST_MSVC_SUPPRESS_WARNING_POP - if(m_at & assertType::is_false) //!OCLINT bitwise operator in conditional - res = !res; - - if(!res || getContextOptions()->success) - return Result(res, toString(lhs)); - return Result(res); - } - - /* This is required for user-defined conversions from Expression_lhs to L */ - //operator L() const { return lhs; } - operator L() const { return lhs; } - - // clang-format off - DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(==, " == ", DOCTEST_CMP_EQ) //!OCLINT bitwise operator in conditional - DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(!=, " != ", DOCTEST_CMP_NE) //!OCLINT bitwise operator in conditional - DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(>, " > ", DOCTEST_CMP_GT) //!OCLINT bitwise operator in conditional - DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(<, " < ", DOCTEST_CMP_LT) //!OCLINT bitwise operator in conditional - DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(>=, " >= ", DOCTEST_CMP_GE) //!OCLINT bitwise operator in conditional - DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(<=, " <= ", DOCTEST_CMP_LE) //!OCLINT bitwise operator in conditional - // clang-format on - - // forbidding some expressions based on this table: https://en.cppreference.com/w/cpp/language/operator_precedence - DOCTEST_FORBIT_EXPRESSION(Expression_lhs, &) - DOCTEST_FORBIT_EXPRESSION(Expression_lhs, ^) - DOCTEST_FORBIT_EXPRESSION(Expression_lhs, |) - DOCTEST_FORBIT_EXPRESSION(Expression_lhs, &&) - DOCTEST_FORBIT_EXPRESSION(Expression_lhs, ||) - DOCTEST_FORBIT_EXPRESSION(Expression_lhs, =) - DOCTEST_FORBIT_EXPRESSION(Expression_lhs, +=) - DOCTEST_FORBIT_EXPRESSION(Expression_lhs, -=) - DOCTEST_FORBIT_EXPRESSION(Expression_lhs, *=) - DOCTEST_FORBIT_EXPRESSION(Expression_lhs, /=) - DOCTEST_FORBIT_EXPRESSION(Expression_lhs, %=) - DOCTEST_FORBIT_EXPRESSION(Expression_lhs, <<=) - DOCTEST_FORBIT_EXPRESSION(Expression_lhs, >>=) - DOCTEST_FORBIT_EXPRESSION(Expression_lhs, &=) - DOCTEST_FORBIT_EXPRESSION(Expression_lhs, ^=) - DOCTEST_FORBIT_EXPRESSION(Expression_lhs, |=) - // these 2 are unfortunate because they should be allowed - they have higher precedence over the comparisons, but the - // ExpressionDecomposer class uses the left shift operator to capture the left operand of the binary expression... - DOCTEST_FORBIT_EXPRESSION(Expression_lhs, <<) - DOCTEST_FORBIT_EXPRESSION(Expression_lhs, >>) - }; - -#ifndef DOCTEST_CONFIG_NO_COMPARISON_WARNING_SUPPRESSION - - DOCTEST_CLANG_SUPPRESS_WARNING_POP - DOCTEST_MSVC_SUPPRESS_WARNING_POP - DOCTEST_GCC_SUPPRESS_WARNING_POP - -#endif // DOCTEST_CONFIG_NO_COMPARISON_WARNING_SUPPRESSION - -#if DOCTEST_CLANG && DOCTEST_CLANG < DOCTEST_COMPILER(3, 6, 0) -DOCTEST_CLANG_SUPPRESS_WARNING_POP -#endif - - struct DOCTEST_INTERFACE ExpressionDecomposer - { - assertType::Enum m_at; - - ExpressionDecomposer(assertType::Enum at); - - // The right operator for capturing expressions is "<=" instead of "<<" (based on the operator precedence table) - // but then there will be warnings from GCC about "-Wparentheses" and since "_Pragma()" is problematic this will stay for now... - // https://github.com/catchorg/Catch2/issues/870 - // https://github.com/catchorg/Catch2/issues/565 - template - Expression_lhs operator<<(L &&operand) { - return Expression_lhs(doctest::detail::forward(operand), m_at); - } - }; - - struct DOCTEST_INTERFACE TestSuite - { - const char* m_test_suite; - const char* m_description; - bool m_skip; - bool m_no_breaks; - bool m_no_output; - bool m_may_fail; - bool m_should_fail; - int m_expected_failures; - double m_timeout; - - TestSuite& operator*(const char* in); - - template - TestSuite& operator*(const T& in) { - in.fill(*this); - return *this; - } - }; - - typedef void (*funcType)(); - - struct DOCTEST_INTERFACE TestCase : public TestCaseData - { - funcType m_test; // a function pointer to the test case - - const char* m_type; // for templated test cases - gets appended to the real name - int m_template_id; // an ID used to distinguish between the different versions of a templated test case - String m_full_name; // contains the name (only for templated test cases!) + the template type - - TestCase(funcType test, const char* file, unsigned line, const TestSuite& test_suite, - const char* type = "", int template_id = -1); - - TestCase(const TestCase& other); - - DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(26434) // hides a non-virtual function - TestCase& operator=(const TestCase& other); - DOCTEST_MSVC_SUPPRESS_WARNING_POP - - TestCase& operator*(const char* in); - - template - TestCase& operator*(const T& in) { - in.fill(*this); - return *this; - } - - bool operator<(const TestCase& other) const; - }; - - // forward declarations of functions used by the macros - DOCTEST_INTERFACE int regTest(const TestCase& tc); - DOCTEST_INTERFACE int setTestSuite(const TestSuite& ts); - DOCTEST_INTERFACE bool isDebuggerActive(); - - template - int instantiationHelper(const T&) { return 0; } - - namespace binaryAssertComparison { - enum Enum - { - eq = 0, - ne, - gt, - lt, - ge, - le - }; - } // namespace binaryAssertComparison - - // clang-format off - template struct RelationalComparator { bool operator()(const DOCTEST_REF_WRAP(L), const DOCTEST_REF_WRAP(R) ) const { return false; } }; - -#define DOCTEST_BINARY_RELATIONAL_OP(n, op) \ - template struct RelationalComparator { bool operator()(const DOCTEST_REF_WRAP(L) lhs, const DOCTEST_REF_WRAP(R) rhs) const { return op(lhs, rhs); } }; - // clang-format on - - DOCTEST_BINARY_RELATIONAL_OP(0, doctest::detail::eq) - DOCTEST_BINARY_RELATIONAL_OP(1, doctest::detail::ne) - DOCTEST_BINARY_RELATIONAL_OP(2, doctest::detail::gt) - DOCTEST_BINARY_RELATIONAL_OP(3, doctest::detail::lt) - DOCTEST_BINARY_RELATIONAL_OP(4, doctest::detail::ge) - DOCTEST_BINARY_RELATIONAL_OP(5, doctest::detail::le) - - struct DOCTEST_INTERFACE ResultBuilder : public AssertData - { - ResultBuilder(assertType::Enum at, const char* file, int line, const char* expr, - const char* exception_type = "", const char* exception_string = ""); - - void setResult(const Result& res); - - template - DOCTEST_NOINLINE void binary_assert(const DOCTEST_REF_WRAP(L) lhs, - const DOCTEST_REF_WRAP(R) rhs) { - m_failed = !RelationalComparator()(lhs, rhs); - if(m_failed || getContextOptions()->success) - m_decomp = stringifyBinaryExpr(lhs, ", ", rhs); - } - - template - DOCTEST_NOINLINE void unary_assert(const DOCTEST_REF_WRAP(L) val) { - m_failed = !val; - - if(m_at & assertType::is_false) //!OCLINT bitwise operator in conditional - m_failed = !m_failed; - - if(m_failed || getContextOptions()->success) - m_decomp = toString(val); - } - - void translateException(); - - bool log(); - void react() const; - }; - - namespace assertAction { - enum Enum - { - nothing = 0, - dbgbreak = 1, - shouldthrow = 2 - }; - } // namespace assertAction - - DOCTEST_INTERFACE void failed_out_of_a_testing_context(const AssertData& ad); - - DOCTEST_INTERFACE void decomp_assert(assertType::Enum at, const char* file, int line, - const char* expr, Result result); - -#define DOCTEST_ASSERT_OUT_OF_TESTS(decomp) \ - do { \ - if(!is_running_in_test) { \ - if(failed) { \ - ResultBuilder rb(at, file, line, expr); \ - rb.m_failed = failed; \ - rb.m_decomp = decomp; \ - failed_out_of_a_testing_context(rb); \ - if(isDebuggerActive() && !getContextOptions()->no_breaks) \ - DOCTEST_BREAK_INTO_DEBUGGER(); \ - if(checkIfShouldThrow(at)) \ - throwException(); \ - } \ - return; \ - } \ - } while(false) - -#define DOCTEST_ASSERT_IN_TESTS(decomp) \ - ResultBuilder rb(at, file, line, expr); \ - rb.m_failed = failed; \ - if(rb.m_failed || getContextOptions()->success) \ - rb.m_decomp = decomp; \ - if(rb.log()) \ - DOCTEST_BREAK_INTO_DEBUGGER(); \ - if(rb.m_failed && checkIfShouldThrow(at)) \ - throwException() - - template - DOCTEST_NOINLINE void binary_assert(assertType::Enum at, const char* file, int line, - const char* expr, const DOCTEST_REF_WRAP(L) lhs, - const DOCTEST_REF_WRAP(R) rhs) { - bool failed = !RelationalComparator()(lhs, rhs); - - // ################################################################################### - // IF THE DEBUGGER BREAKS HERE - GO 1 LEVEL UP IN THE CALLSTACK FOR THE FAILING ASSERT - // THIS IS THE EFFECT OF HAVING 'DOCTEST_CONFIG_SUPER_FAST_ASSERTS' DEFINED - // ################################################################################### - DOCTEST_ASSERT_OUT_OF_TESTS(stringifyBinaryExpr(lhs, ", ", rhs)); - DOCTEST_ASSERT_IN_TESTS(stringifyBinaryExpr(lhs, ", ", rhs)); - } - - template - DOCTEST_NOINLINE void unary_assert(assertType::Enum at, const char* file, int line, - const char* expr, const DOCTEST_REF_WRAP(L) val) { - bool failed = !val; - - if(at & assertType::is_false) //!OCLINT bitwise operator in conditional - failed = !failed; - - // ################################################################################### - // IF THE DEBUGGER BREAKS HERE - GO 1 LEVEL UP IN THE CALLSTACK FOR THE FAILING ASSERT - // THIS IS THE EFFECT OF HAVING 'DOCTEST_CONFIG_SUPER_FAST_ASSERTS' DEFINED - // ################################################################################### - DOCTEST_ASSERT_OUT_OF_TESTS(toString(val)); - DOCTEST_ASSERT_IN_TESTS(toString(val)); - } - - struct DOCTEST_INTERFACE IExceptionTranslator - { - IExceptionTranslator(); - virtual ~IExceptionTranslator(); - virtual bool translate(String&) const = 0; - }; - - template - class ExceptionTranslator : public IExceptionTranslator //!OCLINT destructor of virtual class - { - public: - explicit ExceptionTranslator(String (*translateFunction)(T)) - : m_translateFunction(translateFunction) {} - - bool translate(String& res) const override { -#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS - try { - throw; // lgtm [cpp/rethrow-no-exception] - // cppcheck-suppress catchExceptionByValue - } catch(T ex) { // NOLINT - res = m_translateFunction(ex); //!OCLINT parameter reassignment - return true; - } catch(...) {} //!OCLINT - empty catch statement -#endif // DOCTEST_CONFIG_NO_EXCEPTIONS - static_cast(res); // to silence -Wunused-parameter - return false; - } - - private: - String (*m_translateFunction)(T); - }; - - DOCTEST_INTERFACE void registerExceptionTranslatorImpl(const IExceptionTranslator* et); - - template - struct StringStreamBase - { - template - static void convert(std::ostream* s, const T& in) { - *s << toString(in); - } - - // always treat char* as a string in this context - no matter - // if DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING is defined - static void convert(std::ostream* s, const char* in) { *s << String(in); } - }; - - template <> - struct StringStreamBase - { - template - static void convert(std::ostream* s, const T& in) { - *s << in; - } - }; - - template - struct StringStream : public StringStreamBase::value> - {}; - - template - void toStream(std::ostream* s, const T& value) { - StringStream::convert(s, value); - } - -#ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING - DOCTEST_INTERFACE void toStream(std::ostream* s, char* in); - DOCTEST_INTERFACE void toStream(std::ostream* s, const char* in); -#endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING - DOCTEST_INTERFACE void toStream(std::ostream* s, bool in); - DOCTEST_INTERFACE void toStream(std::ostream* s, float in); - DOCTEST_INTERFACE void toStream(std::ostream* s, double in); - DOCTEST_INTERFACE void toStream(std::ostream* s, double long in); - - DOCTEST_INTERFACE void toStream(std::ostream* s, char in); - DOCTEST_INTERFACE void toStream(std::ostream* s, char signed in); - DOCTEST_INTERFACE void toStream(std::ostream* s, char unsigned in); - DOCTEST_INTERFACE void toStream(std::ostream* s, int short in); - DOCTEST_INTERFACE void toStream(std::ostream* s, int short unsigned in); - DOCTEST_INTERFACE void toStream(std::ostream* s, int in); - DOCTEST_INTERFACE void toStream(std::ostream* s, int unsigned in); - DOCTEST_INTERFACE void toStream(std::ostream* s, int long in); - DOCTEST_INTERFACE void toStream(std::ostream* s, int long unsigned in); - DOCTEST_INTERFACE void toStream(std::ostream* s, int long long in); - DOCTEST_INTERFACE void toStream(std::ostream* s, int long long unsigned in); - - // ContextScope base class used to allow implementing methods of ContextScope - // that don't depend on the template parameter in doctest.cpp. - class DOCTEST_INTERFACE ContextScopeBase : public IContextScope { - protected: - ContextScopeBase(); - - void destroy(); - }; - - template class ContextScope : public ContextScopeBase - { - const L lambda_; - - public: - explicit ContextScope(const L &lambda) : lambda_(lambda) {} - - ContextScope(ContextScope &&other) : lambda_(other.lambda_) {} - - void stringify(std::ostream* s) const override { lambda_(s); } - - ~ContextScope() override { destroy(); } - }; - - struct DOCTEST_INTERFACE MessageBuilder : public MessageData - { - std::ostream* m_stream; - - MessageBuilder(const char* file, int line, assertType::Enum severity); - MessageBuilder() = delete; - ~MessageBuilder(); - - // the preferred way of chaining parameters for stringification - template - MessageBuilder& operator,(const T& in) { - toStream(m_stream, in); - return *this; - } - - // kept here just for backwards-compatibility - the comma operator should be preferred now - template - MessageBuilder& operator<<(const T& in) { return this->operator,(in); } - - // the `,` operator has the lowest operator precedence - if `<<` is used by the user then - // the `,` operator will be called last which is not what we want and thus the `*` operator - // is used first (has higher operator precedence compared to `<<`) so that we guarantee that - // an operator of the MessageBuilder class is called first before the rest of the parameters - template - MessageBuilder& operator*(const T& in) { return this->operator,(in); } - - bool log(); - void react(); - }; - - template - ContextScope MakeContextScope(const L &lambda) { - return ContextScope(lambda); - } -} // namespace detail - -#define DOCTEST_DEFINE_DECORATOR(name, type, def) \ - struct name \ - { \ - type data; \ - name(type in = def) \ - : data(in) {} \ - void fill(detail::TestCase& state) const { state.DOCTEST_CAT(m_, name) = data; } \ - void fill(detail::TestSuite& state) const { state.DOCTEST_CAT(m_, name) = data; } \ - } - -DOCTEST_DEFINE_DECORATOR(test_suite, const char*, ""); -DOCTEST_DEFINE_DECORATOR(description, const char*, ""); -DOCTEST_DEFINE_DECORATOR(skip, bool, true); -DOCTEST_DEFINE_DECORATOR(no_breaks, bool, true); -DOCTEST_DEFINE_DECORATOR(no_output, bool, true); -DOCTEST_DEFINE_DECORATOR(timeout, double, 0); -DOCTEST_DEFINE_DECORATOR(may_fail, bool, true); -DOCTEST_DEFINE_DECORATOR(should_fail, bool, true); -DOCTEST_DEFINE_DECORATOR(expected_failures, int, 0); - -template -int registerExceptionTranslator(String (*translateFunction)(T)) { - DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wexit-time-destructors") - static detail::ExceptionTranslator exceptionTranslator(translateFunction); - DOCTEST_CLANG_SUPPRESS_WARNING_POP - detail::registerExceptionTranslatorImpl(&exceptionTranslator); - return 0; -} - -} // namespace doctest - -// in a separate namespace outside of doctest because the DOCTEST_TEST_SUITE macro -// introduces an anonymous namespace in which getCurrentTestSuite gets overridden -namespace doctest_detail_test_suite_ns { -DOCTEST_INTERFACE doctest::detail::TestSuite& getCurrentTestSuite(); -} // namespace doctest_detail_test_suite_ns - -namespace doctest { -#else // DOCTEST_CONFIG_DISABLE -template -int registerExceptionTranslator(String (*)(T)) { - return 0; -} -#endif // DOCTEST_CONFIG_DISABLE - -namespace detail { - typedef void (*assert_handler)(const AssertData&); - struct ContextState; -} // namespace detail - -class DOCTEST_INTERFACE Context -{ - detail::ContextState* p; - - void parseArgs(int argc, const char* const* argv, bool withDefaults = false); - -public: - explicit Context(int argc = 0, const char* const* argv = nullptr); - - ~Context(); - - void applyCommandLine(int argc, const char* const* argv); - - void addFilter(const char* filter, const char* value); - void clearFilters(); - void setOption(const char* option, int value); - void setOption(const char* option, const char* value); - - bool shouldExit(); - - void setAsDefaultForAssertsOutOfTestCases(); - - void setAssertHandler(detail::assert_handler ah); - - int run(); -}; - -namespace TestCaseFailureReason { - enum Enum - { - None = 0, - AssertFailure = 1, // an assertion has failed in the test case - Exception = 2, // test case threw an exception - Crash = 4, // a crash... - TooManyFailedAsserts = 8, // the abort-after option - Timeout = 16, // see the timeout decorator - ShouldHaveFailedButDidnt = 32, // see the should_fail decorator - ShouldHaveFailedAndDid = 64, // see the should_fail decorator - DidntFailExactlyNumTimes = 128, // see the expected_failures decorator - FailedExactlyNumTimes = 256, // see the expected_failures decorator - CouldHaveFailedAndDid = 512 // see the may_fail decorator - }; -} // namespace TestCaseFailureReason - -struct DOCTEST_INTERFACE CurrentTestCaseStats -{ - int numAssertsCurrentTest; - int numAssertsFailedCurrentTest; - double seconds; - int failure_flags; // use TestCaseFailureReason::Enum -}; - -struct DOCTEST_INTERFACE TestCaseException -{ - String error_string; - bool is_crash; -}; - -struct DOCTEST_INTERFACE TestRunStats -{ - unsigned numTestCases; - unsigned numTestCasesPassingFilters; - unsigned numTestSuitesPassingFilters; - unsigned numTestCasesFailed; - int numAsserts; - int numAssertsFailed; -}; - -struct QueryData -{ - const TestRunStats* run_stats = nullptr; - const TestCaseData** data = nullptr; - unsigned num_data = 0; -}; - -struct DOCTEST_INTERFACE IReporter -{ - // The constructor has to accept "const ContextOptions&" as a single argument - // which has most of the options for the run + a pointer to the stdout stream - // Reporter(const ContextOptions& in) - - // called when a query should be reported (listing test cases, printing the version, etc.) - virtual void report_query(const QueryData&) = 0; - - // called when the whole test run starts - virtual void test_run_start() = 0; - // called when the whole test run ends (caching a pointer to the input doesn't make sense here) - virtual void test_run_end(const TestRunStats&) = 0; - - // called when a test case is started (safe to cache a pointer to the input) - virtual void test_case_start(const TestCaseData&) = 0; - // called when a test case is reentered because of unfinished subcases (safe to cache a pointer to the input) - virtual void test_case_reenter(const TestCaseData&) = 0; - // called when a test case has ended - virtual void test_case_end(const CurrentTestCaseStats&) = 0; - - // called when an exception is thrown from the test case (or it crashes) - virtual void test_case_exception(const TestCaseException&) = 0; - - // called whenever a subcase is entered (don't cache pointers to the input) - virtual void subcase_start(const SubcaseSignature&) = 0; - // called whenever a subcase is exited (don't cache pointers to the input) - virtual void subcase_end() = 0; - - // called for each assert (don't cache pointers to the input) - virtual void log_assert(const AssertData&) = 0; - // called for each message (don't cache pointers to the input) - virtual void log_message(const MessageData&) = 0; - - // called when a test case is skipped either because it doesn't pass the filters, has a skip decorator - // or isn't in the execution range (between first and last) (safe to cache a pointer to the input) - virtual void test_case_skipped(const TestCaseData&) = 0; - - // doctest will not be managing the lifetimes of reporters given to it but this would still be nice to have - virtual ~IReporter(); - - // can obtain all currently active contexts and stringify them if one wishes to do so - static int get_num_active_contexts(); - static const IContextScope* const* get_active_contexts(); - - // can iterate through contexts which have been stringified automatically in their destructors when an exception has been thrown - static int get_num_stringified_contexts(); - static const String* get_stringified_contexts(); -}; - -namespace detail { - typedef IReporter* (*reporterCreatorFunc)(const ContextOptions&); - - DOCTEST_INTERFACE void registerReporterImpl(const char* name, int prio, reporterCreatorFunc c, bool isReporter); - - template - IReporter* reporterCreator(const ContextOptions& o) { - return new Reporter(o); - } -} // namespace detail - -template -int registerReporter(const char* name, int priority, bool isReporter) { - detail::registerReporterImpl(name, priority, detail::reporterCreator, isReporter); - return 0; -} -} // namespace doctest - -// if registering is not disabled -#if !defined(DOCTEST_CONFIG_DISABLE) - -// common code in asserts - for convenience -#define DOCTEST_ASSERT_LOG_AND_REACT(b) \ - if(b.log()) \ - DOCTEST_BREAK_INTO_DEBUGGER(); \ - b.react() - -#ifdef DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS -#define DOCTEST_WRAP_IN_TRY(x) x; -#else // DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS -#define DOCTEST_WRAP_IN_TRY(x) \ - try { \ - x; \ - } catch(...) { _DOCTEST_RB.translateException(); } -#endif // DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS - -#ifdef DOCTEST_CONFIG_VOID_CAST_EXPRESSIONS -#define DOCTEST_CAST_TO_VOID(...) \ - DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wuseless-cast") \ - static_cast(__VA_ARGS__); \ - DOCTEST_GCC_SUPPRESS_WARNING_POP -#else // DOCTEST_CONFIG_VOID_CAST_EXPRESSIONS -#define DOCTEST_CAST_TO_VOID(...) __VA_ARGS__; -#endif // DOCTEST_CONFIG_VOID_CAST_EXPRESSIONS - -// registers the test by initializing a dummy var with a function -#define DOCTEST_REGISTER_FUNCTION(global_prefix, f, decorators) \ - global_prefix DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(_DOCTEST_ANON_VAR_)) = \ - doctest::detail::regTest( \ - doctest::detail::TestCase( \ - f, __FILE__, __LINE__, \ - doctest_detail_test_suite_ns::getCurrentTestSuite()) * \ - decorators); \ - DOCTEST_GLOBAL_NO_WARNINGS_END() - -#define DOCTEST_IMPLEMENT_FIXTURE(der, base, func, decorators) \ - namespace { \ - struct der : public base \ - { \ - void f(); \ - }; \ - static void func() { \ - der v; \ - v.f(); \ - } \ - DOCTEST_REGISTER_FUNCTION(DOCTEST_EMPTY, func, decorators) \ - } \ - inline DOCTEST_NOINLINE void der::f() - -#define DOCTEST_CREATE_AND_REGISTER_FUNCTION(f, decorators) \ - static void f(); \ - DOCTEST_REGISTER_FUNCTION(DOCTEST_EMPTY, f, decorators) \ - static void f() - -#define DOCTEST_CREATE_AND_REGISTER_FUNCTION_IN_CLASS(f, proxy, decorators) \ - static doctest::detail::funcType proxy() { return f; } \ - DOCTEST_REGISTER_FUNCTION(inline const, proxy(), decorators) \ - static void f() - -// for registering tests -#define DOCTEST_TEST_CASE(decorators) \ - DOCTEST_CREATE_AND_REGISTER_FUNCTION(DOCTEST_ANONYMOUS(_DOCTEST_ANON_FUNC_), decorators) - -// for registering tests in classes - requires C++17 for inline variables! -#if __cplusplus >= 201703L || (DOCTEST_MSVC >= DOCTEST_COMPILER(19, 12, 0) && _MSVC_LANG >= 201703L) -#define DOCTEST_TEST_CASE_CLASS(decorators) \ - DOCTEST_CREATE_AND_REGISTER_FUNCTION_IN_CLASS(DOCTEST_ANONYMOUS(_DOCTEST_ANON_FUNC_), \ - DOCTEST_ANONYMOUS(_DOCTEST_ANON_PROXY_), \ - decorators) -#else // DOCTEST_TEST_CASE_CLASS -#define DOCTEST_TEST_CASE_CLASS(...) \ - TEST_CASES_CAN_BE_REGISTERED_IN_CLASSES_ONLY_IN_CPP17_MODE_OR_WITH_VS_2017_OR_NEWER -#endif // DOCTEST_TEST_CASE_CLASS - -// for registering tests with a fixture -#define DOCTEST_TEST_CASE_FIXTURE(c, decorators) \ - DOCTEST_IMPLEMENT_FIXTURE(DOCTEST_ANONYMOUS(_DOCTEST_ANON_CLASS_), c, \ - DOCTEST_ANONYMOUS(_DOCTEST_ANON_FUNC_), decorators) - -// for converting types to strings without the header and demangling -#define DOCTEST_TYPE_TO_STRING_IMPL(...) \ - template <> \ - inline const char* type_to_string<__VA_ARGS__>() { \ - return "<" #__VA_ARGS__ ">"; \ - } -#define DOCTEST_TYPE_TO_STRING(...) \ - namespace doctest { namespace detail { \ - DOCTEST_TYPE_TO_STRING_IMPL(__VA_ARGS__) \ - } \ - } \ - typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_) - -#define DOCTEST_TEST_CASE_TEMPLATE_DEFINE_IMPL(dec, T, iter, func) \ - template \ - static void func(); \ - namespace { \ - template \ - struct iter; \ - template \ - struct iter> \ - { \ - iter(const char* file, unsigned line, int index) { \ - doctest::detail::regTest(doctest::detail::TestCase(func, file, line, \ - doctest_detail_test_suite_ns::getCurrentTestSuite(), \ - doctest::detail::type_to_string(), \ - int(line) * 1000 + index) \ - * dec); \ - iter>(file, line, index + 1); \ - } \ - }; \ - template <> \ - struct iter> \ - { \ - iter(const char*, unsigned, int) {} \ - }; \ - } \ - template \ - static void func() - -#define DOCTEST_TEST_CASE_TEMPLATE_DEFINE(dec, T, id) \ - DOCTEST_TEST_CASE_TEMPLATE_DEFINE_IMPL(dec, T, DOCTEST_CAT(id, ITERATOR), \ - DOCTEST_ANONYMOUS(_DOCTEST_ANON_TMP_)) - -#define DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE_IMPL(id, anon, ...) \ - DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_CAT(anon, DUMMY)) = \ - doctest::detail::instantiationHelper(DOCTEST_CAT(id, ITERATOR)<__VA_ARGS__>(__FILE__, __LINE__, 0));\ - DOCTEST_GLOBAL_NO_WARNINGS_END() - -#define DOCTEST_TEST_CASE_TEMPLATE_INVOKE(id, ...) \ - DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE_IMPL(id, DOCTEST_ANONYMOUS(_DOCTEST_ANON_TMP_), std::tuple<__VA_ARGS__>) \ - typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_) - -#define DOCTEST_TEST_CASE_TEMPLATE_APPLY(id, ...) \ - DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE_IMPL(id, DOCTEST_ANONYMOUS(_DOCTEST_ANON_TMP_), __VA_ARGS__) \ - typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_) - -#define DOCTEST_TEST_CASE_TEMPLATE_IMPL(dec, T, anon, ...) \ - DOCTEST_TEST_CASE_TEMPLATE_DEFINE_IMPL(dec, T, DOCTEST_CAT(anon, ITERATOR), anon); \ - DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE_IMPL(anon, anon, std::tuple<__VA_ARGS__>) \ - template \ - static void anon() - -#define DOCTEST_TEST_CASE_TEMPLATE(dec, T, ...) \ - DOCTEST_TEST_CASE_TEMPLATE_IMPL(dec, T, DOCTEST_ANONYMOUS(_DOCTEST_ANON_TMP_), __VA_ARGS__) - -// for subcases -#define DOCTEST_SUBCASE(name) \ - if(const doctest::detail::Subcase & DOCTEST_ANONYMOUS(_DOCTEST_ANON_SUBCASE_) DOCTEST_UNUSED = \ - doctest::detail::Subcase(name, __FILE__, __LINE__)) - -// for grouping tests in test suites by using code blocks -#define DOCTEST_TEST_SUITE_IMPL(decorators, ns_name) \ - namespace ns_name { namespace doctest_detail_test_suite_ns { \ - static DOCTEST_NOINLINE doctest::detail::TestSuite& getCurrentTestSuite() { \ - DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4640) \ - DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wexit-time-destructors") \ - DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wmissing-field-initializers") \ - static doctest::detail::TestSuite data{}; \ - static bool inited = false; \ - DOCTEST_MSVC_SUPPRESS_WARNING_POP \ - DOCTEST_CLANG_SUPPRESS_WARNING_POP \ - DOCTEST_GCC_SUPPRESS_WARNING_POP \ - if(!inited) { \ - data* decorators; \ - inited = true; \ - } \ - return data; \ - } \ - } \ - } \ - namespace ns_name - -#define DOCTEST_TEST_SUITE(decorators) \ - DOCTEST_TEST_SUITE_IMPL(decorators, DOCTEST_ANONYMOUS(_DOCTEST_ANON_SUITE_)) - -// for starting a testsuite block -#define DOCTEST_TEST_SUITE_BEGIN(decorators) \ - DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(_DOCTEST_ANON_VAR_)) = \ - doctest::detail::setTestSuite(doctest::detail::TestSuite() * decorators); \ - DOCTEST_GLOBAL_NO_WARNINGS_END() \ - typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_) - -// for ending a testsuite block -#define DOCTEST_TEST_SUITE_END \ - DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(_DOCTEST_ANON_VAR_)) = \ - doctest::detail::setTestSuite(doctest::detail::TestSuite() * ""); \ - DOCTEST_GLOBAL_NO_WARNINGS_END() \ - typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_) - -// for registering exception translators -#define DOCTEST_REGISTER_EXCEPTION_TRANSLATOR_IMPL(translatorName, signature) \ - inline doctest::String translatorName(signature); \ - DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(_DOCTEST_ANON_TRANSLATOR_)) = \ - doctest::registerExceptionTranslator(translatorName); \ - DOCTEST_GLOBAL_NO_WARNINGS_END() \ - doctest::String translatorName(signature) - -#define DOCTEST_REGISTER_EXCEPTION_TRANSLATOR(signature) \ - DOCTEST_REGISTER_EXCEPTION_TRANSLATOR_IMPL(DOCTEST_ANONYMOUS(_DOCTEST_ANON_TRANSLATOR_), \ - signature) - -// for registering reporters -#define DOCTEST_REGISTER_REPORTER(name, priority, reporter) \ - DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(_DOCTEST_ANON_REPORTER_)) = \ - doctest::registerReporter(name, priority, true); \ - DOCTEST_GLOBAL_NO_WARNINGS_END() typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_) - -// for registering listeners -#define DOCTEST_REGISTER_LISTENER(name, priority, reporter) \ - DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(_DOCTEST_ANON_REPORTER_)) = \ - doctest::registerReporter(name, priority, false); \ - DOCTEST_GLOBAL_NO_WARNINGS_END() typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_) - -// for logging -#define DOCTEST_INFO(...) \ - DOCTEST_INFO_IMPL(DOCTEST_ANONYMOUS(_DOCTEST_CAPTURE_), DOCTEST_ANONYMOUS(_DOCTEST_CAPTURE_), \ - __VA_ARGS__) - -#define DOCTEST_INFO_IMPL(mb_name, s_name, ...) \ - auto DOCTEST_ANONYMOUS(_DOCTEST_CAPTURE_) = doctest::detail::MakeContextScope( \ - [&](std::ostream* s_name) { \ - doctest::detail::MessageBuilder mb_name(__FILE__, __LINE__, doctest::assertType::is_warn); \ - mb_name.m_stream = s_name; \ - mb_name * __VA_ARGS__; \ - }) - -#define DOCTEST_CAPTURE(x) DOCTEST_INFO(#x " := ", x) - -#define DOCTEST_ADD_AT_IMPL(type, file, line, mb, ...) \ - do { \ - doctest::detail::MessageBuilder mb(file, line, doctest::assertType::type); \ - mb * __VA_ARGS__; \ - DOCTEST_ASSERT_LOG_AND_REACT(mb); \ - } while(false) - -// clang-format off -#define DOCTEST_ADD_MESSAGE_AT(file, line, ...) DOCTEST_ADD_AT_IMPL(is_warn, file, line, DOCTEST_ANONYMOUS(_DOCTEST_MESSAGE_), __VA_ARGS__) -#define DOCTEST_ADD_FAIL_CHECK_AT(file, line, ...) DOCTEST_ADD_AT_IMPL(is_check, file, line, DOCTEST_ANONYMOUS(_DOCTEST_MESSAGE_), __VA_ARGS__) -#define DOCTEST_ADD_FAIL_AT(file, line, ...) DOCTEST_ADD_AT_IMPL(is_require, file, line, DOCTEST_ANONYMOUS(_DOCTEST_MESSAGE_), __VA_ARGS__) -// clang-format on - -#define DOCTEST_MESSAGE(...) DOCTEST_ADD_MESSAGE_AT(__FILE__, __LINE__, __VA_ARGS__) -#define DOCTEST_FAIL_CHECK(...) DOCTEST_ADD_FAIL_CHECK_AT(__FILE__, __LINE__, __VA_ARGS__) -#define DOCTEST_FAIL(...) DOCTEST_ADD_FAIL_AT(__FILE__, __LINE__, __VA_ARGS__) - -#define DOCTEST_TO_LVALUE(...) __VA_ARGS__ // Not removed to keep backwards compatibility. - -#ifndef DOCTEST_CONFIG_SUPER_FAST_ASSERTS - -#define DOCTEST_ASSERT_IMPLEMENT_2(assert_type, ...) \ - DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Woverloaded-shift-op-parentheses") \ - doctest::detail::ResultBuilder _DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \ - __LINE__, #__VA_ARGS__); \ - DOCTEST_WRAP_IN_TRY(_DOCTEST_RB.setResult( \ - doctest::detail::ExpressionDecomposer(doctest::assertType::assert_type) \ - << __VA_ARGS__)) \ - DOCTEST_ASSERT_LOG_AND_REACT(_DOCTEST_RB) \ - DOCTEST_CLANG_SUPPRESS_WARNING_POP - -#define DOCTEST_ASSERT_IMPLEMENT_1(assert_type, ...) \ - do { \ - DOCTEST_ASSERT_IMPLEMENT_2(assert_type, __VA_ARGS__); \ - } while(false) - -#else // DOCTEST_CONFIG_SUPER_FAST_ASSERTS - -// necessary for _MESSAGE -#define DOCTEST_ASSERT_IMPLEMENT_2 DOCTEST_ASSERT_IMPLEMENT_1 - -#define DOCTEST_ASSERT_IMPLEMENT_1(assert_type, ...) \ - DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Woverloaded-shift-op-parentheses") \ - doctest::detail::decomp_assert( \ - doctest::assertType::assert_type, __FILE__, __LINE__, #__VA_ARGS__, \ - doctest::detail::ExpressionDecomposer(doctest::assertType::assert_type) \ - << __VA_ARGS__) DOCTEST_CLANG_SUPPRESS_WARNING_POP - -#endif // DOCTEST_CONFIG_SUPER_FAST_ASSERTS - -#define DOCTEST_WARN(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_WARN, __VA_ARGS__) -#define DOCTEST_CHECK(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_CHECK, __VA_ARGS__) -#define DOCTEST_REQUIRE(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_REQUIRE, __VA_ARGS__) -#define DOCTEST_WARN_FALSE(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_WARN_FALSE, __VA_ARGS__) -#define DOCTEST_CHECK_FALSE(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_CHECK_FALSE, __VA_ARGS__) -#define DOCTEST_REQUIRE_FALSE(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_REQUIRE_FALSE, __VA_ARGS__) - -// clang-format off -#define DOCTEST_WARN_MESSAGE(cond, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_WARN, cond); } while(false) -#define DOCTEST_CHECK_MESSAGE(cond, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_CHECK, cond); } while(false) -#define DOCTEST_REQUIRE_MESSAGE(cond, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_REQUIRE, cond); } while(false) -#define DOCTEST_WARN_FALSE_MESSAGE(cond, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_WARN_FALSE, cond); } while(false) -#define DOCTEST_CHECK_FALSE_MESSAGE(cond, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_CHECK_FALSE, cond); } while(false) -#define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_REQUIRE_FALSE, cond); } while(false) -// clang-format on - -#define DOCTEST_ASSERT_THROWS_AS(expr, assert_type, message, ...) \ - do { \ - if(!doctest::getContextOptions()->no_throw) { \ - doctest::detail::ResultBuilder _DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \ - __LINE__, #expr, #__VA_ARGS__, message); \ - try { \ - DOCTEST_CAST_TO_VOID(expr) \ - } catch(const typename doctest::detail::remove_const< \ - typename doctest::detail::remove_reference<__VA_ARGS__>::type>::type&) { \ - _DOCTEST_RB.translateException(); \ - _DOCTEST_RB.m_threw_as = true; \ - } catch(...) { _DOCTEST_RB.translateException(); } \ - DOCTEST_ASSERT_LOG_AND_REACT(_DOCTEST_RB); \ - } \ - } while(false) - -#define DOCTEST_ASSERT_THROWS_WITH(expr, expr_str, assert_type, ...) \ - do { \ - if(!doctest::getContextOptions()->no_throw) { \ - doctest::detail::ResultBuilder _DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \ - __LINE__, expr_str, "", __VA_ARGS__); \ - try { \ - DOCTEST_CAST_TO_VOID(expr) \ - } catch(...) { _DOCTEST_RB.translateException(); } \ - DOCTEST_ASSERT_LOG_AND_REACT(_DOCTEST_RB); \ - } \ - } while(false) - -#define DOCTEST_ASSERT_NOTHROW(assert_type, ...) \ - do { \ - doctest::detail::ResultBuilder _DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \ - __LINE__, #__VA_ARGS__); \ - try { \ - DOCTEST_CAST_TO_VOID(__VA_ARGS__) \ - } catch(...) { _DOCTEST_RB.translateException(); } \ - DOCTEST_ASSERT_LOG_AND_REACT(_DOCTEST_RB); \ - } while(false) - -// clang-format off -#define DOCTEST_WARN_THROWS(...) DOCTEST_ASSERT_THROWS_WITH((__VA_ARGS__), #__VA_ARGS__, DT_WARN_THROWS, "") -#define DOCTEST_CHECK_THROWS(...) DOCTEST_ASSERT_THROWS_WITH((__VA_ARGS__), #__VA_ARGS__, DT_CHECK_THROWS, "") -#define DOCTEST_REQUIRE_THROWS(...) DOCTEST_ASSERT_THROWS_WITH((__VA_ARGS__), #__VA_ARGS__, DT_REQUIRE_THROWS, "") - -#define DOCTEST_WARN_THROWS_AS(expr, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_WARN_THROWS_AS, "", __VA_ARGS__) -#define DOCTEST_CHECK_THROWS_AS(expr, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_CHECK_THROWS_AS, "", __VA_ARGS__) -#define DOCTEST_REQUIRE_THROWS_AS(expr, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_REQUIRE_THROWS_AS, "", __VA_ARGS__) - -#define DOCTEST_WARN_THROWS_WITH(expr, ...) DOCTEST_ASSERT_THROWS_WITH(expr, #expr, DT_WARN_THROWS_WITH, __VA_ARGS__) -#define DOCTEST_CHECK_THROWS_WITH(expr, ...) DOCTEST_ASSERT_THROWS_WITH(expr, #expr, DT_CHECK_THROWS_WITH, __VA_ARGS__) -#define DOCTEST_REQUIRE_THROWS_WITH(expr, ...) DOCTEST_ASSERT_THROWS_WITH(expr, #expr, DT_REQUIRE_THROWS_WITH, __VA_ARGS__) - -#define DOCTEST_WARN_THROWS_WITH_AS(expr, message, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_WARN_THROWS_WITH_AS, message, __VA_ARGS__) -#define DOCTEST_CHECK_THROWS_WITH_AS(expr, message, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_CHECK_THROWS_WITH_AS, message, __VA_ARGS__) -#define DOCTEST_REQUIRE_THROWS_WITH_AS(expr, message, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_REQUIRE_THROWS_WITH_AS, message, __VA_ARGS__) - -#define DOCTEST_WARN_NOTHROW(...) DOCTEST_ASSERT_NOTHROW(DT_WARN_NOTHROW, __VA_ARGS__) -#define DOCTEST_CHECK_NOTHROW(...) DOCTEST_ASSERT_NOTHROW(DT_CHECK_NOTHROW, __VA_ARGS__) -#define DOCTEST_REQUIRE_NOTHROW(...) DOCTEST_ASSERT_NOTHROW(DT_REQUIRE_NOTHROW, __VA_ARGS__) - -#define DOCTEST_WARN_THROWS_MESSAGE(expr, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS(expr); } while(false) -#define DOCTEST_CHECK_THROWS_MESSAGE(expr, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS(expr); } while(false) -#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS(expr); } while(false) -#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS_AS(expr, ex); } while(false) -#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS_AS(expr, ex); } while(false) -#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS_AS(expr, ex); } while(false) -#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS_WITH(expr, with); } while(false) -#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS_WITH(expr, with); } while(false) -#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS_WITH(expr, with); } while(false) -#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS_WITH_AS(expr, with, ex); } while(false) -#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ex); } while(false) -#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ex); } while(false) -#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_NOTHROW(expr); } while(false) -#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_NOTHROW(expr); } while(false) -#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_NOTHROW(expr); } while(false) -// clang-format on - -#ifndef DOCTEST_CONFIG_SUPER_FAST_ASSERTS - -#define DOCTEST_BINARY_ASSERT(assert_type, comp, ...) \ - do { \ - doctest::detail::ResultBuilder _DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \ - __LINE__, #__VA_ARGS__); \ - DOCTEST_WRAP_IN_TRY( \ - _DOCTEST_RB.binary_assert( \ - __VA_ARGS__)) \ - DOCTEST_ASSERT_LOG_AND_REACT(_DOCTEST_RB); \ - } while(false) - -#define DOCTEST_UNARY_ASSERT(assert_type, ...) \ - do { \ - doctest::detail::ResultBuilder _DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \ - __LINE__, #__VA_ARGS__); \ - DOCTEST_WRAP_IN_TRY(_DOCTEST_RB.unary_assert(__VA_ARGS__)) \ - DOCTEST_ASSERT_LOG_AND_REACT(_DOCTEST_RB); \ - } while(false) - -#else // DOCTEST_CONFIG_SUPER_FAST_ASSERTS - -#define DOCTEST_BINARY_ASSERT(assert_type, comparison, ...) \ - doctest::detail::binary_assert( \ - doctest::assertType::assert_type, __FILE__, __LINE__, #__VA_ARGS__, __VA_ARGS__) - -#define DOCTEST_UNARY_ASSERT(assert_type, ...) \ - doctest::detail::unary_assert(doctest::assertType::assert_type, __FILE__, __LINE__, \ - #__VA_ARGS__, __VA_ARGS__) - -#endif // DOCTEST_CONFIG_SUPER_FAST_ASSERTS - -#define DOCTEST_WARN_EQ(...) DOCTEST_BINARY_ASSERT(DT_WARN_EQ, eq, __VA_ARGS__) -#define DOCTEST_CHECK_EQ(...) DOCTEST_BINARY_ASSERT(DT_CHECK_EQ, eq, __VA_ARGS__) -#define DOCTEST_REQUIRE_EQ(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_EQ, eq, __VA_ARGS__) -#define DOCTEST_WARN_NE(...) DOCTEST_BINARY_ASSERT(DT_WARN_NE, ne, __VA_ARGS__) -#define DOCTEST_CHECK_NE(...) DOCTEST_BINARY_ASSERT(DT_CHECK_NE, ne, __VA_ARGS__) -#define DOCTEST_REQUIRE_NE(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_NE, ne, __VA_ARGS__) -#define DOCTEST_WARN_GT(...) DOCTEST_BINARY_ASSERT(DT_WARN_GT, gt, __VA_ARGS__) -#define DOCTEST_CHECK_GT(...) DOCTEST_BINARY_ASSERT(DT_CHECK_GT, gt, __VA_ARGS__) -#define DOCTEST_REQUIRE_GT(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_GT, gt, __VA_ARGS__) -#define DOCTEST_WARN_LT(...) DOCTEST_BINARY_ASSERT(DT_WARN_LT, lt, __VA_ARGS__) -#define DOCTEST_CHECK_LT(...) DOCTEST_BINARY_ASSERT(DT_CHECK_LT, lt, __VA_ARGS__) -#define DOCTEST_REQUIRE_LT(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_LT, lt, __VA_ARGS__) -#define DOCTEST_WARN_GE(...) DOCTEST_BINARY_ASSERT(DT_WARN_GE, ge, __VA_ARGS__) -#define DOCTEST_CHECK_GE(...) DOCTEST_BINARY_ASSERT(DT_CHECK_GE, ge, __VA_ARGS__) -#define DOCTEST_REQUIRE_GE(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_GE, ge, __VA_ARGS__) -#define DOCTEST_WARN_LE(...) DOCTEST_BINARY_ASSERT(DT_WARN_LE, le, __VA_ARGS__) -#define DOCTEST_CHECK_LE(...) DOCTEST_BINARY_ASSERT(DT_CHECK_LE, le, __VA_ARGS__) -#define DOCTEST_REQUIRE_LE(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_LE, le, __VA_ARGS__) - -#define DOCTEST_WARN_UNARY(...) DOCTEST_UNARY_ASSERT(DT_WARN_UNARY, __VA_ARGS__) -#define DOCTEST_CHECK_UNARY(...) DOCTEST_UNARY_ASSERT(DT_CHECK_UNARY, __VA_ARGS__) -#define DOCTEST_REQUIRE_UNARY(...) DOCTEST_UNARY_ASSERT(DT_REQUIRE_UNARY, __VA_ARGS__) -#define DOCTEST_WARN_UNARY_FALSE(...) DOCTEST_UNARY_ASSERT(DT_WARN_UNARY_FALSE, __VA_ARGS__) -#define DOCTEST_CHECK_UNARY_FALSE(...) DOCTEST_UNARY_ASSERT(DT_CHECK_UNARY_FALSE, __VA_ARGS__) -#define DOCTEST_REQUIRE_UNARY_FALSE(...) DOCTEST_UNARY_ASSERT(DT_REQUIRE_UNARY_FALSE, __VA_ARGS__) - -#ifdef DOCTEST_CONFIG_NO_EXCEPTIONS - -#undef DOCTEST_WARN_THROWS -#undef DOCTEST_CHECK_THROWS -#undef DOCTEST_REQUIRE_THROWS -#undef DOCTEST_WARN_THROWS_AS -#undef DOCTEST_CHECK_THROWS_AS -#undef DOCTEST_REQUIRE_THROWS_AS -#undef DOCTEST_WARN_THROWS_WITH -#undef DOCTEST_CHECK_THROWS_WITH -#undef DOCTEST_REQUIRE_THROWS_WITH -#undef DOCTEST_WARN_THROWS_WITH_AS -#undef DOCTEST_CHECK_THROWS_WITH_AS -#undef DOCTEST_REQUIRE_THROWS_WITH_AS -#undef DOCTEST_WARN_NOTHROW -#undef DOCTEST_CHECK_NOTHROW -#undef DOCTEST_REQUIRE_NOTHROW - -#undef DOCTEST_WARN_THROWS_MESSAGE -#undef DOCTEST_CHECK_THROWS_MESSAGE -#undef DOCTEST_REQUIRE_THROWS_MESSAGE -#undef DOCTEST_WARN_THROWS_AS_MESSAGE -#undef DOCTEST_CHECK_THROWS_AS_MESSAGE -#undef DOCTEST_REQUIRE_THROWS_AS_MESSAGE -#undef DOCTEST_WARN_THROWS_WITH_MESSAGE -#undef DOCTEST_CHECK_THROWS_WITH_MESSAGE -#undef DOCTEST_REQUIRE_THROWS_WITH_MESSAGE -#undef DOCTEST_WARN_THROWS_WITH_AS_MESSAGE -#undef DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE -#undef DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE -#undef DOCTEST_WARN_NOTHROW_MESSAGE -#undef DOCTEST_CHECK_NOTHROW_MESSAGE -#undef DOCTEST_REQUIRE_NOTHROW_MESSAGE - -#ifdef DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS - -#define DOCTEST_WARN_THROWS(...) (static_cast(0)) -#define DOCTEST_CHECK_THROWS(...) (static_cast(0)) -#define DOCTEST_REQUIRE_THROWS(...) (static_cast(0)) -#define DOCTEST_WARN_THROWS_AS(expr, ...) (static_cast(0)) -#define DOCTEST_CHECK_THROWS_AS(expr, ...) (static_cast(0)) -#define DOCTEST_REQUIRE_THROWS_AS(expr, ...) (static_cast(0)) -#define DOCTEST_WARN_THROWS_WITH(expr, ...) (static_cast(0)) -#define DOCTEST_CHECK_THROWS_WITH(expr, ...) (static_cast(0)) -#define DOCTEST_REQUIRE_THROWS_WITH(expr, ...) (static_cast(0)) -#define DOCTEST_WARN_THROWS_WITH_AS(expr, with, ...) (static_cast(0)) -#define DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ...) (static_cast(0)) -#define DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ...) (static_cast(0)) -#define DOCTEST_WARN_NOTHROW(...) (static_cast(0)) -#define DOCTEST_CHECK_NOTHROW(...) (static_cast(0)) -#define DOCTEST_REQUIRE_NOTHROW(...) (static_cast(0)) - -#define DOCTEST_WARN_THROWS_MESSAGE(expr, ...) (static_cast(0)) -#define DOCTEST_CHECK_THROWS_MESSAGE(expr, ...) (static_cast(0)) -#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, ...) (static_cast(0)) -#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, ...) (static_cast(0)) -#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, ...) (static_cast(0)) -#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) (static_cast(0)) -#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, ...) (static_cast(0)) -#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, ...) (static_cast(0)) -#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) (static_cast(0)) -#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) (static_cast(0)) -#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) (static_cast(0)) -#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) (static_cast(0)) -#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, ...) (static_cast(0)) -#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, ...) (static_cast(0)) -#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, ...) (static_cast(0)) - -#else // DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS - -#undef DOCTEST_REQUIRE -#undef DOCTEST_REQUIRE_FALSE -#undef DOCTEST_REQUIRE_MESSAGE -#undef DOCTEST_REQUIRE_FALSE_MESSAGE -#undef DOCTEST_REQUIRE_EQ -#undef DOCTEST_REQUIRE_NE -#undef DOCTEST_REQUIRE_GT -#undef DOCTEST_REQUIRE_LT -#undef DOCTEST_REQUIRE_GE -#undef DOCTEST_REQUIRE_LE -#undef DOCTEST_REQUIRE_UNARY -#undef DOCTEST_REQUIRE_UNARY_FALSE - -#endif // DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS - -#endif // DOCTEST_CONFIG_NO_EXCEPTIONS - -// ================================================================================================= -// == WHAT FOLLOWS IS VERSIONS OF THE MACROS THAT DO NOT DO ANY REGISTERING! == -// == THIS CAN BE ENABLED BY DEFINING DOCTEST_CONFIG_DISABLE GLOBALLY! == -// ================================================================================================= -#else // DOCTEST_CONFIG_DISABLE - -#define DOCTEST_IMPLEMENT_FIXTURE(der, base, func, name) \ - namespace { \ - template \ - struct der : public base \ - { void f(); }; \ - } \ - template \ - inline void der::f() - -#define DOCTEST_CREATE_AND_REGISTER_FUNCTION(f, name) \ - template \ - static inline void f() - -// for registering tests -#define DOCTEST_TEST_CASE(name) \ - DOCTEST_CREATE_AND_REGISTER_FUNCTION(DOCTEST_ANONYMOUS(_DOCTEST_ANON_FUNC_), name) - -// for registering tests in classes -#define DOCTEST_TEST_CASE_CLASS(name) \ - DOCTEST_CREATE_AND_REGISTER_FUNCTION(DOCTEST_ANONYMOUS(_DOCTEST_ANON_FUNC_), name) - -// for registering tests with a fixture -#define DOCTEST_TEST_CASE_FIXTURE(x, name) \ - DOCTEST_IMPLEMENT_FIXTURE(DOCTEST_ANONYMOUS(_DOCTEST_ANON_CLASS_), x, \ - DOCTEST_ANONYMOUS(_DOCTEST_ANON_FUNC_), name) - -// for converting types to strings without the header and demangling -#define DOCTEST_TYPE_TO_STRING(...) typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_) -#define DOCTEST_TYPE_TO_STRING_IMPL(...) - -// for typed tests -#define DOCTEST_TEST_CASE_TEMPLATE(name, type, ...) \ - template \ - inline void DOCTEST_ANONYMOUS(_DOCTEST_ANON_TMP_)() - -#define DOCTEST_TEST_CASE_TEMPLATE_DEFINE(name, type, id) \ - template \ - inline void DOCTEST_ANONYMOUS(_DOCTEST_ANON_TMP_)() - -#define DOCTEST_TEST_CASE_TEMPLATE_INVOKE(id, ...) \ - typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_) - -#define DOCTEST_TEST_CASE_TEMPLATE_APPLY(id, ...) \ - typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_) - -// for subcases -#define DOCTEST_SUBCASE(name) - -// for a testsuite block -#define DOCTEST_TEST_SUITE(name) namespace - -// for starting a testsuite block -#define DOCTEST_TEST_SUITE_BEGIN(name) typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_) - -// for ending a testsuite block -#define DOCTEST_TEST_SUITE_END typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_) - -#define DOCTEST_REGISTER_EXCEPTION_TRANSLATOR(signature) \ - template \ - static inline doctest::String DOCTEST_ANONYMOUS(_DOCTEST_ANON_TRANSLATOR_)(signature) - -#define DOCTEST_REGISTER_REPORTER(name, priority, reporter) -#define DOCTEST_REGISTER_LISTENER(name, priority, reporter) - -#define DOCTEST_INFO(...) (static_cast(0)) -#define DOCTEST_CAPTURE(x) (static_cast(0)) -#define DOCTEST_ADD_MESSAGE_AT(file, line, ...) (static_cast(0)) -#define DOCTEST_ADD_FAIL_CHECK_AT(file, line, ...) (static_cast(0)) -#define DOCTEST_ADD_FAIL_AT(file, line, ...) (static_cast(0)) -#define DOCTEST_MESSAGE(...) (static_cast(0)) -#define DOCTEST_FAIL_CHECK(...) (static_cast(0)) -#define DOCTEST_FAIL(...) (static_cast(0)) - -#define DOCTEST_WARN(...) (static_cast(0)) -#define DOCTEST_CHECK(...) (static_cast(0)) -#define DOCTEST_REQUIRE(...) (static_cast(0)) -#define DOCTEST_WARN_FALSE(...) (static_cast(0)) -#define DOCTEST_CHECK_FALSE(...) (static_cast(0)) -#define DOCTEST_REQUIRE_FALSE(...) (static_cast(0)) - -#define DOCTEST_WARN_MESSAGE(cond, ...) (static_cast(0)) -#define DOCTEST_CHECK_MESSAGE(cond, ...) (static_cast(0)) -#define DOCTEST_REQUIRE_MESSAGE(cond, ...) (static_cast(0)) -#define DOCTEST_WARN_FALSE_MESSAGE(cond, ...) (static_cast(0)) -#define DOCTEST_CHECK_FALSE_MESSAGE(cond, ...) (static_cast(0)) -#define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, ...) (static_cast(0)) - -#define DOCTEST_WARN_THROWS(...) (static_cast(0)) -#define DOCTEST_CHECK_THROWS(...) (static_cast(0)) -#define DOCTEST_REQUIRE_THROWS(...) (static_cast(0)) -#define DOCTEST_WARN_THROWS_AS(expr, ...) (static_cast(0)) -#define DOCTEST_CHECK_THROWS_AS(expr, ...) (static_cast(0)) -#define DOCTEST_REQUIRE_THROWS_AS(expr, ...) (static_cast(0)) -#define DOCTEST_WARN_THROWS_WITH(expr, ...) (static_cast(0)) -#define DOCTEST_CHECK_THROWS_WITH(expr, ...) (static_cast(0)) -#define DOCTEST_REQUIRE_THROWS_WITH(expr, ...) (static_cast(0)) -#define DOCTEST_WARN_THROWS_WITH_AS(expr, with, ...) (static_cast(0)) -#define DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ...) (static_cast(0)) -#define DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ...) (static_cast(0)) -#define DOCTEST_WARN_NOTHROW(...) (static_cast(0)) -#define DOCTEST_CHECK_NOTHROW(...) (static_cast(0)) -#define DOCTEST_REQUIRE_NOTHROW(...) (static_cast(0)) - -#define DOCTEST_WARN_THROWS_MESSAGE(expr, ...) (static_cast(0)) -#define DOCTEST_CHECK_THROWS_MESSAGE(expr, ...) (static_cast(0)) -#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, ...) (static_cast(0)) -#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, ...) (static_cast(0)) -#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, ...) (static_cast(0)) -#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) (static_cast(0)) -#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, ...) (static_cast(0)) -#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, ...) (static_cast(0)) -#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) (static_cast(0)) -#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) (static_cast(0)) -#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) (static_cast(0)) -#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) (static_cast(0)) -#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, ...) (static_cast(0)) -#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, ...) (static_cast(0)) -#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, ...) (static_cast(0)) - -#define DOCTEST_WARN_EQ(...) (static_cast(0)) -#define DOCTEST_CHECK_EQ(...) (static_cast(0)) -#define DOCTEST_REQUIRE_EQ(...) (static_cast(0)) -#define DOCTEST_WARN_NE(...) (static_cast(0)) -#define DOCTEST_CHECK_NE(...) (static_cast(0)) -#define DOCTEST_REQUIRE_NE(...) (static_cast(0)) -#define DOCTEST_WARN_GT(...) (static_cast(0)) -#define DOCTEST_CHECK_GT(...) (static_cast(0)) -#define DOCTEST_REQUIRE_GT(...) (static_cast(0)) -#define DOCTEST_WARN_LT(...) (static_cast(0)) -#define DOCTEST_CHECK_LT(...) (static_cast(0)) -#define DOCTEST_REQUIRE_LT(...) (static_cast(0)) -#define DOCTEST_WARN_GE(...) (static_cast(0)) -#define DOCTEST_CHECK_GE(...) (static_cast(0)) -#define DOCTEST_REQUIRE_GE(...) (static_cast(0)) -#define DOCTEST_WARN_LE(...) (static_cast(0)) -#define DOCTEST_CHECK_LE(...) (static_cast(0)) -#define DOCTEST_REQUIRE_LE(...) (static_cast(0)) - -#define DOCTEST_WARN_UNARY(...) (static_cast(0)) -#define DOCTEST_CHECK_UNARY(...) (static_cast(0)) -#define DOCTEST_REQUIRE_UNARY(...) (static_cast(0)) -#define DOCTEST_WARN_UNARY_FALSE(...) (static_cast(0)) -#define DOCTEST_CHECK_UNARY_FALSE(...) (static_cast(0)) -#define DOCTEST_REQUIRE_UNARY_FALSE(...) (static_cast(0)) - -#endif // DOCTEST_CONFIG_DISABLE - -// clang-format off -// KEPT FOR BACKWARDS COMPATIBILITY - FORWARDING TO THE RIGHT MACROS -#define DOCTEST_FAST_WARN_EQ DOCTEST_WARN_EQ -#define DOCTEST_FAST_CHECK_EQ DOCTEST_CHECK_EQ -#define DOCTEST_FAST_REQUIRE_EQ DOCTEST_REQUIRE_EQ -#define DOCTEST_FAST_WARN_NE DOCTEST_WARN_NE -#define DOCTEST_FAST_CHECK_NE DOCTEST_CHECK_NE -#define DOCTEST_FAST_REQUIRE_NE DOCTEST_REQUIRE_NE -#define DOCTEST_FAST_WARN_GT DOCTEST_WARN_GT -#define DOCTEST_FAST_CHECK_GT DOCTEST_CHECK_GT -#define DOCTEST_FAST_REQUIRE_GT DOCTEST_REQUIRE_GT -#define DOCTEST_FAST_WARN_LT DOCTEST_WARN_LT -#define DOCTEST_FAST_CHECK_LT DOCTEST_CHECK_LT -#define DOCTEST_FAST_REQUIRE_LT DOCTEST_REQUIRE_LT -#define DOCTEST_FAST_WARN_GE DOCTEST_WARN_GE -#define DOCTEST_FAST_CHECK_GE DOCTEST_CHECK_GE -#define DOCTEST_FAST_REQUIRE_GE DOCTEST_REQUIRE_GE -#define DOCTEST_FAST_WARN_LE DOCTEST_WARN_LE -#define DOCTEST_FAST_CHECK_LE DOCTEST_CHECK_LE -#define DOCTEST_FAST_REQUIRE_LE DOCTEST_REQUIRE_LE - -#define DOCTEST_FAST_WARN_UNARY DOCTEST_WARN_UNARY -#define DOCTEST_FAST_CHECK_UNARY DOCTEST_CHECK_UNARY -#define DOCTEST_FAST_REQUIRE_UNARY DOCTEST_REQUIRE_UNARY -#define DOCTEST_FAST_WARN_UNARY_FALSE DOCTEST_WARN_UNARY_FALSE -#define DOCTEST_FAST_CHECK_UNARY_FALSE DOCTEST_CHECK_UNARY_FALSE -#define DOCTEST_FAST_REQUIRE_UNARY_FALSE DOCTEST_REQUIRE_UNARY_FALSE - -#define DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE(id, ...) DOCTEST_TEST_CASE_TEMPLATE_INVOKE(id,__VA_ARGS__) -// clang-format on - -// BDD style macros -// clang-format off -#define DOCTEST_SCENARIO(name) DOCTEST_TEST_CASE(" Scenario: " name) -#define DOCTEST_SCENARIO_CLASS(name) DOCTEST_TEST_CASE_CLASS(" Scenario: " name) -#define DOCTEST_SCENARIO_TEMPLATE(name, T, ...) DOCTEST_TEST_CASE_TEMPLATE(" Scenario: " name, T, __VA_ARGS__) -#define DOCTEST_SCENARIO_TEMPLATE_DEFINE(name, T, id) DOCTEST_TEST_CASE_TEMPLATE_DEFINE(" Scenario: " name, T, id) - -#define DOCTEST_GIVEN(name) DOCTEST_SUBCASE(" Given: " name) -#define DOCTEST_WHEN(name) DOCTEST_SUBCASE(" When: " name) -#define DOCTEST_AND_WHEN(name) DOCTEST_SUBCASE("And when: " name) -#define DOCTEST_THEN(name) DOCTEST_SUBCASE(" Then: " name) -#define DOCTEST_AND_THEN(name) DOCTEST_SUBCASE(" And: " name) -// clang-format on - -// == SHORT VERSIONS OF THE MACROS -#if !defined(DOCTEST_CONFIG_NO_SHORT_MACRO_NAMES) - -#define TEST_CASE(name) DOCTEST_TEST_CASE(name) -#define TEST_CASE_CLASS(name) DOCTEST_TEST_CASE_CLASS(name) -#define TEST_CASE_FIXTURE(x, name) DOCTEST_TEST_CASE_FIXTURE(x, name) -#define TYPE_TO_STRING(...) DOCTEST_TYPE_TO_STRING(__VA_ARGS__) -#define TEST_CASE_TEMPLATE(name, T, ...) DOCTEST_TEST_CASE_TEMPLATE(name, T, __VA_ARGS__) -#define TEST_CASE_TEMPLATE_DEFINE(name, T, id) DOCTEST_TEST_CASE_TEMPLATE_DEFINE(name, T, id) -#define TEST_CASE_TEMPLATE_INVOKE(id, ...) DOCTEST_TEST_CASE_TEMPLATE_INVOKE(id, __VA_ARGS__) -#define TEST_CASE_TEMPLATE_APPLY(id, ...) DOCTEST_TEST_CASE_TEMPLATE_APPLY(id, __VA_ARGS__) -#define SUBCASE(name) DOCTEST_SUBCASE(name) -#define TEST_SUITE(decorators) DOCTEST_TEST_SUITE(decorators) -#define TEST_SUITE_BEGIN(name) DOCTEST_TEST_SUITE_BEGIN(name) -#define TEST_SUITE_END DOCTEST_TEST_SUITE_END -#define REGISTER_EXCEPTION_TRANSLATOR(signature) DOCTEST_REGISTER_EXCEPTION_TRANSLATOR(signature) -#define REGISTER_REPORTER(name, priority, reporter) DOCTEST_REGISTER_REPORTER(name, priority, reporter) -#define REGISTER_LISTENER(name, priority, reporter) DOCTEST_REGISTER_LISTENER(name, priority, reporter) -#define INFO(...) DOCTEST_INFO(__VA_ARGS__) -#define CAPTURE(x) DOCTEST_CAPTURE(x) -#define ADD_MESSAGE_AT(file, line, ...) DOCTEST_ADD_MESSAGE_AT(file, line, __VA_ARGS__) -#define ADD_FAIL_CHECK_AT(file, line, ...) DOCTEST_ADD_FAIL_CHECK_AT(file, line, __VA_ARGS__) -#define ADD_FAIL_AT(file, line, ...) DOCTEST_ADD_FAIL_AT(file, line, __VA_ARGS__) -#define MESSAGE(...) DOCTEST_MESSAGE(__VA_ARGS__) -#define FAIL_CHECK(...) DOCTEST_FAIL_CHECK(__VA_ARGS__) -#define FAIL(...) DOCTEST_FAIL(__VA_ARGS__) -#define TO_LVALUE(...) DOCTEST_TO_LVALUE(__VA_ARGS__) - -#define WARN(...) DOCTEST_WARN(__VA_ARGS__) -#define WARN_FALSE(...) DOCTEST_WARN_FALSE(__VA_ARGS__) -#define WARN_THROWS(...) DOCTEST_WARN_THROWS(__VA_ARGS__) -#define WARN_THROWS_AS(expr, ...) DOCTEST_WARN_THROWS_AS(expr, __VA_ARGS__) -#define WARN_THROWS_WITH(expr, ...) DOCTEST_WARN_THROWS_WITH(expr, __VA_ARGS__) -#define WARN_THROWS_WITH_AS(expr, with, ...) DOCTEST_WARN_THROWS_WITH_AS(expr, with, __VA_ARGS__) -#define WARN_NOTHROW(...) DOCTEST_WARN_NOTHROW(__VA_ARGS__) -#define CHECK(...) DOCTEST_CHECK(__VA_ARGS__) -#define CHECK_FALSE(...) DOCTEST_CHECK_FALSE(__VA_ARGS__) -#define CHECK_THROWS(...) DOCTEST_CHECK_THROWS(__VA_ARGS__) -#define CHECK_THROWS_AS(expr, ...) DOCTEST_CHECK_THROWS_AS(expr, __VA_ARGS__) -#define CHECK_THROWS_WITH(expr, ...) DOCTEST_CHECK_THROWS_WITH(expr, __VA_ARGS__) -#define CHECK_THROWS_WITH_AS(expr, with, ...) DOCTEST_CHECK_THROWS_WITH_AS(expr, with, __VA_ARGS__) -#define CHECK_NOTHROW(...) DOCTEST_CHECK_NOTHROW(__VA_ARGS__) -#define REQUIRE(...) DOCTEST_REQUIRE(__VA_ARGS__) -#define REQUIRE_FALSE(...) DOCTEST_REQUIRE_FALSE(__VA_ARGS__) -#define REQUIRE_THROWS(...) DOCTEST_REQUIRE_THROWS(__VA_ARGS__) -#define REQUIRE_THROWS_AS(expr, ...) DOCTEST_REQUIRE_THROWS_AS(expr, __VA_ARGS__) -#define REQUIRE_THROWS_WITH(expr, ...) DOCTEST_REQUIRE_THROWS_WITH(expr, __VA_ARGS__) -#define REQUIRE_THROWS_WITH_AS(expr, with, ...) DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, __VA_ARGS__) -#define REQUIRE_NOTHROW(...) DOCTEST_REQUIRE_NOTHROW(__VA_ARGS__) - -#define WARN_MESSAGE(cond, ...) DOCTEST_WARN_MESSAGE(cond, __VA_ARGS__) -#define WARN_FALSE_MESSAGE(cond, ...) DOCTEST_WARN_FALSE_MESSAGE(cond, __VA_ARGS__) -#define WARN_THROWS_MESSAGE(expr, ...) DOCTEST_WARN_THROWS_MESSAGE(expr, __VA_ARGS__) -#define WARN_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, __VA_ARGS__) -#define WARN_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, __VA_ARGS__) -#define WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, __VA_ARGS__) -#define WARN_NOTHROW_MESSAGE(expr, ...) DOCTEST_WARN_NOTHROW_MESSAGE(expr, __VA_ARGS__) -#define CHECK_MESSAGE(cond, ...) DOCTEST_CHECK_MESSAGE(cond, __VA_ARGS__) -#define CHECK_FALSE_MESSAGE(cond, ...) DOCTEST_CHECK_FALSE_MESSAGE(cond, __VA_ARGS__) -#define CHECK_THROWS_MESSAGE(expr, ...) DOCTEST_CHECK_THROWS_MESSAGE(expr, __VA_ARGS__) -#define CHECK_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, __VA_ARGS__) -#define CHECK_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, __VA_ARGS__) -#define CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, __VA_ARGS__) -#define CHECK_NOTHROW_MESSAGE(expr, ...) DOCTEST_CHECK_NOTHROW_MESSAGE(expr, __VA_ARGS__) -#define REQUIRE_MESSAGE(cond, ...) DOCTEST_REQUIRE_MESSAGE(cond, __VA_ARGS__) -#define REQUIRE_FALSE_MESSAGE(cond, ...) DOCTEST_REQUIRE_FALSE_MESSAGE(cond, __VA_ARGS__) -#define REQUIRE_THROWS_MESSAGE(expr, ...) DOCTEST_REQUIRE_THROWS_MESSAGE(expr, __VA_ARGS__) -#define REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, __VA_ARGS__) -#define REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, __VA_ARGS__) -#define REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, __VA_ARGS__) -#define REQUIRE_NOTHROW_MESSAGE(expr, ...) DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, __VA_ARGS__) - -#define SCENARIO(name) DOCTEST_SCENARIO(name) -#define SCENARIO_CLASS(name) DOCTEST_SCENARIO_CLASS(name) -#define SCENARIO_TEMPLATE(name, T, ...) DOCTEST_SCENARIO_TEMPLATE(name, T, __VA_ARGS__) -#define SCENARIO_TEMPLATE_DEFINE(name, T, id) DOCTEST_SCENARIO_TEMPLATE_DEFINE(name, T, id) -#define GIVEN(name) DOCTEST_GIVEN(name) -#define WHEN(name) DOCTEST_WHEN(name) -#define AND_WHEN(name) DOCTEST_AND_WHEN(name) -#define THEN(name) DOCTEST_THEN(name) -#define AND_THEN(name) DOCTEST_AND_THEN(name) - -#define WARN_EQ(...) DOCTEST_WARN_EQ(__VA_ARGS__) -#define CHECK_EQ(...) DOCTEST_CHECK_EQ(__VA_ARGS__) -#define REQUIRE_EQ(...) DOCTEST_REQUIRE_EQ(__VA_ARGS__) -#define WARN_NE(...) DOCTEST_WARN_NE(__VA_ARGS__) -#define CHECK_NE(...) DOCTEST_CHECK_NE(__VA_ARGS__) -#define REQUIRE_NE(...) DOCTEST_REQUIRE_NE(__VA_ARGS__) -#define WARN_GT(...) DOCTEST_WARN_GT(__VA_ARGS__) -#define CHECK_GT(...) DOCTEST_CHECK_GT(__VA_ARGS__) -#define REQUIRE_GT(...) DOCTEST_REQUIRE_GT(__VA_ARGS__) -#define WARN_LT(...) DOCTEST_WARN_LT(__VA_ARGS__) -#define CHECK_LT(...) DOCTEST_CHECK_LT(__VA_ARGS__) -#define REQUIRE_LT(...) DOCTEST_REQUIRE_LT(__VA_ARGS__) -#define WARN_GE(...) DOCTEST_WARN_GE(__VA_ARGS__) -#define CHECK_GE(...) DOCTEST_CHECK_GE(__VA_ARGS__) -#define REQUIRE_GE(...) DOCTEST_REQUIRE_GE(__VA_ARGS__) -#define WARN_LE(...) DOCTEST_WARN_LE(__VA_ARGS__) -#define CHECK_LE(...) DOCTEST_CHECK_LE(__VA_ARGS__) -#define REQUIRE_LE(...) DOCTEST_REQUIRE_LE(__VA_ARGS__) -#define WARN_UNARY(...) DOCTEST_WARN_UNARY(__VA_ARGS__) -#define CHECK_UNARY(...) DOCTEST_CHECK_UNARY(__VA_ARGS__) -#define REQUIRE_UNARY(...) DOCTEST_REQUIRE_UNARY(__VA_ARGS__) -#define WARN_UNARY_FALSE(...) DOCTEST_WARN_UNARY_FALSE(__VA_ARGS__) -#define CHECK_UNARY_FALSE(...) DOCTEST_CHECK_UNARY_FALSE(__VA_ARGS__) -#define REQUIRE_UNARY_FALSE(...) DOCTEST_REQUIRE_UNARY_FALSE(__VA_ARGS__) - -// KEPT FOR BACKWARDS COMPATIBILITY -#define FAST_WARN_EQ(...) DOCTEST_FAST_WARN_EQ(__VA_ARGS__) -#define FAST_CHECK_EQ(...) DOCTEST_FAST_CHECK_EQ(__VA_ARGS__) -#define FAST_REQUIRE_EQ(...) DOCTEST_FAST_REQUIRE_EQ(__VA_ARGS__) -#define FAST_WARN_NE(...) DOCTEST_FAST_WARN_NE(__VA_ARGS__) -#define FAST_CHECK_NE(...) DOCTEST_FAST_CHECK_NE(__VA_ARGS__) -#define FAST_REQUIRE_NE(...) DOCTEST_FAST_REQUIRE_NE(__VA_ARGS__) -#define FAST_WARN_GT(...) DOCTEST_FAST_WARN_GT(__VA_ARGS__) -#define FAST_CHECK_GT(...) DOCTEST_FAST_CHECK_GT(__VA_ARGS__) -#define FAST_REQUIRE_GT(...) DOCTEST_FAST_REQUIRE_GT(__VA_ARGS__) -#define FAST_WARN_LT(...) DOCTEST_FAST_WARN_LT(__VA_ARGS__) -#define FAST_CHECK_LT(...) DOCTEST_FAST_CHECK_LT(__VA_ARGS__) -#define FAST_REQUIRE_LT(...) DOCTEST_FAST_REQUIRE_LT(__VA_ARGS__) -#define FAST_WARN_GE(...) DOCTEST_FAST_WARN_GE(__VA_ARGS__) -#define FAST_CHECK_GE(...) DOCTEST_FAST_CHECK_GE(__VA_ARGS__) -#define FAST_REQUIRE_GE(...) DOCTEST_FAST_REQUIRE_GE(__VA_ARGS__) -#define FAST_WARN_LE(...) DOCTEST_FAST_WARN_LE(__VA_ARGS__) -#define FAST_CHECK_LE(...) DOCTEST_FAST_CHECK_LE(__VA_ARGS__) -#define FAST_REQUIRE_LE(...) DOCTEST_FAST_REQUIRE_LE(__VA_ARGS__) - -#define FAST_WARN_UNARY(...) DOCTEST_FAST_WARN_UNARY(__VA_ARGS__) -#define FAST_CHECK_UNARY(...) DOCTEST_FAST_CHECK_UNARY(__VA_ARGS__) -#define FAST_REQUIRE_UNARY(...) DOCTEST_FAST_REQUIRE_UNARY(__VA_ARGS__) -#define FAST_WARN_UNARY_FALSE(...) DOCTEST_FAST_WARN_UNARY_FALSE(__VA_ARGS__) -#define FAST_CHECK_UNARY_FALSE(...) DOCTEST_FAST_CHECK_UNARY_FALSE(__VA_ARGS__) -#define FAST_REQUIRE_UNARY_FALSE(...) DOCTEST_FAST_REQUIRE_UNARY_FALSE(__VA_ARGS__) - -#define TEST_CASE_TEMPLATE_INSTANTIATE(id, ...) DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE(id, __VA_ARGS__) - -#endif // DOCTEST_CONFIG_NO_SHORT_MACRO_NAMES - -#if !defined(DOCTEST_CONFIG_DISABLE) - -// this is here to clear the 'current test suite' for the current translation unit - at the top -DOCTEST_TEST_SUITE_END(); - -// add stringification for primitive/fundamental types -namespace doctest { namespace detail { - DOCTEST_TYPE_TO_STRING_IMPL(bool) - DOCTEST_TYPE_TO_STRING_IMPL(float) - DOCTEST_TYPE_TO_STRING_IMPL(double) - DOCTEST_TYPE_TO_STRING_IMPL(long double) - DOCTEST_TYPE_TO_STRING_IMPL(char) - DOCTEST_TYPE_TO_STRING_IMPL(signed char) - DOCTEST_TYPE_TO_STRING_IMPL(unsigned char) -#if !DOCTEST_MSVC || defined(_NATIVE_WCHAR_T_DEFINED) - DOCTEST_TYPE_TO_STRING_IMPL(wchar_t) -#endif // not MSVC or wchar_t support enabled - DOCTEST_TYPE_TO_STRING_IMPL(short int) - DOCTEST_TYPE_TO_STRING_IMPL(unsigned short int) - DOCTEST_TYPE_TO_STRING_IMPL(int) - DOCTEST_TYPE_TO_STRING_IMPL(unsigned int) - DOCTEST_TYPE_TO_STRING_IMPL(long int) - DOCTEST_TYPE_TO_STRING_IMPL(unsigned long int) - DOCTEST_TYPE_TO_STRING_IMPL(long long int) - DOCTEST_TYPE_TO_STRING_IMPL(unsigned long long int) -}} // namespace doctest::detail - -#endif // DOCTEST_CONFIG_DISABLE - -DOCTEST_CLANG_SUPPRESS_WARNING_POP -DOCTEST_MSVC_SUPPRESS_WARNING_POP -DOCTEST_GCC_SUPPRESS_WARNING_POP - -#endif // DOCTEST_LIBRARY_INCLUDED - -#ifndef DOCTEST_SINGLE_HEADER -#define DOCTEST_SINGLE_HEADER -#endif // DOCTEST_SINGLE_HEADER - -#if defined(DOCTEST_CONFIG_IMPLEMENT) || !defined(DOCTEST_SINGLE_HEADER) - -#ifndef DOCTEST_SINGLE_HEADER -#include "doctest_fwd.h" -#endif // DOCTEST_SINGLE_HEADER - -DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wunused-macros") - -#ifndef DOCTEST_LIBRARY_IMPLEMENTATION -#define DOCTEST_LIBRARY_IMPLEMENTATION - -DOCTEST_CLANG_SUPPRESS_WARNING_POP - -DOCTEST_CLANG_SUPPRESS_WARNING_PUSH -DOCTEST_CLANG_SUPPRESS_WARNING("-Wunknown-pragmas") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wpadded") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wweak-vtables") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wglobal-constructors") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wexit-time-destructors") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wmissing-prototypes") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wsign-conversion") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wshorten-64-to-32") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wmissing-variable-declarations") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wswitch") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wswitch-enum") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wcovered-switch-default") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wmissing-noreturn") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wunused-local-typedef") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wdisabled-macro-expansion") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wmissing-braces") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wmissing-field-initializers") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wc++98-compat") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wc++98-compat-pedantic") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wunused-member-function") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wnonportable-system-include-path") - -DOCTEST_GCC_SUPPRESS_WARNING_PUSH -DOCTEST_GCC_SUPPRESS_WARNING("-Wunknown-pragmas") -DOCTEST_GCC_SUPPRESS_WARNING("-Wpragmas") -DOCTEST_GCC_SUPPRESS_WARNING("-Wconversion") -DOCTEST_GCC_SUPPRESS_WARNING("-Weffc++") -DOCTEST_GCC_SUPPRESS_WARNING("-Wsign-conversion") -DOCTEST_GCC_SUPPRESS_WARNING("-Wstrict-overflow") -DOCTEST_GCC_SUPPRESS_WARNING("-Wstrict-aliasing") -DOCTEST_GCC_SUPPRESS_WARNING("-Wmissing-field-initializers") -DOCTEST_GCC_SUPPRESS_WARNING("-Wmissing-braces") -DOCTEST_GCC_SUPPRESS_WARNING("-Wmissing-declarations") -DOCTEST_GCC_SUPPRESS_WARNING("-Wswitch") -DOCTEST_GCC_SUPPRESS_WARNING("-Wswitch-enum") -DOCTEST_GCC_SUPPRESS_WARNING("-Wswitch-default") -DOCTEST_GCC_SUPPRESS_WARNING("-Wunsafe-loop-optimizations") -DOCTEST_GCC_SUPPRESS_WARNING("-Wold-style-cast") -DOCTEST_GCC_SUPPRESS_WARNING("-Wunused-local-typedefs") -DOCTEST_GCC_SUPPRESS_WARNING("-Wuseless-cast") -DOCTEST_GCC_SUPPRESS_WARNING("-Wunused-function") -DOCTEST_GCC_SUPPRESS_WARNING("-Wmultiple-inheritance") -DOCTEST_GCC_SUPPRESS_WARNING("-Wnoexcept") -DOCTEST_GCC_SUPPRESS_WARNING("-Wsuggest-attribute") - -DOCTEST_MSVC_SUPPRESS_WARNING_PUSH -DOCTEST_MSVC_SUPPRESS_WARNING(4616) // invalid compiler warning -DOCTEST_MSVC_SUPPRESS_WARNING(4619) // invalid compiler warning -DOCTEST_MSVC_SUPPRESS_WARNING(4996) // The compiler encountered a deprecated declaration -DOCTEST_MSVC_SUPPRESS_WARNING(4267) // 'var' : conversion from 'x' to 'y', possible loss of data -DOCTEST_MSVC_SUPPRESS_WARNING(4706) // assignment within conditional expression -DOCTEST_MSVC_SUPPRESS_WARNING(4512) // 'class' : assignment operator could not be generated -DOCTEST_MSVC_SUPPRESS_WARNING(4127) // conditional expression is constant -DOCTEST_MSVC_SUPPRESS_WARNING(4530) // C++ exception handler used, but unwind semantics not enabled -DOCTEST_MSVC_SUPPRESS_WARNING(4577) // 'noexcept' used with no exception handling mode specified -DOCTEST_MSVC_SUPPRESS_WARNING(4774) // format string expected in argument is not a string literal -DOCTEST_MSVC_SUPPRESS_WARNING(4365) // conversion from 'int' to 'unsigned', signed/unsigned mismatch -DOCTEST_MSVC_SUPPRESS_WARNING(4820) // padding in structs -DOCTEST_MSVC_SUPPRESS_WARNING(4640) // construction of local static object is not thread-safe -DOCTEST_MSVC_SUPPRESS_WARNING(5039) // pointer to potentially throwing function passed to extern C -DOCTEST_MSVC_SUPPRESS_WARNING(5045) // Spectre mitigation stuff -DOCTEST_MSVC_SUPPRESS_WARNING(4626) // assignment operator was implicitly defined as deleted -DOCTEST_MSVC_SUPPRESS_WARNING(5027) // move assignment operator was implicitly defined as deleted -DOCTEST_MSVC_SUPPRESS_WARNING(5026) // move constructor was implicitly defined as deleted -DOCTEST_MSVC_SUPPRESS_WARNING(4625) // copy constructor was implicitly defined as deleted -DOCTEST_MSVC_SUPPRESS_WARNING(4800) // forcing value to bool 'true' or 'false' (performance warning) -// static analysis -DOCTEST_MSVC_SUPPRESS_WARNING(26439) // This kind of function may not throw. Declare it 'noexcept' -DOCTEST_MSVC_SUPPRESS_WARNING(26495) // Always initialize a member variable -DOCTEST_MSVC_SUPPRESS_WARNING(26451) // Arithmetic overflow ... -DOCTEST_MSVC_SUPPRESS_WARNING(26444) // Avoid unnamed objects with custom construction and dtor... -DOCTEST_MSVC_SUPPRESS_WARNING(26812) // Prefer 'enum class' over 'enum' - -DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_BEGIN - -// required includes - will go only in one translation unit! -#include -#include -#include -// borland (Embarcadero) compiler requires math.h and not cmath - https://github.com/onqtam/doctest/pull/37 -#ifdef __BORLANDC__ -#include -#endif // __BORLANDC__ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef DOCTEST_PLATFORM_MAC -#include -#include -#include -#endif // DOCTEST_PLATFORM_MAC - -#ifdef DOCTEST_PLATFORM_WINDOWS - -// defines for a leaner windows.h -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif // WIN32_LEAN_AND_MEAN -#ifndef NOMINMAX -#define NOMINMAX -#endif // NOMINMAX - -// not sure what AfxWin.h is for - here I do what Catch does -#ifdef __AFXDLL -#include -#else -#include -#endif -#include - -#else // DOCTEST_PLATFORM_WINDOWS - -#include -#include - -#endif // DOCTEST_PLATFORM_WINDOWS - -// this is a fix for https://github.com/onqtam/doctest/issues/348 -// https://mail.gnome.org/archives/xml/2012-January/msg00000.html -#if !defined(HAVE_UNISTD_H) && !defined(STDOUT_FILENO) -#define STDOUT_FILENO fileno(stdout) -#endif // HAVE_UNISTD_H - -DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_END - -// counts the number of elements in a C array -#define DOCTEST_COUNTOF(x) (sizeof(x) / sizeof(x[0])) - -#ifdef DOCTEST_CONFIG_DISABLE -#define DOCTEST_BRANCH_ON_DISABLED(if_disabled, if_not_disabled) if_disabled -#else // DOCTEST_CONFIG_DISABLE -#define DOCTEST_BRANCH_ON_DISABLED(if_disabled, if_not_disabled) if_not_disabled -#endif // DOCTEST_CONFIG_DISABLE - -#ifndef DOCTEST_CONFIG_OPTIONS_PREFIX -#define DOCTEST_CONFIG_OPTIONS_PREFIX "dt-" -#endif - -#ifndef DOCTEST_THREAD_LOCAL -#define DOCTEST_THREAD_LOCAL thread_local -#endif - -#ifndef DOCTEST_MULTI_LANE_ATOMICS_THREAD_LANES -#define DOCTEST_MULTI_LANE_ATOMICS_THREAD_LANES 32 -#endif - -#ifndef DOCTEST_MULTI_LANE_ATOMICS_CACHE_LINE_SIZE -#define DOCTEST_MULTI_LANE_ATOMICS_CACHE_LINE_SIZE 64 -#endif - -#ifdef DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS -#define DOCTEST_OPTIONS_PREFIX_DISPLAY DOCTEST_CONFIG_OPTIONS_PREFIX -#else -#define DOCTEST_OPTIONS_PREFIX_DISPLAY "" -#endif - -#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) -#define DOCTEST_CONFIG_NO_MULTI_LANE_ATOMICS -#endif - -namespace doctest { - -bool is_running_in_test = false; - -namespace { - using namespace detail; - // case insensitive strcmp - int stricmp(const char* a, const char* b) { - for(;; a++, b++) { - const int d = tolower(*a) - tolower(*b); - if(d != 0 || !*a) - return d; - } - } - - template - String fpToString(T value, int precision) { - std::ostringstream oss; - oss << std::setprecision(precision) << std::fixed << value; - std::string d = oss.str(); - size_t i = d.find_last_not_of('0'); - if(i != std::string::npos && i != d.size() - 1) { - if(d[i] == '.') - i++; - d = d.substr(0, i + 1); - } - return d.c_str(); - } - - struct Endianness - { - enum Arch - { - Big, - Little - }; - - static Arch which() { - int x = 1; - // casting any data pointer to char* is allowed - auto ptr = reinterpret_cast(&x); - if(*ptr) - return Little; - return Big; - } - }; -} // namespace - -namespace detail { - void my_memcpy(void* dest, const void* src, unsigned num) { memcpy(dest, src, num); } - - String rawMemoryToString(const void* object, unsigned size) { - // Reverse order for little endian architectures - int i = 0, end = static_cast(size), inc = 1; - if(Endianness::which() == Endianness::Little) { - i = end - 1; - end = inc = -1; - } - - unsigned const char* bytes = static_cast(object); - std::ostringstream oss; - oss << "0x" << std::setfill('0') << std::hex; - for(; i != end; i += inc) - oss << std::setw(2) << static_cast(bytes[i]); - return oss.str().c_str(); - } - - DOCTEST_THREAD_LOCAL std::ostringstream g_oss; // NOLINT(cert-err58-cpp) - - std::ostream* getTlsOss() { - g_oss.clear(); // there shouldn't be anything worth clearing in the flags - g_oss.str(""); // the slow way of resetting a string stream - //g_oss.seekp(0); // optimal reset - as seen here: https://stackoverflow.com/a/624291/3162383 - return &g_oss; - } - - String getTlsOssResult() { - //g_oss << std::ends; // needed - as shown here: https://stackoverflow.com/a/624291/3162383 - return g_oss.str().c_str(); - } - -#ifndef DOCTEST_CONFIG_DISABLE - -namespace timer_large_integer -{ - -#if defined(DOCTEST_PLATFORM_WINDOWS) - typedef ULONGLONG type; -#else // DOCTEST_PLATFORM_WINDOWS - using namespace std; - typedef uint64_t type; -#endif // DOCTEST_PLATFORM_WINDOWS -} - -typedef timer_large_integer::type ticks_t; - -#ifdef DOCTEST_CONFIG_GETCURRENTTICKS - ticks_t getCurrentTicks() { return DOCTEST_CONFIG_GETCURRENTTICKS(); } -#elif defined(DOCTEST_PLATFORM_WINDOWS) - ticks_t getCurrentTicks() { - static LARGE_INTEGER hz = {0}, hzo = {0}; - if(!hz.QuadPart) { - QueryPerformanceFrequency(&hz); - QueryPerformanceCounter(&hzo); - } - LARGE_INTEGER t; - QueryPerformanceCounter(&t); - return ((t.QuadPart - hzo.QuadPart) * LONGLONG(1000000)) / hz.QuadPart; - } -#else // DOCTEST_PLATFORM_WINDOWS - ticks_t getCurrentTicks() { - timeval t; - gettimeofday(&t, nullptr); - return static_cast(t.tv_sec) * 1000000 + static_cast(t.tv_usec); - } -#endif // DOCTEST_PLATFORM_WINDOWS - - struct Timer - { - void start() { m_ticks = getCurrentTicks(); } - unsigned int getElapsedMicroseconds() const { - return static_cast(getCurrentTicks() - m_ticks); - } - //unsigned int getElapsedMilliseconds() const { - // return static_cast(getElapsedMicroseconds() / 1000); - //} - double getElapsedSeconds() const { return static_cast(getCurrentTicks() - m_ticks) / 1000000.0; } - - private: - ticks_t m_ticks = 0; - }; - -#ifdef DOCTEST_CONFIG_NO_MULTI_LANE_ATOMICS - template - using AtomicOrMultiLaneAtomic = std::atomic; -#else // DOCTEST_CONFIG_NO_MULTI_LANE_ATOMICS - // Provides a multilane implementation of an atomic variable that supports add, sub, load, - // store. Instead of using a single atomic variable, this splits up into multiple ones, - // each sitting on a separate cache line. The goal is to provide a speedup when most - // operations are modifying. It achieves this with two properties: - // - // * Multiple atomics are used, so chance of congestion from the same atomic is reduced. - // * Each atomic sits on a separate cache line, so false sharing is reduced. - // - // The disadvantage is that there is a small overhead due to the use of TLS, and load/store - // is slower because all atomics have to be accessed. - template - class MultiLaneAtomic - { - struct CacheLineAlignedAtomic - { - std::atomic atomic{}; - char padding[DOCTEST_MULTI_LANE_ATOMICS_CACHE_LINE_SIZE - sizeof(std::atomic)]; - }; - CacheLineAlignedAtomic m_atomics[DOCTEST_MULTI_LANE_ATOMICS_THREAD_LANES]; - - static_assert(sizeof(CacheLineAlignedAtomic) == DOCTEST_MULTI_LANE_ATOMICS_CACHE_LINE_SIZE, - "guarantee one atomic takes exactly one cache line"); - - public: - T operator++() DOCTEST_NOEXCEPT { return fetch_add(1) + 1; } - - T operator++(int) DOCTEST_NOEXCEPT { return fetch_add(1); } - - T fetch_add(T arg, std::memory_order order = std::memory_order_seq_cst) DOCTEST_NOEXCEPT { - return myAtomic().fetch_add(arg, order); - } - - T fetch_sub(T arg, std::memory_order order = std::memory_order_seq_cst) DOCTEST_NOEXCEPT { - return myAtomic().fetch_sub(arg, order); - } - - operator T() const DOCTEST_NOEXCEPT { return load(); } - - T load(std::memory_order order = std::memory_order_seq_cst) const DOCTEST_NOEXCEPT { - auto result = T(); - for(auto const& c : m_atomics) { - result += c.atomic.load(order); - } - return result; - } - - T operator=(T desired) DOCTEST_NOEXCEPT { - store(desired); - return desired; - } - - void store(T desired, std::memory_order order = std::memory_order_seq_cst) DOCTEST_NOEXCEPT { - // first value becomes desired", all others become 0. - for(auto& c : m_atomics) { - c.atomic.store(desired, order); - desired = {}; - } - } - - private: - // Each thread has a different atomic that it operates on. If more than NumLanes threads - // use this, some will use the same atomic. So performance will degrate a bit, but still - // everything will work. - // - // The logic here is a bit tricky. The call should be as fast as possible, so that there - // is minimal to no overhead in determining the correct atomic for the current thread. - // - // 1. A global static counter laneCounter counts continuously up. - // 2. Each successive thread will use modulo operation of that counter so it gets an atomic - // assigned in a round-robin fashion. - // 3. This tlsLaneIdx is stored in the thread local data, so it is directly available with - // little overhead. - std::atomic& myAtomic() DOCTEST_NOEXCEPT { - static std::atomic laneCounter; - DOCTEST_THREAD_LOCAL size_t tlsLaneIdx = - laneCounter++ % DOCTEST_MULTI_LANE_ATOMICS_THREAD_LANES; - - return m_atomics[tlsLaneIdx].atomic; - } - }; - - template - using AtomicOrMultiLaneAtomic = MultiLaneAtomic; -#endif // DOCTEST_CONFIG_NO_MULTI_LANE_ATOMICS - - // this holds both parameters from the command line and runtime data for tests - struct ContextState : ContextOptions, TestRunStats, CurrentTestCaseStats - { - AtomicOrMultiLaneAtomic numAssertsCurrentTest_atomic; - AtomicOrMultiLaneAtomic numAssertsFailedCurrentTest_atomic; - - std::vector> filters = decltype(filters)(9); // 9 different filters - - std::vector reporters_currently_used; - - assert_handler ah = nullptr; - - Timer timer; - - std::vector stringifiedContexts; // logging from INFO() due to an exception - - // stuff for subcases - std::vector subcasesStack; - std::set subcasesPassed; - int subcasesCurrentMaxLevel; - bool should_reenter; - std::atomic shouldLogCurrentException; - - void resetRunData() { - numTestCases = 0; - numTestCasesPassingFilters = 0; - numTestSuitesPassingFilters = 0; - numTestCasesFailed = 0; - numAsserts = 0; - numAssertsFailed = 0; - numAssertsCurrentTest = 0; - numAssertsFailedCurrentTest = 0; - } - - void finalizeTestCaseData() { - seconds = timer.getElapsedSeconds(); - - // update the non-atomic counters - numAsserts += numAssertsCurrentTest_atomic; - numAssertsFailed += numAssertsFailedCurrentTest_atomic; - numAssertsCurrentTest = numAssertsCurrentTest_atomic; - numAssertsFailedCurrentTest = numAssertsFailedCurrentTest_atomic; - - if(numAssertsFailedCurrentTest) - failure_flags |= TestCaseFailureReason::AssertFailure; - - if(Approx(currentTest->m_timeout).epsilon(DBL_EPSILON) != 0 && - Approx(seconds).epsilon(DBL_EPSILON) > currentTest->m_timeout) - failure_flags |= TestCaseFailureReason::Timeout; - - if(currentTest->m_should_fail) { - if(failure_flags) { - failure_flags |= TestCaseFailureReason::ShouldHaveFailedAndDid; - } else { - failure_flags |= TestCaseFailureReason::ShouldHaveFailedButDidnt; - } - } else if(failure_flags && currentTest->m_may_fail) { - failure_flags |= TestCaseFailureReason::CouldHaveFailedAndDid; - } else if(currentTest->m_expected_failures > 0) { - if(numAssertsFailedCurrentTest == currentTest->m_expected_failures) { - failure_flags |= TestCaseFailureReason::FailedExactlyNumTimes; - } else { - failure_flags |= TestCaseFailureReason::DidntFailExactlyNumTimes; - } - } - - bool ok_to_fail = (TestCaseFailureReason::ShouldHaveFailedAndDid & failure_flags) || - (TestCaseFailureReason::CouldHaveFailedAndDid & failure_flags) || - (TestCaseFailureReason::FailedExactlyNumTimes & failure_flags); - - // if any subcase has failed - the whole test case has failed - if(failure_flags && !ok_to_fail) - numTestCasesFailed++; - } - }; - - ContextState* g_cs = nullptr; - - // used to avoid locks for the debug output - // TODO: figure out if this is indeed necessary/correct - seems like either there still - // could be a race or that there wouldn't be a race even if using the context directly - DOCTEST_THREAD_LOCAL bool g_no_colors; - -#endif // DOCTEST_CONFIG_DISABLE -} // namespace detail - -void String::setOnHeap() { *reinterpret_cast(&buf[last]) = 128; } -void String::setLast(unsigned in) { buf[last] = char(in); } - -void String::copy(const String& other) { - using namespace std; - if(other.isOnStack()) { - memcpy(buf, other.buf, len); - } else { - setOnHeap(); - data.size = other.data.size; - data.capacity = data.size + 1; - data.ptr = new char[data.capacity]; - memcpy(data.ptr, other.data.ptr, data.size + 1); - } -} - -String::String() { - buf[0] = '\0'; - setLast(); -} - -String::~String() { - if(!isOnStack()) - delete[] data.ptr; - // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) -} - -String::String(const char* in) - : String(in, strlen(in)) {} - -String::String(const char* in, unsigned in_size) { - using namespace std; - if(in_size <= last) { - memcpy(buf, in, in_size); - buf[in_size] = '\0'; - setLast(last - in_size); - } else { - setOnHeap(); - data.size = in_size; - data.capacity = data.size + 1; - data.ptr = new char[data.capacity]; - memcpy(data.ptr, in, in_size); - data.ptr[in_size] = '\0'; - } -} - -String::String(const String& other) { copy(other); } - -String& String::operator=(const String& other) { - if(this != &other) { - if(!isOnStack()) - delete[] data.ptr; - - copy(other); - } - - return *this; -} - -String& String::operator+=(const String& other) { - const unsigned my_old_size = size(); - const unsigned other_size = other.size(); - const unsigned total_size = my_old_size + other_size; - using namespace std; - if(isOnStack()) { - if(total_size < len) { - // append to the current stack space - memcpy(buf + my_old_size, other.c_str(), other_size + 1); - // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) - setLast(last - total_size); - } else { - // alloc new chunk - char* temp = new char[total_size + 1]; - // copy current data to new location before writing in the union - memcpy(temp, buf, my_old_size); // skip the +1 ('\0') for speed - // update data in union - setOnHeap(); - data.size = total_size; - data.capacity = data.size + 1; - data.ptr = temp; - // transfer the rest of the data - memcpy(data.ptr + my_old_size, other.c_str(), other_size + 1); - } - } else { - if(data.capacity > total_size) { - // append to the current heap block - data.size = total_size; - memcpy(data.ptr + my_old_size, other.c_str(), other_size + 1); - } else { - // resize - data.capacity *= 2; - if(data.capacity <= total_size) - data.capacity = total_size + 1; - // alloc new chunk - char* temp = new char[data.capacity]; - // copy current data to new location before releasing it - memcpy(temp, data.ptr, my_old_size); // skip the +1 ('\0') for speed - // release old chunk - delete[] data.ptr; - // update the rest of the union members - data.size = total_size; - data.ptr = temp; - // transfer the rest of the data - memcpy(data.ptr + my_old_size, other.c_str(), other_size + 1); - } - } - - return *this; -} - -// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) -String String::operator+(const String& other) const { return String(*this) += other; } - -String::String(String&& other) { - using namespace std; - memcpy(buf, other.buf, len); - other.buf[0] = '\0'; - other.setLast(); -} - -String& String::operator=(String&& other) { - using namespace std; - if(this != &other) { - if(!isOnStack()) - delete[] data.ptr; - memcpy(buf, other.buf, len); - other.buf[0] = '\0'; - other.setLast(); - } - return *this; -} - -char String::operator[](unsigned i) const { - return const_cast(this)->operator[](i); // NOLINT -} - -char& String::operator[](unsigned i) { - if(isOnStack()) - return reinterpret_cast(buf)[i]; - return data.ptr[i]; -} - -DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wmaybe-uninitialized") -unsigned String::size() const { - if(isOnStack()) - return last - (unsigned(buf[last]) & 31); // using "last" would work only if "len" is 32 - return data.size; -} -DOCTEST_GCC_SUPPRESS_WARNING_POP - -unsigned String::capacity() const { - if(isOnStack()) - return len; - return data.capacity; -} - -int String::compare(const char* other, bool no_case) const { - if(no_case) - return doctest::stricmp(c_str(), other); - return std::strcmp(c_str(), other); -} - -int String::compare(const String& other, bool no_case) const { - return compare(other.c_str(), no_case); -} - -// clang-format off -bool operator==(const String& lhs, const String& rhs) { return lhs.compare(rhs) == 0; } -bool operator!=(const String& lhs, const String& rhs) { return lhs.compare(rhs) != 0; } -bool operator< (const String& lhs, const String& rhs) { return lhs.compare(rhs) < 0; } -bool operator> (const String& lhs, const String& rhs) { return lhs.compare(rhs) > 0; } -bool operator<=(const String& lhs, const String& rhs) { return (lhs != rhs) ? lhs.compare(rhs) < 0 : true; } -bool operator>=(const String& lhs, const String& rhs) { return (lhs != rhs) ? lhs.compare(rhs) > 0 : true; } -// clang-format on - -std::ostream& operator<<(std::ostream& s, const String& in) { return s << in.c_str(); } - -namespace { - void color_to_stream(std::ostream&, Color::Enum) DOCTEST_BRANCH_ON_DISABLED({}, ;) -} // namespace - -namespace Color { - std::ostream& operator<<(std::ostream& s, Color::Enum code) { - color_to_stream(s, code); - return s; - } -} // namespace Color - -// clang-format off -const char* assertString(assertType::Enum at) { - DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4062) // enum 'x' in switch of enum 'y' is not handled - switch(at) { //!OCLINT missing default in switch statements - case assertType::DT_WARN : return "WARN"; - case assertType::DT_CHECK : return "CHECK"; - case assertType::DT_REQUIRE : return "REQUIRE"; - - case assertType::DT_WARN_FALSE : return "WARN_FALSE"; - case assertType::DT_CHECK_FALSE : return "CHECK_FALSE"; - case assertType::DT_REQUIRE_FALSE : return "REQUIRE_FALSE"; - - case assertType::DT_WARN_THROWS : return "WARN_THROWS"; - case assertType::DT_CHECK_THROWS : return "CHECK_THROWS"; - case assertType::DT_REQUIRE_THROWS : return "REQUIRE_THROWS"; - - case assertType::DT_WARN_THROWS_AS : return "WARN_THROWS_AS"; - case assertType::DT_CHECK_THROWS_AS : return "CHECK_THROWS_AS"; - case assertType::DT_REQUIRE_THROWS_AS : return "REQUIRE_THROWS_AS"; - - case assertType::DT_WARN_THROWS_WITH : return "WARN_THROWS_WITH"; - case assertType::DT_CHECK_THROWS_WITH : return "CHECK_THROWS_WITH"; - case assertType::DT_REQUIRE_THROWS_WITH : return "REQUIRE_THROWS_WITH"; - - case assertType::DT_WARN_THROWS_WITH_AS : return "WARN_THROWS_WITH_AS"; - case assertType::DT_CHECK_THROWS_WITH_AS : return "CHECK_THROWS_WITH_AS"; - case assertType::DT_REQUIRE_THROWS_WITH_AS : return "REQUIRE_THROWS_WITH_AS"; - - case assertType::DT_WARN_NOTHROW : return "WARN_NOTHROW"; - case assertType::DT_CHECK_NOTHROW : return "CHECK_NOTHROW"; - case assertType::DT_REQUIRE_NOTHROW : return "REQUIRE_NOTHROW"; - - case assertType::DT_WARN_EQ : return "WARN_EQ"; - case assertType::DT_CHECK_EQ : return "CHECK_EQ"; - case assertType::DT_REQUIRE_EQ : return "REQUIRE_EQ"; - case assertType::DT_WARN_NE : return "WARN_NE"; - case assertType::DT_CHECK_NE : return "CHECK_NE"; - case assertType::DT_REQUIRE_NE : return "REQUIRE_NE"; - case assertType::DT_WARN_GT : return "WARN_GT"; - case assertType::DT_CHECK_GT : return "CHECK_GT"; - case assertType::DT_REQUIRE_GT : return "REQUIRE_GT"; - case assertType::DT_WARN_LT : return "WARN_LT"; - case assertType::DT_CHECK_LT : return "CHECK_LT"; - case assertType::DT_REQUIRE_LT : return "REQUIRE_LT"; - case assertType::DT_WARN_GE : return "WARN_GE"; - case assertType::DT_CHECK_GE : return "CHECK_GE"; - case assertType::DT_REQUIRE_GE : return "REQUIRE_GE"; - case assertType::DT_WARN_LE : return "WARN_LE"; - case assertType::DT_CHECK_LE : return "CHECK_LE"; - case assertType::DT_REQUIRE_LE : return "REQUIRE_LE"; - - case assertType::DT_WARN_UNARY : return "WARN_UNARY"; - case assertType::DT_CHECK_UNARY : return "CHECK_UNARY"; - case assertType::DT_REQUIRE_UNARY : return "REQUIRE_UNARY"; - case assertType::DT_WARN_UNARY_FALSE : return "WARN_UNARY_FALSE"; - case assertType::DT_CHECK_UNARY_FALSE : return "CHECK_UNARY_FALSE"; - case assertType::DT_REQUIRE_UNARY_FALSE : return "REQUIRE_UNARY_FALSE"; - } - DOCTEST_MSVC_SUPPRESS_WARNING_POP - return ""; -} -// clang-format on - -const char* failureString(assertType::Enum at) { - if(at & assertType::is_warn) //!OCLINT bitwise operator in conditional - return "WARNING"; - if(at & assertType::is_check) //!OCLINT bitwise operator in conditional - return "ERROR"; - if(at & assertType::is_require) //!OCLINT bitwise operator in conditional - return "FATAL ERROR"; - return ""; -} - -DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wnull-dereference") -DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wnull-dereference") -// depending on the current options this will remove the path of filenames -const char* skipPathFromFilename(const char* file) { -#ifndef DOCTEST_CONFIG_DISABLE - if(getContextOptions()->no_path_in_filenames) { - auto back = std::strrchr(file, '\\'); - auto forward = std::strrchr(file, '/'); - if(back || forward) { - if(back > forward) - forward = back; - return forward + 1; - } - } -#endif // DOCTEST_CONFIG_DISABLE - return file; -} -DOCTEST_CLANG_SUPPRESS_WARNING_POP -DOCTEST_GCC_SUPPRESS_WARNING_POP - -bool SubcaseSignature::operator<(const SubcaseSignature& other) const { - if(m_line != other.m_line) - return m_line < other.m_line; - if(std::strcmp(m_file, other.m_file) != 0) - return std::strcmp(m_file, other.m_file) < 0; - return m_name.compare(other.m_name) < 0; -} - -IContextScope::IContextScope() = default; -IContextScope::~IContextScope() = default; - -#ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING -String toString(char* in) { return toString(static_cast(in)); } -// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) -String toString(const char* in) { return String("\"") + (in ? in : "{null string}") + "\""; } -#endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING -String toString(bool in) { return in ? "true" : "false"; } -String toString(float in) { return fpToString(in, 5) + "f"; } -String toString(double in) { return fpToString(in, 10); } -String toString(double long in) { return fpToString(in, 15); } - -#define DOCTEST_TO_STRING_OVERLOAD(type, fmt) \ - String toString(type in) { \ - char buf[64]; \ - std::sprintf(buf, fmt, in); \ - return buf; \ - } - -DOCTEST_TO_STRING_OVERLOAD(char, "%d") -DOCTEST_TO_STRING_OVERLOAD(char signed, "%d") -DOCTEST_TO_STRING_OVERLOAD(char unsigned, "%u") -DOCTEST_TO_STRING_OVERLOAD(int short, "%d") -DOCTEST_TO_STRING_OVERLOAD(int short unsigned, "%u") -DOCTEST_TO_STRING_OVERLOAD(int, "%d") -DOCTEST_TO_STRING_OVERLOAD(unsigned, "%u") -DOCTEST_TO_STRING_OVERLOAD(int long, "%ld") -DOCTEST_TO_STRING_OVERLOAD(int long unsigned, "%lu") -DOCTEST_TO_STRING_OVERLOAD(int long long, "%lld") -DOCTEST_TO_STRING_OVERLOAD(int long long unsigned, "%llu") - -String toString(std::nullptr_t) { return "NULL"; } - -#if DOCTEST_MSVC >= DOCTEST_COMPILER(19, 20, 0) -// see this issue on why this is needed: https://github.com/onqtam/doctest/issues/183 -String toString(const std::string& in) { return in.c_str(); } -#endif // VS 2019 - -Approx::Approx(double value) - : m_epsilon(static_cast(std::numeric_limits::epsilon()) * 100) - , m_scale(1.0) - , m_value(value) {} - -Approx Approx::operator()(double value) const { - Approx approx(value); - approx.epsilon(m_epsilon); - approx.scale(m_scale); - return approx; -} - -Approx& Approx::epsilon(double newEpsilon) { - m_epsilon = newEpsilon; - return *this; -} -Approx& Approx::scale(double newScale) { - m_scale = newScale; - return *this; -} - -bool operator==(double lhs, const Approx& rhs) { - // Thanks to Richard Harris for his help refining this formula - return std::fabs(lhs - rhs.m_value) < - rhs.m_epsilon * (rhs.m_scale + std::max(std::fabs(lhs), std::fabs(rhs.m_value))); -} -bool operator==(const Approx& lhs, double rhs) { return operator==(rhs, lhs); } -bool operator!=(double lhs, const Approx& rhs) { return !operator==(lhs, rhs); } -bool operator!=(const Approx& lhs, double rhs) { return !operator==(rhs, lhs); } -bool operator<=(double lhs, const Approx& rhs) { return lhs < rhs.m_value || lhs == rhs; } -bool operator<=(const Approx& lhs, double rhs) { return lhs.m_value < rhs || lhs == rhs; } -bool operator>=(double lhs, const Approx& rhs) { return lhs > rhs.m_value || lhs == rhs; } -bool operator>=(const Approx& lhs, double rhs) { return lhs.m_value > rhs || lhs == rhs; } -bool operator<(double lhs, const Approx& rhs) { return lhs < rhs.m_value && lhs != rhs; } -bool operator<(const Approx& lhs, double rhs) { return lhs.m_value < rhs && lhs != rhs; } -bool operator>(double lhs, const Approx& rhs) { return lhs > rhs.m_value && lhs != rhs; } -bool operator>(const Approx& lhs, double rhs) { return lhs.m_value > rhs && lhs != rhs; } - -String toString(const Approx& in) { - // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) - return String("Approx( ") + doctest::toString(in.m_value) + " )"; -} -const ContextOptions* getContextOptions() { return DOCTEST_BRANCH_ON_DISABLED(nullptr, g_cs); } - -} // namespace doctest - -#ifdef DOCTEST_CONFIG_DISABLE -namespace doctest { -Context::Context(int, const char* const*) {} -Context::~Context() = default; -void Context::applyCommandLine(int, const char* const*) {} -void Context::addFilter(const char*, const char*) {} -void Context::clearFilters() {} -void Context::setOption(const char*, int) {} -void Context::setOption(const char*, const char*) {} -bool Context::shouldExit() { return false; } -void Context::setAsDefaultForAssertsOutOfTestCases() {} -void Context::setAssertHandler(detail::assert_handler) {} -int Context::run() { return 0; } - -IReporter::~IReporter() = default; - -int IReporter::get_num_active_contexts() { return 0; } -const IContextScope* const* IReporter::get_active_contexts() { return nullptr; } -int IReporter::get_num_stringified_contexts() { return 0; } -const String* IReporter::get_stringified_contexts() { return nullptr; } - -int registerReporter(const char*, int, IReporter*) { return 0; } - -} // namespace doctest -#else // DOCTEST_CONFIG_DISABLE - -#if !defined(DOCTEST_CONFIG_COLORS_NONE) -#if !defined(DOCTEST_CONFIG_COLORS_WINDOWS) && !defined(DOCTEST_CONFIG_COLORS_ANSI) -#ifdef DOCTEST_PLATFORM_WINDOWS -#define DOCTEST_CONFIG_COLORS_WINDOWS -#else // linux -#define DOCTEST_CONFIG_COLORS_ANSI -#endif // platform -#endif // DOCTEST_CONFIG_COLORS_WINDOWS && DOCTEST_CONFIG_COLORS_ANSI -#endif // DOCTEST_CONFIG_COLORS_NONE - -namespace doctest_detail_test_suite_ns { -// holds the current test suite -doctest::detail::TestSuite& getCurrentTestSuite() { - static doctest::detail::TestSuite data{}; - return data; -} -} // namespace doctest_detail_test_suite_ns - -namespace doctest { -namespace { - // the int (priority) is part of the key for automatic sorting - sadly one can register a - // reporter with a duplicate name and a different priority but hopefully that won't happen often :| - typedef std::map, reporterCreatorFunc> reporterMap; - - reporterMap& getReporters() { - static reporterMap data; - return data; - } - reporterMap& getListeners() { - static reporterMap data; - return data; - } -} // namespace -namespace detail { -#define DOCTEST_ITERATE_THROUGH_REPORTERS(function, ...) \ - for(auto& curr_rep : g_cs->reporters_currently_used) \ - curr_rep->function(__VA_ARGS__) - - bool checkIfShouldThrow(assertType::Enum at) { - if(at & assertType::is_require) //!OCLINT bitwise operator in conditional - return true; - - if((at & assertType::is_check) //!OCLINT bitwise operator in conditional - && getContextOptions()->abort_after > 0 && - (g_cs->numAssertsFailed + g_cs->numAssertsFailedCurrentTest_atomic) >= - getContextOptions()->abort_after) - return true; - - return false; - } - -#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS - DOCTEST_NORETURN void throwException() { - g_cs->shouldLogCurrentException = false; - throw TestFailureException(); - } // NOLINT(cert-err60-cpp) -#else // DOCTEST_CONFIG_NO_EXCEPTIONS - void throwException() {} -#endif // DOCTEST_CONFIG_NO_EXCEPTIONS -} // namespace detail - -namespace { - using namespace detail; - // matching of a string against a wildcard mask (case sensitivity configurable) taken from - // https://www.codeproject.com/Articles/1088/Wildcard-string-compare-globbing - int wildcmp(const char* str, const char* wild, bool caseSensitive) { - const char* cp = str; - const char* mp = wild; - - while((*str) && (*wild != '*')) { - if((caseSensitive ? (*wild != *str) : (tolower(*wild) != tolower(*str))) && - (*wild != '?')) { - return 0; - } - wild++; - str++; - } - - while(*str) { - if(*wild == '*') { - if(!*++wild) { - return 1; - } - mp = wild; - cp = str + 1; - } else if((caseSensitive ? (*wild == *str) : (tolower(*wild) == tolower(*str))) || - (*wild == '?')) { - wild++; - str++; - } else { - wild = mp; //!OCLINT parameter reassignment - str = cp++; //!OCLINT parameter reassignment - } - } - - while(*wild == '*') { - wild++; - } - return !*wild; - } - - //// C string hash function (djb2) - taken from http://www.cse.yorku.ca/~oz/hash.html - //unsigned hashStr(unsigned const char* str) { - // unsigned long hash = 5381; - // char c; - // while((c = *str++)) - // hash = ((hash << 5) + hash) + c; // hash * 33 + c - // return hash; - //} - - // checks if the name matches any of the filters (and can be configured what to do when empty) - bool matchesAny(const char* name, const std::vector& filters, bool matchEmpty, - bool caseSensitive) { - if(filters.empty() && matchEmpty) - return true; - for(auto& curr : filters) - if(wildcmp(name, curr.c_str(), caseSensitive)) - return true; - return false; - } -} // namespace -namespace detail { - - Subcase::Subcase(const String& name, const char* file, int line) - : m_signature({name, file, line}) { - auto* s = g_cs; - - // check subcase filters - if(s->subcasesStack.size() < size_t(s->subcase_filter_levels)) { - if(!matchesAny(m_signature.m_name.c_str(), s->filters[6], true, s->case_sensitive)) - return; - if(matchesAny(m_signature.m_name.c_str(), s->filters[7], false, s->case_sensitive)) - return; - } - - // if a Subcase on the same level has already been entered - if(s->subcasesStack.size() < size_t(s->subcasesCurrentMaxLevel)) { - s->should_reenter = true; - return; - } - - // push the current signature to the stack so we can check if the - // current stack + the current new subcase have been traversed - s->subcasesStack.push_back(m_signature); - if(s->subcasesPassed.count(s->subcasesStack) != 0) { - // pop - revert to previous stack since we've already passed this - s->subcasesStack.pop_back(); - return; - } - - s->subcasesCurrentMaxLevel = s->subcasesStack.size(); - m_entered = true; - - DOCTEST_ITERATE_THROUGH_REPORTERS(subcase_start, m_signature); - } - - DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4996) // std::uncaught_exception is deprecated in C++17 - DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations") - DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations") - - Subcase::~Subcase() { - if(m_entered) { - // only mark the subcase stack as passed if no subcases have been skipped - if(g_cs->should_reenter == false) - g_cs->subcasesPassed.insert(g_cs->subcasesStack); - g_cs->subcasesStack.pop_back(); - -#if defined(__cpp_lib_uncaught_exceptions) && __cpp_lib_uncaught_exceptions >= 201411L && (!defined(__MAC_OS_X_VERSION_MIN_REQUIRED) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200) - if(std::uncaught_exceptions() > 0 -#else - if(std::uncaught_exception() -#endif - && g_cs->shouldLogCurrentException) { - DOCTEST_ITERATE_THROUGH_REPORTERS( - test_case_exception, {"exception thrown in subcase - will translate later " - "when the whole test case has been exited (cannot " - "translate while there is an active exception)", - false}); - g_cs->shouldLogCurrentException = false; - } - DOCTEST_ITERATE_THROUGH_REPORTERS(subcase_end, DOCTEST_EMPTY); - } - } - - DOCTEST_CLANG_SUPPRESS_WARNING_POP - DOCTEST_GCC_SUPPRESS_WARNING_POP - DOCTEST_MSVC_SUPPRESS_WARNING_POP - - Subcase::operator bool() const { return m_entered; } - - Result::Result(bool passed, const String& decomposition) - : m_passed(passed) - , m_decomp(decomposition) {} - - ExpressionDecomposer::ExpressionDecomposer(assertType::Enum at) - : m_at(at) {} - - TestSuite& TestSuite::operator*(const char* in) { - m_test_suite = in; - // clear state - m_description = nullptr; - m_skip = false; - m_no_breaks = false; - m_no_output = false; - m_may_fail = false; - m_should_fail = false; - m_expected_failures = 0; - m_timeout = 0; - return *this; - } - - TestCase::TestCase(funcType test, const char* file, unsigned line, const TestSuite& test_suite, - const char* type, int template_id) { - m_file = file; - m_line = line; - m_name = nullptr; // will be later overridden in operator* - m_test_suite = test_suite.m_test_suite; - m_description = test_suite.m_description; - m_skip = test_suite.m_skip; - m_no_breaks = test_suite.m_no_breaks; - m_no_output = test_suite.m_no_output; - m_may_fail = test_suite.m_may_fail; - m_should_fail = test_suite.m_should_fail; - m_expected_failures = test_suite.m_expected_failures; - m_timeout = test_suite.m_timeout; - - m_test = test; - m_type = type; - m_template_id = template_id; - } - - TestCase::TestCase(const TestCase& other) - : TestCaseData() { - *this = other; - } - - DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(26434) // hides a non-virtual function - DOCTEST_MSVC_SUPPRESS_WARNING(26437) // Do not slice - TestCase& TestCase::operator=(const TestCase& other) { - static_cast(*this) = static_cast(other); - - m_test = other.m_test; - m_type = other.m_type; - m_template_id = other.m_template_id; - m_full_name = other.m_full_name; - - if(m_template_id != -1) - m_name = m_full_name.c_str(); - return *this; - } - DOCTEST_MSVC_SUPPRESS_WARNING_POP - - TestCase& TestCase::operator*(const char* in) { - m_name = in; - // make a new name with an appended type for templated test case - if(m_template_id != -1) { - m_full_name = String(m_name) + m_type; - // redirect the name to point to the newly constructed full name - m_name = m_full_name.c_str(); - } - return *this; - } - - bool TestCase::operator<(const TestCase& other) const { - // this will be used only to differentiate between test cases - not relevant for sorting - if(m_line != other.m_line) - return m_line < other.m_line; - const int name_cmp = strcmp(m_name, other.m_name); - if(name_cmp != 0) - return name_cmp < 0; - const int file_cmp = m_file.compare(other.m_file); - if(file_cmp != 0) - return file_cmp < 0; - return m_template_id < other.m_template_id; - } - - // all the registered tests - std::set& getRegisteredTests() { - static std::set data; - return data; - } -} // namespace detail -namespace { - using namespace detail; - // for sorting tests by file/line - bool fileOrderComparator(const TestCase* lhs, const TestCase* rhs) { - // this is needed because MSVC gives different case for drive letters - // for __FILE__ when evaluated in a header and a source file - const int res = lhs->m_file.compare(rhs->m_file, bool(DOCTEST_MSVC)); - if(res != 0) - return res < 0; - if(lhs->m_line != rhs->m_line) - return lhs->m_line < rhs->m_line; - return lhs->m_template_id < rhs->m_template_id; - } - - // for sorting tests by suite/file/line - bool suiteOrderComparator(const TestCase* lhs, const TestCase* rhs) { - const int res = std::strcmp(lhs->m_test_suite, rhs->m_test_suite); - if(res != 0) - return res < 0; - return fileOrderComparator(lhs, rhs); - } - - // for sorting tests by name/suite/file/line - bool nameOrderComparator(const TestCase* lhs, const TestCase* rhs) { - const int res = std::strcmp(lhs->m_name, rhs->m_name); - if(res != 0) - return res < 0; - return suiteOrderComparator(lhs, rhs); - } - -#ifdef DOCTEST_CONFIG_COLORS_WINDOWS - HANDLE g_stdoutHandle; - WORD g_origFgAttrs; - WORD g_origBgAttrs; - bool g_attrsInitted = false; - - int colors_init() { - if(!g_attrsInitted) { - g_stdoutHandle = GetStdHandle(STD_OUTPUT_HANDLE); - g_attrsInitted = true; - CONSOLE_SCREEN_BUFFER_INFO csbiInfo; - GetConsoleScreenBufferInfo(g_stdoutHandle, &csbiInfo); - g_origFgAttrs = csbiInfo.wAttributes & ~(BACKGROUND_GREEN | BACKGROUND_RED | - BACKGROUND_BLUE | BACKGROUND_INTENSITY); - g_origBgAttrs = csbiInfo.wAttributes & ~(FOREGROUND_GREEN | FOREGROUND_RED | - FOREGROUND_BLUE | FOREGROUND_INTENSITY); - } - return 0; - } - - int dumy_init_console_colors = colors_init(); -#endif // DOCTEST_CONFIG_COLORS_WINDOWS - - DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations") - void color_to_stream(std::ostream& s, Color::Enum code) { - static_cast(s); // for DOCTEST_CONFIG_COLORS_NONE or DOCTEST_CONFIG_COLORS_WINDOWS - static_cast(code); // for DOCTEST_CONFIG_COLORS_NONE -#ifdef DOCTEST_CONFIG_COLORS_ANSI - if(g_no_colors || - (isatty(STDOUT_FILENO) == false && getContextOptions()->force_colors == false)) - return; - - auto col = ""; - // clang-format off - switch(code) { //!OCLINT missing break in switch statement / unnecessary default statement in covered switch statement - case Color::Red: col = "[0;31m"; break; - case Color::Green: col = "[0;32m"; break; - case Color::Blue: col = "[0;34m"; break; - case Color::Cyan: col = "[0;36m"; break; - case Color::Yellow: col = "[0;33m"; break; - case Color::Grey: col = "[1;30m"; break; - case Color::LightGrey: col = "[0;37m"; break; - case Color::BrightRed: col = "[1;31m"; break; - case Color::BrightGreen: col = "[1;32m"; break; - case Color::BrightWhite: col = "[1;37m"; break; - case Color::Bright: // invalid - case Color::None: - case Color::White: - default: col = "[0m"; - } - // clang-format on - s << "\033" << col; -#endif // DOCTEST_CONFIG_COLORS_ANSI - -#ifdef DOCTEST_CONFIG_COLORS_WINDOWS - if(g_no_colors || - (isatty(fileno(stdout)) == false && getContextOptions()->force_colors == false)) - return; - -#define DOCTEST_SET_ATTR(x) SetConsoleTextAttribute(g_stdoutHandle, x | g_origBgAttrs) - - // clang-format off - switch (code) { - case Color::White: DOCTEST_SET_ATTR(FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE); break; - case Color::Red: DOCTEST_SET_ATTR(FOREGROUND_RED); break; - case Color::Green: DOCTEST_SET_ATTR(FOREGROUND_GREEN); break; - case Color::Blue: DOCTEST_SET_ATTR(FOREGROUND_BLUE); break; - case Color::Cyan: DOCTEST_SET_ATTR(FOREGROUND_BLUE | FOREGROUND_GREEN); break; - case Color::Yellow: DOCTEST_SET_ATTR(FOREGROUND_RED | FOREGROUND_GREEN); break; - case Color::Grey: DOCTEST_SET_ATTR(0); break; - case Color::LightGrey: DOCTEST_SET_ATTR(FOREGROUND_INTENSITY); break; - case Color::BrightRed: DOCTEST_SET_ATTR(FOREGROUND_INTENSITY | FOREGROUND_RED); break; - case Color::BrightGreen: DOCTEST_SET_ATTR(FOREGROUND_INTENSITY | FOREGROUND_GREEN); break; - case Color::BrightWhite: DOCTEST_SET_ATTR(FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE); break; - case Color::None: - case Color::Bright: // invalid - default: DOCTEST_SET_ATTR(g_origFgAttrs); - } - // clang-format on -#endif // DOCTEST_CONFIG_COLORS_WINDOWS - } - DOCTEST_CLANG_SUPPRESS_WARNING_POP - - std::vector& getExceptionTranslators() { - static std::vector data; - return data; - } - - String translateActiveException() { -#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS - String res; - auto& translators = getExceptionTranslators(); - for(auto& curr : translators) - if(curr->translate(res)) - return res; - // clang-format off - DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wcatch-value") - try { - throw; - } catch(std::exception& ex) { - return ex.what(); - } catch(std::string& msg) { - return msg.c_str(); - } catch(const char* msg) { - return msg; - } catch(...) { - return "unknown exception"; - } - DOCTEST_GCC_SUPPRESS_WARNING_POP -// clang-format on -#else // DOCTEST_CONFIG_NO_EXCEPTIONS - return ""; -#endif // DOCTEST_CONFIG_NO_EXCEPTIONS - } -} // namespace - -namespace detail { - // used by the macros for registering tests - int regTest(const TestCase& tc) { - getRegisteredTests().insert(tc); - return 0; - } - - // sets the current test suite - int setTestSuite(const TestSuite& ts) { - doctest_detail_test_suite_ns::getCurrentTestSuite() = ts; - return 0; - } - -#ifdef DOCTEST_IS_DEBUGGER_ACTIVE - bool isDebuggerActive() { return DOCTEST_IS_DEBUGGER_ACTIVE(); } -#else // DOCTEST_IS_DEBUGGER_ACTIVE -#ifdef DOCTEST_PLATFORM_LINUX - class ErrnoGuard { - public: - ErrnoGuard() : m_oldErrno(errno) {} - ~ErrnoGuard() { errno = m_oldErrno; } - private: - int m_oldErrno; - }; - // See the comments in Catch2 for the reasoning behind this implementation: - // https://github.com/catchorg/Catch2/blob/v2.13.1/include/internal/catch_debugger.cpp#L79-L102 - bool isDebuggerActive() { - ErrnoGuard guard; - std::ifstream in("/proc/self/status"); - for(std::string line; std::getline(in, line);) { - static const int PREFIX_LEN = 11; - if(line.compare(0, PREFIX_LEN, "TracerPid:\t") == 0) { - return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0'; - } - } - return false; - } -#elif defined(DOCTEST_PLATFORM_MAC) - // The following function is taken directly from the following technical note: - // https://developer.apple.com/library/archive/qa/qa1361/_index.html - // Returns true if the current process is being debugged (either - // running under the debugger or has a debugger attached post facto). - bool isDebuggerActive() { - int mib[4]; - kinfo_proc info; - size_t size; - // Initialize the flags so that, if sysctl fails for some bizarre - // reason, we get a predictable result. - info.kp_proc.p_flag = 0; - // Initialize mib, which tells sysctl the info we want, in this case - // we're looking for information about a specific process ID. - mib[0] = CTL_KERN; - mib[1] = KERN_PROC; - mib[2] = KERN_PROC_PID; - mib[3] = getpid(); - // Call sysctl. - size = sizeof(info); - if(sysctl(mib, DOCTEST_COUNTOF(mib), &info, &size, 0, 0) != 0) { - std::cerr << "\nCall to sysctl failed - unable to determine if debugger is active **\n"; - return false; - } - // We're being debugged if the P_TRACED flag is set. - return ((info.kp_proc.p_flag & P_TRACED) != 0); - } -#elif DOCTEST_MSVC || defined(__MINGW32__) || defined(__MINGW64__) - bool isDebuggerActive() { return ::IsDebuggerPresent() != 0; } -#else - bool isDebuggerActive() { return false; } -#endif // Platform -#endif // DOCTEST_IS_DEBUGGER_ACTIVE - - void registerExceptionTranslatorImpl(const IExceptionTranslator* et) { - if(std::find(getExceptionTranslators().begin(), getExceptionTranslators().end(), et) == - getExceptionTranslators().end()) - getExceptionTranslators().push_back(et); - } - -#ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING - void toStream(std::ostream* s, char* in) { *s << in; } - void toStream(std::ostream* s, const char* in) { *s << in; } -#endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING - void toStream(std::ostream* s, bool in) { *s << std::boolalpha << in << std::noboolalpha; } - void toStream(std::ostream* s, float in) { *s << in; } - void toStream(std::ostream* s, double in) { *s << in; } - void toStream(std::ostream* s, double long in) { *s << in; } - - void toStream(std::ostream* s, char in) { *s << in; } - void toStream(std::ostream* s, char signed in) { *s << in; } - void toStream(std::ostream* s, char unsigned in) { *s << in; } - void toStream(std::ostream* s, int short in) { *s << in; } - void toStream(std::ostream* s, int short unsigned in) { *s << in; } - void toStream(std::ostream* s, int in) { *s << in; } - void toStream(std::ostream* s, int unsigned in) { *s << in; } - void toStream(std::ostream* s, int long in) { *s << in; } - void toStream(std::ostream* s, int long unsigned in) { *s << in; } - void toStream(std::ostream* s, int long long in) { *s << in; } - void toStream(std::ostream* s, int long long unsigned in) { *s << in; } - - DOCTEST_THREAD_LOCAL std::vector g_infoContexts; // for logging with INFO() - - ContextScopeBase::ContextScopeBase() { - g_infoContexts.push_back(this); - } - - DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4996) // std::uncaught_exception is deprecated in C++17 - DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations") - DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations") - - // destroy cannot be inlined into the destructor because that would mean calling stringify after - // ContextScope has been destroyed (base class destructors run after derived class destructors). - // Instead, ContextScope calls this method directly from its destructor. - void ContextScopeBase::destroy() { -#if defined(__cpp_lib_uncaught_exceptions) && __cpp_lib_uncaught_exceptions >= 201411L && (!defined(__MAC_OS_X_VERSION_MIN_REQUIRED) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200) - if(std::uncaught_exceptions() > 0) { -#else - if(std::uncaught_exception()) { -#endif - std::ostringstream s; - this->stringify(&s); - g_cs->stringifiedContexts.push_back(s.str().c_str()); - } - g_infoContexts.pop_back(); - } - - DOCTEST_CLANG_SUPPRESS_WARNING_POP - DOCTEST_GCC_SUPPRESS_WARNING_POP - DOCTEST_MSVC_SUPPRESS_WARNING_POP -} // namespace detail -namespace { - using namespace detail; - -#if !defined(DOCTEST_CONFIG_POSIX_SIGNALS) && !defined(DOCTEST_CONFIG_WINDOWS_SEH) - struct FatalConditionHandler - { - static void reset() {} - static void allocateAltStackMem() {} - static void freeAltStackMem() {} - }; -#else // DOCTEST_CONFIG_POSIX_SIGNALS || DOCTEST_CONFIG_WINDOWS_SEH - - void reportFatal(const std::string&); - -#ifdef DOCTEST_PLATFORM_WINDOWS - - struct SignalDefs - { - DWORD id; - const char* name; - }; - // There is no 1-1 mapping between signals and windows exceptions. - // Windows can easily distinguish between SO and SigSegV, - // but SigInt, SigTerm, etc are handled differently. - SignalDefs signalDefs[] = { - {static_cast(EXCEPTION_ILLEGAL_INSTRUCTION), - "SIGILL - Illegal instruction signal"}, - {static_cast(EXCEPTION_STACK_OVERFLOW), "SIGSEGV - Stack overflow"}, - {static_cast(EXCEPTION_ACCESS_VIOLATION), - "SIGSEGV - Segmentation violation signal"}, - {static_cast(EXCEPTION_INT_DIVIDE_BY_ZERO), "Divide by zero error"}, - }; - - struct FatalConditionHandler - { - static LONG CALLBACK handleException(PEXCEPTION_POINTERS ExceptionInfo) { - // Multiple threads may enter this filter/handler at once. We want the error message to be printed on the - // console just once no matter how many threads have crashed. - static std::mutex mutex; - static bool execute = true; - { - std::lock_guard lock(mutex); - if(execute) { - bool reported = false; - for(size_t i = 0; i < DOCTEST_COUNTOF(signalDefs); ++i) { - if(ExceptionInfo->ExceptionRecord->ExceptionCode == signalDefs[i].id) { - reportFatal(signalDefs[i].name); - reported = true; - break; - } - } - if(reported == false) - reportFatal("Unhandled SEH exception caught"); - if(isDebuggerActive() && !g_cs->no_breaks) - DOCTEST_BREAK_INTO_DEBUGGER(); - } - execute = false; - } - std::exit(EXIT_FAILURE); - } - - static void allocateAltStackMem() {} - static void freeAltStackMem() {} - - FatalConditionHandler() { - isSet = true; - // 32k seems enough for doctest to handle stack overflow, - // but the value was found experimentally, so there is no strong guarantee - guaranteeSize = 32 * 1024; - // Register an unhandled exception filter - previousTop = SetUnhandledExceptionFilter(handleException); - // Pass in guarantee size to be filled - SetThreadStackGuarantee(&guaranteeSize); - - // On Windows uncaught exceptions from another thread, exceptions from - // destructors, or calls to std::terminate are not a SEH exception - - // The terminal handler gets called when: - // - std::terminate is called FROM THE TEST RUNNER THREAD - // - an exception is thrown from a destructor FROM THE TEST RUNNER THREAD - original_terminate_handler = std::get_terminate(); - std::set_terminate([]() DOCTEST_NOEXCEPT { - reportFatal("Terminate handler called"); - if(isDebuggerActive() && !g_cs->no_breaks) - DOCTEST_BREAK_INTO_DEBUGGER(); - std::exit(EXIT_FAILURE); // explicitly exit - otherwise the SIGABRT handler may be called as well - }); - - // SIGABRT is raised when: - // - std::terminate is called FROM A DIFFERENT THREAD - // - an exception is thrown from a destructor FROM A DIFFERENT THREAD - // - an uncaught exception is thrown FROM A DIFFERENT THREAD - prev_sigabrt_handler = std::signal(SIGABRT, [](int signal) DOCTEST_NOEXCEPT { - if(signal == SIGABRT) { - reportFatal("SIGABRT - Abort (abnormal termination) signal"); - if(isDebuggerActive() && !g_cs->no_breaks) - DOCTEST_BREAK_INTO_DEBUGGER(); - std::exit(EXIT_FAILURE); - } - }); - - // The following settings are taken from google test, and more - // specifically from UnitTest::Run() inside of gtest.cc - - // the user does not want to see pop-up dialogs about crashes - prev_error_mode_1 = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT | - SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); - // This forces the abort message to go to stderr in all circumstances. - prev_error_mode_2 = _set_error_mode(_OUT_TO_STDERR); - // In the debug version, Visual Studio pops up a separate dialog - // offering a choice to debug the aborted program - we want to disable that. - prev_abort_behavior = _set_abort_behavior(0x0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); - // In debug mode, the Windows CRT can crash with an assertion over invalid - // input (e.g. passing an invalid file descriptor). The default handling - // for these assertions is to pop up a dialog and wait for user input. - // Instead ask the CRT to dump such assertions to stderr non-interactively. - prev_report_mode = _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG); - prev_report_file = _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR); - } - - static void reset() { - if(isSet) { - // Unregister handler and restore the old guarantee - SetUnhandledExceptionFilter(previousTop); - SetThreadStackGuarantee(&guaranteeSize); - std::set_terminate(original_terminate_handler); - std::signal(SIGABRT, prev_sigabrt_handler); - SetErrorMode(prev_error_mode_1); - _set_error_mode(prev_error_mode_2); - _set_abort_behavior(prev_abort_behavior, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); - static_cast(_CrtSetReportMode(_CRT_ASSERT, prev_report_mode)); - static_cast(_CrtSetReportFile(_CRT_ASSERT, prev_report_file)); - isSet = false; - } - } - - ~FatalConditionHandler() { reset(); } - - private: - static UINT prev_error_mode_1; - static int prev_error_mode_2; - static unsigned int prev_abort_behavior; - static int prev_report_mode; - static _HFILE prev_report_file; - static void (*prev_sigabrt_handler)(int); - static std::terminate_handler original_terminate_handler; - static bool isSet; - static ULONG guaranteeSize; - static LPTOP_LEVEL_EXCEPTION_FILTER previousTop; - }; - - UINT FatalConditionHandler::prev_error_mode_1; - int FatalConditionHandler::prev_error_mode_2; - unsigned int FatalConditionHandler::prev_abort_behavior; - int FatalConditionHandler::prev_report_mode; - _HFILE FatalConditionHandler::prev_report_file; - void (*FatalConditionHandler::prev_sigabrt_handler)(int); - std::terminate_handler FatalConditionHandler::original_terminate_handler; - bool FatalConditionHandler::isSet = false; - ULONG FatalConditionHandler::guaranteeSize = 0; - LPTOP_LEVEL_EXCEPTION_FILTER FatalConditionHandler::previousTop = nullptr; - -#else // DOCTEST_PLATFORM_WINDOWS - - struct SignalDefs - { - int id; - const char* name; - }; - SignalDefs signalDefs[] = {{SIGINT, "SIGINT - Terminal interrupt signal"}, - {SIGILL, "SIGILL - Illegal instruction signal"}, - {SIGFPE, "SIGFPE - Floating point error signal"}, - {SIGSEGV, "SIGSEGV - Segmentation violation signal"}, - {SIGTERM, "SIGTERM - Termination request signal"}, - {SIGABRT, "SIGABRT - Abort (abnormal termination) signal"}}; - - struct FatalConditionHandler - { - static bool isSet; - static struct sigaction oldSigActions[DOCTEST_COUNTOF(signalDefs)]; - static stack_t oldSigStack; - static size_t altStackSize; - static char* altStackMem; - - static void handleSignal(int sig) { - const char* name = ""; - for(std::size_t i = 0; i < DOCTEST_COUNTOF(signalDefs); ++i) { - SignalDefs& def = signalDefs[i]; - if(sig == def.id) { - name = def.name; - break; - } - } - reset(); - reportFatal(name); - raise(sig); - } - - static void allocateAltStackMem() { - altStackMem = new char[altStackSize]; - } - - static void freeAltStackMem() { - delete[] altStackMem; - } - - FatalConditionHandler() { - isSet = true; - stack_t sigStack; - sigStack.ss_sp = altStackMem; - sigStack.ss_size = altStackSize; - sigStack.ss_flags = 0; - sigaltstack(&sigStack, &oldSigStack); - struct sigaction sa = {}; - sa.sa_handler = handleSignal; // NOLINT - sa.sa_flags = SA_ONSTACK; - for(std::size_t i = 0; i < DOCTEST_COUNTOF(signalDefs); ++i) { - sigaction(signalDefs[i].id, &sa, &oldSigActions[i]); - } - } - - ~FatalConditionHandler() { reset(); } - static void reset() { - if(isSet) { - // Set signals back to previous values -- hopefully nobody overwrote them in the meantime - for(std::size_t i = 0; i < DOCTEST_COUNTOF(signalDefs); ++i) { - sigaction(signalDefs[i].id, &oldSigActions[i], nullptr); - } - // Return the old stack - sigaltstack(&oldSigStack, nullptr); - isSet = false; - } - } - }; - - bool FatalConditionHandler::isSet = false; - struct sigaction FatalConditionHandler::oldSigActions[DOCTEST_COUNTOF(signalDefs)] = {}; - stack_t FatalConditionHandler::oldSigStack = {}; - size_t FatalConditionHandler::altStackSize = 4 * SIGSTKSZ; - char* FatalConditionHandler::altStackMem = nullptr; - -#endif // DOCTEST_PLATFORM_WINDOWS -#endif // DOCTEST_CONFIG_POSIX_SIGNALS || DOCTEST_CONFIG_WINDOWS_SEH - -} // namespace - -namespace { - using namespace detail; - -#ifdef DOCTEST_PLATFORM_WINDOWS -#define DOCTEST_OUTPUT_DEBUG_STRING(text) ::OutputDebugStringA(text) -#else - // TODO: integration with XCode and other IDEs -#define DOCTEST_OUTPUT_DEBUG_STRING(text) // NOLINT(clang-diagnostic-unused-macros) -#endif // Platform - - void addAssert(assertType::Enum at) { - if((at & assertType::is_warn) == 0) //!OCLINT bitwise operator in conditional - g_cs->numAssertsCurrentTest_atomic++; - } - - void addFailedAssert(assertType::Enum at) { - if((at & assertType::is_warn) == 0) //!OCLINT bitwise operator in conditional - g_cs->numAssertsFailedCurrentTest_atomic++; - } - -#if defined(DOCTEST_CONFIG_POSIX_SIGNALS) || defined(DOCTEST_CONFIG_WINDOWS_SEH) - void reportFatal(const std::string& message) { - g_cs->failure_flags |= TestCaseFailureReason::Crash; - - DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_exception, {message.c_str(), true}); - - while(g_cs->subcasesStack.size()) { - g_cs->subcasesStack.pop_back(); - DOCTEST_ITERATE_THROUGH_REPORTERS(subcase_end, DOCTEST_EMPTY); - } - - g_cs->finalizeTestCaseData(); - - DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_end, *g_cs); - - DOCTEST_ITERATE_THROUGH_REPORTERS(test_run_end, *g_cs); - } -#endif // DOCTEST_CONFIG_POSIX_SIGNALS || DOCTEST_CONFIG_WINDOWS_SEH -} // namespace -namespace detail { - - ResultBuilder::ResultBuilder(assertType::Enum at, const char* file, int line, const char* expr, - const char* exception_type, const char* exception_string) { - m_test_case = g_cs->currentTest; - m_at = at; - m_file = file; - m_line = line; - m_expr = expr; - m_failed = true; - m_threw = false; - m_threw_as = false; - m_exception_type = exception_type; - m_exception_string = exception_string; -#if DOCTEST_MSVC - if(m_expr[0] == ' ') // this happens when variadic macros are disabled under MSVC - ++m_expr; -#endif // MSVC - } - - void ResultBuilder::setResult(const Result& res) { - m_decomp = res.m_decomp; - m_failed = !res.m_passed; - } - - void ResultBuilder::translateException() { - m_threw = true; - m_exception = translateActiveException(); - } - - bool ResultBuilder::log() { - if(m_at & assertType::is_throws) { //!OCLINT bitwise operator in conditional - m_failed = !m_threw; - } else if((m_at & assertType::is_throws_as) && (m_at & assertType::is_throws_with)) { //!OCLINT - m_failed = !m_threw_as || (m_exception != m_exception_string); - } else if(m_at & assertType::is_throws_as) { //!OCLINT bitwise operator in conditional - m_failed = !m_threw_as; - } else if(m_at & assertType::is_throws_with) { //!OCLINT bitwise operator in conditional - m_failed = m_exception != m_exception_string; - } else if(m_at & assertType::is_nothrow) { //!OCLINT bitwise operator in conditional - m_failed = m_threw; - } - - if(m_exception.size()) - m_exception = String("\"") + m_exception + "\""; - - if(is_running_in_test) { - addAssert(m_at); - DOCTEST_ITERATE_THROUGH_REPORTERS(log_assert, *this); - - if(m_failed) - addFailedAssert(m_at); - } else if(m_failed) { - failed_out_of_a_testing_context(*this); - } - - return m_failed && isDebuggerActive() && !getContextOptions()->no_breaks && - (g_cs->currentTest == nullptr || !g_cs->currentTest->m_no_breaks); // break into debugger - } - - void ResultBuilder::react() const { - if(m_failed && checkIfShouldThrow(m_at)) - throwException(); - } - - void failed_out_of_a_testing_context(const AssertData& ad) { - if(g_cs->ah) - g_cs->ah(ad); - else - std::abort(); - } - - void decomp_assert(assertType::Enum at, const char* file, int line, const char* expr, - Result result) { - bool failed = !result.m_passed; - - // ################################################################################### - // IF THE DEBUGGER BREAKS HERE - GO 1 LEVEL UP IN THE CALLSTACK FOR THE FAILING ASSERT - // THIS IS THE EFFECT OF HAVING 'DOCTEST_CONFIG_SUPER_FAST_ASSERTS' DEFINED - // ################################################################################### - DOCTEST_ASSERT_OUT_OF_TESTS(result.m_decomp); - DOCTEST_ASSERT_IN_TESTS(result.m_decomp); - // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) - } - - MessageBuilder::MessageBuilder(const char* file, int line, assertType::Enum severity) { - m_stream = getTlsOss(); - m_file = file; - m_line = line; - m_severity = severity; - } - - IExceptionTranslator::IExceptionTranslator() = default; - IExceptionTranslator::~IExceptionTranslator() = default; - - bool MessageBuilder::log() { - m_string = getTlsOssResult(); - DOCTEST_ITERATE_THROUGH_REPORTERS(log_message, *this); - - const bool isWarn = m_severity & assertType::is_warn; - - // warn is just a message in this context so we don't treat it as an assert - if(!isWarn) { - addAssert(m_severity); - addFailedAssert(m_severity); - } - - return isDebuggerActive() && !getContextOptions()->no_breaks && !isWarn && - (g_cs->currentTest == nullptr || !g_cs->currentTest->m_no_breaks); // break into debugger - } - - void MessageBuilder::react() { - if(m_severity & assertType::is_require) //!OCLINT bitwise operator in conditional - throwException(); - } - - MessageBuilder::~MessageBuilder() = default; -} // namespace detail -namespace { - using namespace detail; - - template - DOCTEST_NORETURN void throw_exception(Ex const& e) { -#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS - throw e; -#else // DOCTEST_CONFIG_NO_EXCEPTIONS - std::cerr << "doctest will terminate because it needed to throw an exception.\n" - << "The message was: " << e.what() << '\n'; - std::terminate(); -#endif // DOCTEST_CONFIG_NO_EXCEPTIONS - } - -#ifndef DOCTEST_INTERNAL_ERROR -#define DOCTEST_INTERNAL_ERROR(msg) \ - throw_exception(std::logic_error( \ - __FILE__ ":" DOCTEST_TOSTR(__LINE__) ": Internal doctest error: " msg)) -#endif // DOCTEST_INTERNAL_ERROR - - // clang-format off - -// ================================================================================================= -// The following code has been taken verbatim from Catch2/include/internal/catch_xmlwriter.h/cpp -// This is done so cherry-picking bug fixes is trivial - even the style/formatting is untouched. -// ================================================================================================= - - class XmlEncode { - public: - enum ForWhat { ForTextNodes, ForAttributes }; - - XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes ); - - void encodeTo( std::ostream& os ) const; - - friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ); - - private: - std::string m_str; - ForWhat m_forWhat; - }; - - class XmlWriter { - public: - - class ScopedElement { - public: - ScopedElement( XmlWriter* writer ); - - ScopedElement( ScopedElement&& other ) DOCTEST_NOEXCEPT; - ScopedElement& operator=( ScopedElement&& other ) DOCTEST_NOEXCEPT; - - ~ScopedElement(); - - ScopedElement& writeText( std::string const& text, bool indent = true ); - - template - ScopedElement& writeAttribute( std::string const& name, T const& attribute ) { - m_writer->writeAttribute( name, attribute ); - return *this; - } - - private: - mutable XmlWriter* m_writer = nullptr; - }; - - XmlWriter( std::ostream& os = std::cout ); - ~XmlWriter(); - - XmlWriter( XmlWriter const& ) = delete; - XmlWriter& operator=( XmlWriter const& ) = delete; - - XmlWriter& startElement( std::string const& name ); - - ScopedElement scopedElement( std::string const& name ); - - XmlWriter& endElement(); - - XmlWriter& writeAttribute( std::string const& name, std::string const& attribute ); - - XmlWriter& writeAttribute( std::string const& name, const char* attribute ); - - XmlWriter& writeAttribute( std::string const& name, bool attribute ); - - template - XmlWriter& writeAttribute( std::string const& name, T const& attribute ) { - std::stringstream rss; - rss << attribute; - return writeAttribute( name, rss.str() ); - } - - XmlWriter& writeText( std::string const& text, bool indent = true ); - - //XmlWriter& writeComment( std::string const& text ); - - //void writeStylesheetRef( std::string const& url ); - - //XmlWriter& writeBlankLine(); - - void ensureTagClosed(); - - private: - - void writeDeclaration(); - - void newlineIfNecessary(); - - bool m_tagIsOpen = false; - bool m_needsNewline = false; - std::vector m_tags; - std::string m_indent; - std::ostream& m_os; - }; - -// ================================================================================================= -// The following code has been taken verbatim from Catch2/include/internal/catch_xmlwriter.h/cpp -// This is done so cherry-picking bug fixes is trivial - even the style/formatting is untouched. -// ================================================================================================= - -using uchar = unsigned char; - -namespace { - - size_t trailingBytes(unsigned char c) { - if ((c & 0xE0) == 0xC0) { - return 2; - } - if ((c & 0xF0) == 0xE0) { - return 3; - } - if ((c & 0xF8) == 0xF0) { - return 4; - } - DOCTEST_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered"); - } - - uint32_t headerValue(unsigned char c) { - if ((c & 0xE0) == 0xC0) { - return c & 0x1F; - } - if ((c & 0xF0) == 0xE0) { - return c & 0x0F; - } - if ((c & 0xF8) == 0xF0) { - return c & 0x07; - } - DOCTEST_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered"); - } - - void hexEscapeChar(std::ostream& os, unsigned char c) { - std::ios_base::fmtflags f(os.flags()); - os << "\\x" - << std::uppercase << std::hex << std::setfill('0') << std::setw(2) - << static_cast(c); - os.flags(f); - } - -} // anonymous namespace - - XmlEncode::XmlEncode( std::string const& str, ForWhat forWhat ) - : m_str( str ), - m_forWhat( forWhat ) - {} - - void XmlEncode::encodeTo( std::ostream& os ) const { - // Apostrophe escaping not necessary if we always use " to write attributes - // (see: https://www.w3.org/TR/xml/#syntax) - - for( std::size_t idx = 0; idx < m_str.size(); ++ idx ) { - uchar c = m_str[idx]; - switch (c) { - case '<': os << "<"; break; - case '&': os << "&"; break; - - case '>': - // See: https://www.w3.org/TR/xml/#syntax - if (idx > 2 && m_str[idx - 1] == ']' && m_str[idx - 2] == ']') - os << ">"; - else - os << c; - break; - - case '\"': - if (m_forWhat == ForAttributes) - os << """; - else - os << c; - break; - - default: - // Check for control characters and invalid utf-8 - - // Escape control characters in standard ascii - // see https://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0 - if (c < 0x09 || (c > 0x0D && c < 0x20) || c == 0x7F) { - hexEscapeChar(os, c); - break; - } - - // Plain ASCII: Write it to stream - if (c < 0x7F) { - os << c; - break; - } - - // UTF-8 territory - // Check if the encoding is valid and if it is not, hex escape bytes. - // Important: We do not check the exact decoded values for validity, only the encoding format - // First check that this bytes is a valid lead byte: - // This means that it is not encoded as 1111 1XXX - // Or as 10XX XXXX - if (c < 0xC0 || - c >= 0xF8) { - hexEscapeChar(os, c); - break; - } - - auto encBytes = trailingBytes(c); - // Are there enough bytes left to avoid accessing out-of-bounds memory? - if (idx + encBytes - 1 >= m_str.size()) { - hexEscapeChar(os, c); - break; - } - // The header is valid, check data - // The next encBytes bytes must together be a valid utf-8 - // This means: bitpattern 10XX XXXX and the extracted value is sane (ish) - bool valid = true; - uint32_t value = headerValue(c); - for (std::size_t n = 1; n < encBytes; ++n) { - uchar nc = m_str[idx + n]; - valid &= ((nc & 0xC0) == 0x80); - value = (value << 6) | (nc & 0x3F); - } - - if ( - // Wrong bit pattern of following bytes - (!valid) || - // Overlong encodings - (value < 0x80) || - ( value < 0x800 && encBytes > 2) || // removed "0x80 <= value &&" because redundant - (0x800 < value && value < 0x10000 && encBytes > 3) || - // Encoded value out of range - (value >= 0x110000) - ) { - hexEscapeChar(os, c); - break; - } - - // If we got here, this is in fact a valid(ish) utf-8 sequence - for (std::size_t n = 0; n < encBytes; ++n) { - os << m_str[idx + n]; - } - idx += encBytes - 1; - break; - } - } - } - - std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) { - xmlEncode.encodeTo( os ); - return os; - } - - XmlWriter::ScopedElement::ScopedElement( XmlWriter* writer ) - : m_writer( writer ) - {} - - XmlWriter::ScopedElement::ScopedElement( ScopedElement&& other ) DOCTEST_NOEXCEPT - : m_writer( other.m_writer ){ - other.m_writer = nullptr; - } - XmlWriter::ScopedElement& XmlWriter::ScopedElement::operator=( ScopedElement&& other ) DOCTEST_NOEXCEPT { - if ( m_writer ) { - m_writer->endElement(); - } - m_writer = other.m_writer; - other.m_writer = nullptr; - return *this; - } - - - XmlWriter::ScopedElement::~ScopedElement() { - if( m_writer ) - m_writer->endElement(); - } - - XmlWriter::ScopedElement& XmlWriter::ScopedElement::writeText( std::string const& text, bool indent ) { - m_writer->writeText( text, indent ); - return *this; - } - - XmlWriter::XmlWriter( std::ostream& os ) : m_os( os ) - { - writeDeclaration(); - } - - XmlWriter::~XmlWriter() { - while( !m_tags.empty() ) - endElement(); - } - - XmlWriter& XmlWriter::startElement( std::string const& name ) { - ensureTagClosed(); - newlineIfNecessary(); - m_os << m_indent << '<' << name; - m_tags.push_back( name ); - m_indent += " "; - m_tagIsOpen = true; - return *this; - } - - XmlWriter::ScopedElement XmlWriter::scopedElement( std::string const& name ) { - ScopedElement scoped( this ); - startElement( name ); - return scoped; - } - - XmlWriter& XmlWriter::endElement() { - newlineIfNecessary(); - m_indent = m_indent.substr( 0, m_indent.size()-2 ); - if( m_tagIsOpen ) { - m_os << "/>"; - m_tagIsOpen = false; - } - else { - m_os << m_indent << ""; - } - m_os << std::endl; - m_tags.pop_back(); - return *this; - } - - XmlWriter& XmlWriter::writeAttribute( std::string const& name, std::string const& attribute ) { - if( !name.empty() && !attribute.empty() ) - m_os << ' ' << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '"'; - return *this; - } - - XmlWriter& XmlWriter::writeAttribute( std::string const& name, const char* attribute ) { - if( !name.empty() && attribute && attribute[0] != '\0' ) - m_os << ' ' << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '"'; - return *this; - } - - XmlWriter& XmlWriter::writeAttribute( std::string const& name, bool attribute ) { - m_os << ' ' << name << "=\"" << ( attribute ? "true" : "false" ) << '"'; - return *this; - } - - XmlWriter& XmlWriter::writeText( std::string const& text, bool indent ) { - if( !text.empty() ){ - bool tagWasOpen = m_tagIsOpen; - ensureTagClosed(); - if( tagWasOpen && indent ) - m_os << m_indent; - m_os << XmlEncode( text ); - m_needsNewline = true; - } - return *this; - } - - //XmlWriter& XmlWriter::writeComment( std::string const& text ) { - // ensureTagClosed(); - // m_os << m_indent << ""; - // m_needsNewline = true; - // return *this; - //} - - //void XmlWriter::writeStylesheetRef( std::string const& url ) { - // m_os << "\n"; - //} - - //XmlWriter& XmlWriter::writeBlankLine() { - // ensureTagClosed(); - // m_os << '\n'; - // return *this; - //} - - void XmlWriter::ensureTagClosed() { - if( m_tagIsOpen ) { - m_os << ">" << std::endl; - m_tagIsOpen = false; - } - } - - void XmlWriter::writeDeclaration() { - m_os << "\n"; - } - - void XmlWriter::newlineIfNecessary() { - if( m_needsNewline ) { - m_os << std::endl; - m_needsNewline = false; - } - } - -// ================================================================================================= -// End of copy-pasted code from Catch -// ================================================================================================= - - // clang-format on - - struct XmlReporter : public IReporter - { - XmlWriter xml; - std::mutex mutex; - - // caching pointers/references to objects of these types - safe to do - const ContextOptions& opt; - const TestCaseData* tc = nullptr; - - XmlReporter(const ContextOptions& co) - : xml(*co.cout) - , opt(co) {} - - void log_contexts() { - int num_contexts = get_num_active_contexts(); - if(num_contexts) { - auto contexts = get_active_contexts(); - std::stringstream ss; - for(int i = 0; i < num_contexts; ++i) { - contexts[i]->stringify(&ss); - xml.scopedElement("Info").writeText(ss.str()); - ss.str(""); - } - } - } - - unsigned line(unsigned l) const { return opt.no_line_numbers ? 0 : l; } - - void test_case_start_impl(const TestCaseData& in) { - bool open_ts_tag = false; - if(tc != nullptr) { // we have already opened a test suite - if(std::strcmp(tc->m_test_suite, in.m_test_suite) != 0) { - xml.endElement(); - open_ts_tag = true; - } - } - else { - open_ts_tag = true; // first test case ==> first test suite - } - - if(open_ts_tag) { - xml.startElement("TestSuite"); - xml.writeAttribute("name", in.m_test_suite); - } - - tc = ∈ - xml.startElement("TestCase") - .writeAttribute("name", in.m_name) - .writeAttribute("filename", skipPathFromFilename(in.m_file.c_str())) - .writeAttribute("line", line(in.m_line)) - .writeAttribute("description", in.m_description); - - if(Approx(in.m_timeout) != 0) - xml.writeAttribute("timeout", in.m_timeout); - if(in.m_may_fail) - xml.writeAttribute("may_fail", true); - if(in.m_should_fail) - xml.writeAttribute("should_fail", true); - } - - // ========================================================================================= - // WHAT FOLLOWS ARE OVERRIDES OF THE VIRTUAL METHODS OF THE REPORTER INTERFACE - // ========================================================================================= - - void report_query(const QueryData& in) override { - test_run_start(); - if(opt.list_reporters) { - for(auto& curr : getListeners()) - xml.scopedElement("Listener") - .writeAttribute("priority", curr.first.first) - .writeAttribute("name", curr.first.second); - for(auto& curr : getReporters()) - xml.scopedElement("Reporter") - .writeAttribute("priority", curr.first.first) - .writeAttribute("name", curr.first.second); - } else if(opt.count || opt.list_test_cases) { - for(unsigned i = 0; i < in.num_data; ++i) { - xml.scopedElement("TestCase").writeAttribute("name", in.data[i]->m_name) - .writeAttribute("testsuite", in.data[i]->m_test_suite) - .writeAttribute("filename", skipPathFromFilename(in.data[i]->m_file.c_str())) - .writeAttribute("line", line(in.data[i]->m_line)); - } - xml.scopedElement("OverallResultsTestCases") - .writeAttribute("unskipped", in.run_stats->numTestCasesPassingFilters); - } else if(opt.list_test_suites) { - for(unsigned i = 0; i < in.num_data; ++i) - xml.scopedElement("TestSuite").writeAttribute("name", in.data[i]->m_test_suite); - xml.scopedElement("OverallResultsTestCases") - .writeAttribute("unskipped", in.run_stats->numTestCasesPassingFilters); - xml.scopedElement("OverallResultsTestSuites") - .writeAttribute("unskipped", in.run_stats->numTestSuitesPassingFilters); - } - xml.endElement(); - } - - void test_run_start() override { - // remove .exe extension - mainly to have the same output on UNIX and Windows - std::string binary_name = skipPathFromFilename(opt.binary_name.c_str()); -#ifdef DOCTEST_PLATFORM_WINDOWS - if(binary_name.rfind(".exe") != std::string::npos) - binary_name = binary_name.substr(0, binary_name.length() - 4); -#endif // DOCTEST_PLATFORM_WINDOWS - - xml.startElement("doctest").writeAttribute("binary", binary_name); - if(opt.no_version == false) - xml.writeAttribute("version", DOCTEST_VERSION_STR); - - // only the consequential ones (TODO: filters) - xml.scopedElement("Options") - .writeAttribute("order_by", opt.order_by.c_str()) - .writeAttribute("rand_seed", opt.rand_seed) - .writeAttribute("first", opt.first) - .writeAttribute("last", opt.last) - .writeAttribute("abort_after", opt.abort_after) - .writeAttribute("subcase_filter_levels", opt.subcase_filter_levels) - .writeAttribute("case_sensitive", opt.case_sensitive) - .writeAttribute("no_throw", opt.no_throw) - .writeAttribute("no_skip", opt.no_skip); - } - - void test_run_end(const TestRunStats& p) override { - if(tc) // the TestSuite tag - only if there has been at least 1 test case - xml.endElement(); - - xml.scopedElement("OverallResultsAsserts") - .writeAttribute("successes", p.numAsserts - p.numAssertsFailed) - .writeAttribute("failures", p.numAssertsFailed); - - xml.startElement("OverallResultsTestCases") - .writeAttribute("successes", - p.numTestCasesPassingFilters - p.numTestCasesFailed) - .writeAttribute("failures", p.numTestCasesFailed); - if(opt.no_skipped_summary == false) - xml.writeAttribute("skipped", p.numTestCases - p.numTestCasesPassingFilters); - xml.endElement(); - - xml.endElement(); - } - - void test_case_start(const TestCaseData& in) override { - test_case_start_impl(in); - xml.ensureTagClosed(); - } - - void test_case_reenter(const TestCaseData&) override {} - - void test_case_end(const CurrentTestCaseStats& st) override { - xml.startElement("OverallResultsAsserts") - .writeAttribute("successes", - st.numAssertsCurrentTest - st.numAssertsFailedCurrentTest) - .writeAttribute("failures", st.numAssertsFailedCurrentTest); - if(opt.duration) - xml.writeAttribute("duration", st.seconds); - if(tc->m_expected_failures) - xml.writeAttribute("expected_failures", tc->m_expected_failures); - xml.endElement(); - - xml.endElement(); - } - - void test_case_exception(const TestCaseException& e) override { - std::lock_guard lock(mutex); - - xml.scopedElement("Exception") - .writeAttribute("crash", e.is_crash) - .writeText(e.error_string.c_str()); - } - - void subcase_start(const SubcaseSignature& in) override { - std::lock_guard lock(mutex); - - xml.startElement("SubCase") - .writeAttribute("name", in.m_name) - .writeAttribute("filename", skipPathFromFilename(in.m_file)) - .writeAttribute("line", line(in.m_line)); - xml.ensureTagClosed(); - } - - void subcase_end() override { xml.endElement(); } - - void log_assert(const AssertData& rb) override { - if(!rb.m_failed && !opt.success) - return; - - std::lock_guard lock(mutex); - - xml.startElement("Expression") - .writeAttribute("success", !rb.m_failed) - .writeAttribute("type", assertString(rb.m_at)) - .writeAttribute("filename", skipPathFromFilename(rb.m_file)) - .writeAttribute("line", line(rb.m_line)); - - xml.scopedElement("Original").writeText(rb.m_expr); - - if(rb.m_threw) - xml.scopedElement("Exception").writeText(rb.m_exception.c_str()); - - if(rb.m_at & assertType::is_throws_as) - xml.scopedElement("ExpectedException").writeText(rb.m_exception_type); - if(rb.m_at & assertType::is_throws_with) - xml.scopedElement("ExpectedExceptionString").writeText(rb.m_exception_string); - if((rb.m_at & assertType::is_normal) && !rb.m_threw) - xml.scopedElement("Expanded").writeText(rb.m_decomp.c_str()); - - log_contexts(); - - xml.endElement(); - } - - void log_message(const MessageData& mb) override { - std::lock_guard lock(mutex); - - xml.startElement("Message") - .writeAttribute("type", failureString(mb.m_severity)) - .writeAttribute("filename", skipPathFromFilename(mb.m_file)) - .writeAttribute("line", line(mb.m_line)); - - xml.scopedElement("Text").writeText(mb.m_string.c_str()); - - log_contexts(); - - xml.endElement(); - } - - void test_case_skipped(const TestCaseData& in) override { - if(opt.no_skipped_summary == false) { - test_case_start_impl(in); - xml.writeAttribute("skipped", "true"); - xml.endElement(); - } - } - }; - - DOCTEST_REGISTER_REPORTER("xml", 0, XmlReporter); - - void fulltext_log_assert_to_stream(std::ostream& s, const AssertData& rb) { - if((rb.m_at & (assertType::is_throws_as | assertType::is_throws_with)) == - 0) //!OCLINT bitwise operator in conditional - s << Color::Cyan << assertString(rb.m_at) << "( " << rb.m_expr << " ) " - << Color::None; - - if(rb.m_at & assertType::is_throws) { //!OCLINT bitwise operator in conditional - s << (rb.m_threw ? "threw as expected!" : "did NOT throw at all!") << "\n"; - } else if((rb.m_at & assertType::is_throws_as) && - (rb.m_at & assertType::is_throws_with)) { //!OCLINT - s << Color::Cyan << assertString(rb.m_at) << "( " << rb.m_expr << ", \"" - << rb.m_exception_string << "\", " << rb.m_exception_type << " ) " << Color::None; - if(rb.m_threw) { - if(!rb.m_failed) { - s << "threw as expected!\n"; - } else { - s << "threw a DIFFERENT exception! (contents: " << rb.m_exception << ")\n"; - } - } else { - s << "did NOT throw at all!\n"; - } - } else if(rb.m_at & - assertType::is_throws_as) { //!OCLINT bitwise operator in conditional - s << Color::Cyan << assertString(rb.m_at) << "( " << rb.m_expr << ", " - << rb.m_exception_type << " ) " << Color::None - << (rb.m_threw ? (rb.m_threw_as ? "threw as expected!" : - "threw a DIFFERENT exception: ") : - "did NOT throw at all!") - << Color::Cyan << rb.m_exception << "\n"; - } else if(rb.m_at & - assertType::is_throws_with) { //!OCLINT bitwise operator in conditional - s << Color::Cyan << assertString(rb.m_at) << "( " << rb.m_expr << ", \"" - << rb.m_exception_string << "\" ) " << Color::None - << (rb.m_threw ? (!rb.m_failed ? "threw as expected!" : - "threw a DIFFERENT exception: ") : - "did NOT throw at all!") - << Color::Cyan << rb.m_exception << "\n"; - } else if(rb.m_at & assertType::is_nothrow) { //!OCLINT bitwise operator in conditional - s << (rb.m_threw ? "THREW exception: " : "didn't throw!") << Color::Cyan - << rb.m_exception << "\n"; - } else { - s << (rb.m_threw ? "THREW exception: " : - (!rb.m_failed ? "is correct!\n" : "is NOT correct!\n")); - if(rb.m_threw) - s << rb.m_exception << "\n"; - else - s << " values: " << assertString(rb.m_at) << "( " << rb.m_decomp << " )\n"; - } - } - - // TODO: - // - log_message() - // - respond to queries - // - honor remaining options - // - more attributes in tags - struct JUnitReporter : public IReporter - { - XmlWriter xml; - std::mutex mutex; - Timer timer; - std::vector deepestSubcaseStackNames; - - struct JUnitTestCaseData - { - static std::string getCurrentTimestamp() { - // Beware, this is not reentrant because of backward compatibility issues - // Also, UTC only, again because of backward compatibility (%z is C++11) - time_t rawtime; - std::time(&rawtime); - auto const timeStampSize = sizeof("2017-01-16T17:06:45Z"); - - std::tm timeInfo; -#ifdef DOCTEST_PLATFORM_WINDOWS - gmtime_s(&timeInfo, &rawtime); -#else // DOCTEST_PLATFORM_WINDOWS - gmtime_r(&rawtime, &timeInfo); -#endif // DOCTEST_PLATFORM_WINDOWS - - char timeStamp[timeStampSize]; - const char* const fmt = "%Y-%m-%dT%H:%M:%SZ"; - - std::strftime(timeStamp, timeStampSize, fmt, &timeInfo); - return std::string(timeStamp); - } - - struct JUnitTestMessage - { - JUnitTestMessage(const std::string& _message, const std::string& _type, const std::string& _details) - : message(_message), type(_type), details(_details) {} - - JUnitTestMessage(const std::string& _message, const std::string& _details) - : message(_message), type(), details(_details) {} - - std::string message, type, details; - }; - - struct JUnitTestCase - { - JUnitTestCase(const std::string& _classname, const std::string& _name) - : classname(_classname), name(_name), time(0), failures() {} - - std::string classname, name; - double time; - std::vector failures, errors; - }; - - void add(const std::string& classname, const std::string& name) { - testcases.emplace_back(classname, name); - } - - void appendSubcaseNamesToLastTestcase(std::vector nameStack) { - for(auto& curr: nameStack) - if(curr.size()) - testcases.back().name += std::string("/") + curr.c_str(); - } - - void addTime(double time) { - if(time < 1e-4) - time = 0; - testcases.back().time = time; - totalSeconds += time; - } - - void addFailure(const std::string& message, const std::string& type, const std::string& details) { - testcases.back().failures.emplace_back(message, type, details); - ++totalFailures; - } - - void addError(const std::string& message, const std::string& details) { - testcases.back().errors.emplace_back(message, details); - ++totalErrors; - } - - std::vector testcases; - double totalSeconds = 0; - int totalErrors = 0, totalFailures = 0; - }; - - JUnitTestCaseData testCaseData; - - // caching pointers/references to objects of these types - safe to do - const ContextOptions& opt; - const TestCaseData* tc = nullptr; - - JUnitReporter(const ContextOptions& co) - : xml(*co.cout) - , opt(co) {} - - unsigned line(unsigned l) const { return opt.no_line_numbers ? 0 : l; } - - // ========================================================================================= - // WHAT FOLLOWS ARE OVERRIDES OF THE VIRTUAL METHODS OF THE REPORTER INTERFACE - // ========================================================================================= - - void report_query(const QueryData&) override {} - - void test_run_start() override {} - - void test_run_end(const TestRunStats& p) override { - // remove .exe extension - mainly to have the same output on UNIX and Windows - std::string binary_name = skipPathFromFilename(opt.binary_name.c_str()); -#ifdef DOCTEST_PLATFORM_WINDOWS - if(binary_name.rfind(".exe") != std::string::npos) - binary_name = binary_name.substr(0, binary_name.length() - 4); -#endif // DOCTEST_PLATFORM_WINDOWS - xml.startElement("testsuites"); - xml.startElement("testsuite").writeAttribute("name", binary_name) - .writeAttribute("errors", testCaseData.totalErrors) - .writeAttribute("failures", testCaseData.totalFailures) - .writeAttribute("tests", p.numAsserts); - if(opt.no_time_in_output == false) { - xml.writeAttribute("time", testCaseData.totalSeconds); - xml.writeAttribute("timestamp", JUnitTestCaseData::getCurrentTimestamp()); - } - if(opt.no_version == false) - xml.writeAttribute("doctest_version", DOCTEST_VERSION_STR); - - for(const auto& testCase : testCaseData.testcases) { - xml.startElement("testcase") - .writeAttribute("classname", testCase.classname) - .writeAttribute("name", testCase.name); - if(opt.no_time_in_output == false) - xml.writeAttribute("time", testCase.time); - // This is not ideal, but it should be enough to mimic gtest's junit output. - xml.writeAttribute("status", "run"); - - for(const auto& failure : testCase.failures) { - xml.scopedElement("failure") - .writeAttribute("message", failure.message) - .writeAttribute("type", failure.type) - .writeText(failure.details, false); - } - - for(const auto& error : testCase.errors) { - xml.scopedElement("error") - .writeAttribute("message", error.message) - .writeText(error.details); - } - - xml.endElement(); - } - xml.endElement(); - xml.endElement(); - } - - void test_case_start(const TestCaseData& in) override { - testCaseData.add(skipPathFromFilename(in.m_file.c_str()), in.m_name); - timer.start(); - } - - void test_case_reenter(const TestCaseData& in) override { - testCaseData.addTime(timer.getElapsedSeconds()); - testCaseData.appendSubcaseNamesToLastTestcase(deepestSubcaseStackNames); - deepestSubcaseStackNames.clear(); - - timer.start(); - testCaseData.add(skipPathFromFilename(in.m_file.c_str()), in.m_name); - } - - void test_case_end(const CurrentTestCaseStats&) override { - testCaseData.addTime(timer.getElapsedSeconds()); - testCaseData.appendSubcaseNamesToLastTestcase(deepestSubcaseStackNames); - deepestSubcaseStackNames.clear(); - } - - void test_case_exception(const TestCaseException& e) override { - std::lock_guard lock(mutex); - testCaseData.addError("exception", e.error_string.c_str()); - } - - void subcase_start(const SubcaseSignature& in) override { - std::lock_guard lock(mutex); - deepestSubcaseStackNames.push_back(in.m_name); - } - - void subcase_end() override {} - - void log_assert(const AssertData& rb) override { - if(!rb.m_failed) // report only failures & ignore the `success` option - return; - - std::lock_guard lock(mutex); - - std::ostringstream os; - os << skipPathFromFilename(rb.m_file) << (opt.gnu_file_line ? ":" : "(") - << line(rb.m_line) << (opt.gnu_file_line ? ":" : "):") << std::endl; - - fulltext_log_assert_to_stream(os, rb); - log_contexts(os); - testCaseData.addFailure(rb.m_decomp.c_str(), assertString(rb.m_at), os.str()); - } - - void log_message(const MessageData&) override {} - - void test_case_skipped(const TestCaseData&) override {} - - void log_contexts(std::ostringstream& s) { - int num_contexts = get_num_active_contexts(); - if(num_contexts) { - auto contexts = get_active_contexts(); - - s << " logged: "; - for(int i = 0; i < num_contexts; ++i) { - s << (i == 0 ? "" : " "); - contexts[i]->stringify(&s); - s << std::endl; - } - } - } - }; - - DOCTEST_REGISTER_REPORTER("junit", 0, JUnitReporter); - - struct Whitespace - { - int nrSpaces; - explicit Whitespace(int nr) - : nrSpaces(nr) {} - }; - - std::ostream& operator<<(std::ostream& out, const Whitespace& ws) { - if(ws.nrSpaces != 0) - out << std::setw(ws.nrSpaces) << ' '; - return out; - } - - struct ConsoleReporter : public IReporter - { - std::ostream& s; - bool hasLoggedCurrentTestStart; - std::vector subcasesStack; - size_t currentSubcaseLevel; - std::mutex mutex; - - // caching pointers/references to objects of these types - safe to do - const ContextOptions& opt; - const TestCaseData* tc; - - ConsoleReporter(const ContextOptions& co) - : s(*co.cout) - , opt(co) {} - - ConsoleReporter(const ContextOptions& co, std::ostream& ostr) - : s(ostr) - , opt(co) {} - - // ========================================================================================= - // WHAT FOLLOWS ARE HELPERS USED BY THE OVERRIDES OF THE VIRTUAL METHODS OF THE INTERFACE - // ========================================================================================= - - void separator_to_stream() { - s << Color::Yellow - << "===============================================================================" - "\n"; - } - - const char* getSuccessOrFailString(bool success, assertType::Enum at, - const char* success_str) { - if(success) - return success_str; - return failureString(at); - } - - Color::Enum getSuccessOrFailColor(bool success, assertType::Enum at) { - return success ? Color::BrightGreen : - (at & assertType::is_warn) ? Color::Yellow : Color::Red; - } - - void successOrFailColoredStringToStream(bool success, assertType::Enum at, - const char* success_str = "SUCCESS") { - s << getSuccessOrFailColor(success, at) - << getSuccessOrFailString(success, at, success_str) << ": "; - } - - void log_contexts() { - int num_contexts = get_num_active_contexts(); - if(num_contexts) { - auto contexts = get_active_contexts(); - - s << Color::None << " logged: "; - for(int i = 0; i < num_contexts; ++i) { - s << (i == 0 ? "" : " "); - contexts[i]->stringify(&s); - s << "\n"; - } - } - - s << "\n"; - } - - // this was requested to be made virtual so users could override it - virtual void file_line_to_stream(const char* file, int line, - const char* tail = "") { - s << Color::LightGrey << skipPathFromFilename(file) << (opt.gnu_file_line ? ":" : "(") - << (opt.no_line_numbers ? 0 : line) // 0 or the real num depending on the option - << (opt.gnu_file_line ? ":" : "):") << tail; - } - - void logTestStart() { - if(hasLoggedCurrentTestStart) - return; - - separator_to_stream(); - file_line_to_stream(tc->m_file.c_str(), tc->m_line, "\n"); - if(tc->m_description) - s << Color::Yellow << "DESCRIPTION: " << Color::None << tc->m_description << "\n"; - if(tc->m_test_suite && tc->m_test_suite[0] != '\0') - s << Color::Yellow << "TEST SUITE: " << Color::None << tc->m_test_suite << "\n"; - if(strncmp(tc->m_name, " Scenario:", 11) != 0) - s << Color::Yellow << "TEST CASE: "; - s << Color::None << tc->m_name << "\n"; - - for(size_t i = 0; i < currentSubcaseLevel; ++i) { - if(subcasesStack[i].m_name[0] != '\0') - s << " " << subcasesStack[i].m_name << "\n"; - } - - if(currentSubcaseLevel != subcasesStack.size()) { - s << Color::Yellow << "\nDEEPEST SUBCASE STACK REACHED (DIFFERENT FROM THE CURRENT ONE):\n" << Color::None; - for(size_t i = 0; i < subcasesStack.size(); ++i) { - if(subcasesStack[i].m_name[0] != '\0') - s << " " << subcasesStack[i].m_name << "\n"; - } - } - - s << "\n"; - - hasLoggedCurrentTestStart = true; - } - - void printVersion() { - if(opt.no_version == false) - s << Color::Cyan << "[doctest] " << Color::None << "doctest version is \"" - << DOCTEST_VERSION_STR << "\"\n"; - } - - void printIntro() { - printVersion(); - s << Color::Cyan << "[doctest] " << Color::None - << "run with \"--" DOCTEST_OPTIONS_PREFIX_DISPLAY "help\" for options\n"; - } - - void printHelp() { - int sizePrefixDisplay = static_cast(strlen(DOCTEST_OPTIONS_PREFIX_DISPLAY)); - printVersion(); - // clang-format off - s << Color::Cyan << "[doctest]\n" << Color::None; - s << Color::Cyan << "[doctest] " << Color::None; - s << "boolean values: \"1/on/yes/true\" or \"0/off/no/false\"\n"; - s << Color::Cyan << "[doctest] " << Color::None; - s << "filter values: \"str1,str2,str3\" (comma separated strings)\n"; - s << Color::Cyan << "[doctest]\n" << Color::None; - s << Color::Cyan << "[doctest] " << Color::None; - s << "filters use wildcards for matching strings\n"; - s << Color::Cyan << "[doctest] " << Color::None; - s << "something passes a filter if any of the strings in a filter matches\n"; -#ifndef DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS - s << Color::Cyan << "[doctest]\n" << Color::None; - s << Color::Cyan << "[doctest] " << Color::None; - s << "ALL FLAGS, OPTIONS AND FILTERS ALSO AVAILABLE WITH A \"" DOCTEST_CONFIG_OPTIONS_PREFIX "\" PREFIX!!!\n"; -#endif - s << Color::Cyan << "[doctest]\n" << Color::None; - s << Color::Cyan << "[doctest] " << Color::None; - s << "Query flags - the program quits after them. Available:\n\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "?, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "help, -" DOCTEST_OPTIONS_PREFIX_DISPLAY "h " - << Whitespace(sizePrefixDisplay*0) << "prints this message\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "v, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "version " - << Whitespace(sizePrefixDisplay*1) << "prints the version\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "c, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "count " - << Whitespace(sizePrefixDisplay*1) << "prints the number of matching tests\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "ltc, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "list-test-cases " - << Whitespace(sizePrefixDisplay*1) << "lists all matching tests by name\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "lts, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "list-test-suites " - << Whitespace(sizePrefixDisplay*1) << "lists all matching test suites\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "lr, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "list-reporters " - << Whitespace(sizePrefixDisplay*1) << "lists all registered reporters\n\n"; - // ================================================================================== << 79 - s << Color::Cyan << "[doctest] " << Color::None; - s << "The available / options/filters are:\n\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "tc, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "test-case= " - << Whitespace(sizePrefixDisplay*1) << "filters tests by their name\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "tce, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "test-case-exclude= " - << Whitespace(sizePrefixDisplay*1) << "filters OUT tests by their name\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "sf, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "source-file= " - << Whitespace(sizePrefixDisplay*1) << "filters tests by their file\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "sfe, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "source-file-exclude= " - << Whitespace(sizePrefixDisplay*1) << "filters OUT tests by their file\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "ts, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "test-suite= " - << Whitespace(sizePrefixDisplay*1) << "filters tests by their test suite\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "tse, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "test-suite-exclude= " - << Whitespace(sizePrefixDisplay*1) << "filters OUT tests by their test suite\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "sc, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "subcase= " - << Whitespace(sizePrefixDisplay*1) << "filters subcases by their name\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "sce, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "subcase-exclude= " - << Whitespace(sizePrefixDisplay*1) << "filters OUT subcases by their name\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "r, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "reporters= " - << Whitespace(sizePrefixDisplay*1) << "reporters to use (console is default)\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "o, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "out= " - << Whitespace(sizePrefixDisplay*1) << "output filename\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "ob, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "order-by= " - << Whitespace(sizePrefixDisplay*1) << "how the tests should be ordered\n"; - s << Whitespace(sizePrefixDisplay*3) << " - [file/suite/name/rand/none]\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "rs, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "rand-seed= " - << Whitespace(sizePrefixDisplay*1) << "seed for random ordering\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "f, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "first= " - << Whitespace(sizePrefixDisplay*1) << "the first test passing the filters to\n"; - s << Whitespace(sizePrefixDisplay*3) << " execute - for range-based execution\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "l, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "last= " - << Whitespace(sizePrefixDisplay*1) << "the last test passing the filters to\n"; - s << Whitespace(sizePrefixDisplay*3) << " execute - for range-based execution\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "aa, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "abort-after= " - << Whitespace(sizePrefixDisplay*1) << "stop after failed assertions\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "scfl,--" DOCTEST_OPTIONS_PREFIX_DISPLAY "subcase-filter-levels= " - << Whitespace(sizePrefixDisplay*1) << "apply filters for the first levels\n"; - s << Color::Cyan << "\n[doctest] " << Color::None; - s << "Bool options - can be used like flags and true is assumed. Available:\n\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "s, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "success= " - << Whitespace(sizePrefixDisplay*1) << "include successful assertions in output\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "cs, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "case-sensitive= " - << Whitespace(sizePrefixDisplay*1) << "filters being treated as case sensitive\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "e, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "exit= " - << Whitespace(sizePrefixDisplay*1) << "exits after the tests finish\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "d, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "duration= " - << Whitespace(sizePrefixDisplay*1) << "prints the time duration of each test\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "nt, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-throw= " - << Whitespace(sizePrefixDisplay*1) << "skips exceptions-related assert checks\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "ne, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-exitcode= " - << Whitespace(sizePrefixDisplay*1) << "returns (or exits) always with success\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "nr, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-run= " - << Whitespace(sizePrefixDisplay*1) << "skips all runtime doctest operations\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "nv, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-version= " - << Whitespace(sizePrefixDisplay*1) << "omit the framework version in the output\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "nc, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-colors= " - << Whitespace(sizePrefixDisplay*1) << "disables colors in output\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "fc, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "force-colors= " - << Whitespace(sizePrefixDisplay*1) << "use colors even when not in a tty\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "nb, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-breaks= " - << Whitespace(sizePrefixDisplay*1) << "disables breakpoints in debuggers\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "ns, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-skip= " - << Whitespace(sizePrefixDisplay*1) << "don't skip test cases marked as skip\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "gfl, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "gnu-file-line= " - << Whitespace(sizePrefixDisplay*1) << ":n: vs (n): for line numbers in output\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "npf, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-path-filenames= " - << Whitespace(sizePrefixDisplay*1) << "only filenames and no paths in output\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "nln, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-line-numbers= " - << Whitespace(sizePrefixDisplay*1) << "0 instead of real line numbers in output\n"; - // ================================================================================== << 79 - // clang-format on - - s << Color::Cyan << "\n[doctest] " << Color::None; - s << "for more information visit the project documentation\n\n"; - } - - void printRegisteredReporters() { - printVersion(); - auto printReporters = [this] (const reporterMap& reporters, const char* type) { - if(reporters.size()) { - s << Color::Cyan << "[doctest] " << Color::None << "listing all registered " << type << "\n"; - for(auto& curr : reporters) - s << "priority: " << std::setw(5) << curr.first.first - << " name: " << curr.first.second << "\n"; - } - }; - printReporters(getListeners(), "listeners"); - printReporters(getReporters(), "reporters"); - } - - void list_query_results() { - separator_to_stream(); - if(opt.count || opt.list_test_cases) { - s << Color::Cyan << "[doctest] " << Color::None - << "unskipped test cases passing the current filters: " - << g_cs->numTestCasesPassingFilters << "\n"; - } else if(opt.list_test_suites) { - s << Color::Cyan << "[doctest] " << Color::None - << "unskipped test cases passing the current filters: " - << g_cs->numTestCasesPassingFilters << "\n"; - s << Color::Cyan << "[doctest] " << Color::None - << "test suites with unskipped test cases passing the current filters: " - << g_cs->numTestSuitesPassingFilters << "\n"; - } - } - - // ========================================================================================= - // WHAT FOLLOWS ARE OVERRIDES OF THE VIRTUAL METHODS OF THE REPORTER INTERFACE - // ========================================================================================= - - void report_query(const QueryData& in) override { - if(opt.version) { - printVersion(); - } else if(opt.help) { - printHelp(); - } else if(opt.list_reporters) { - printRegisteredReporters(); - } else if(opt.count || opt.list_test_cases) { - if(opt.list_test_cases) { - s << Color::Cyan << "[doctest] " << Color::None - << "listing all test case names\n"; - separator_to_stream(); - } - - for(unsigned i = 0; i < in.num_data; ++i) - s << Color::None << in.data[i]->m_name << "\n"; - - separator_to_stream(); - - s << Color::Cyan << "[doctest] " << Color::None - << "unskipped test cases passing the current filters: " - << g_cs->numTestCasesPassingFilters << "\n"; - - } else if(opt.list_test_suites) { - s << Color::Cyan << "[doctest] " << Color::None << "listing all test suites\n"; - separator_to_stream(); - - for(unsigned i = 0; i < in.num_data; ++i) - s << Color::None << in.data[i]->m_test_suite << "\n"; - - separator_to_stream(); - - s << Color::Cyan << "[doctest] " << Color::None - << "unskipped test cases passing the current filters: " - << g_cs->numTestCasesPassingFilters << "\n"; - s << Color::Cyan << "[doctest] " << Color::None - << "test suites with unskipped test cases passing the current filters: " - << g_cs->numTestSuitesPassingFilters << "\n"; - } - } - - void test_run_start() override { printIntro(); } - - void test_run_end(const TestRunStats& p) override { - separator_to_stream(); - s << std::dec; - - auto totwidth = int(std::ceil(log10((std::max(p.numTestCasesPassingFilters, static_cast(p.numAsserts))) + 1))); - auto passwidth = int(std::ceil(log10((std::max(p.numTestCasesPassingFilters - p.numTestCasesFailed, static_cast(p.numAsserts - p.numAssertsFailed))) + 1))); - auto failwidth = int(std::ceil(log10((std::max(p.numTestCasesFailed, static_cast(p.numAssertsFailed))) + 1))); - const bool anythingFailed = p.numTestCasesFailed > 0 || p.numAssertsFailed > 0; - s << Color::Cyan << "[doctest] " << Color::None << "test cases: " << std::setw(totwidth) - << p.numTestCasesPassingFilters << " | " - << ((p.numTestCasesPassingFilters == 0 || anythingFailed) ? Color::None : - Color::Green) - << std::setw(passwidth) << p.numTestCasesPassingFilters - p.numTestCasesFailed << " passed" - << Color::None << " | " << (p.numTestCasesFailed > 0 ? Color::Red : Color::None) - << std::setw(failwidth) << p.numTestCasesFailed << " failed" << Color::None << " |"; - if(opt.no_skipped_summary == false) { - const int numSkipped = p.numTestCases - p.numTestCasesPassingFilters; - s << " " << (numSkipped == 0 ? Color::None : Color::Yellow) << numSkipped - << " skipped" << Color::None; - } - s << "\n"; - s << Color::Cyan << "[doctest] " << Color::None << "assertions: " << std::setw(totwidth) - << p.numAsserts << " | " - << ((p.numAsserts == 0 || anythingFailed) ? Color::None : Color::Green) - << std::setw(passwidth) << (p.numAsserts - p.numAssertsFailed) << " passed" << Color::None - << " | " << (p.numAssertsFailed > 0 ? Color::Red : Color::None) << std::setw(failwidth) - << p.numAssertsFailed << " failed" << Color::None << " |\n"; - s << Color::Cyan << "[doctest] " << Color::None - << "Status: " << (p.numTestCasesFailed > 0 ? Color::Red : Color::Green) - << ((p.numTestCasesFailed > 0) ? "FAILURE!" : "SUCCESS!") << Color::None << std::endl; - } - - void test_case_start(const TestCaseData& in) override { - hasLoggedCurrentTestStart = false; - tc = ∈ - subcasesStack.clear(); - currentSubcaseLevel = 0; - } - - void test_case_reenter(const TestCaseData&) override { - subcasesStack.clear(); - } - - void test_case_end(const CurrentTestCaseStats& st) override { - if(tc->m_no_output) - return; - - // log the preamble of the test case only if there is something - // else to print - something other than that an assert has failed - if(opt.duration || - (st.failure_flags && st.failure_flags != TestCaseFailureReason::AssertFailure)) - logTestStart(); - - if(opt.duration) - s << Color::None << std::setprecision(6) << std::fixed << st.seconds - << " s: " << tc->m_name << "\n"; - - if(st.failure_flags & TestCaseFailureReason::Timeout) - s << Color::Red << "Test case exceeded time limit of " << std::setprecision(6) - << std::fixed << tc->m_timeout << "!\n"; - - if(st.failure_flags & TestCaseFailureReason::ShouldHaveFailedButDidnt) { - s << Color::Red << "Should have failed but didn't! Marking it as failed!\n"; - } else if(st.failure_flags & TestCaseFailureReason::ShouldHaveFailedAndDid) { - s << Color::Yellow << "Failed as expected so marking it as not failed\n"; - } else if(st.failure_flags & TestCaseFailureReason::CouldHaveFailedAndDid) { - s << Color::Yellow << "Allowed to fail so marking it as not failed\n"; - } else if(st.failure_flags & TestCaseFailureReason::DidntFailExactlyNumTimes) { - s << Color::Red << "Didn't fail exactly " << tc->m_expected_failures - << " times so marking it as failed!\n"; - } else if(st.failure_flags & TestCaseFailureReason::FailedExactlyNumTimes) { - s << Color::Yellow << "Failed exactly " << tc->m_expected_failures - << " times as expected so marking it as not failed!\n"; - } - if(st.failure_flags & TestCaseFailureReason::TooManyFailedAsserts) { - s << Color::Red << "Aborting - too many failed asserts!\n"; - } - s << Color::None; // lgtm [cpp/useless-expression] - } - - void test_case_exception(const TestCaseException& e) override { - if(tc->m_no_output) - return; - - logTestStart(); - - file_line_to_stream(tc->m_file.c_str(), tc->m_line, " "); - successOrFailColoredStringToStream(false, e.is_crash ? assertType::is_require : - assertType::is_check); - s << Color::Red << (e.is_crash ? "test case CRASHED: " : "test case THREW exception: ") - << Color::Cyan << e.error_string << "\n"; - - int num_stringified_contexts = get_num_stringified_contexts(); - if(num_stringified_contexts) { - auto stringified_contexts = get_stringified_contexts(); - s << Color::None << " logged: "; - for(int i = num_stringified_contexts; i > 0; --i) { - s << (i == num_stringified_contexts ? "" : " ") - << stringified_contexts[i - 1] << "\n"; - } - } - s << "\n" << Color::None; - } - - void subcase_start(const SubcaseSignature& subc) override { - std::lock_guard lock(mutex); - subcasesStack.push_back(subc); - ++currentSubcaseLevel; - hasLoggedCurrentTestStart = false; - } - - void subcase_end() override { - std::lock_guard lock(mutex); - --currentSubcaseLevel; - hasLoggedCurrentTestStart = false; - } - - void log_assert(const AssertData& rb) override { - if((!rb.m_failed && !opt.success) || tc->m_no_output) - return; - - std::lock_guard lock(mutex); - - logTestStart(); - - file_line_to_stream(rb.m_file, rb.m_line, " "); - successOrFailColoredStringToStream(!rb.m_failed, rb.m_at); - - fulltext_log_assert_to_stream(s, rb); - - log_contexts(); - } - - void log_message(const MessageData& mb) override { - if(tc->m_no_output) - return; - - std::lock_guard lock(mutex); - - logTestStart(); - - file_line_to_stream(mb.m_file, mb.m_line, " "); - s << getSuccessOrFailColor(false, mb.m_severity) - << getSuccessOrFailString(mb.m_severity & assertType::is_warn, mb.m_severity, - "MESSAGE") << ": "; - s << Color::None << mb.m_string << "\n"; - log_contexts(); - } - - void test_case_skipped(const TestCaseData&) override {} - }; - - DOCTEST_REGISTER_REPORTER("console", 0, ConsoleReporter); - -#ifdef DOCTEST_PLATFORM_WINDOWS - struct DebugOutputWindowReporter : public ConsoleReporter - { - DOCTEST_THREAD_LOCAL static std::ostringstream oss; - - DebugOutputWindowReporter(const ContextOptions& co) - : ConsoleReporter(co, oss) {} - -#define DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(func, type, arg) \ - void func(type arg) override { \ - bool with_col = g_no_colors; \ - g_no_colors = false; \ - ConsoleReporter::func(arg); \ - if(oss.tellp() != std::streampos{}) { \ - DOCTEST_OUTPUT_DEBUG_STRING(oss.str().c_str()); \ - oss.str(""); \ - } \ - g_no_colors = with_col; \ - } - - DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_run_start, DOCTEST_EMPTY, DOCTEST_EMPTY) - DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_run_end, const TestRunStats&, in) - DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_case_start, const TestCaseData&, in) - DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_case_reenter, const TestCaseData&, in) - DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_case_end, const CurrentTestCaseStats&, in) - DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_case_exception, const TestCaseException&, in) - DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(subcase_start, const SubcaseSignature&, in) - DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(subcase_end, DOCTEST_EMPTY, DOCTEST_EMPTY) - DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(log_assert, const AssertData&, in) - DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(log_message, const MessageData&, in) - DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_case_skipped, const TestCaseData&, in) - }; - - DOCTEST_THREAD_LOCAL std::ostringstream DebugOutputWindowReporter::oss; -#endif // DOCTEST_PLATFORM_WINDOWS - - // the implementation of parseOption() - bool parseOptionImpl(int argc, const char* const* argv, const char* pattern, String* value) { - // going from the end to the beginning and stopping on the first occurrence from the end - for(int i = argc; i > 0; --i) { - auto index = i - 1; - auto temp = std::strstr(argv[index], pattern); - if(temp && (value || strlen(temp) == strlen(pattern))) { //!OCLINT prefer early exits and continue - // eliminate matches in which the chars before the option are not '-' - bool noBadCharsFound = true; - auto curr = argv[index]; - while(curr != temp) { - if(*curr++ != '-') { - noBadCharsFound = false; - break; - } - } - if(noBadCharsFound && argv[index][0] == '-') { - if(value) { - // parsing the value of an option - temp += strlen(pattern); - const unsigned len = strlen(temp); - if(len) { - *value = temp; - return true; - } - } else { - // just a flag - no value - return true; - } - } - } - } - return false; - } - - // parses an option and returns the string after the '=' character - bool parseOption(int argc, const char* const* argv, const char* pattern, String* value = nullptr, - const String& defaultVal = String()) { - if(value) - *value = defaultVal; -#ifndef DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS - // offset (normally 3 for "dt-") to skip prefix - if(parseOptionImpl(argc, argv, pattern + strlen(DOCTEST_CONFIG_OPTIONS_PREFIX), value)) - return true; -#endif // DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS - return parseOptionImpl(argc, argv, pattern, value); - } - - // locates a flag on the command line - bool parseFlag(int argc, const char* const* argv, const char* pattern) { - return parseOption(argc, argv, pattern); - } - - // parses a comma separated list of words after a pattern in one of the arguments in argv - bool parseCommaSepArgs(int argc, const char* const* argv, const char* pattern, - std::vector& res) { - String filtersString; - if(parseOption(argc, argv, pattern, &filtersString)) { - // tokenize with "," as a separator - // cppcheck-suppress strtokCalled - DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations") - auto pch = std::strtok(filtersString.c_str(), ","); // modifies the string - while(pch != nullptr) { - if(strlen(pch)) - res.push_back(pch); - // uses the strtok() internal state to go to the next token - // cppcheck-suppress strtokCalled - pch = std::strtok(nullptr, ","); - } - DOCTEST_CLANG_SUPPRESS_WARNING_POP - return true; - } - return false; - } - - enum optionType - { - option_bool, - option_int - }; - - // parses an int/bool option from the command line - bool parseIntOption(int argc, const char* const* argv, const char* pattern, optionType type, - int& res) { - String parsedValue; - if(!parseOption(argc, argv, pattern, &parsedValue)) - return false; - - if(type == 0) { - // boolean - const char positive[][5] = {"1", "true", "on", "yes"}; // 5 - strlen("true") + 1 - const char negative[][6] = {"0", "false", "off", "no"}; // 6 - strlen("false") + 1 - - // if the value matches any of the positive/negative possibilities - for(unsigned i = 0; i < 4; i++) { - if(parsedValue.compare(positive[i], true) == 0) { - res = 1; //!OCLINT parameter reassignment - return true; - } - if(parsedValue.compare(negative[i], true) == 0) { - res = 0; //!OCLINT parameter reassignment - return true; - } - } - } else { - // integer - // TODO: change this to use std::stoi or something else! currently it uses undefined behavior - assumes '0' on failed parse... - int theInt = std::atoi(parsedValue.c_str()); // NOLINT - if(theInt != 0) { - res = theInt; //!OCLINT parameter reassignment - return true; - } - } - return false; - } -} // namespace - -Context::Context(int argc, const char* const* argv) - : p(new detail::ContextState) { - parseArgs(argc, argv, true); - if(argc) - p->binary_name = argv[0]; -} - -Context::~Context() { - if(g_cs == p) - g_cs = nullptr; - delete p; -} - -void Context::applyCommandLine(int argc, const char* const* argv) { - parseArgs(argc, argv); - if(argc) - p->binary_name = argv[0]; -} - -// parses args -void Context::parseArgs(int argc, const char* const* argv, bool withDefaults) { - using namespace detail; - - // clang-format off - parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "source-file=", p->filters[0]); - parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "sf=", p->filters[0]); - parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "source-file-exclude=",p->filters[1]); - parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "sfe=", p->filters[1]); - parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "test-suite=", p->filters[2]); - parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "ts=", p->filters[2]); - parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "test-suite-exclude=", p->filters[3]); - parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "tse=", p->filters[3]); - parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "test-case=", p->filters[4]); - parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "tc=", p->filters[4]); - parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "test-case-exclude=", p->filters[5]); - parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "tce=", p->filters[5]); - parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "subcase=", p->filters[6]); - parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "sc=", p->filters[6]); - parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "subcase-exclude=", p->filters[7]); - parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "sce=", p->filters[7]); - parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "reporters=", p->filters[8]); - parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "r=", p->filters[8]); - // clang-format on - - int intRes = 0; - String strRes; - -#define DOCTEST_PARSE_AS_BOOL_OR_FLAG(name, sname, var, default) \ - if(parseIntOption(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX name "=", option_bool, intRes) || \ - parseIntOption(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX sname "=", option_bool, intRes)) \ - p->var = static_cast(intRes); \ - else if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX name) || \ - parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX sname)) \ - p->var = true; \ - else if(withDefaults) \ - p->var = default - -#define DOCTEST_PARSE_INT_OPTION(name, sname, var, default) \ - if(parseIntOption(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX name "=", option_int, intRes) || \ - parseIntOption(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX sname "=", option_int, intRes)) \ - p->var = intRes; \ - else if(withDefaults) \ - p->var = default - -#define DOCTEST_PARSE_STR_OPTION(name, sname, var, default) \ - if(parseOption(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX name "=", &strRes, default) || \ - parseOption(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX sname "=", &strRes, default) || \ - withDefaults) \ - p->var = strRes - - // clang-format off - DOCTEST_PARSE_STR_OPTION("out", "o", out, ""); - DOCTEST_PARSE_STR_OPTION("order-by", "ob", order_by, "file"); - DOCTEST_PARSE_INT_OPTION("rand-seed", "rs", rand_seed, 0); - - DOCTEST_PARSE_INT_OPTION("first", "f", first, 0); - DOCTEST_PARSE_INT_OPTION("last", "l", last, UINT_MAX); - - DOCTEST_PARSE_INT_OPTION("abort-after", "aa", abort_after, 0); - DOCTEST_PARSE_INT_OPTION("subcase-filter-levels", "scfl", subcase_filter_levels, INT_MAX); - - DOCTEST_PARSE_AS_BOOL_OR_FLAG("success", "s", success, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG("case-sensitive", "cs", case_sensitive, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG("exit", "e", exit, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG("duration", "d", duration, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-throw", "nt", no_throw, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-exitcode", "ne", no_exitcode, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-run", "nr", no_run, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-version", "nv", no_version, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-colors", "nc", no_colors, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG("force-colors", "fc", force_colors, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-breaks", "nb", no_breaks, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-skip", "ns", no_skip, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG("gnu-file-line", "gfl", gnu_file_line, !bool(DOCTEST_MSVC)); - DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-path-filenames", "npf", no_path_in_filenames, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-line-numbers", "nln", no_line_numbers, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-debug-output", "ndo", no_debug_output, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-skipped-summary", "nss", no_skipped_summary, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-time-in-output", "ntio", no_time_in_output, false); - // clang-format on - - if(withDefaults) { - p->help = false; - p->version = false; - p->count = false; - p->list_test_cases = false; - p->list_test_suites = false; - p->list_reporters = false; - } - if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "help") || - parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "h") || - parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "?")) { - p->help = true; - p->exit = true; - } - if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "version") || - parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "v")) { - p->version = true; - p->exit = true; - } - if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "count") || - parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "c")) { - p->count = true; - p->exit = true; - } - if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "list-test-cases") || - parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "ltc")) { - p->list_test_cases = true; - p->exit = true; - } - if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "list-test-suites") || - parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "lts")) { - p->list_test_suites = true; - p->exit = true; - } - if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "list-reporters") || - parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "lr")) { - p->list_reporters = true; - p->exit = true; - } -} - -// allows the user to add procedurally to the filters from the command line -void Context::addFilter(const char* filter, const char* value) { setOption(filter, value); } - -// allows the user to clear all filters from the command line -void Context::clearFilters() { - for(auto& curr : p->filters) - curr.clear(); -} - -// allows the user to override procedurally the int/bool options from the command line -void Context::setOption(const char* option, int value) { - setOption(option, toString(value).c_str()); - // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) -} - -// allows the user to override procedurally the string options from the command line -void Context::setOption(const char* option, const char* value) { - auto argv = String("-") + option + "=" + value; - auto lvalue = argv.c_str(); - parseArgs(1, &lvalue); -} - -// users should query this in their main() and exit the program if true -bool Context::shouldExit() { return p->exit; } - -void Context::setAsDefaultForAssertsOutOfTestCases() { g_cs = p; } - -void Context::setAssertHandler(detail::assert_handler ah) { p->ah = ah; } - -// the main function that does all the filtering and test running -int Context::run() { - using namespace detail; - - // save the old context state in case such was setup - for using asserts out of a testing context - auto old_cs = g_cs; - // this is the current contest - g_cs = p; - is_running_in_test = true; - - g_no_colors = p->no_colors; - p->resetRunData(); - - // stdout by default - p->cout = &std::cout; - p->cerr = &std::cerr; - - // or to a file if specified - std::fstream fstr; - if(p->out.size()) { - fstr.open(p->out.c_str(), std::fstream::out); - p->cout = &fstr; - } - - FatalConditionHandler::allocateAltStackMem(); - - auto cleanup_and_return = [&]() { - FatalConditionHandler::freeAltStackMem(); - - if(fstr.is_open()) - fstr.close(); - - // restore context - g_cs = old_cs; - is_running_in_test = false; - - // we have to free the reporters which were allocated when the run started - for(auto& curr : p->reporters_currently_used) - delete curr; - p->reporters_currently_used.clear(); - - if(p->numTestCasesFailed && !p->no_exitcode) - return EXIT_FAILURE; - return EXIT_SUCCESS; - }; - - // setup default reporter if none is given through the command line - if(p->filters[8].empty()) - p->filters[8].push_back("console"); - - // check to see if any of the registered reporters has been selected - for(auto& curr : getReporters()) { - if(matchesAny(curr.first.second.c_str(), p->filters[8], false, p->case_sensitive)) - p->reporters_currently_used.push_back(curr.second(*g_cs)); - } - - // TODO: check if there is nothing in reporters_currently_used - - // prepend all listeners - for(auto& curr : getListeners()) - p->reporters_currently_used.insert(p->reporters_currently_used.begin(), curr.second(*g_cs)); - -#ifdef DOCTEST_PLATFORM_WINDOWS - if(isDebuggerActive() && p->no_debug_output == false) - p->reporters_currently_used.push_back(new DebugOutputWindowReporter(*g_cs)); -#endif // DOCTEST_PLATFORM_WINDOWS - - // handle version, help and no_run - if(p->no_run || p->version || p->help || p->list_reporters) { - DOCTEST_ITERATE_THROUGH_REPORTERS(report_query, QueryData()); - - return cleanup_and_return(); - } - - std::vector testArray; - for(auto& curr : getRegisteredTests()) - testArray.push_back(&curr); - p->numTestCases = testArray.size(); - - // sort the collected records - if(!testArray.empty()) { - if(p->order_by.compare("file", true) == 0) { - std::sort(testArray.begin(), testArray.end(), fileOrderComparator); - } else if(p->order_by.compare("suite", true) == 0) { - std::sort(testArray.begin(), testArray.end(), suiteOrderComparator); - } else if(p->order_by.compare("name", true) == 0) { - std::sort(testArray.begin(), testArray.end(), nameOrderComparator); - } else if(p->order_by.compare("rand", true) == 0) { - std::srand(p->rand_seed); - - // random_shuffle implementation - const auto first = &testArray[0]; - for(size_t i = testArray.size() - 1; i > 0; --i) { - int idxToSwap = std::rand() % (i + 1); // NOLINT - - const auto temp = first[i]; - - first[i] = first[idxToSwap]; - first[idxToSwap] = temp; - } - } else if(p->order_by.compare("none", true) == 0) { - // means no sorting - beneficial for death tests which call into the executable - // with a specific test case in mind - we don't want to slow down the startup times - } - } - - std::set testSuitesPassingFilt; - - bool query_mode = p->count || p->list_test_cases || p->list_test_suites; - std::vector queryResults; - - if(!query_mode) - DOCTEST_ITERATE_THROUGH_REPORTERS(test_run_start, DOCTEST_EMPTY); - - // invoke the registered functions if they match the filter criteria (or just count them) - for(auto& curr : testArray) { - const auto& tc = *curr; - - bool skip_me = false; - if(tc.m_skip && !p->no_skip) - skip_me = true; - - if(!matchesAny(tc.m_file.c_str(), p->filters[0], true, p->case_sensitive)) - skip_me = true; - if(matchesAny(tc.m_file.c_str(), p->filters[1], false, p->case_sensitive)) - skip_me = true; - if(!matchesAny(tc.m_test_suite, p->filters[2], true, p->case_sensitive)) - skip_me = true; - if(matchesAny(tc.m_test_suite, p->filters[3], false, p->case_sensitive)) - skip_me = true; - if(!matchesAny(tc.m_name, p->filters[4], true, p->case_sensitive)) - skip_me = true; - if(matchesAny(tc.m_name, p->filters[5], false, p->case_sensitive)) - skip_me = true; - - if(!skip_me) - p->numTestCasesPassingFilters++; - - // skip the test if it is not in the execution range - if((p->last < p->numTestCasesPassingFilters && p->first <= p->last) || - (p->first > p->numTestCasesPassingFilters)) - skip_me = true; - - if(skip_me) { - if(!query_mode) - DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_skipped, tc); - continue; - } - - // do not execute the test if we are to only count the number of filter passing tests - if(p->count) - continue; - - // print the name of the test and don't execute it - if(p->list_test_cases) { - queryResults.push_back(&tc); - continue; - } - - // print the name of the test suite if not done already and don't execute it - if(p->list_test_suites) { - if((testSuitesPassingFilt.count(tc.m_test_suite) == 0) && tc.m_test_suite[0] != '\0') { - queryResults.push_back(&tc); - testSuitesPassingFilt.insert(tc.m_test_suite); - p->numTestSuitesPassingFilters++; - } - continue; - } - - // execute the test if it passes all the filtering - { - p->currentTest = &tc; - - p->failure_flags = TestCaseFailureReason::None; - p->seconds = 0; - - // reset atomic counters - p->numAssertsFailedCurrentTest_atomic = 0; - p->numAssertsCurrentTest_atomic = 0; - - p->subcasesPassed.clear(); - - DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_start, tc); - - p->timer.start(); - - bool run_test = true; - - do { - // reset some of the fields for subcases (except for the set of fully passed ones) - p->should_reenter = false; - p->subcasesCurrentMaxLevel = 0; - p->subcasesStack.clear(); - - p->shouldLogCurrentException = true; - - // reset stuff for logging with INFO() - p->stringifiedContexts.clear(); - -#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS - try { -#endif // DOCTEST_CONFIG_NO_EXCEPTIONS -// MSVC 2015 diagnoses fatalConditionHandler as unused (because reset() is a static method) -DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4101) // unreferenced local variable - FatalConditionHandler fatalConditionHandler; // Handle signals - // execute the test - tc.m_test(); - fatalConditionHandler.reset(); -DOCTEST_MSVC_SUPPRESS_WARNING_POP -#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS - } catch(const TestFailureException&) { - p->failure_flags |= TestCaseFailureReason::AssertFailure; - } catch(...) { - DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_exception, - {translateActiveException(), false}); - p->failure_flags |= TestCaseFailureReason::Exception; - } -#endif // DOCTEST_CONFIG_NO_EXCEPTIONS - - // exit this loop if enough assertions have failed - even if there are more subcases - if(p->abort_after > 0 && - p->numAssertsFailed + p->numAssertsFailedCurrentTest_atomic >= p->abort_after) { - run_test = false; - p->failure_flags |= TestCaseFailureReason::TooManyFailedAsserts; - } - - if(p->should_reenter && run_test) - DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_reenter, tc); - if(!p->should_reenter) - run_test = false; - } while(run_test); - - p->finalizeTestCaseData(); - - DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_end, *g_cs); - - p->currentTest = nullptr; - - // stop executing tests if enough assertions have failed - if(p->abort_after > 0 && p->numAssertsFailed >= p->abort_after) - break; - } - } - - if(!query_mode) { - DOCTEST_ITERATE_THROUGH_REPORTERS(test_run_end, *g_cs); - } else { - QueryData qdata; - qdata.run_stats = g_cs; - qdata.data = queryResults.data(); - qdata.num_data = unsigned(queryResults.size()); - DOCTEST_ITERATE_THROUGH_REPORTERS(report_query, qdata); - } - - // see these issues on the reasoning for this: - // - https://github.com/onqtam/doctest/issues/143#issuecomment-414418903 - // - https://github.com/onqtam/doctest/issues/126 - auto DOCTEST_FIX_FOR_MACOS_LIBCPP_IOSFWD_STRING_LINK_ERRORS = []() DOCTEST_NOINLINE - { std::cout << std::string(); }; - DOCTEST_FIX_FOR_MACOS_LIBCPP_IOSFWD_STRING_LINK_ERRORS(); - - return cleanup_and_return(); -} - -IReporter::~IReporter() = default; - -int IReporter::get_num_active_contexts() { return detail::g_infoContexts.size(); } -const IContextScope* const* IReporter::get_active_contexts() { - return get_num_active_contexts() ? &detail::g_infoContexts[0] : nullptr; -} - -int IReporter::get_num_stringified_contexts() { return detail::g_cs->stringifiedContexts.size(); } -const String* IReporter::get_stringified_contexts() { - return get_num_stringified_contexts() ? &detail::g_cs->stringifiedContexts[0] : nullptr; -} - -namespace detail { - void registerReporterImpl(const char* name, int priority, reporterCreatorFunc c, bool isReporter) { - if(isReporter) - getReporters().insert(reporterMap::value_type(reporterMap::key_type(priority, name), c)); - else - getListeners().insert(reporterMap::value_type(reporterMap::key_type(priority, name), c)); - } -} // namespace detail - -} // namespace doctest - -#endif // DOCTEST_CONFIG_DISABLE - -#ifdef DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN -DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4007) // 'function' : must be 'attribute' - see issue #182 -int main(int argc, char** argv) { return doctest::Context(argc, argv).run(); } -DOCTEST_MSVC_SUPPRESS_WARNING_POP -#endif // DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN - -DOCTEST_CLANG_SUPPRESS_WARNING_POP -DOCTEST_MSVC_SUPPRESS_WARNING_POP -DOCTEST_GCC_SUPPRESS_WARNING_POP - -#endif // DOCTEST_LIBRARY_IMPLEMENTATION -#endif // DOCTEST_CONFIG_IMPLEMENT diff --git a/untests/doctest/doctest.hpp b/untests/doctest/doctest.hpp deleted file mode 100644 index 139d4b6..0000000 --- a/untests/doctest/doctest.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "doctest.h" - -// https://github.com/onqtam/doctest/issues/126 -#include - -#define STATIC_CHECK(...)\ - static_assert(__VA_ARGS__, #__VA_ARGS__);\ - CHECK(__VA_ARGS__) - -#define STATIC_CHECK_FALSE(...)\ - static_assert(!(__VA_ARGS__), "!(" #__VA_ARGS__ ")");\ - CHECK(!(__VA_ARGS__)) diff --git a/untests/meta_tests.hpp b/untests/meta_tests.hpp index 150e971..158f803 100644 --- a/untests/meta_tests.hpp +++ b/untests/meta_tests.hpp @@ -7,4 +7,4 @@ #pragma once #include -#include "doctest/doctest.hpp" +#include diff --git a/vendors/doctest b/vendors/doctest new file mode 160000 index 0000000..4d8716f --- /dev/null +++ b/vendors/doctest @@ -0,0 +1 @@ +Subproject commit 4d8716f1efc1d14aa736ef52ee727bd4204f4c40 From f8ba7267ad54058642aa4a072ef55374de5020b2 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 6 Aug 2021 02:53:49 +0700 Subject: [PATCH 082/233] fix github actions --- .github/workflows/coverage.yml | 2 ++ .github/workflows/darwin.yml | 2 ++ .github/workflows/linux.yml | 2 ++ .github/workflows/windows.yml | 2 ++ 4 files changed, 8 insertions(+) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index b0b79f4..09e95e1 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -8,6 +8,8 @@ jobs: name: "coverage" steps: - uses: actions/checkout@v2 + with: + submodules: recursive - name: Install lcov by Homebrew run: brew install lcov - name: Build && Test && Upload diff --git a/.github/workflows/darwin.yml b/.github/workflows/darwin.yml index 85a0aeb..07e86ea 100644 --- a/.github/workflows/darwin.yml +++ b/.github/workflows/darwin.yml @@ -16,6 +16,8 @@ jobs: name: "xcode-${{matrix.config.xcode}}" steps: - uses: actions/checkout@v2 + with: + submodules: recursive - name: Select Xcode run: sudo xcode-select --switch "/Applications/Xcode_${{matrix.config.xcode}}.app" - name: Build && Test diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 8d7085b..c785bc7 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -24,6 +24,8 @@ jobs: run: sudo apt-get -y install "${{matrix.config.cc}}" "${{matrix.config.cxx}}" - name: Checkout uses: actions/checkout@v2 + with: + submodules: recursive - name: Build && Test run: .ci/build_linux.sh env: { CC: "${{matrix.config.cc}}", CXX: "${{matrix.config.cxx}}" } diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 1c48908..1486034 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -17,5 +17,7 @@ jobs: name: "${{matrix.config.vs}} ${{matrix.config.arch}}" steps: - uses: actions/checkout@v2 + with: + submodules: recursive - name: Build && Test run: .ci\build_windows_${{matrix.config.arch}}.bat From 6b69a31724fef1fdb7ea6fb7d8e12d44237f31b8 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 6 Aug 2021 02:58:47 +0700 Subject: [PATCH 083/233] fix doctest compilation --- untests/meta_tests.hpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/untests/meta_tests.hpp b/untests/meta_tests.hpp index 158f803..32f0e65 100644 --- a/untests/meta_tests.hpp +++ b/untests/meta_tests.hpp @@ -8,3 +8,6 @@ #include #include + +// https://github.com/onqtam/doctest/issues/126 +#include From 072eabf36b279ce44e0620fdeda7609ba7da92aa Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 6 Aug 2021 03:15:39 +0700 Subject: [PATCH 084/233] fix using as submodule --- CMakeLists.txt | 2 ++ vendors/enum.hpp | 2 +- vendors/kari.hpp | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a007d89..fd019e6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,6 +3,8 @@ cmake_minimum_required(VERSION 3.8 FATAL_ERROR) if(NOT DEFINED PROJECT_NAME) set(BUILD_AS_STANDALONE ON) +else() + set(BUILD_AS_STANDALONE OFF) endif() project(meta.hpp) diff --git a/vendors/enum.hpp b/vendors/enum.hpp index ba3d7db..9e9dc26 160000 --- a/vendors/enum.hpp +++ b/vendors/enum.hpp @@ -1 +1 @@ -Subproject commit ba3d7db0ad3612358ffbbebdd9bc922e8c144189 +Subproject commit 9e9dc269238e4f43254282042bc0367b8b5e7aeb diff --git a/vendors/kari.hpp b/vendors/kari.hpp index c6f6a73..3b9dea6 160000 --- a/vendors/kari.hpp +++ b/vendors/kari.hpp @@ -1 +1 @@ -Subproject commit c6f6a73a4f7ed9d60677ae5376a218aea379be38 +Subproject commit 3b9dea6dc7006f36b842e05d3d1766641e428a82 From 999a57dc62da6d802b44712d887172837cb1ea69 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 6 Aug 2021 11:16:01 +0700 Subject: [PATCH 085/233] mistype fix --- headers/meta.hpp/meta_types/member_type.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/headers/meta.hpp/meta_types/member_type.hpp b/headers/meta.hpp/meta_types/member_type.hpp index 93a4ed7..5ef70c3 100644 --- a/headers/meta.hpp/meta_types/member_type.hpp +++ b/headers/meta.hpp/meta_types/member_type.hpp @@ -42,10 +42,10 @@ namespace meta_hpp namespace meta_hpp::detail { template < typename T > - struct method_pointer_traits; + struct member_pointer_traits; template < typename V, typename C > - struct method_pointer_traits { + struct member_pointer_traits { using class_type = C; using value_type = V; }; @@ -57,8 +57,8 @@ namespace meta_hpp inline member_type::member_type(typename_arg_t) : base_type{typename_arg} , state_{std::make_shared(state{ - type_db::get::class_type>(), - type_db::get::value_type>(), + type_db::get::class_type>(), + type_db::get::value_type>(), })} { static_assert(std::is_member_object_pointer_v); } From b2c3ec6584dd5429e745be784da018fe63ed10d0 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 6 Aug 2021 14:21:30 +0700 Subject: [PATCH 086/233] bitflags instead bool list --- headers/meta.hpp/meta_fwd.hpp | 6 ++ .../meta.hpp/meta_types/arithmetic_type.hpp | 88 ++++++++++-------- headers/meta.hpp/meta_types/array_type.hpp | 61 +++++++++---- headers/meta.hpp/meta_types/class_type.hpp | 88 ++++++++++-------- headers/meta.hpp/meta_types/ctor_type.hpp | 62 ++++++++----- headers/meta.hpp/meta_types/enum_type.hpp | 57 ++++++++---- headers/meta.hpp/meta_types/function_type.hpp | 64 ++++++++----- headers/meta.hpp/meta_types/member_type.hpp | 15 +++- headers/meta.hpp/meta_types/method_type.hpp | 89 ++++++++++++------- headers/meta.hpp/meta_types/pointer_type.hpp | 49 ++++++---- .../meta.hpp/meta_types/reference_type.hpp | 58 +++++++----- headers/meta.hpp/meta_types/void_type.hpp | 36 ++++++-- 12 files changed, 443 insertions(+), 230 deletions(-) diff --git a/headers/meta.hpp/meta_fwd.hpp b/headers/meta.hpp/meta_fwd.hpp index f405320..841ebe1 100644 --- a/headers/meta.hpp/meta_fwd.hpp +++ b/headers/meta.hpp/meta_fwd.hpp @@ -32,6 +32,12 @@ #include +namespace meta_hpp +{ + template < typename Enum > + using bitflags = enum_hpp::bitflags::bitflags; +} + namespace meta_hpp { class class_info; diff --git a/headers/meta.hpp/meta_types/arithmetic_type.hpp b/headers/meta.hpp/meta_types/arithmetic_type.hpp index 089678a..7a3d5e6 100644 --- a/headers/meta.hpp/meta_types/arithmetic_type.hpp +++ b/headers/meta.hpp/meta_types/arithmetic_type.hpp @@ -10,6 +10,16 @@ namespace meta_hpp { + enum class arithmetic_flags : unsigned { + is_const = 1 << 0, + is_signed = 1 << 1, + is_unsigned = 1 << 2, + is_integral = 1 << 3, + is_floating_point = 1 << 4, + }; + + ENUM_HPP_OPERATORS_DECL(arithmetic_flags) + class arithmetic_type final : public base_type { public: arithmetic_type() = default; @@ -23,8 +33,10 @@ namespace meta_hpp template < typename T > explicit arithmetic_type(typename_arg_t); - any_type raw_type() const noexcept; std::size_t size() const noexcept; + any_type raw_type() const noexcept; + + bitflags flags() const noexcept; bool is_const() const noexcept; bool is_signed() const noexcept; bool is_unsigned() const noexcept; @@ -36,19 +48,6 @@ namespace meta_hpp }; } -namespace meta_hpp -{ - struct arithmetic_type::state final { - const any_type raw_type; - const std::size_t size; - const bool is_const; - const bool is_signed; - const bool is_unsigned; - const bool is_integral; - const bool is_floating_point; - }; -} - namespace meta_hpp::detail { template < typename T, typename = void > @@ -56,60 +55,75 @@ namespace meta_hpp::detail template < typename T > struct arithmetic_traits>> { - using raw_type = std::remove_const_t; static constexpr std::size_t size{sizeof(T)}; - static constexpr bool is_const{std::is_const_v}; - static constexpr bool is_signed{std::is_signed_v}; - static constexpr bool is_unsigned{std::is_unsigned_v}; - static constexpr bool is_integral{std::is_integral_v}; - static constexpr bool is_floating_point{std::is_floating_point_v}; + + static any_type make_raw_type(const arithmetic_type& self) { + using raw_type = std::remove_const_t; + return std::is_same_v + ? any_type{self} + : type_db::get(); + } + + static bitflags make_flags() noexcept { + bitflags flags; + if ( std::is_const_v ) flags.set(arithmetic_flags::is_const); + if ( std::is_signed_v ) flags.set(arithmetic_flags::is_signed); + if ( std::is_unsigned_v ) flags.set(arithmetic_flags::is_unsigned); + if ( std::is_integral_v ) flags.set(arithmetic_flags::is_integral); + if ( std::is_floating_point_v ) flags.set(arithmetic_flags::is_floating_point); + return flags; + } }; } namespace meta_hpp { + struct arithmetic_type::state final { + const std::size_t size; + const any_type raw_type; + const bitflags flags; + }; + template < typename T > inline arithmetic_type::arithmetic_type(typename_arg_t) : base_type{typename_arg} , state_{std::make_shared(state{ - std::is_same_v::raw_type> - ? any_type{*this} - : type_db::get::raw_type>(), detail::arithmetic_traits::size, - detail::arithmetic_traits::is_const, - detail::arithmetic_traits::is_signed, - detail::arithmetic_traits::is_unsigned, - detail::arithmetic_traits::is_integral, - detail::arithmetic_traits::is_floating_point, + detail::arithmetic_traits::make_raw_type(*this), + detail::arithmetic_traits::make_flags(), })} { static_assert(std::is_arithmetic_v); } - inline any_type arithmetic_type::raw_type() const noexcept { - return state_->raw_type; - } - inline std::size_t arithmetic_type::size() const noexcept { return state_->size; } + inline any_type arithmetic_type::raw_type() const noexcept { + return state_->raw_type; + } + + inline bitflags arithmetic_type::flags() const noexcept { + return state_->flags; + } + inline bool arithmetic_type::is_const() const noexcept { - return state_->is_const; + return state_->flags.has(arithmetic_flags::is_const); } inline bool arithmetic_type::is_signed() const noexcept { - return state_->is_signed; + return state_->flags.has(arithmetic_flags::is_signed); } inline bool arithmetic_type::is_unsigned() const noexcept { - return state_->is_unsigned; + return state_->flags.has(arithmetic_flags::is_unsigned); } inline bool arithmetic_type::is_integral() const noexcept { - return state_->is_integral; + return state_->flags.has(arithmetic_flags::is_integral); } inline bool arithmetic_type::is_floating_point() const noexcept { - return state_->is_floating_point; + return state_->flags.has(arithmetic_flags::is_floating_point); } } diff --git a/headers/meta.hpp/meta_types/array_type.hpp b/headers/meta.hpp/meta_types/array_type.hpp index 1d9ea78..94e766d 100644 --- a/headers/meta.hpp/meta_types/array_type.hpp +++ b/headers/meta.hpp/meta_types/array_type.hpp @@ -10,6 +10,13 @@ namespace meta_hpp { + enum class array_flags : unsigned { + is_bounded = 1 << 0, + is_unbounded = 1 << 1, + }; + + ENUM_HPP_OPERATORS_DECL(array_flags) + class array_type final : public base_type { public: array_type() = default; @@ -23,8 +30,10 @@ namespace meta_hpp template < typename T > explicit array_type(typename_arg_t); - any_type data_type() const noexcept; std::size_t extent() const noexcept; + any_type data_type() const noexcept; + + bitflags flags() const noexcept; bool is_bounded() const noexcept; bool is_unbounded() const noexcept; private: @@ -36,10 +45,9 @@ namespace meta_hpp namespace meta_hpp { struct array_type::state final { - const any_type data_type; const std::size_t extent; - const bool is_bounded; - const bool is_unbounded; + const any_type data_type; + const bitflags flags; }; } @@ -50,18 +58,30 @@ namespace meta_hpp::detail template < typename T > struct array_traits { - using data_type = T; static constexpr std::size_t extent{0}; - static constexpr bool is_bounded{false}; - static constexpr bool is_unbounded{true}; + + static any_type make_data_type() { + using data_type = T; + return type_db::get(); + } + + static bitflags make_flags() noexcept { + return array_flags::is_unbounded; + } }; template < typename T, std::size_t N > struct array_traits { - using data_type = T; static constexpr std::size_t extent{N}; - static constexpr bool is_bounded{true}; - static constexpr bool is_unbounded{false}; + + static any_type make_data_type() { + using data_type = T; + return type_db::get(); + } + + static bitflags make_flags() noexcept { + return array_flags::is_bounded; + } }; } @@ -71,27 +91,30 @@ namespace meta_hpp inline array_type::array_type(typename_arg_t) : base_type{typename_arg} , state_{std::make_shared(state{ - type_db::get::data_type>(), detail::array_traits::extent, - detail::array_traits::is_bounded, - detail::array_traits::is_unbounded, + detail::array_traits::make_data_type(), + detail::array_traits::make_flags(), })} { static_assert(std::is_array_v); } - inline any_type array_type::data_type() const noexcept { - return state_->data_type; - } - inline std::size_t array_type::extent() const noexcept { return state_->extent; } + inline any_type array_type::data_type() const noexcept { + return state_->data_type; + } + + inline bitflags array_type::flags() const noexcept { + return state_->flags; + } + inline bool array_type::is_bounded() const noexcept { - return state_->is_bounded; + return state_->flags.has(array_flags::is_bounded); } inline bool array_type::is_unbounded() const noexcept { - return state_->is_unbounded; + return state_->flags.has(array_flags::is_unbounded); } } diff --git a/headers/meta.hpp/meta_types/class_type.hpp b/headers/meta.hpp/meta_types/class_type.hpp index 3bf64cf..70e1628 100644 --- a/headers/meta.hpp/meta_types/class_type.hpp +++ b/headers/meta.hpp/meta_types/class_type.hpp @@ -10,6 +10,16 @@ namespace meta_hpp { + enum class class_flags : unsigned { + is_const = 1 << 0, + is_empty = 1 << 1, + is_final = 1 << 2, + is_abstract = 1 << 3, + is_polymorphic = 1 << 4, + }; + + ENUM_HPP_OPERATORS_DECL(class_flags) + class class_type final : public base_type { public: class_type() = default; @@ -23,8 +33,10 @@ namespace meta_hpp template < typename T > explicit class_type(typename_arg_t); - any_type raw_type() const noexcept; std::size_t size() const noexcept; + any_type raw_type() const noexcept; + + bitflags flags() const noexcept; bool is_const() const noexcept; bool is_empty() const noexcept; bool is_final() const noexcept; @@ -36,19 +48,6 @@ namespace meta_hpp }; } -namespace meta_hpp -{ - struct class_type::state final { - const any_type raw_type; - const std::size_t size; - const bool is_const; - const bool is_empty; - const bool is_final; - const bool is_abstract; - const bool is_polymorphic; - }; -} - namespace meta_hpp::detail { template < typename T, typename = void > @@ -56,60 +55,75 @@ namespace meta_hpp::detail template < typename T > struct class_traits>> { - using raw_type = std::remove_const_t; static constexpr std::size_t size{sizeof(T)}; - static constexpr bool is_const{std::is_const_v}; - static constexpr bool is_empty{std::is_empty_v}; - static constexpr bool is_final{std::is_final_v}; - static constexpr bool is_abstract{std::is_abstract_v}; - static constexpr bool is_polymorphic{std::is_polymorphic_v}; + + static any_type make_raw_type(const class_type& self) { + using raw_type = std::remove_const_t; + return std::is_same_v + ? any_type{self} + : type_db::get(); + } + + static bitflags make_flags() noexcept { + bitflags flags; + if ( std::is_const_v ) flags.set(class_flags::is_const); + if ( std::is_empty_v ) flags.set(class_flags::is_empty); + if ( std::is_final_v ) flags.set(class_flags::is_final); + if ( std::is_abstract_v ) flags.set(class_flags::is_abstract); + if ( std::is_polymorphic_v ) flags.set(class_flags::is_polymorphic); + return flags; + } }; } namespace meta_hpp { + struct class_type::state final { + const std::size_t size; + const any_type raw_type; + const bitflags flags; + }; + template < typename T > inline class_type::class_type(typename_arg_t) : base_type{typename_arg} , state_{std::make_shared(state{ - std::is_same_v::raw_type> - ? any_type{*this} - : type_db::get::raw_type>(), detail::class_traits::size, - detail::class_traits::is_const, - detail::class_traits::is_empty, - detail::class_traits::is_final, - detail::class_traits::is_abstract, - detail::class_traits::is_polymorphic, + detail::class_traits::make_raw_type(*this), + detail::class_traits::make_flags(), })} { static_assert(std::is_class_v); } - inline any_type class_type::raw_type() const noexcept { - return state_->raw_type; - } - inline std::size_t class_type::size() const noexcept { return state_->size; } + inline any_type class_type::raw_type() const noexcept { + return state_->raw_type; + } + + inline bitflags class_type::flags() const noexcept { + return state_->flags; + } + inline bool class_type::is_const() const noexcept { - return state_->is_const; + return state_->flags.has(class_flags::is_const); } inline bool class_type::is_empty() const noexcept { - return state_->is_empty; + return state_->flags.has(class_flags::is_empty); } inline bool class_type::is_final() const noexcept { - return state_->is_final; + return state_->flags.has(class_flags::is_final); } inline bool class_type::is_abstract() const noexcept { - return state_->is_abstract; + return state_->flags.has(class_flags::is_abstract); } inline bool class_type::is_polymorphic() const noexcept { - return state_->is_polymorphic; + return state_->flags.has(class_flags::is_polymorphic); } } diff --git a/headers/meta.hpp/meta_types/ctor_type.hpp b/headers/meta.hpp/meta_types/ctor_type.hpp index aa7ea57..871ff9a 100644 --- a/headers/meta.hpp/meta_types/ctor_type.hpp +++ b/headers/meta.hpp/meta_types/ctor_type.hpp @@ -10,6 +10,12 @@ namespace meta_hpp { + enum class ctor_flags : unsigned { + is_noexcept = 1 << 0, + }; + + ENUM_HPP_OPERATORS_DECL(ctor_flags) + class ctor_type final : public base_type { public: ctor_type() = default; @@ -23,10 +29,12 @@ namespace meta_hpp template < typename Class, typename... Args > explicit ctor_type(typename_arg_t, typename_arg_t); + std::size_t arity() const noexcept; any_type class_type() const noexcept; any_type argument_type(std::size_t i) const noexcept; const std::vector& argument_types() const noexcept; - std::size_t arity() const noexcept; + + bitflags flags() const noexcept; bool is_noexcept() const noexcept; private: struct state; @@ -34,43 +42,57 @@ namespace meta_hpp }; } -namespace meta_hpp -{ - struct ctor_type::state final { - const any_type class_type; - const std::vector argument_types; - const std::size_t arity; - const bool is_noexcept; - }; -} - namespace meta_hpp::detail { template < typename C, typename... Args > struct ctor_traits { static_assert(std::is_constructible_v); - using class_type = C; - using argument_types = std::tuple; static constexpr std::size_t arity{sizeof...(Args)}; - static constexpr bool is_noexcept{std::is_nothrow_constructible_v}; + + static any_type make_class_type() { + using class_type = C; + return type_db::get(); + } + + static std::vector make_argument_types() { + using argument_types = std::tuple; + return type_db::multi_get(); + } + + static bitflags make_flags() noexcept { + bitflags flags; + if ( std::is_nothrow_constructible_v ) flags.set(ctor_flags::is_noexcept); + return flags; + } }; } namespace meta_hpp { + struct ctor_type::state final { + const std::size_t arity; + const any_type class_type; + const std::vector argument_types; + const bitflags flags; + }; + template < typename Class, typename... Args > inline ctor_type::ctor_type(typename_arg_t, typename_arg_t) : base_type{typename_arg} , state_{std::make_shared(state{ - type_db::get::class_type>(), - type_db::multi_get::argument_types>(), detail::ctor_traits::arity, - detail::ctor_traits::is_noexcept, + detail::ctor_traits::make_class_type(), + detail::ctor_traits::make_argument_types(), + detail::ctor_traits::make_flags(), })} { static_assert(std::is_class_v); static_assert(std::is_constructible_v); } + inline std::size_t ctor_type::arity() const noexcept { + return state_->arity; + } + inline any_type ctor_type::class_type() const noexcept { return state_->class_type; } @@ -85,11 +107,11 @@ namespace meta_hpp return state_->argument_types; } - inline std::size_t ctor_type::arity() const noexcept { - return state_->arity; + inline bitflags ctor_type::flags() const noexcept { + return state_->flags; } inline bool ctor_type::is_noexcept() const noexcept { - return state_->is_noexcept; + return state_->flags.has(ctor_flags::is_noexcept); } } diff --git a/headers/meta.hpp/meta_types/enum_type.hpp b/headers/meta.hpp/meta_types/enum_type.hpp index 6feaaef..eaec0cf 100644 --- a/headers/meta.hpp/meta_types/enum_type.hpp +++ b/headers/meta.hpp/meta_types/enum_type.hpp @@ -10,6 +10,12 @@ namespace meta_hpp { + enum class enum_flags : unsigned { + is_const = 1 << 0, + }; + + ENUM_HPP_OPERATORS_DECL(enum_flags) + class enum_type final : public base_type { public: enum_type() = default; @@ -25,6 +31,8 @@ namespace meta_hpp any_type raw_type() const noexcept; any_type underlying_type() const noexcept; + + bitflags flags() const noexcept; bool is_const() const noexcept; private: struct state; @@ -32,15 +40,6 @@ namespace meta_hpp }; } -namespace meta_hpp -{ - struct enum_type::state final { - const any_type raw_type; - const any_type underlying_type; - const bool is_const; - }; -} - namespace meta_hpp::detail { template < typename T, typename = void > @@ -48,23 +47,41 @@ namespace meta_hpp::detail template < typename T > struct enum_traits>> { - using raw_type = std::remove_const_t; - using underlying_type = std::underlying_type_t; - static constexpr bool is_const{std::is_const_v}; + static any_type make_raw_type(const enum_type& self) { + using raw_type = std::remove_const_t; + return std::is_same_v + ? any_type{self} + : type_db::get(); + } + + static any_type make_underlying_type() { + using underlying_type = std::underlying_type_t; + return type_db::get(); + } + + static bitflags make_flags() noexcept { + bitflags flags; + if ( std::is_const_v ) flags.set(enum_flags::is_const); + return flags; + } }; } namespace meta_hpp { + struct enum_type::state final { + const any_type raw_type; + const any_type underlying_type; + const bitflags flags; + }; + template < typename T > inline enum_type::enum_type(typename_arg_t) : base_type{typename_arg} , state_{std::make_shared(state{ - std::is_same_v::raw_type> - ? any_type{*this} - : type_db::get::raw_type>(), - type_db::get::underlying_type>(), - detail::enum_traits::is_const, + detail::enum_traits::make_raw_type(*this), + detail::enum_traits::make_underlying_type(), + detail::enum_traits::make_flags(), })} { static_assert(std::is_enum_v); } @@ -77,7 +94,11 @@ namespace meta_hpp return state_->underlying_type; } + inline bitflags enum_type::flags() const noexcept { + return state_->flags; + } + inline bool enum_type::is_const() const noexcept { - return state_->is_const; + return state_->flags.has(enum_flags::is_const); } } diff --git a/headers/meta.hpp/meta_types/function_type.hpp b/headers/meta.hpp/meta_types/function_type.hpp index b4f4b4a..7008368 100644 --- a/headers/meta.hpp/meta_types/function_type.hpp +++ b/headers/meta.hpp/meta_types/function_type.hpp @@ -10,6 +10,12 @@ namespace meta_hpp { + enum class function_flags : unsigned { + is_noexcept = 1 << 0, + }; + + ENUM_HPP_OPERATORS_DECL(function_flags) + class function_type final : public base_type { public: function_type() = default; @@ -23,10 +29,12 @@ namespace meta_hpp template < typename T > explicit function_type(typename_arg_t); + std::size_t arity() const noexcept; any_type return_type() const noexcept; any_type argument_type(std::size_t i) const noexcept; const std::vector& argument_types() const noexcept; - std::size_t arity() const noexcept; + + bitflags flags() const noexcept; bool is_noexcept() const noexcept; private: struct state; @@ -34,16 +42,6 @@ namespace meta_hpp }; } -namespace meta_hpp -{ - struct function_type::state final { - const any_type return_type; - const std::vector argument_types; - const std::size_t arity; - const bool is_noexcept; - }; -} - namespace meta_hpp::detail { template < typename T > @@ -51,33 +49,57 @@ namespace meta_hpp::detail template < typename R, typename... Args > struct function_pointer_traits { - using return_type = R; - using argument_types = std::tuple; static constexpr std::size_t arity{sizeof...(Args)}; - static constexpr bool is_noexcept{false}; + + static any_type make_return_type() { + using return_type = R; + return type_db::get(); + } + + static std::vector make_argument_types() { + using argument_types = std::tuple; + return type_db::multi_get(); + } + + static bitflags make_flags() noexcept { + return bitflags{}; + } }; template < typename R, typename... Args > struct function_pointer_traits : function_pointer_traits { - static constexpr bool is_noexcept{true}; + static bitflags make_flags() noexcept { + return function_flags::is_noexcept; + } }; } namespace meta_hpp { + struct function_type::state final { + const std::size_t arity; + const any_type return_type; + const std::vector argument_types; + const bitflags flags; + }; + template < typename T > inline function_type::function_type(typename_arg_t) : base_type{typename_arg} , state_{std::make_shared(state{ - type_db::get::return_type>(), - type_db::multi_get::argument_types>(), detail::function_pointer_traits::arity, - detail::function_pointer_traits::is_noexcept, + detail::function_pointer_traits::make_return_type(), + detail::function_pointer_traits::make_argument_types(), + detail::function_pointer_traits::make_flags(), })} { static_assert(std::is_pointer_v); static_assert(std::is_function_v>); } + inline std::size_t function_type::arity() const noexcept { + return state_->arity; + } + inline any_type function_type::return_type() const noexcept { return state_->return_type; } @@ -92,11 +114,11 @@ namespace meta_hpp return state_->argument_types; } - inline std::size_t function_type::arity() const noexcept { - return state_->arity; + inline bitflags function_type::flags() const noexcept { + return state_->flags; } inline bool function_type::is_noexcept() const noexcept { - return state_->is_noexcept; + return state_->flags.has(function_flags::is_noexcept); } } diff --git a/headers/meta.hpp/meta_types/member_type.hpp b/headers/meta.hpp/meta_types/member_type.hpp index 5ef70c3..3fdcea7 100644 --- a/headers/meta.hpp/meta_types/member_type.hpp +++ b/headers/meta.hpp/meta_types/member_type.hpp @@ -46,8 +46,15 @@ namespace meta_hpp::detail template < typename V, typename C > struct member_pointer_traits { - using class_type = C; - using value_type = V; + static any_type make_class_type() { + using class_type = C; + return type_db::get(); + } + + static any_type make_value_type() { + using value_type = V; + return type_db::get(); + } }; } @@ -57,8 +64,8 @@ namespace meta_hpp inline member_type::member_type(typename_arg_t) : base_type{typename_arg} , state_{std::make_shared(state{ - type_db::get::class_type>(), - type_db::get::value_type>(), + detail::member_pointer_traits::make_class_type(), + detail::member_pointer_traits::make_value_type(), })} { static_assert(std::is_member_object_pointer_v); } diff --git a/headers/meta.hpp/meta_types/method_type.hpp b/headers/meta.hpp/meta_types/method_type.hpp index 1be2a77..8ee04ee 100644 --- a/headers/meta.hpp/meta_types/method_type.hpp +++ b/headers/meta.hpp/meta_types/method_type.hpp @@ -10,6 +10,13 @@ namespace meta_hpp { + enum class method_flags : unsigned { + is_const = 1 << 0, + is_noexcept = 1 << 1, + }; + + ENUM_HPP_OPERATORS_DECL(method_flags) + class method_type final : public base_type { public: method_type() = default; @@ -23,11 +30,13 @@ namespace meta_hpp template < typename T > explicit method_type(typename_arg_t); + std::size_t arity() const noexcept; any_type class_type() const noexcept; any_type return_type() const noexcept; any_type argument_type(std::size_t i) const noexcept; const std::vector& argument_types() const noexcept; - std::size_t arity() const noexcept; + + bitflags flags() const noexcept; bool is_const() const noexcept; bool is_noexcept() const noexcept; private: @@ -36,18 +45,6 @@ namespace meta_hpp }; } -namespace meta_hpp -{ - struct method_type::state final { - const any_type class_type; - const any_type return_type; - const std::vector argument_types; - const std::size_t arity; - const bool is_const; - const bool is_noexcept; - }; -} - namespace meta_hpp::detail { template < typename T > @@ -55,47 +52,77 @@ namespace meta_hpp::detail template < typename R, typename C, typename... Args > struct method_pointer_traits { - using class_type = C; - using return_type = R; - using argument_types = std::tuple; static constexpr std::size_t arity{sizeof...(Args)}; - static constexpr bool is_const{false}; - static constexpr bool is_noexcept{false}; + + static any_type make_class_type() { + using class_type = C; + return type_db::get(); + } + + static any_type make_return_type() { + using return_type = R; + return type_db::get(); + } + + static std::vector make_argument_types() { + using argument_types = std::tuple; + return type_db::multi_get(); + } + + static bitflags make_flags() noexcept { + return bitflags{}; + } }; template < typename R, typename C, typename... Args > struct method_pointer_traits : method_pointer_traits { - static constexpr bool is_const{true}; + static bitflags make_flags() noexcept { + return method_flags::is_const; + } }; template < typename R, typename C, typename... Args > struct method_pointer_traits : method_pointer_traits { - static constexpr bool is_noexcept{true}; + static bitflags make_flags() noexcept { + return method_flags::is_noexcept; + } }; template < typename R, typename C, typename... Args > struct method_pointer_traits : method_pointer_traits { - static constexpr bool is_const{true}; - static constexpr bool is_noexcept{true}; + static bitflags make_flags() noexcept { + return method_flags::is_const | method_flags::is_noexcept; + } }; } namespace meta_hpp { + struct method_type::state final { + const std::size_t arity; + const any_type class_type; + const any_type return_type; + const std::vector argument_types; + const bitflags flags; + }; + template < typename T > inline method_type::method_type(typename_arg_t) : base_type{typename_arg} , state_{std::make_shared(state{ - type_db::get::class_type>(), - type_db::get::return_type>(), - type_db::multi_get::argument_types>(), detail::method_pointer_traits::arity, - detail::method_pointer_traits::is_const, - detail::method_pointer_traits::is_noexcept, + detail::method_pointer_traits::make_class_type(), + detail::method_pointer_traits::make_return_type(), + detail::method_pointer_traits::make_argument_types(), + detail::method_pointer_traits::make_flags(), })} { static_assert(std::is_member_function_pointer_v); } + inline std::size_t method_type::arity() const noexcept { + return state_->arity; + } + inline any_type method_type::class_type() const noexcept { return state_->class_type; } @@ -114,15 +141,15 @@ namespace meta_hpp return state_->argument_types; } - inline std::size_t method_type::arity() const noexcept { - return state_->arity; + inline bitflags method_type::flags() const noexcept { + return state_->flags; } inline bool method_type::is_const() const noexcept { - return state_->is_const; + return state_->flags.has(method_flags::is_const); } inline bool method_type::is_noexcept() const noexcept { - return state_->is_noexcept; + return state_->flags.has(method_flags::is_noexcept); } } diff --git a/headers/meta.hpp/meta_types/pointer_type.hpp b/headers/meta.hpp/meta_types/pointer_type.hpp index 5038f30..db2c431 100644 --- a/headers/meta.hpp/meta_types/pointer_type.hpp +++ b/headers/meta.hpp/meta_types/pointer_type.hpp @@ -10,6 +10,10 @@ namespace meta_hpp { + enum class pointer_flags : unsigned { + is_const = 1 << 0, + }; + class pointer_type final : public base_type { public: pointer_type() = default; @@ -24,6 +28,8 @@ namespace meta_hpp explicit pointer_type(typename_arg_t); any_type data_type() const noexcept; + + bitflags flags() const noexcept; bool is_const() const noexcept; private: struct state; @@ -31,14 +37,6 @@ namespace meta_hpp }; } -namespace meta_hpp -{ - struct pointer_type::state final { - const any_type data_type; - const bool is_const; - }; -} - namespace meta_hpp::detail { template < typename T > @@ -46,25 +44,42 @@ namespace meta_hpp::detail template < typename T > struct pointer_traits { - using data_type = T; - static constexpr bool is_const{false}; + static any_type make_data_type() { + using data_type = T; + return type_db::get(); + } + + static bitflags make_flags() noexcept { + return bitflags{}; + } }; template < typename T > struct pointer_traits { - using data_type = T; - static constexpr bool is_const{true}; + static any_type make_data_type() { + using data_type = T; + return type_db::get(); + } + + static bitflags make_flags() noexcept { + return pointer_flags::is_const; + } }; } namespace meta_hpp { + struct pointer_type::state final { + const any_type data_type; + const bitflags flags; + }; + template < typename T > inline pointer_type::pointer_type(typename_arg_t) : base_type{typename_arg} , state_{std::make_shared(state{ - type_db::get::data_type>(), - detail::pointer_traits::is_const, + detail::pointer_traits::make_data_type(), + detail::pointer_traits::make_flags(), })} { static_assert(std::is_pointer_v); static_assert(!std::is_function_v>); @@ -74,7 +89,11 @@ namespace meta_hpp return state_->data_type; } + inline bitflags pointer_type::flags() const noexcept { + return state_->flags; + } + inline bool pointer_type::is_const() const noexcept { - return state_->is_const; + return state_->flags.has(pointer_flags::is_const); } } diff --git a/headers/meta.hpp/meta_types/reference_type.hpp b/headers/meta.hpp/meta_types/reference_type.hpp index 3821359..8c9d24b 100644 --- a/headers/meta.hpp/meta_types/reference_type.hpp +++ b/headers/meta.hpp/meta_types/reference_type.hpp @@ -10,6 +10,13 @@ namespace meta_hpp { + enum class reference_flags : unsigned { + is_lvalue = 1 << 0, + is_rvalue = 1 << 1, + }; + + ENUM_HPP_OPERATORS_DECL(reference_flags) + class reference_type final : public base_type { public: reference_type() = default; @@ -24,6 +31,8 @@ namespace meta_hpp explicit reference_type(typename_arg_t); any_type data_type() const noexcept; + + bitflags flags() const noexcept; bool is_lvalue() const noexcept; bool is_rvalue() const noexcept; private: @@ -32,15 +41,6 @@ namespace meta_hpp }; } -namespace meta_hpp -{ - struct reference_type::state final { - const any_type data_type; - const bool is_lvalue; - const bool is_rvalue; - }; -} - namespace meta_hpp::detail { template < typename T > @@ -48,28 +48,42 @@ namespace meta_hpp::detail template < typename T > struct reference_traits { - using data_type = T; - static constexpr bool is_lvalue{true}; - static constexpr bool is_rvalue{false}; + static any_type make_data_type() { + using data_type = T; + return type_db::get(); + } + + static bitflags make_flags() noexcept { + return reference_flags::is_lvalue; + } }; template < typename T > struct reference_traits { - using data_type = T; - static constexpr bool is_lvalue{false}; - static constexpr bool is_rvalue{true}; + static any_type make_data_type() { + using data_type = T; + return type_db::get(); + } + + static bitflags make_flags() noexcept { + return reference_flags::is_rvalue; + } }; } namespace meta_hpp { + struct reference_type::state final { + const any_type data_type; + const bitflags flags; + }; + template < typename T > inline reference_type::reference_type(typename_arg_t) : base_type{typename_arg} , state_{std::make_shared(state{ - type_db::get::data_type>(), - detail::reference_traits::is_lvalue, - detail::reference_traits::is_rvalue, + detail::reference_traits::make_data_type(), + detail::reference_traits::make_flags(), })} { static_assert(std::is_reference_v); } @@ -78,11 +92,15 @@ namespace meta_hpp return state_->data_type; } + inline bitflags reference_type::flags() const noexcept { + return state_->flags; + } + inline bool reference_type::is_lvalue() const noexcept { - return state_->is_lvalue; + return state_->flags.has(reference_flags::is_lvalue); } inline bool reference_type::is_rvalue() const noexcept { - return state_->is_rvalue; + return state_->flags.has(reference_flags::is_rvalue); } } diff --git a/headers/meta.hpp/meta_types/void_type.hpp b/headers/meta.hpp/meta_types/void_type.hpp index 2e7a962..63b8f53 100644 --- a/headers/meta.hpp/meta_types/void_type.hpp +++ b/headers/meta.hpp/meta_types/void_type.hpp @@ -10,6 +10,12 @@ namespace meta_hpp { + enum class void_flags : unsigned { + is_const = 1 << 0, + }; + + ENUM_HPP_OPERATORS_DECL(void_flags) + class void_type final : public base_type { public: void_type() = default; @@ -24,6 +30,8 @@ namespace meta_hpp explicit void_type(typename_arg_t); any_type raw_type() const noexcept; + + bitflags flags() const noexcept; bool is_const() const noexcept; private: struct state; @@ -35,7 +43,7 @@ namespace meta_hpp { struct void_type::state final { const any_type raw_type; - const bool is_const; + const bitflags flags; }; } @@ -46,8 +54,18 @@ namespace meta_hpp::detail template < typename T > struct void_traits>> { - using raw_type = std::remove_const_t; - static constexpr bool is_const{std::is_const_v}; + static any_type make_raw_type(const void_type& self) { + using raw_type = std::remove_const_t; + return std::is_same_v + ? any_type{self} + : type_db::get(); + } + + static bitflags make_flags() noexcept { + bitflags flags; + if ( std::is_const_v ) flags.set(void_flags::is_const); + return flags; + } }; } @@ -57,10 +75,8 @@ namespace meta_hpp inline void_type::void_type(typename_arg_t) : base_type{typename_arg} , state_{std::make_shared(state{ - std::is_same_v::raw_type> - ? any_type{*this} - : type_db::get::raw_type>(), - detail::void_traits::is_const, + detail::void_traits::make_raw_type(*this), + detail::void_traits::make_flags(), })} { static_assert(std::is_void_v); } @@ -69,7 +85,11 @@ namespace meta_hpp return state_->raw_type; } + inline bitflags void_type::flags() const noexcept { + return state_->flags; + } + inline bool void_type::is_const() const noexcept { - return state_->is_const; + return state_->flags.has(void_flags::is_const); } } From 44f4a76052f4e1f772383d927a9a45a70d4d01ea Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 6 Aug 2021 16:43:18 +0700 Subject: [PATCH 087/233] type flag tests --- .../features/types/arithmetic_type_tests.cpp | 14 ++++++++++++++ untests/features/types/array_type_tests.cpp | 6 ++++++ untests/features/types/class_type_tests.cpp | 19 +++++++++++++++++++ untests/features/types/ctor_type_tests.cpp | 8 +++++++- untests/features/types/enum_type_tests.cpp | 4 ++++ .../features/types/function_type_tests.cpp | 6 ++++++ untests/features/types/method_type_tests.cpp | 8 ++++++++ untests/features/types/pointer_type_tests.cpp | 8 ++++++++ .../features/types/reference_type_tests.cpp | 6 ++++++ untests/features/types/void_type_tests.cpp | 4 ++++ 10 files changed, 82 insertions(+), 1 deletion(-) diff --git a/untests/features/types/arithmetic_type_tests.cpp b/untests/features/types/arithmetic_type_tests.cpp index a120637..4d71486 100644 --- a/untests/features/types/arithmetic_type_tests.cpp +++ b/untests/features/types/arithmetic_type_tests.cpp @@ -25,6 +25,10 @@ TEST_CASE("features/types/arithmetic") { CHECK(at.raw_type().id() == type_db::get().id()); CHECK(at.size() == sizeof(type)); + CHECK(at.flags() == ( + arithmetic_flags::is_signed | + arithmetic_flags::is_integral)); + CHECK_FALSE(at.is_const()); CHECK(at.is_signed()); CHECK_FALSE(at.is_unsigned()); @@ -44,6 +48,11 @@ TEST_CASE("features/types/arithmetic") { CHECK(at.raw_type().id() == type_db::get().id()); CHECK(at.size() == sizeof(type)); + CHECK(at.flags() == ( + arithmetic_flags::is_const | + arithmetic_flags::is_signed | + arithmetic_flags::is_floating_point)); + CHECK(at.is_const()); CHECK(at.is_signed()); CHECK_FALSE(at.is_unsigned()); @@ -63,6 +72,11 @@ TEST_CASE("features/types/arithmetic") { CHECK(at.raw_type().id() == type_db::get().id()); CHECK(at.size() == sizeof(type)); + CHECK(at.flags() == ( + arithmetic_flags::is_const | + arithmetic_flags::is_unsigned | + arithmetic_flags::is_integral)); + CHECK(at.is_const()); CHECK_FALSE(at.is_signed()); CHECK(at.is_unsigned()); diff --git a/untests/features/types/array_type_tests.cpp b/untests/features/types/array_type_tests.cpp index 8ad653e..e0c2a5a 100644 --- a/untests/features/types/array_type_tests.cpp +++ b/untests/features/types/array_type_tests.cpp @@ -24,6 +24,9 @@ TEST_CASE("features/types/array") { CHECK(at.data_type().id() == type_db::get().id()); CHECK(at.extent() == 0); + + CHECK(at.flags() == (array_flags::is_unbounded)); + CHECK_FALSE(at.is_bounded()); CHECK(at.is_unbounded()); } @@ -39,6 +42,9 @@ TEST_CASE("features/types/array") { CHECK(at.data_type().id() == type_db::get().id()); CHECK(at.extent() == 42); + + CHECK(at.flags() == (array_flags::is_bounded)); + CHECK(at.is_bounded()); CHECK_FALSE(at.is_unbounded()); } diff --git a/untests/features/types/class_type_tests.cpp b/untests/features/types/class_type_tests.cpp index 99b5b37..16ea475 100644 --- a/untests/features/types/class_type_tests.cpp +++ b/untests/features/types/class_type_tests.cpp @@ -43,6 +43,10 @@ TEST_CASE("features/types/class") { CHECK(ct.raw_type().id() == type_db::get().id()); CHECK(ct.size() == sizeof(type)); + CHECK(ct.flags() == ( + class_flags::is_abstract | + class_flags::is_polymorphic)); + CHECK_FALSE(ct.is_const()); CHECK_FALSE(ct.is_empty()); CHECK_FALSE(ct.is_final()); @@ -62,6 +66,10 @@ TEST_CASE("features/types/class") { CHECK(ct.raw_type().id() == type_db::get().id()); CHECK(ct.size() == sizeof(type)); + CHECK(ct.flags() == ( + class_flags::is_final | + class_flags::is_polymorphic)); + CHECK_FALSE(ct.is_const()); CHECK_FALSE(ct.is_empty()); CHECK(ct.is_final()); @@ -81,6 +89,10 @@ TEST_CASE("features/types/class") { CHECK(ct.raw_type().id() == type_db::get().id()); CHECK(ct.size() == sizeof(type)); + CHECK(ct.flags() == ( + class_flags::is_empty | + class_flags::is_final)); + CHECK_FALSE(ct.is_const()); CHECK(ct.is_empty()); CHECK(ct.is_final()); @@ -100,6 +112,9 @@ TEST_CASE("features/types/class") { CHECK(ct.raw_type().id() == type_db::get().id()); CHECK(ct.size() == sizeof(type)); + CHECK(ct.flags() == ( + class_flags::is_final)); + CHECK_FALSE(ct.is_const()); CHECK_FALSE(ct.is_empty()); CHECK(ct.is_final()); @@ -119,6 +134,10 @@ TEST_CASE("features/types/class") { CHECK(ct.raw_type().id() == type_db::get().id()); CHECK(ct.size() == sizeof(type)); + CHECK(ct.flags() == ( + class_flags::is_const | + class_flags::is_final)); + CHECK(ct.is_const()); CHECK_FALSE(ct.is_empty()); CHECK(ct.is_final()); diff --git a/untests/features/types/ctor_type_tests.cpp b/untests/features/types/ctor_type_tests.cpp index 61b8f53..3cdc84d 100644 --- a/untests/features/types/ctor_type_tests.cpp +++ b/untests/features/types/ctor_type_tests.cpp @@ -31,6 +31,8 @@ TEST_CASE("features/types/ctor") { CHECK(ct.class_type().id() == type_db::get().id()); CHECK(ct.argument_types().size() == 0); CHECK(ct.arity() == 0); + + CHECK(ct.flags() == (ctor_flags::is_noexcept)); CHECK(ct.is_noexcept()); { @@ -41,11 +43,13 @@ TEST_CASE("features/types/ctor") { SUBCASE("ivec2_int") { ctor_type ct{typename_arg, typename_arg}; - CHECK_FALSE(ct.is_noexcept()); CHECK(ct.arity() == 1); CHECK(ct.class_type().id() == type_db::get().id()); CHECK(ct.argument_types().size() == 1); + CHECK(ct.flags() == (ctor_flags{})); + CHECK_FALSE(ct.is_noexcept()); + { REQUIRE(ct.argument_type(0)); const any_type arg0 = ct.argument_type(0); @@ -63,6 +67,8 @@ TEST_CASE("features/types/ctor") { CHECK(ct.class_type().id() == type_db::get().id()); CHECK(ct.argument_types().size() == 2); CHECK(ct.arity() == 2); + + CHECK(ct.flags() == (ctor_flags{})); CHECK_FALSE(ct.is_noexcept()); { diff --git a/untests/features/types/enum_type_tests.cpp b/untests/features/types/enum_type_tests.cpp index 8ba737e..f7d1195 100644 --- a/untests/features/types/enum_type_tests.cpp +++ b/untests/features/types/enum_type_tests.cpp @@ -33,6 +33,8 @@ TEST_CASE("features/types/enum") { CHECK(et.raw_type().id() == type_db::get().id()); CHECK(et.underlying_type().id() == type_db::get().id()); + + CHECK(et.flags() == (enum_flags{})); CHECK_FALSE(et.is_const()); } @@ -47,6 +49,8 @@ TEST_CASE("features/types/enum") { CHECK(et.raw_type().id() == type_db::get().id()); CHECK(et.underlying_type().id() == type_db::get().id()); + + CHECK(et.flags() == (enum_flags::is_const)); CHECK(et.is_const()); } } diff --git a/untests/features/types/function_type_tests.cpp b/untests/features/types/function_type_tests.cpp index b76a244..38632ab 100644 --- a/untests/features/types/function_type_tests.cpp +++ b/untests/features/types/function_type_tests.cpp @@ -35,6 +35,8 @@ TEST_CASE("features/types/function") { CHECK(ft.return_type().id() == type_db::get().id()); CHECK(ft.argument_types().size() == 1); CHECK(ft.arity() == 1); + + CHECK(ft.flags() == (function_flags{})); CHECK_FALSE(ft.is_noexcept()); { @@ -58,6 +60,8 @@ TEST_CASE("features/types/function") { CHECK(ft.return_type().id() == type_db::get().id()); CHECK(ft.argument_types().size() == 1); CHECK(ft.arity() == 1); + + CHECK(ft.flags() == (function_flags::is_noexcept)); CHECK(ft.is_noexcept()); { @@ -81,6 +85,8 @@ TEST_CASE("features/types/function") { CHECK(ft.return_type().id() == type_db::get().id()); CHECK(ft.argument_types().size() == 1); CHECK(ft.arity() == 1); + + CHECK(ft.flags() == (function_flags::is_noexcept)); CHECK(ft.is_noexcept()); { diff --git a/untests/features/types/method_type_tests.cpp b/untests/features/types/method_type_tests.cpp index 952422e..084db51 100644 --- a/untests/features/types/method_type_tests.cpp +++ b/untests/features/types/method_type_tests.cpp @@ -44,6 +44,9 @@ TEST_CASE("features/types/method") { CHECK(mt.return_type().id() == type_db::get().id()); CHECK(mt.argument_types().size() == 1); CHECK(mt.arity() == 1); + + CHECK(mt.flags() == (method_flags{})); + CHECK_FALSE(mt.is_const()); CHECK_FALSE(mt.is_noexcept()); @@ -69,6 +72,11 @@ TEST_CASE("features/types/method") { CHECK(mt.return_type().id() == type_db::get().id()); CHECK(mt.argument_types().size() == 0); CHECK(mt.arity() == 0); + + CHECK(mt.flags() == ( + method_flags::is_const | + method_flags::is_noexcept)); + CHECK(mt.is_const()); CHECK(mt.is_noexcept()); diff --git a/untests/features/types/pointer_type_tests.cpp b/untests/features/types/pointer_type_tests.cpp index ef67ec0..60e95c4 100644 --- a/untests/features/types/pointer_type_tests.cpp +++ b/untests/features/types/pointer_type_tests.cpp @@ -31,6 +31,8 @@ TEST_CASE("features/types/pointer") { CHECK(pt.id() == type_id{typename_arg>}); CHECK(pt.data_type().id() == type_db::get().id()); + + CHECK(pt.flags() == (pointer_flags{})); CHECK_FALSE(pt.is_const()); } @@ -44,6 +46,8 @@ TEST_CASE("features/types/pointer") { CHECK(pt.id() == type_id{typename_arg>}); CHECK(pt.data_type().id() == type_db::get().id()); + + CHECK(pt.flags() == (pointer_flags{})); CHECK_FALSE(pt.is_const()); } @@ -57,6 +61,8 @@ TEST_CASE("features/types/pointer") { CHECK(pt.id() == type_id{typename_arg>}); CHECK(pt.data_type().id() == type_db::get().id()); + + CHECK(pt.flags() == (pointer_flags::is_const)); CHECK(pt.is_const()); } @@ -70,6 +76,8 @@ TEST_CASE("features/types/pointer") { CHECK(pt.id() == type_id{typename_arg>}); CHECK(pt.data_type().id() == type_db::get().id()); + + CHECK(pt.flags() == (pointer_flags::is_const)); CHECK(pt.is_const()); } } diff --git a/untests/features/types/reference_type_tests.cpp b/untests/features/types/reference_type_tests.cpp index 6c4617b..49833d3 100644 --- a/untests/features/types/reference_type_tests.cpp +++ b/untests/features/types/reference_type_tests.cpp @@ -29,6 +29,9 @@ TEST_CASE("features/types/reference") { CHECK(rt.id() == type_id{typename_arg>}); CHECK(rt.data_type().id() == type_db::get().id()); + + CHECK(rt.flags() == (reference_flags::is_lvalue)); + CHECK(rt.is_lvalue()); CHECK_FALSE(rt.is_rvalue()); } @@ -41,6 +44,9 @@ TEST_CASE("features/types/reference") { CHECK(rt.id() == type_id{typename_arg>}); CHECK(rt.data_type().id() == type_db::get().id()); + + CHECK(rt.flags() == (reference_flags::is_rvalue)); + CHECK_FALSE(rt.is_lvalue()); CHECK(rt.is_rvalue()); } diff --git a/untests/features/types/void_type_tests.cpp b/untests/features/types/void_type_tests.cpp index f1d8103..95fe709 100644 --- a/untests/features/types/void_type_tests.cpp +++ b/untests/features/types/void_type_tests.cpp @@ -23,6 +23,8 @@ TEST_CASE("features/types/void") { CHECK(vt.id() == type_id{typename_arg>}); CHECK(vt.raw_type().id() == type_db::get().id()); + + CHECK(vt.flags() == (void_flags{})); CHECK_FALSE(vt.is_const()); } @@ -36,6 +38,8 @@ TEST_CASE("features/types/void") { CHECK(vt.id() == type_id{typename_arg>}); CHECK(vt.raw_type().id() == type_db::get().id()); + + CHECK(vt.flags() == (void_flags::is_const)); CHECK(vt.is_const()); } } From 0a0c12b592c1c5a7fb79d0bdb46f5151a1ea2372 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sun, 8 Aug 2021 15:59:03 +0700 Subject: [PATCH 088/233] first version of argument view class --- headers/meta.hpp/meta_fwd.hpp | 35 + headers/meta.hpp/meta_utilities/arg.hpp | 195 +++++ untests/features/utilities/arg_tests.cpp | 1017 +++++++++++++++++++++- 3 files changed, 1246 insertions(+), 1 deletion(-) diff --git a/headers/meta.hpp/meta_fwd.hpp b/headers/meta.hpp/meta_fwd.hpp index 841ebe1..5c2234b 100644 --- a/headers/meta.hpp/meta_fwd.hpp +++ b/headers/meta.hpp/meta_fwd.hpp @@ -112,6 +112,41 @@ namespace meta_hpp inline typename_arg_t typename_arg; } +namespace meta_hpp +{ + template < typename T > + struct add_ptr { + using type = std::add_pointer_t; + }; + + template < typename T > + struct remove_cv { + using type = std::remove_cv_t; + }; + + template < typename T > + struct remove_ref { + using type = std::remove_reference_t; + }; + + template < typename T > + struct remove_cvref { + using type = std::remove_cv_t>; + }; + + template < typename T > + using add_ptr_t = typename add_ptr::type; + + template < typename T > + using remove_cv_t = typename remove_cv::type; + + template < typename T > + using remove_ref_t = typename remove_ref::type; + + template < typename T > + using remove_cvref_t = typename remove_cvref::type; +} + namespace meta_hpp::detail { template < typename K, typename V, typename C, typename A, typename K2, typename U > diff --git a/headers/meta.hpp/meta_utilities/arg.hpp b/headers/meta.hpp/meta_utilities/arg.hpp index a581f49..291a56d 100644 --- a/headers/meta.hpp/meta_utilities/arg.hpp +++ b/headers/meta.hpp/meta_utilities/arg.hpp @@ -11,6 +11,13 @@ namespace meta_hpp { class arg final { + public: + enum class ref_types { + ref, + rref, + cref, + crref, + }; public: arg() = delete; @@ -19,5 +26,193 @@ namespace meta_hpp arg(const arg&) = delete; arg& operator=(const arg&) = delete; + + template < typename T + , std::enable_if_t, int> = 0 > + explicit arg(T&& v); + + template < typename T + , std::enable_if_t, int> = 0 > + explicit arg(T&& v); + + template < typename To > + To cast() const; + + template < typename To > + bool can_cast() const noexcept; + + any_type raw_type() const noexcept; + ref_types ref_type() const noexcept; + + bool is_const() const noexcept; + bool is_lvalue() const noexcept; + bool is_rvalue() const noexcept; + private: + void* data_{}; + any_type raw_type_{}; + ref_types ref_type_{}; }; } + +namespace meta_hpp +{ + template < typename T + , std::enable_if_t, int> > + inline arg::arg(T&& v) + : data_{const_cast>>(std::addressof(v))} + , raw_type_{type_db::get>()} + , ref_type_{std::is_const_v ? ref_types::crref : ref_types::rref} {} + + template < typename T + , std::enable_if_t, int> > + inline arg::arg(T&& v) + : data_{const_cast>>(std::addressof(v))} + , raw_type_{type_db::get>()} + , ref_type_{std::is_const_v> ? ref_types::cref : ref_types::ref} {} + + template < typename To > + inline To arg::cast() const { + if ( !can_cast() ) { + throw std::logic_error("bad argument cast"); + } + + if constexpr ( std::is_pointer_v ) { + return *static_cast(data_); + } + + if constexpr ( std::is_reference_v ) { + using raw_type = remove_cvref_t; + + if constexpr ( std::is_lvalue_reference_v ) { + return *static_cast(data_); + } + + if constexpr ( std::is_rvalue_reference_v ) { + return std::move(*static_cast(data_)); + } + } + + if constexpr ( !std::is_pointer_v && !std::is_reference_v ) { + using raw_type = remove_cvref_t; + + if ( ref_type() == ref_types::ref ) { + if constexpr ( std::is_constructible_v ) { + return To{*static_cast(data_)}; + } + } + + if ( ref_type() == ref_types::cref ) { + if constexpr ( std::is_constructible_v ) { + return To{std::as_const(*static_cast(data_))}; + } + } + + if ( ref_type() == ref_types::rref ) { + if constexpr ( std::is_constructible_v ) { + return To{std::move(*static_cast(data_))}; + } + } + + if ( ref_type() == ref_types::crref ) { + if constexpr ( std::is_constructible_v ) { + return To{std::move(std::as_const(*static_cast(data_)))}; + } + } + } + + throw std::logic_error("bad argument cast"); + } + + template < typename To > + inline bool arg::can_cast() const noexcept { + if constexpr ( std::is_pointer_v ) { + using to_raw_type = remove_cv_t; + using to_raw_ptr_type = remove_cv_t>; + return raw_type().id() == type_db::get().id() + || raw_type().id() == type_db::get>().id(); + } + + if constexpr ( std::is_lvalue_reference_v ) { + constexpr bool to_const = std::is_const_v>; + + if ( !to_const && is_rvalue() ) { + return false; + } + + if ( !to_const && is_const() ) { + return false; + } + + using to_raw_type = remove_cvref_t; + if ( raw_type().id() == type_db::get().id() ) { + return true; + } + + if constexpr ( to_const && std::is_pointer_v ) { + using to_raw_ptr_type = remove_cv_t>; + return raw_type().id() == type_db::get>().id(); + } + + return false; + } + + if constexpr ( std::is_rvalue_reference_v ) { + constexpr bool to_const = std::is_const_v>; + + if ( !is_rvalue() ) { + return false; + } + + if ( !to_const && is_const() ) { + return false; + } + + using to_raw_type = remove_cvref_t; + if ( raw_type().id() == type_db::get().id() ) { + return true; + } + + if constexpr ( to_const && std::is_pointer_v ) { + using to_raw_ptr_type = remove_cv_t>; + return raw_type().id() == type_db::get>().id(); + } + + return false; + } + + if constexpr ( !std::is_pointer_v && !std::is_reference_v ) { + using to_raw_type = remove_cv_t; + if ( raw_type().id() != type_db::get().id() ) { + return false; + } + + return (ref_type() == ref_types::ref && std::is_constructible_v) + || (ref_type() == ref_types::cref && std::is_constructible_v) + || (ref_type() == ref_types::rref && std::is_constructible_v) + || (ref_type() == ref_types::crref && std::is_constructible_v); + } + } + + inline any_type arg::raw_type() const noexcept { + return raw_type_; + } + + inline arg::ref_types arg::ref_type() const noexcept { + return ref_type_; + } + + inline bool arg::is_const() const noexcept { + return ref_type_ == ref_types::cref + || ref_type_ == ref_types::crref; + } + + inline bool arg::is_lvalue() const noexcept { + return ref_type_ == ref_types::ref + || ref_type_ == ref_types::cref; + } + + inline bool arg::is_rvalue() const noexcept { + return ref_type_ == ref_types::rref + || ref_type_ == ref_types::crref; + } +} diff --git a/untests/features/utilities/arg_tests.cpp b/untests/features/utilities/arg_tests.cpp index ed05cf2..4043821 100644 --- a/untests/features/utilities/arg_tests.cpp +++ b/untests/features/utilities/arg_tests.cpp @@ -8,7 +8,1022 @@ namespace { + using namespace meta_hpp; + using namespace std::string_literals; } -TEST_CASE("features/utilities/arg") { +namespace +{ + struct ivec2 { + int x{}; + int y{}; + + [[maybe_unused]] ivec2() = default; + [[maybe_unused]] explicit ivec2(int v): x{v}, y{v} {} + [[maybe_unused]] ivec2(int x, int y): x{x}, y{y} {} + + [[maybe_unused]] ivec2(ivec2&& other) noexcept { + x = other.x; + y = other.y; + other.x = 0; + other.y = 0; + } + + [[maybe_unused]] ivec2(const ivec2& other) noexcept { + x = other.x; + y = other.y; + } + + ivec2& operator=(ivec2&&) = delete; + ivec2& operator=(const ivec2&) = delete; + }; + + struct ivec3 { + int x{}; + int y{}; + int z{}; + + [[maybe_unused]] ivec3() = default; + [[maybe_unused]] explicit ivec3(int v): x{v}, y{v}, z{v} {} + [[maybe_unused]] ivec3(int x, int y, int z): x{x}, y{y}, z{z} {} + + [[maybe_unused]] ivec3(ivec3&& other) noexcept { + x = other.x; + y = other.y; + z = other.z; + other.x = 0; + other.y = 0; + other.z = 0; + } + + [[maybe_unused]] ivec3(const ivec3& other) noexcept { + x = other.x; + y = other.y; + z = other.z; + } + + ivec3& operator=(ivec3&&) = delete; + ivec3& operator=(const ivec3&) = delete; + }; + + [[maybe_unused]] bool operator==(const ivec2& l, const ivec2& r) noexcept { + return l.x == r.x && l.y == r.y; + } + + [[maybe_unused]] bool operator==(const ivec3& l, const ivec3& r) noexcept { + return l.x == r.x && l.y == r.y && l.z == r.z; + } +} + +TEST_CASE("features/utilities/arg/type") { + SUBCASE("ptr") { + ivec2 v{1,2}; + ivec2* vp = &v; + arg a{vp}; + + CHECK(a.raw_type().id() == type_db::get().id()); + CHECK(a.ref_type() == arg::ref_types::ref); + } + + SUBCASE("rptr") { + ivec2 v{1,2}; + ivec2* vp = &v; + arg a{std::move(vp)}; + + CHECK(a.raw_type().id() == type_db::get().id()); + CHECK(a.ref_type() == arg::ref_types::rref); + } + + SUBCASE("ptr_c") { + ivec2 v{1,2}; + ivec2* const vp = &v; + arg a{vp}; + + CHECK(a.raw_type().id() == type_db::get().id()); + CHECK(a.ref_type() == arg::ref_types::cref); + } + + SUBCASE("rptr_c") { + ivec2 v{1,2}; + ivec2* const vp = &v; + arg a{std::move(vp)}; + + CHECK(a.raw_type().id() == type_db::get().id()); + CHECK(a.ref_type() == arg::ref_types::crref); + } + + SUBCASE("cptr") { + const ivec2 v{1,2}; + const ivec2* vp = &v; + arg a{vp}; + + CHECK(a.raw_type().id() == type_db::get().id()); + CHECK(a.ref_type() == arg::ref_types::ref); + } + + SUBCASE("crptr") { + const ivec2 v{1,2}; + const ivec2* vp = &v; + arg a{std::move(vp)}; + + CHECK(a.raw_type().id() == type_db::get().id()); + CHECK(a.ref_type() == arg::ref_types::rref); + } + + SUBCASE("cptr_c") { + const ivec2 v{1,2}; + const ivec2* const vp = &v; + arg a{vp}; + + CHECK(a.raw_type().id() == type_db::get().id()); + CHECK(a.ref_type() == arg::ref_types::cref); + } + + SUBCASE("crptr_c") { + const ivec2 v{1,2}; + const ivec2* const vp = &v; + arg a{std::move(vp)}; + + CHECK(a.raw_type().id() == type_db::get().id()); + CHECK(a.ref_type() == arg::ref_types::crref); + } + + SUBCASE("ref") { + ivec2 v{1,2}; + ivec2& vr = v; + arg a{vr}; + + CHECK(a.raw_type().id() == type_db::get().id()); + CHECK(a.ref_type() == arg::ref_types::ref); + } + + SUBCASE("cref") { + const ivec2 v{1,2}; + const ivec2& vr = v; + arg a{vr}; + + CHECK(a.raw_type().id() == type_db::get().id()); + CHECK(a.ref_type() == arg::ref_types::cref); + } + + SUBCASE("rref") { + ivec2 v{1,2}; + arg a{std::move(v)}; + + CHECK(a.raw_type().id() == type_db::get().id()); + CHECK(a.ref_type() == arg::ref_types::rref); + } + + SUBCASE("crref") { + const ivec2 v{1,2}; + arg a{std::move(v)}; + + CHECK(a.raw_type().id() == type_db::get().id()); + CHECK(a.ref_type() == arg::ref_types::crref); + } +} + +TEST_CASE("features/utilities/arg/can_cast") { + SUBCASE("ptr") { + ivec2 v{1,2}; + ivec2* vp = &v; + arg a{vp}; + + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + + CHECK(a.can_cast()); + CHECK(a.can_cast()); + CHECK(a.can_cast()); + CHECK(a.can_cast()); + + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + + { + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + } + + { + CHECK(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK(a.can_cast()); + CHECK(a.can_cast()); + + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + + []([[maybe_unused]] ivec2 *&){}(vp); + //[]([[maybe_unused]] const ivec2 *&){}(vp); + []([[maybe_unused]] ivec2 *const &){}(vp); + []([[maybe_unused]] const ivec2 *const &){}(vp); + + //[]([[maybe_unused]] ivec2 *&&){}(vp); + //[]([[maybe_unused]] const ivec2 *&&){}(vp); + //[]([[maybe_unused]] ivec2 *const &&){}(vp); + //[]([[maybe_unused]] const ivec2 *const &&){}(vp); + } + } + + SUBCASE("rptr") { + ivec2 v{1,2}; + ivec2* vp = &v; + arg a{std::move(vp)}; + + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + + CHECK(a.can_cast()); + CHECK(a.can_cast()); + CHECK(a.can_cast()); + CHECK(a.can_cast()); + + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + + { + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + } + + { + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK(a.can_cast()); + CHECK(a.can_cast()); + + CHECK(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK(a.can_cast()); + CHECK(a.can_cast()); + + //[]([[maybe_unused]] ivec2 *&){}(std::move(vp)); + //[]([[maybe_unused]] const ivec2 *&){}(std::move(vp)); + []([[maybe_unused]] ivec2 *const &){}(std::move(vp)); + []([[maybe_unused]] const ivec2 *const &){}(std::move(vp)); + + []([[maybe_unused]] ivec2 *&&){}(std::move(vp)); + //[]([[maybe_unused]] const ivec2 *&&){}(std::move(vp)); + []([[maybe_unused]] ivec2 *const &&){}(std::move(vp)); + []([[maybe_unused]] const ivec2 *const &&){}(std::move(vp)); + } + } + + SUBCASE("ptr_c") { + ivec2 v{1,2}; + ivec2* const vp = &v; + arg a{vp}; + + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + + CHECK(a.can_cast()); + CHECK(a.can_cast()); + CHECK(a.can_cast()); + CHECK(a.can_cast()); + + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + + { + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + } + + { + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK(a.can_cast()); + CHECK(a.can_cast()); + + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + + // []([[maybe_unused]] ivec2 *&){}(vp); + // []([[maybe_unused]] const ivec2 *&){}(vp); + []([[maybe_unused]] ivec2 *const &){}(vp); + []([[maybe_unused]] const ivec2 *const &){}(vp); + + //[]([[maybe_unused]] ivec2 *&&){}(vp); + //[]([[maybe_unused]] const ivec2 *&&){}(vp); + //[]([[maybe_unused]] ivec2 *const &&){}(vp); + //[]([[maybe_unused]] const ivec2 *const &&){}(vp); + } + } + + SUBCASE("rptr_c") { + ivec2 v{1,2}; + ivec2* const vp = &v; + arg a{std::move(vp)}; + + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + + CHECK(a.can_cast()); + CHECK(a.can_cast()); + CHECK(a.can_cast()); + CHECK(a.can_cast()); + + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + + { + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + } + + { + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK(a.can_cast()); + CHECK(a.can_cast()); + + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK(a.can_cast()); + CHECK(a.can_cast()); + + //[]([[maybe_unused]] ivec2 *&){}(std::move(vp)); + //[]([[maybe_unused]] const ivec2 *&){}(std::move(vp)); + []([[maybe_unused]] ivec2 *const &){}(std::move(vp)); + []([[maybe_unused]] const ivec2 *const &){}(std::move(vp)); + + //[]([[maybe_unused]] ivec2 *&&){}(std::move(vp)); + //[]([[maybe_unused]] const ivec2 *&&){}(std::move(vp)); + []([[maybe_unused]] ivec2 *const &&){}(std::move(vp)); + []([[maybe_unused]] const ivec2 *const &&){}(std::move(vp)); + } + } + + SUBCASE("cptr") { + const ivec2 v{1,2}; + const ivec2* vp = &v; + arg a{vp}; + + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + + CHECK_FALSE(a.can_cast()); + CHECK(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK(a.can_cast()); + + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + + { + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + } + + { + CHECK_FALSE(a.can_cast()); + CHECK(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK(a.can_cast()); + + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + + //[]([[maybe_unused]] ivec2 *&){}(vp); + []([[maybe_unused]] const ivec2 *&){}(vp); + //[]([[maybe_unused]] ivec2 *const &){}(vp); + []([[maybe_unused]] const ivec2 *const &){}(vp); + + //[]([[maybe_unused]] ivec2 *&&){}(vp); + //[]([[maybe_unused]] const ivec2 *&&){}(vp); + //[]([[maybe_unused]] ivec2 *const &&){}(vp); + //[]([[maybe_unused]] const ivec2 *const &&){}(vp); + } + } + + SUBCASE("crptr") { + const ivec2 v{1,2}; + const ivec2* vp = &v; + arg a{std::move(vp)}; + + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + + CHECK_FALSE(a.can_cast()); + CHECK(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK(a.can_cast()); + + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + + { + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + } + + { + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK(a.can_cast()); + + CHECK_FALSE(a.can_cast()); + CHECK(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK(a.can_cast()); + + //[]([[maybe_unused]] ivec2 *&){}(std::move(vp)); + //[]([[maybe_unused]] const ivec2 *&){}(std::move(vp)); + //[]([[maybe_unused]] ivec2 *const &){}(std::move(vp)); + []([[maybe_unused]] const ivec2 *const &){}(std::move(vp)); + + //[]([[maybe_unused]] ivec2 *&&){}(std::move(vp)); + []([[maybe_unused]] const ivec2 *&&){}(std::move(vp)); + //[]([[maybe_unused]] ivec2 *const &&){}(std::move(vp)); + []([[maybe_unused]] const ivec2 *const &&){}(std::move(vp)); + } + } + + SUBCASE("cptr_c") { + const ivec2 v{1,2}; + const ivec2* const vp = &v; + arg a{vp}; + + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK(a.can_cast()); + + CHECK_FALSE(a.can_cast()); + CHECK(a.can_cast()); + + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + + { + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + } + + { + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK(a.can_cast()); + + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + + //[]([[maybe_unused]] ivec2 *&){}(vp); + //[]([[maybe_unused]] const ivec2 *&){}(vp); + //[]([[maybe_unused]] ivec2 *const &){}(vp); + []([[maybe_unused]] const ivec2 *const &){}(vp); + + //[]([[maybe_unused]] ivec2 *&&){}(vp); + //[]([[maybe_unused]] const ivec2 *&&){}(vp); + //[]([[maybe_unused]] ivec2 *const &&){}(vp); + //[]([[maybe_unused]] const ivec2 *const &&){}(vp); + } + } + + SUBCASE("crptr_c") { + const ivec2 v{1,2}; + const ivec2* const vp = &v; + arg a{std::move(vp)}; + + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + + CHECK_FALSE(a.can_cast()); + CHECK(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK(a.can_cast()); + + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + + { + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + } + + { + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK(a.can_cast()); + + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK(a.can_cast()); + + //[]([[maybe_unused]] ivec2 *&){}(std::move(vp)); + //[]([[maybe_unused]] const ivec2 *&){}(std::move(vp)); + //[]([[maybe_unused]] ivec2 *const &){}(std::move(vp)); + []([[maybe_unused]] const ivec2 *const &){}(std::move(vp)); + + //[]([[maybe_unused]] ivec2 *&&){}(std::move(vp)); + //[]([[maybe_unused]] const ivec2 *&&){}(std::move(vp)); + //[]([[maybe_unused]] ivec2 *const &&){}(std::move(vp)); + []([[maybe_unused]] const ivec2 *const &&){}(std::move(vp)); + } + } + + SUBCASE("ref") { + ivec2 v{1,2}; + ivec2& vr = v; + arg a{vr}; + + CHECK(a.can_cast()); + CHECK(a.can_cast()); + + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + + CHECK(a.can_cast()); + CHECK(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + + { + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + } + + { + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + } + } + + SUBCASE("cref") { + const ivec2 v{1,2}; + const ivec2& vr = v; + arg a{vr}; + + CHECK(a.can_cast()); + CHECK(a.can_cast()); + + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + + CHECK_FALSE(a.can_cast()); + CHECK(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + + { + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + } + + { + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + } + } + + SUBCASE("rref") { + ivec2 v{1,2}; + arg a{std::move(v)}; + + CHECK(a.can_cast()); + CHECK(a.can_cast()); + + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + + CHECK_FALSE(a.can_cast()); + CHECK(a.can_cast()); + CHECK(a.can_cast()); + CHECK(a.can_cast()); + + { + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + } + + { + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + } + } + + SUBCASE("crref") { + const ivec2 v{1,2}; + arg a{std::move(v)}; + + CHECK(a.can_cast()); + CHECK(a.can_cast()); + + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + + CHECK_FALSE(a.can_cast()); + CHECK(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK(a.can_cast()); + + { + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + } + + { + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast()); + } + } +} + +TEST_CASE("features/utilities/arg/cast") { + SUBCASE("ptr") { + ivec2 v{1,2}; + ivec2* vp = &v; + arg a{vp}; + + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + + CHECK(a.cast() == vp); + CHECK(a.cast() == vp); + CHECK(a.cast() == vp); + CHECK(a.cast() == vp); + + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + + { + CHECK(a.cast() == vp); + CHECK_THROWS(a.cast()); + CHECK(a.cast() == vp); + CHECK(a.cast() == vp); + + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + } + } + + SUBCASE("rptr") { + ivec2 v{1,2}; + ivec2* vp = &v; + + CHECK_THROWS(arg{std::move(vp)}.cast()); + CHECK_THROWS(arg{std::move(vp)}.cast()); + + CHECK(arg{std::move(vp)}.cast() == vp); + CHECK(arg{std::move(vp)}.cast() == vp); + CHECK(arg{std::move(vp)}.cast() == vp); + CHECK(arg{std::move(vp)}.cast() == vp); + + CHECK_THROWS(arg{std::move(vp)}.cast()); + CHECK_THROWS(arg{std::move(vp)}.cast()); + CHECK_THROWS(arg{std::move(vp)}.cast()); + CHECK_THROWS(arg{std::move(vp)}.cast()); + + { + CHECK_THROWS(arg{std::move(vp)}.cast()); + CHECK_THROWS(arg{std::move(vp)}.cast()); + CHECK(arg{std::move(vp)}.cast() == vp); + CHECK(arg{std::move(vp)}.cast() == vp); + + CHECK(arg{std::move(vp)}.cast() == vp); + CHECK_THROWS(arg{std::move(vp)}.cast()); + CHECK(arg{std::move(vp)}.cast() == vp); + CHECK(arg{std::move(vp)}.cast() == vp); + } + } + + SUBCASE("ptr_c") { + ivec2 v{1,2}; + ivec2* const vp = &v; + arg a{vp}; + + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + + CHECK(a.cast() == vp); + CHECK(a.cast() == vp); + CHECK(a.cast() == vp); + CHECK(a.cast() == vp); + + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + + { + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK(a.cast() == vp); + CHECK(a.cast() == vp); + + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + } + } + + SUBCASE("rptr_c") { + ivec2 v{1,2}; + ivec2* const vp = &v; + + CHECK_THROWS(arg{std::move(vp)}.cast()); + CHECK_THROWS(arg{std::move(vp)}.cast()); + + CHECK(arg{std::move(vp)}.cast() == vp); + CHECK(arg{std::move(vp)}.cast() == vp); + CHECK(arg{std::move(vp)}.cast() == vp); + CHECK(arg{std::move(vp)}.cast() == vp); + + CHECK_THROWS(arg{std::move(vp)}.cast()); + CHECK_THROWS(arg{std::move(vp)}.cast()); + CHECK_THROWS(arg{std::move(vp)}.cast()); + CHECK_THROWS(arg{std::move(vp)}.cast()); + + { + CHECK_THROWS(arg{std::move(vp)}.cast()); + CHECK_THROWS(arg{std::move(vp)}.cast()); + CHECK(arg{std::move(vp)}.cast() == vp); + CHECK(arg{std::move(vp)}.cast() == vp); + + CHECK_THROWS(arg{std::move(vp)}.cast()); + CHECK_THROWS(arg{std::move(vp)}.cast()); + CHECK(arg{std::move(vp)}.cast() == vp); + CHECK(arg{std::move(vp)}.cast() == vp); + } + } + + SUBCASE("cptr") { + const ivec2 v{1,2}; + const ivec2* vp = &v; + arg a{vp}; + + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + + CHECK_THROWS(a.cast()); + CHECK(a.cast() == vp); + CHECK_THROWS(a.cast()); + CHECK(a.cast() == vp); + + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + + { + CHECK_THROWS(a.cast()); + CHECK(a.cast() == vp); + CHECK_THROWS(a.cast()); + CHECK(a.cast() == vp); + + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + } + } + + SUBCASE("crptr") { + const ivec2 v{1,2}; + const ivec2* vp = &v; + + CHECK_THROWS(arg{std::move(vp)}.cast()); + CHECK_THROWS(arg{std::move(vp)}.cast()); + + CHECK_THROWS(arg{std::move(vp)}.cast()); + CHECK(arg{std::move(vp)}.cast() == vp); + CHECK_THROWS(arg{std::move(vp)}.cast()); + CHECK(arg{std::move(vp)}.cast() == vp); + + CHECK_THROWS(arg{std::move(vp)}.cast()); + CHECK_THROWS(arg{std::move(vp)}.cast()); + CHECK_THROWS(arg{std::move(vp)}.cast()); + CHECK_THROWS(arg{std::move(vp)}.cast()); + + { + CHECK_THROWS(arg{std::move(vp)}.cast()); + CHECK_THROWS(arg{std::move(vp)}.cast()); + CHECK_THROWS(arg{std::move(vp)}.cast()); + CHECK(arg{std::move(vp)}.cast() == vp); + + CHECK_THROWS(arg{std::move(vp)}.cast()); + CHECK(arg{std::move(vp)}.cast() == vp); + CHECK_THROWS(arg{std::move(vp)}.cast()); + CHECK(arg{std::move(vp)}.cast() == vp); + } + } + + SUBCASE("cptr_c") { + const ivec2 v{1,2}; + const ivec2* const vp = &v; + arg a{vp}; + + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + + CHECK_THROWS(a.cast()); + CHECK(a.cast() == vp); + CHECK_THROWS(a.cast()); + CHECK(a.cast() == vp); + + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + + { + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK(a.cast() == vp); + + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + } + } + + SUBCASE("crptr_c") { + const ivec2 v{1,2}; + const ivec2* const vp = &v; + + CHECK_THROWS(arg{std::move(vp)}.cast()); + CHECK_THROWS(arg{std::move(vp)}.cast()); + + CHECK_THROWS(arg{std::move(vp)}.cast()); + CHECK(arg{std::move(vp)}.cast() == vp); + CHECK_THROWS(arg{std::move(vp)}.cast()); + CHECK(arg{std::move(vp)}.cast() == vp); + + CHECK_THROWS(arg{std::move(vp)}.cast()); + CHECK_THROWS(arg{std::move(vp)}.cast()); + CHECK_THROWS(arg{std::move(vp)}.cast()); + CHECK_THROWS(arg{std::move(vp)}.cast()); + + { + CHECK_THROWS(arg{std::move(vp)}.cast()); + CHECK_THROWS(arg{std::move(vp)}.cast()); + CHECK_THROWS(arg{std::move(vp)}.cast()); + CHECK(arg{std::move(vp)}.cast() == vp); + + CHECK_THROWS(arg{std::move(vp)}.cast()); + CHECK_THROWS(arg{std::move(vp)}.cast()); + CHECK_THROWS(arg{std::move(vp)}.cast()); + CHECK(arg{std::move(vp)}.cast() == vp); + } + } + + SUBCASE("ref") { + ivec2 v{1,2}; + ivec2& vr = v; + arg a{vr}; + + CHECK(a.cast() == ivec2{1,2}); + CHECK(a.cast() == ivec2{1,2}); + + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + + CHECK(&a.cast() == &v); + CHECK(&a.cast() == &vr); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + } + + SUBCASE("cref") { + const ivec2 v{1,2}; + const ivec2& vr = v; + arg a{vr}; + + CHECK(a.cast() == v); + CHECK(a.cast() == v); + + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + + CHECK_THROWS(a.cast()); + CHECK(&a.cast() == &vr); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + } + + SUBCASE("rref") { + CHECK(arg{ivec2{1,2}}.cast() == ivec2{1,2}); + CHECK(arg{ivec2{1,2}}.cast() == ivec2{1,2}); + + CHECK_THROWS(arg{ivec2{1,2}}.cast()); + CHECK_THROWS(arg{ivec2{1,2}}.cast()); + CHECK_THROWS(arg{ivec2{1,2}}.cast()); + CHECK_THROWS(arg{ivec2{1,2}}.cast()); + + CHECK_THROWS(arg{ivec2{1,2}}.cast()); + CHECK(arg{ivec2{1,2}}.cast() == ivec2{1,2}); + CHECK(arg{ivec2{1,2}}.cast() == ivec2{1,2}); + CHECK(arg{ivec2{1,2}}.cast() == ivec2{1,2}); + } + + SUBCASE("crref") { + const ivec2 v{1,2}; + arg a{std::move(v)}; + + CHECK(a.cast() == ivec2{1,2}); + CHECK(a.cast() == ivec2{1,2}); + + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + + CHECK_THROWS(a.cast()); + CHECK(&a.cast() == &v); + CHECK_THROWS(a.cast()); + CHECK(a.cast() == v); + } } From 7f944eff92c82e736365ffc50f0525af8da3163c Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sun, 8 Aug 2021 18:56:25 +0700 Subject: [PATCH 089/233] hide any_type ctor --- headers/meta.hpp/meta_types.hpp | 2 +- headers/meta.hpp/meta_types/_types_fwd.hpp | 33 ++++++++++--------- .../meta.hpp/meta_types/arithmetic_type.hpp | 10 +++--- headers/meta.hpp/meta_types/array_type.hpp | 4 +-- headers/meta.hpp/meta_types/class_type.hpp | 10 +++--- headers/meta.hpp/meta_types/ctor_type.hpp | 4 +-- headers/meta.hpp/meta_types/enum_type.hpp | 10 +++--- headers/meta.hpp/meta_types/function_type.hpp | 4 +-- headers/meta.hpp/meta_types/member_type.hpp | 4 +-- headers/meta.hpp/meta_types/method_type.hpp | 4 +-- headers/meta.hpp/meta_types/pointer_type.hpp | 4 +-- .../meta.hpp/meta_types/reference_type.hpp | 4 +-- headers/meta.hpp/meta_types/void_type.hpp | 10 +++--- .../features/types/arithmetic_type_tests.cpp | 2 +- untests/features/types/class_type_tests.cpp | 9 ++--- untests/features/types/enum_type_tests.cpp | 3 +- untests/features/types/void_type_tests.cpp | 3 +- 17 files changed, 63 insertions(+), 57 deletions(-) diff --git a/headers/meta.hpp/meta_types.hpp b/headers/meta.hpp/meta_types.hpp index 39d7152..00db3db 100644 --- a/headers/meta.hpp/meta_types.hpp +++ b/headers/meta.hpp/meta_types.hpp @@ -72,7 +72,7 @@ namespace meta_hpp template < typename T > inline any_type type_db::get() { static const auto raw_type = detail::make_any_type(); - return raw_type; + return any_type{raw_type}; } template < typename Tuple > diff --git a/headers/meta.hpp/meta_types/_types_fwd.hpp b/headers/meta.hpp/meta_types/_types_fwd.hpp index b160c9f..3910e6d 100644 --- a/headers/meta.hpp/meta_types/_types_fwd.hpp +++ b/headers/meta.hpp/meta_types/_types_fwd.hpp @@ -72,22 +72,22 @@ namespace std namespace meta_hpp { - class base_type { + class type_base { public: template < typename... Ts > struct tag {}; public: - base_type() = default; - virtual ~base_type() = default; + type_base() = default; + virtual ~type_base() = default; - base_type(base_type&&) = default; - base_type& operator=(base_type&&) = default; + type_base(type_base&&) = default; + type_base& operator=(type_base&&) = default; - base_type(const base_type&) = default; - base_type& operator=(const base_type&) = default; + type_base(const type_base&) = default; + type_base& operator=(const type_base&) = default; template < typename... Ts > - explicit base_type(typename_arg_t) + explicit type_base(typename_arg_t) : id_{typename_arg>} {} type_id id() const noexcept { @@ -114,11 +114,6 @@ namespace meta_hpp any_type(const any_type&) = default; any_type& operator=(const any_type&) = default; - template < typename T, std::enable_if_t, int> = 0 > - any_type(const T& type) - : id_{type.id()} - , type_{std::addressof(type)} {} - type_id id() const noexcept { return id_; } @@ -128,16 +123,24 @@ namespace meta_hpp } template < typename T > - std::enable_if_t, T> as() const noexcept { + std::enable_if_t, T> as() const noexcept { using Tptr = std::add_pointer_t>; return is() ? *std::get(type_) : T{}; } template < typename T > - std::enable_if_t, bool> is() const noexcept { + std::enable_if_t, bool> is() const noexcept { using Tptr = std::add_pointer_t>; return std::holds_alternative(type_); } + private: + friend class type_db; + + template < typename T + , std::enable_if_t, int> = 0 > + explicit any_type(const T& type) + : id_{type.id()} + , type_{std::addressof(type)} {} private: type_id id_; std::variant< diff --git a/headers/meta.hpp/meta_types/arithmetic_type.hpp b/headers/meta.hpp/meta_types/arithmetic_type.hpp index 7a3d5e6..1e1d142 100644 --- a/headers/meta.hpp/meta_types/arithmetic_type.hpp +++ b/headers/meta.hpp/meta_types/arithmetic_type.hpp @@ -20,7 +20,7 @@ namespace meta_hpp ENUM_HPP_OPERATORS_DECL(arithmetic_flags) - class arithmetic_type final : public base_type { + class arithmetic_type final : public type_base { public: arithmetic_type() = default; @@ -57,10 +57,10 @@ namespace meta_hpp::detail struct arithmetic_traits>> { static constexpr std::size_t size{sizeof(T)}; - static any_type make_raw_type(const arithmetic_type& self) { + static any_type make_raw_type() { using raw_type = std::remove_const_t; return std::is_same_v - ? any_type{self} + ? any_type{} : type_db::get(); } @@ -86,10 +86,10 @@ namespace meta_hpp template < typename T > inline arithmetic_type::arithmetic_type(typename_arg_t) - : base_type{typename_arg} + : type_base{typename_arg} , state_{std::make_shared(state{ detail::arithmetic_traits::size, - detail::arithmetic_traits::make_raw_type(*this), + detail::arithmetic_traits::make_raw_type(), detail::arithmetic_traits::make_flags(), })} { static_assert(std::is_arithmetic_v); diff --git a/headers/meta.hpp/meta_types/array_type.hpp b/headers/meta.hpp/meta_types/array_type.hpp index 94e766d..c0dce99 100644 --- a/headers/meta.hpp/meta_types/array_type.hpp +++ b/headers/meta.hpp/meta_types/array_type.hpp @@ -17,7 +17,7 @@ namespace meta_hpp ENUM_HPP_OPERATORS_DECL(array_flags) - class array_type final : public base_type { + class array_type final : public type_base { public: array_type() = default; @@ -89,7 +89,7 @@ namespace meta_hpp { template < typename T > inline array_type::array_type(typename_arg_t) - : base_type{typename_arg} + : type_base{typename_arg} , state_{std::make_shared(state{ detail::array_traits::extent, detail::array_traits::make_data_type(), diff --git a/headers/meta.hpp/meta_types/class_type.hpp b/headers/meta.hpp/meta_types/class_type.hpp index 70e1628..008d039 100644 --- a/headers/meta.hpp/meta_types/class_type.hpp +++ b/headers/meta.hpp/meta_types/class_type.hpp @@ -20,7 +20,7 @@ namespace meta_hpp ENUM_HPP_OPERATORS_DECL(class_flags) - class class_type final : public base_type { + class class_type final : public type_base { public: class_type() = default; @@ -57,10 +57,10 @@ namespace meta_hpp::detail struct class_traits>> { static constexpr std::size_t size{sizeof(T)}; - static any_type make_raw_type(const class_type& self) { + static any_type make_raw_type() { using raw_type = std::remove_const_t; return std::is_same_v - ? any_type{self} + ? any_type{} : type_db::get(); } @@ -86,10 +86,10 @@ namespace meta_hpp template < typename T > inline class_type::class_type(typename_arg_t) - : base_type{typename_arg} + : type_base{typename_arg} , state_{std::make_shared(state{ detail::class_traits::size, - detail::class_traits::make_raw_type(*this), + detail::class_traits::make_raw_type(), detail::class_traits::make_flags(), })} { static_assert(std::is_class_v); diff --git a/headers/meta.hpp/meta_types/ctor_type.hpp b/headers/meta.hpp/meta_types/ctor_type.hpp index 871ff9a..c14d305 100644 --- a/headers/meta.hpp/meta_types/ctor_type.hpp +++ b/headers/meta.hpp/meta_types/ctor_type.hpp @@ -16,7 +16,7 @@ namespace meta_hpp ENUM_HPP_OPERATORS_DECL(ctor_flags) - class ctor_type final : public base_type { + class ctor_type final : public type_base { public: ctor_type() = default; @@ -78,7 +78,7 @@ namespace meta_hpp template < typename Class, typename... Args > inline ctor_type::ctor_type(typename_arg_t, typename_arg_t) - : base_type{typename_arg} + : type_base{typename_arg} , state_{std::make_shared(state{ detail::ctor_traits::arity, detail::ctor_traits::make_class_type(), diff --git a/headers/meta.hpp/meta_types/enum_type.hpp b/headers/meta.hpp/meta_types/enum_type.hpp index eaec0cf..3a25707 100644 --- a/headers/meta.hpp/meta_types/enum_type.hpp +++ b/headers/meta.hpp/meta_types/enum_type.hpp @@ -16,7 +16,7 @@ namespace meta_hpp ENUM_HPP_OPERATORS_DECL(enum_flags) - class enum_type final : public base_type { + class enum_type final : public type_base { public: enum_type() = default; @@ -47,10 +47,10 @@ namespace meta_hpp::detail template < typename T > struct enum_traits>> { - static any_type make_raw_type(const enum_type& self) { + static any_type make_raw_type() { using raw_type = std::remove_const_t; return std::is_same_v - ? any_type{self} + ? any_type{} : type_db::get(); } @@ -77,9 +77,9 @@ namespace meta_hpp template < typename T > inline enum_type::enum_type(typename_arg_t) - : base_type{typename_arg} + : type_base{typename_arg} , state_{std::make_shared(state{ - detail::enum_traits::make_raw_type(*this), + detail::enum_traits::make_raw_type(), detail::enum_traits::make_underlying_type(), detail::enum_traits::make_flags(), })} { diff --git a/headers/meta.hpp/meta_types/function_type.hpp b/headers/meta.hpp/meta_types/function_type.hpp index 7008368..34f00ad 100644 --- a/headers/meta.hpp/meta_types/function_type.hpp +++ b/headers/meta.hpp/meta_types/function_type.hpp @@ -16,7 +16,7 @@ namespace meta_hpp ENUM_HPP_OPERATORS_DECL(function_flags) - class function_type final : public base_type { + class function_type final : public type_base { public: function_type() = default; @@ -85,7 +85,7 @@ namespace meta_hpp template < typename T > inline function_type::function_type(typename_arg_t) - : base_type{typename_arg} + : type_base{typename_arg} , state_{std::make_shared(state{ detail::function_pointer_traits::arity, detail::function_pointer_traits::make_return_type(), diff --git a/headers/meta.hpp/meta_types/member_type.hpp b/headers/meta.hpp/meta_types/member_type.hpp index 3fdcea7..8c01fc0 100644 --- a/headers/meta.hpp/meta_types/member_type.hpp +++ b/headers/meta.hpp/meta_types/member_type.hpp @@ -10,7 +10,7 @@ namespace meta_hpp { - class member_type final : public base_type { + class member_type final : public type_base { public: member_type() = default; @@ -62,7 +62,7 @@ namespace meta_hpp { template < typename T > inline member_type::member_type(typename_arg_t) - : base_type{typename_arg} + : type_base{typename_arg} , state_{std::make_shared(state{ detail::member_pointer_traits::make_class_type(), detail::member_pointer_traits::make_value_type(), diff --git a/headers/meta.hpp/meta_types/method_type.hpp b/headers/meta.hpp/meta_types/method_type.hpp index 8ee04ee..e377d71 100644 --- a/headers/meta.hpp/meta_types/method_type.hpp +++ b/headers/meta.hpp/meta_types/method_type.hpp @@ -17,7 +17,7 @@ namespace meta_hpp ENUM_HPP_OPERATORS_DECL(method_flags) - class method_type final : public base_type { + class method_type final : public type_base { public: method_type() = default; @@ -108,7 +108,7 @@ namespace meta_hpp template < typename T > inline method_type::method_type(typename_arg_t) - : base_type{typename_arg} + : type_base{typename_arg} , state_{std::make_shared(state{ detail::method_pointer_traits::arity, detail::method_pointer_traits::make_class_type(), diff --git a/headers/meta.hpp/meta_types/pointer_type.hpp b/headers/meta.hpp/meta_types/pointer_type.hpp index db2c431..5cdb830 100644 --- a/headers/meta.hpp/meta_types/pointer_type.hpp +++ b/headers/meta.hpp/meta_types/pointer_type.hpp @@ -14,7 +14,7 @@ namespace meta_hpp is_const = 1 << 0, }; - class pointer_type final : public base_type { + class pointer_type final : public type_base { public: pointer_type() = default; @@ -76,7 +76,7 @@ namespace meta_hpp template < typename T > inline pointer_type::pointer_type(typename_arg_t) - : base_type{typename_arg} + : type_base{typename_arg} , state_{std::make_shared(state{ detail::pointer_traits::make_data_type(), detail::pointer_traits::make_flags(), diff --git a/headers/meta.hpp/meta_types/reference_type.hpp b/headers/meta.hpp/meta_types/reference_type.hpp index 8c9d24b..c9732af 100644 --- a/headers/meta.hpp/meta_types/reference_type.hpp +++ b/headers/meta.hpp/meta_types/reference_type.hpp @@ -17,7 +17,7 @@ namespace meta_hpp ENUM_HPP_OPERATORS_DECL(reference_flags) - class reference_type final : public base_type { + class reference_type final : public type_base { public: reference_type() = default; @@ -80,7 +80,7 @@ namespace meta_hpp template < typename T > inline reference_type::reference_type(typename_arg_t) - : base_type{typename_arg} + : type_base{typename_arg} , state_{std::make_shared(state{ detail::reference_traits::make_data_type(), detail::reference_traits::make_flags(), diff --git a/headers/meta.hpp/meta_types/void_type.hpp b/headers/meta.hpp/meta_types/void_type.hpp index 63b8f53..8dbf265 100644 --- a/headers/meta.hpp/meta_types/void_type.hpp +++ b/headers/meta.hpp/meta_types/void_type.hpp @@ -16,7 +16,7 @@ namespace meta_hpp ENUM_HPP_OPERATORS_DECL(void_flags) - class void_type final : public base_type { + class void_type final : public type_base { public: void_type() = default; @@ -54,10 +54,10 @@ namespace meta_hpp::detail template < typename T > struct void_traits>> { - static any_type make_raw_type(const void_type& self) { + static any_type make_raw_type() { using raw_type = std::remove_const_t; return std::is_same_v - ? any_type{self} + ? any_type{} : type_db::get(); } @@ -73,9 +73,9 @@ namespace meta_hpp { template < typename T > inline void_type::void_type(typename_arg_t) - : base_type{typename_arg} + : type_base{typename_arg} , state_{std::make_shared(state{ - detail::void_traits::make_raw_type(*this), + detail::void_traits::make_raw_type(), detail::void_traits::make_flags(), })} { static_assert(std::is_void_v); diff --git a/untests/features/types/arithmetic_type_tests.cpp b/untests/features/types/arithmetic_type_tests.cpp index 4d71486..4a0de20 100644 --- a/untests/features/types/arithmetic_type_tests.cpp +++ b/untests/features/types/arithmetic_type_tests.cpp @@ -22,7 +22,7 @@ TEST_CASE("features/types/arithmetic") { const arithmetic_type at = type_db::get().as(); CHECK(at.id() == type_id{typename_arg>}); - CHECK(at.raw_type().id() == type_db::get().id()); + CHECK_FALSE(at.raw_type()); CHECK(at.size() == sizeof(type)); CHECK(at.flags() == ( diff --git a/untests/features/types/class_type_tests.cpp b/untests/features/types/class_type_tests.cpp index 16ea475..3163b89 100644 --- a/untests/features/types/class_type_tests.cpp +++ b/untests/features/types/class_type_tests.cpp @@ -40,7 +40,7 @@ TEST_CASE("features/types/class") { const class_type ct = type_db::get().as(); CHECK(ct.id() == type_id{typename_arg>}); - CHECK(ct.raw_type().id() == type_db::get().id()); + CHECK_FALSE(ct.raw_type()); CHECK(ct.size() == sizeof(type)); CHECK(ct.flags() == ( @@ -63,7 +63,7 @@ TEST_CASE("features/types/class") { const class_type ct = type_db::get().as(); CHECK(ct.id() == type_id{typename_arg>}); - CHECK(ct.raw_type().id() == type_db::get().id()); + CHECK_FALSE(ct.raw_type()); CHECK(ct.size() == sizeof(type)); CHECK(ct.flags() == ( @@ -86,7 +86,7 @@ TEST_CASE("features/types/class") { const class_type ct = type_db::get().as(); CHECK(ct.id() == type_id{typename_arg>}); - CHECK(ct.raw_type().id() == type_db::get().id()); + CHECK_FALSE(ct.raw_type()); CHECK(ct.size() == sizeof(type)); CHECK(ct.flags() == ( @@ -109,7 +109,7 @@ TEST_CASE("features/types/class") { const class_type ct = type_db::get().as(); CHECK(ct.id() == type_id{typename_arg>}); - CHECK(ct.raw_type().id() == type_db::get().id()); + CHECK_FALSE(ct.raw_type()); CHECK(ct.size() == sizeof(type)); CHECK(ct.flags() == ( @@ -131,6 +131,7 @@ TEST_CASE("features/types/class") { const class_type ct = type_db::get().as(); CHECK(ct.id() == type_id{typename_arg>}); + REQUIRE(ct.raw_type()); CHECK(ct.raw_type().id() == type_db::get().id()); CHECK(ct.size() == sizeof(type)); diff --git a/untests/features/types/enum_type_tests.cpp b/untests/features/types/enum_type_tests.cpp index f7d1195..52841c5 100644 --- a/untests/features/types/enum_type_tests.cpp +++ b/untests/features/types/enum_type_tests.cpp @@ -31,7 +31,7 @@ TEST_CASE("features/types/enum") { const enum_type et = type_db::get().as(); CHECK(et.id() == type_id{typename_arg>}); - CHECK(et.raw_type().id() == type_db::get().id()); + CHECK_FALSE(et.raw_type()); CHECK(et.underlying_type().id() == type_db::get().id()); CHECK(et.flags() == (enum_flags{})); @@ -47,6 +47,7 @@ TEST_CASE("features/types/enum") { const enum_type et = type_db::get().as(); CHECK(et.id() == type_id{typename_arg>}); + REQUIRE(et.raw_type()); CHECK(et.raw_type().id() == type_db::get().id()); CHECK(et.underlying_type().id() == type_db::get().id()); diff --git a/untests/features/types/void_type_tests.cpp b/untests/features/types/void_type_tests.cpp index 95fe709..b9740f8 100644 --- a/untests/features/types/void_type_tests.cpp +++ b/untests/features/types/void_type_tests.cpp @@ -22,7 +22,7 @@ TEST_CASE("features/types/void") { const void_type vt = type_db::get().as(); CHECK(vt.id() == type_id{typename_arg>}); - CHECK(vt.raw_type().id() == type_db::get().id()); + CHECK_FALSE(vt.raw_type()); CHECK(vt.flags() == (void_flags{})); CHECK_FALSE(vt.is_const()); @@ -37,6 +37,7 @@ TEST_CASE("features/types/void") { const void_type vt = type_db::get().as(); CHECK(vt.id() == type_id{typename_arg>}); + REQUIRE(vt.raw_type()); CHECK(vt.raw_type().id() == type_db::get().id()); CHECK(vt.flags() == (void_flags::is_const)); From a9dafed5b5fc0555ae8811efac926a892d8dc2c2 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sun, 8 Aug 2021 19:23:38 +0700 Subject: [PATCH 090/233] hide type_id ctor --- headers/meta.hpp/meta_infos/ctor_info.hpp | 2 +- headers/meta.hpp/meta_infos/enum_info.hpp | 2 +- headers/meta.hpp/meta_infos/evalue_info.hpp | 2 +- headers/meta.hpp/meta_infos/function_info.hpp | 2 +- headers/meta.hpp/meta_infos/member_info.hpp | 2 +- headers/meta.hpp/meta_infos/method_info.hpp | 2 +- headers/meta.hpp/meta_registry/class_.hpp | 20 +++++++++---------- headers/meta.hpp/meta_registry/ctor_.hpp | 6 +++--- headers/meta.hpp/meta_registry/data_.hpp | 2 +- headers/meta.hpp/meta_registry/enum_.hpp | 10 +++++----- headers/meta.hpp/meta_registry/evalue_.hpp | 8 ++++---- headers/meta.hpp/meta_registry/function_.hpp | 8 ++++---- headers/meta.hpp/meta_registry/member_.hpp | 8 ++++---- headers/meta.hpp/meta_registry/method_.hpp | 8 ++++---- headers/meta.hpp/meta_registry/namespace_.hpp | 8 ++++---- headers/meta.hpp/meta_types/_types_fwd.hpp | 18 +++++++++-------- .../meta.hpp/meta_types/arithmetic_type.hpp | 4 ++-- headers/meta.hpp/meta_types/array_type.hpp | 4 ++-- headers/meta.hpp/meta_types/class_type.hpp | 4 ++-- headers/meta.hpp/meta_types/ctor_type.hpp | 2 +- headers/meta.hpp/meta_types/enum_type.hpp | 4 ++-- headers/meta.hpp/meta_types/function_type.hpp | 4 ++-- headers/meta.hpp/meta_types/member_type.hpp | 4 ++-- headers/meta.hpp/meta_types/method_type.hpp | 4 ++-- headers/meta.hpp/meta_types/pointer_type.hpp | 4 ++-- .../meta.hpp/meta_types/reference_type.hpp | 4 ++-- headers/meta.hpp/meta_types/void_type.hpp | 4 ++-- .../features/types/arithmetic_type_tests.cpp | 3 --- untests/features/types/array_type_tests.cpp | 2 -- untests/features/types/class_type_tests.cpp | 5 ----- untests/features/types/enum_type_tests.cpp | 2 -- untests/features/types/pointer_type_tests.cpp | 4 ---- .../features/types/reference_type_tests.cpp | 2 -- untests/features/types/void_type_tests.cpp | 2 -- 34 files changed, 76 insertions(+), 94 deletions(-) diff --git a/headers/meta.hpp/meta_infos/ctor_info.hpp b/headers/meta.hpp/meta_infos/ctor_info.hpp index 970840c..5e6069f 100644 --- a/headers/meta.hpp/meta_infos/ctor_info.hpp +++ b/headers/meta.hpp/meta_infos/ctor_info.hpp @@ -85,7 +85,7 @@ namespace meta_hpp namespace meta_hpp { template < typename Class, typename... Args > - inline ctor_info::ctor_info(typename_arg_t, typename_arg_t) + ctor_info::ctor_info(typename_arg_t, typename_arg_t) : state_{std::make_shared(state{ ctor_type{typename_arg, typename_arg}, {} diff --git a/headers/meta.hpp/meta_infos/enum_info.hpp b/headers/meta.hpp/meta_infos/enum_info.hpp index 1e37ba6..44ffb44 100644 --- a/headers/meta.hpp/meta_infos/enum_info.hpp +++ b/headers/meta.hpp/meta_infos/enum_info.hpp @@ -109,7 +109,7 @@ namespace meta_hpp namespace meta_hpp { template < typename Enum > - inline enum_info::enum_info(typename_arg_t, std::string name) + enum_info::enum_info(typename_arg_t, std::string name) : state_{std::make_shared(state{ std::move(name), type_db::get().template as(), diff --git a/headers/meta.hpp/meta_infos/evalue_info.hpp b/headers/meta.hpp/meta_infos/evalue_info.hpp index 7bb90a8..e516f72 100644 --- a/headers/meta.hpp/meta_infos/evalue_info.hpp +++ b/headers/meta.hpp/meta_infos/evalue_info.hpp @@ -91,7 +91,7 @@ namespace meta_hpp namespace meta_hpp { template < typename Enum > - inline evalue_info::evalue_info(std::string name, Enum value) + evalue_info::evalue_info(std::string name, Enum value) : state_{std::make_shared(state{ std::move(name), std::move(value), diff --git a/headers/meta.hpp/meta_infos/function_info.hpp b/headers/meta.hpp/meta_infos/function_info.hpp index b25c453..3b12110 100644 --- a/headers/meta.hpp/meta_infos/function_info.hpp +++ b/headers/meta.hpp/meta_infos/function_info.hpp @@ -91,7 +91,7 @@ namespace meta_hpp namespace meta_hpp { template < typename Function > - inline function_info::function_info(std::string name, Function instance) + function_info::function_info(std::string name, Function instance) : state_{std::make_shared(state{ std::move(name), type_db::get().template as(), diff --git a/headers/meta.hpp/meta_infos/member_info.hpp b/headers/meta.hpp/meta_infos/member_info.hpp index 3945fc0..a3d1a7d 100644 --- a/headers/meta.hpp/meta_infos/member_info.hpp +++ b/headers/meta.hpp/meta_infos/member_info.hpp @@ -91,7 +91,7 @@ namespace meta_hpp namespace meta_hpp { template < typename Member > - inline member_info::member_info(std::string name, Member instance) + member_info::member_info(std::string name, Member instance) : state_{std::make_shared(state{ std::move(name), type_db::get().template as(), diff --git a/headers/meta.hpp/meta_infos/method_info.hpp b/headers/meta.hpp/meta_infos/method_info.hpp index 82c670d..b3f812b 100644 --- a/headers/meta.hpp/meta_infos/method_info.hpp +++ b/headers/meta.hpp/meta_infos/method_info.hpp @@ -91,7 +91,7 @@ namespace meta_hpp namespace meta_hpp { template < typename Method > - inline method_info::method_info(std::string name, Method instance) + method_info::method_info(std::string name, Method instance) : state_{std::make_shared(state{ std::move(name), type_db::get().template as(), diff --git a/headers/meta.hpp/meta_registry/class_.hpp b/headers/meta.hpp/meta_registry/class_.hpp index 8207e89..cbf131c 100644 --- a/headers/meta.hpp/meta_registry/class_.hpp +++ b/headers/meta.hpp/meta_registry/class_.hpp @@ -56,11 +56,11 @@ namespace meta_hpp namespace meta_hpp { template < typename Class > - inline class_::class_(std::string name) + class_::class_(std::string name) : name_{std::move(name)} {} template < typename Class > - inline class_info class_::make_info() const { + class_info class_::make_info() const { class_info info{typename_arg, name_}; info.state_->classes.insert(classes_.begin(), classes_.end()); info.state_->ctors.insert(ctors_.begin(), ctors_.end()); @@ -74,7 +74,7 @@ namespace meta_hpp template < typename Class > template < typename... Internals > - inline class_& class_::operator()(Internals&&...internals) { + class_& class_::operator()(Internals&&...internals) { (add_(std::forward(internals)), ...); return *this; } @@ -84,48 +84,48 @@ namespace meta_hpp { template < typename Class > template < typename Class2 > - inline void class_::add_(const class_& internal) { + void class_::add_(const class_& internal) { auto info = internal.make_info(); detail::merge_with(classes_, info.name(), info, &class_info::merge); } template < typename Class > template < typename... Args > - inline void class_::add_(const ctor_& internal) { + void class_::add_(const ctor_& internal) { auto info = internal.template make_info(); detail::merge_with(ctors_, info.type().id(), info, &ctor_info::merge); } template < typename Class > - inline void class_::add_(const data_& internal) { + void class_::add_(const data_& internal) { auto info = internal.make_info(); detail::merge_with(datas_, info.name(), info, &data_info::merge); } template < typename Class > template < typename Enum > - inline void class_::add_(const enum_& internal) { + void class_::add_(const enum_& internal) { auto info = internal.make_info(); detail::merge_with(enums_, info.name(), info, &enum_info::merge); } template < typename Class > template < typename Function > - inline void class_::add_(const function_& internal) { + void class_::add_(const function_& internal) { auto info = internal.make_info(); detail::merge_with(functions_, info.name(), info, &function_info::merge); } template < typename Class > template < typename Member > - inline void class_::add_(const member_& internal) { + void class_::add_(const member_& internal) { auto info = internal.make_info(); detail::merge_with(members_, info.name(), info, &member_info::merge); } template < typename Class > template < typename Method > - inline void class_::add_(const method_& internal) { + void class_::add_(const method_& internal) { auto info = internal.make_info(); detail::merge_with(methods_, info.name(), info, &method_info::merge); } diff --git a/headers/meta.hpp/meta_registry/ctor_.hpp b/headers/meta.hpp/meta_registry/ctor_.hpp index 7a32c38..94046b4 100644 --- a/headers/meta.hpp/meta_registry/ctor_.hpp +++ b/headers/meta.hpp/meta_registry/ctor_.hpp @@ -34,7 +34,7 @@ namespace meta_hpp { template < typename... Args > template < typename Class > - inline ctor_info ctor_::make_info() const { + ctor_info ctor_::make_info() const { ctor_info info{typename_arg, typename_arg}; info.state_->datas.insert(datas_.begin(), datas_.end()); return info; @@ -42,7 +42,7 @@ namespace meta_hpp template < typename... Args > template < typename... Internals > - inline ctor_& ctor_::operator()(Internals&&...internals) { + ctor_& ctor_::operator()(Internals&&...internals) { (add_(std::forward(internals)), ...); return *this; } @@ -51,7 +51,7 @@ namespace meta_hpp namespace meta_hpp { template < typename... Args > - inline void ctor_::add_(const data_& internal) { + void ctor_::add_(const data_& internal) { auto info = internal.make_info(); detail::merge_with(datas_, info.name(), info, &data_info::merge); } diff --git a/headers/meta.hpp/meta_registry/data_.hpp b/headers/meta.hpp/meta_registry/data_.hpp index 5b6a9d3..e07bde2 100644 --- a/headers/meta.hpp/meta_registry/data_.hpp +++ b/headers/meta.hpp/meta_registry/data_.hpp @@ -41,7 +41,7 @@ namespace meta_hpp } template < typename... Internals > - inline data_& data_::operator()(Internals&&...internals) { + data_& data_::operator()(Internals&&...internals) { (add_(std::forward(internals)), ...); return *this; } diff --git a/headers/meta.hpp/meta_registry/enum_.hpp b/headers/meta.hpp/meta_registry/enum_.hpp index 5734f85..b3a1ef0 100644 --- a/headers/meta.hpp/meta_registry/enum_.hpp +++ b/headers/meta.hpp/meta_registry/enum_.hpp @@ -36,11 +36,11 @@ namespace meta_hpp namespace meta_hpp { template < typename Enum > - inline enum_::enum_(std::string name) + enum_::enum_(std::string name) : name_{std::move(name)} {} template < typename Enum > - inline enum_info enum_::make_info() const { + enum_info enum_::make_info() const { enum_info info{typename_arg, name_}; info.state_->datas.insert(datas_.begin(), datas_.end()); info.state_->evalues.insert(evalues_.begin(), evalues_.end()); @@ -49,7 +49,7 @@ namespace meta_hpp template < typename Enum > template < typename... Internals > - inline enum_& enum_::operator()(Internals&&...internals) { + enum_& enum_::operator()(Internals&&...internals) { (add_(std::forward(internals)), ...); return *this; } @@ -58,13 +58,13 @@ namespace meta_hpp namespace meta_hpp { template < typename Enum > - inline void enum_::add_(const data_& internal) { + void enum_::add_(const data_& internal) { auto info = internal.make_info(); detail::merge_with(datas_, info.name(), info, &data_info::merge); } template < typename Enum > - inline void enum_::add_(const evalue_& internal) { + void enum_::add_(const evalue_& internal) { auto info = internal.make_info(); detail::merge_with(evalues_, info.name(), info, &evalue_info::merge); } diff --git a/headers/meta.hpp/meta_registry/evalue_.hpp b/headers/meta.hpp/meta_registry/evalue_.hpp index a8705e1..52ee112 100644 --- a/headers/meta.hpp/meta_registry/evalue_.hpp +++ b/headers/meta.hpp/meta_registry/evalue_.hpp @@ -34,12 +34,12 @@ namespace meta_hpp namespace meta_hpp { template < typename Enum > - inline evalue_::evalue_(std::string name, Enum value) + evalue_::evalue_(std::string name, Enum value) : name_{std::move(name)} , value_{std::move(value)} {} template < typename Enum > - inline evalue_info evalue_::make_info() const { + evalue_info evalue_::make_info() const { evalue_info info{name_, value_}; info.state_->datas.insert(datas_.begin(), datas_.end()); return info; @@ -47,7 +47,7 @@ namespace meta_hpp template < typename Enum > template < typename... Internals > - inline evalue_& evalue_::operator()(Internals&&...internals) { + evalue_& evalue_::operator()(Internals&&...internals) { (add_(std::forward(internals)), ...); return *this; } @@ -56,7 +56,7 @@ namespace meta_hpp namespace meta_hpp { template < typename Enum > - inline void evalue_::add_(const data_& internal) { + void evalue_::add_(const data_& internal) { auto info = internal.make_info(); detail::merge_with(datas_, info.name(), info, &data_info::merge); } diff --git a/headers/meta.hpp/meta_registry/function_.hpp b/headers/meta.hpp/meta_registry/function_.hpp index 924516d..807b058 100644 --- a/headers/meta.hpp/meta_registry/function_.hpp +++ b/headers/meta.hpp/meta_registry/function_.hpp @@ -34,12 +34,12 @@ namespace meta_hpp namespace meta_hpp { template < typename Function > - inline function_::function_(std::string name, Function instance) + function_::function_(std::string name, Function instance) : name_{std::move(name)} , instance_{std::move(instance)} {} template < typename Function > - inline function_info function_::make_info() const { + function_info function_::make_info() const { function_info info{name_, instance_}; info.state_->datas.insert(datas_.begin(), datas_.end()); return info; @@ -47,7 +47,7 @@ namespace meta_hpp template < typename Function > template < typename... Internals > - inline function_& function_::operator()(Internals&&...internals) { + function_& function_::operator()(Internals&&...internals) { (add_(std::forward(internals)), ...); return *this; } @@ -56,7 +56,7 @@ namespace meta_hpp namespace meta_hpp { template < typename Function > - inline void function_::add_(const data_& internal) { + void function_::add_(const data_& internal) { auto info = internal.make_info(); detail::merge_with(datas_, info.name(), info, &data_info::merge); } diff --git a/headers/meta.hpp/meta_registry/member_.hpp b/headers/meta.hpp/meta_registry/member_.hpp index 44073cb..4572a66 100644 --- a/headers/meta.hpp/meta_registry/member_.hpp +++ b/headers/meta.hpp/meta_registry/member_.hpp @@ -34,12 +34,12 @@ namespace meta_hpp namespace meta_hpp { template < typename Member > - inline member_::member_(std::string name, Member instance) + member_::member_(std::string name, Member instance) : name_{std::move(name)} , instance_{std::move(instance)} {} template < typename Member > - inline member_info member_::make_info() const { + member_info member_::make_info() const { member_info info{name_, instance_}; info.state_->datas.insert(datas_.begin(), datas_.end()); return info; @@ -47,7 +47,7 @@ namespace meta_hpp template < typename Member > template < typename... Internals > - inline member_& member_::operator()(Internals&&...internals) { + member_& member_::operator()(Internals&&...internals) { (add_(std::forward(internals)), ...); return *this; } @@ -56,7 +56,7 @@ namespace meta_hpp namespace meta_hpp { template < typename Member > - inline void member_::add_(const data_& internal) { + void member_::add_(const data_& internal) { auto info = internal.make_info(); detail::merge_with(datas_, info.name(), info, &data_info::merge); } diff --git a/headers/meta.hpp/meta_registry/method_.hpp b/headers/meta.hpp/meta_registry/method_.hpp index 911ffe6..f85f9f5 100644 --- a/headers/meta.hpp/meta_registry/method_.hpp +++ b/headers/meta.hpp/meta_registry/method_.hpp @@ -34,12 +34,12 @@ namespace meta_hpp namespace meta_hpp { template < typename Method > - inline method_::method_(std::string name, Method instance) + method_::method_(std::string name, Method instance) : name_{std::move(name)} , instance_{std::move(instance)} {} template < typename Method > - inline method_info method_::make_info() const { + method_info method_::make_info() const { method_info info{name_, instance_}; info.state_->datas.insert(datas_.begin(), datas_.end()); return info; @@ -47,7 +47,7 @@ namespace meta_hpp template < typename Method > template < typename... Internals > - inline method_& method_::operator()(Internals&&...internals) { + method_& method_::operator()(Internals&&...internals) { (add_(std::forward(internals)), ...); return *this; } @@ -56,7 +56,7 @@ namespace meta_hpp namespace meta_hpp { template < typename Method > - inline void method_::add_(const data_& internal) { + void method_::add_(const data_& internal) { auto info = internal.make_info(); detail::merge_with(datas_, info.name(), info, &data_info::merge); } diff --git a/headers/meta.hpp/meta_registry/namespace_.hpp b/headers/meta.hpp/meta_registry/namespace_.hpp index bd15745..b1c720b 100644 --- a/headers/meta.hpp/meta_registry/namespace_.hpp +++ b/headers/meta.hpp/meta_registry/namespace_.hpp @@ -59,7 +59,7 @@ namespace meta_hpp } template < typename... Internals > - inline namespace_& namespace_::operator()(Internals&&...internals) { + namespace_& namespace_::operator()(Internals&&...internals) { (add_(std::forward(internals)), ...); return *this; } @@ -68,7 +68,7 @@ namespace meta_hpp namespace meta_hpp { template < typename Class > - inline void namespace_::add_(const class_& internal) { + void namespace_::add_(const class_& internal) { auto info = internal.make_info(); detail::merge_with(classes_, info.name(), info, &class_info::merge); } @@ -79,13 +79,13 @@ namespace meta_hpp } template < typename Enum > - inline void namespace_::add_(const enum_& internal) { + void namespace_::add_(const enum_& internal) { auto info = internal.make_info(); detail::merge_with(enums_, info.name(), info, &enum_info::merge); } template < typename Function > - inline void namespace_::add_(const function_& internal) { + void namespace_::add_(const function_& internal) { auto info = internal.make_info(); detail::merge_with(functions_, info.name(), info, &function_info::merge); } diff --git a/headers/meta.hpp/meta_types/_types_fwd.hpp b/headers/meta.hpp/meta_types/_types_fwd.hpp index 3910e6d..eb00b20 100644 --- a/headers/meta.hpp/meta_types/_types_fwd.hpp +++ b/headers/meta.hpp/meta_types/_types_fwd.hpp @@ -20,10 +20,6 @@ namespace meta_hpp type_id(const type_id&) = default; type_id& operator=(const type_id&) = default; - template < typename T > - explicit type_id(typename_arg_t) noexcept - : id_{type_to_id()} {} - explicit operator bool() const noexcept { return !!id_; } @@ -47,6 +43,12 @@ namespace meta_hpp using underlying_type = std::size_t; underlying_type id_{0u}; private: + friend class type_base; + + template < typename T > + explicit type_id(typename_arg_t) noexcept + : id_{type_to_id()} {} + static underlying_type next() noexcept { static std::atomic id{}; return ++id; @@ -86,10 +88,6 @@ namespace meta_hpp type_base(const type_base&) = default; type_base& operator=(const type_base&) = default; - template < typename... Ts > - explicit type_base(typename_arg_t) - : id_{typename_arg>} {} - type_id id() const noexcept { return id_; } @@ -97,6 +95,10 @@ namespace meta_hpp explicit operator bool() const noexcept { return !!id_; } + protected: + template < typename... Ts > + explicit type_base(typename_arg_t) + : id_{typename_arg>} {} private: type_id id_; }; diff --git a/headers/meta.hpp/meta_types/arithmetic_type.hpp b/headers/meta.hpp/meta_types/arithmetic_type.hpp index 1e1d142..af36656 100644 --- a/headers/meta.hpp/meta_types/arithmetic_type.hpp +++ b/headers/meta.hpp/meta_types/arithmetic_type.hpp @@ -85,8 +85,8 @@ namespace meta_hpp }; template < typename T > - inline arithmetic_type::arithmetic_type(typename_arg_t) - : type_base{typename_arg} + arithmetic_type::arithmetic_type(typename_arg_t) + : type_base{typename_arg} , state_{std::make_shared(state{ detail::arithmetic_traits::size, detail::arithmetic_traits::make_raw_type(), diff --git a/headers/meta.hpp/meta_types/array_type.hpp b/headers/meta.hpp/meta_types/array_type.hpp index c0dce99..74dfc30 100644 --- a/headers/meta.hpp/meta_types/array_type.hpp +++ b/headers/meta.hpp/meta_types/array_type.hpp @@ -88,8 +88,8 @@ namespace meta_hpp::detail namespace meta_hpp { template < typename T > - inline array_type::array_type(typename_arg_t) - : type_base{typename_arg} + array_type::array_type(typename_arg_t) + : type_base{typename_arg} , state_{std::make_shared(state{ detail::array_traits::extent, detail::array_traits::make_data_type(), diff --git a/headers/meta.hpp/meta_types/class_type.hpp b/headers/meta.hpp/meta_types/class_type.hpp index 008d039..e6c6321 100644 --- a/headers/meta.hpp/meta_types/class_type.hpp +++ b/headers/meta.hpp/meta_types/class_type.hpp @@ -85,8 +85,8 @@ namespace meta_hpp }; template < typename T > - inline class_type::class_type(typename_arg_t) - : type_base{typename_arg} + class_type::class_type(typename_arg_t) + : type_base{typename_arg} , state_{std::make_shared(state{ detail::class_traits::size, detail::class_traits::make_raw_type(), diff --git a/headers/meta.hpp/meta_types/ctor_type.hpp b/headers/meta.hpp/meta_types/ctor_type.hpp index c14d305..69eae28 100644 --- a/headers/meta.hpp/meta_types/ctor_type.hpp +++ b/headers/meta.hpp/meta_types/ctor_type.hpp @@ -77,7 +77,7 @@ namespace meta_hpp }; template < typename Class, typename... Args > - inline ctor_type::ctor_type(typename_arg_t, typename_arg_t) + ctor_type::ctor_type(typename_arg_t, typename_arg_t) : type_base{typename_arg} , state_{std::make_shared(state{ detail::ctor_traits::arity, diff --git a/headers/meta.hpp/meta_types/enum_type.hpp b/headers/meta.hpp/meta_types/enum_type.hpp index 3a25707..dba99d1 100644 --- a/headers/meta.hpp/meta_types/enum_type.hpp +++ b/headers/meta.hpp/meta_types/enum_type.hpp @@ -76,8 +76,8 @@ namespace meta_hpp }; template < typename T > - inline enum_type::enum_type(typename_arg_t) - : type_base{typename_arg} + enum_type::enum_type(typename_arg_t) + : type_base{typename_arg} , state_{std::make_shared(state{ detail::enum_traits::make_raw_type(), detail::enum_traits::make_underlying_type(), diff --git a/headers/meta.hpp/meta_types/function_type.hpp b/headers/meta.hpp/meta_types/function_type.hpp index 34f00ad..3473322 100644 --- a/headers/meta.hpp/meta_types/function_type.hpp +++ b/headers/meta.hpp/meta_types/function_type.hpp @@ -84,8 +84,8 @@ namespace meta_hpp }; template < typename T > - inline function_type::function_type(typename_arg_t) - : type_base{typename_arg} + function_type::function_type(typename_arg_t) + : type_base{typename_arg} , state_{std::make_shared(state{ detail::function_pointer_traits::arity, detail::function_pointer_traits::make_return_type(), diff --git a/headers/meta.hpp/meta_types/member_type.hpp b/headers/meta.hpp/meta_types/member_type.hpp index 8c01fc0..e8a5b3a 100644 --- a/headers/meta.hpp/meta_types/member_type.hpp +++ b/headers/meta.hpp/meta_types/member_type.hpp @@ -61,8 +61,8 @@ namespace meta_hpp::detail namespace meta_hpp { template < typename T > - inline member_type::member_type(typename_arg_t) - : type_base{typename_arg} + member_type::member_type(typename_arg_t) + : type_base{typename_arg} , state_{std::make_shared(state{ detail::member_pointer_traits::make_class_type(), detail::member_pointer_traits::make_value_type(), diff --git a/headers/meta.hpp/meta_types/method_type.hpp b/headers/meta.hpp/meta_types/method_type.hpp index e377d71..e4263b6 100644 --- a/headers/meta.hpp/meta_types/method_type.hpp +++ b/headers/meta.hpp/meta_types/method_type.hpp @@ -107,8 +107,8 @@ namespace meta_hpp }; template < typename T > - inline method_type::method_type(typename_arg_t) - : type_base{typename_arg} + method_type::method_type(typename_arg_t) + : type_base{typename_arg} , state_{std::make_shared(state{ detail::method_pointer_traits::arity, detail::method_pointer_traits::make_class_type(), diff --git a/headers/meta.hpp/meta_types/pointer_type.hpp b/headers/meta.hpp/meta_types/pointer_type.hpp index 5cdb830..5026724 100644 --- a/headers/meta.hpp/meta_types/pointer_type.hpp +++ b/headers/meta.hpp/meta_types/pointer_type.hpp @@ -75,8 +75,8 @@ namespace meta_hpp }; template < typename T > - inline pointer_type::pointer_type(typename_arg_t) - : type_base{typename_arg} + pointer_type::pointer_type(typename_arg_t) + : type_base{typename_arg} , state_{std::make_shared(state{ detail::pointer_traits::make_data_type(), detail::pointer_traits::make_flags(), diff --git a/headers/meta.hpp/meta_types/reference_type.hpp b/headers/meta.hpp/meta_types/reference_type.hpp index c9732af..51add95 100644 --- a/headers/meta.hpp/meta_types/reference_type.hpp +++ b/headers/meta.hpp/meta_types/reference_type.hpp @@ -79,8 +79,8 @@ namespace meta_hpp }; template < typename T > - inline reference_type::reference_type(typename_arg_t) - : type_base{typename_arg} + reference_type::reference_type(typename_arg_t) + : type_base{typename_arg} , state_{std::make_shared(state{ detail::reference_traits::make_data_type(), detail::reference_traits::make_flags(), diff --git a/headers/meta.hpp/meta_types/void_type.hpp b/headers/meta.hpp/meta_types/void_type.hpp index 8dbf265..d788a1f 100644 --- a/headers/meta.hpp/meta_types/void_type.hpp +++ b/headers/meta.hpp/meta_types/void_type.hpp @@ -72,8 +72,8 @@ namespace meta_hpp::detail namespace meta_hpp { template < typename T > - inline void_type::void_type(typename_arg_t) - : type_base{typename_arg} + void_type::void_type(typename_arg_t) + : type_base{typename_arg} , state_{std::make_shared(state{ detail::void_traits::make_raw_type(), detail::void_traits::make_flags(), diff --git a/untests/features/types/arithmetic_type_tests.cpp b/untests/features/types/arithmetic_type_tests.cpp index 4a0de20..5815e8e 100644 --- a/untests/features/types/arithmetic_type_tests.cpp +++ b/untests/features/types/arithmetic_type_tests.cpp @@ -20,7 +20,6 @@ TEST_CASE("features/types/arithmetic") { REQUIRE(type_db::get().is()); const arithmetic_type at = type_db::get().as(); - CHECK(at.id() == type_id{typename_arg>}); CHECK_FALSE(at.raw_type()); CHECK(at.size() == sizeof(type)); @@ -43,7 +42,6 @@ TEST_CASE("features/types/arithmetic") { REQUIRE(type_db::get().is()); const arithmetic_type at = type_db::get().as(); - CHECK(at.id() == type_id{typename_arg>}); CHECK(at.raw_type().id() == type_db::get().id()); CHECK(at.size() == sizeof(type)); @@ -67,7 +65,6 @@ TEST_CASE("features/types/arithmetic") { REQUIRE(type_db::get().is()); const arithmetic_type at = type_db::get().as(); - CHECK(at.id() == type_id{typename_arg>}); CHECK(at.raw_type().id() == type_db::get().id()); CHECK(at.size() == sizeof(type)); diff --git a/untests/features/types/array_type_tests.cpp b/untests/features/types/array_type_tests.cpp index e0c2a5a..c4fe394 100644 --- a/untests/features/types/array_type_tests.cpp +++ b/untests/features/types/array_type_tests.cpp @@ -20,7 +20,6 @@ TEST_CASE("features/types/array") { REQUIRE(type_db::get().is()); const array_type at = type_db::get().as(); - CHECK(at.id() == type_id{typename_arg>}); CHECK(at.data_type().id() == type_db::get().id()); CHECK(at.extent() == 0); @@ -38,7 +37,6 @@ TEST_CASE("features/types/array") { REQUIRE(type_db::get().is()); const array_type at = type_db::get().as(); - CHECK(at.id() == type_id{typename_arg>}); CHECK(at.data_type().id() == type_db::get().id()); CHECK(at.extent() == 42); diff --git a/untests/features/types/class_type_tests.cpp b/untests/features/types/class_type_tests.cpp index 3163b89..00db749 100644 --- a/untests/features/types/class_type_tests.cpp +++ b/untests/features/types/class_type_tests.cpp @@ -38,7 +38,6 @@ TEST_CASE("features/types/class") { REQUIRE(type_db::get().is()); const class_type ct = type_db::get().as(); - CHECK(ct.id() == type_id{typename_arg>}); CHECK_FALSE(ct.raw_type()); CHECK(ct.size() == sizeof(type)); @@ -61,7 +60,6 @@ TEST_CASE("features/types/class") { REQUIRE(type_db::get().is()); const class_type ct = type_db::get().as(); - CHECK(ct.id() == type_id{typename_arg>}); CHECK_FALSE(ct.raw_type()); CHECK(ct.size() == sizeof(type)); @@ -84,7 +82,6 @@ TEST_CASE("features/types/class") { REQUIRE(type_db::get().is()); const class_type ct = type_db::get().as(); - CHECK(ct.id() == type_id{typename_arg>}); CHECK_FALSE(ct.raw_type()); CHECK(ct.size() == sizeof(type)); @@ -107,7 +104,6 @@ TEST_CASE("features/types/class") { REQUIRE(type_db::get().is()); const class_type ct = type_db::get().as(); - CHECK(ct.id() == type_id{typename_arg>}); CHECK_FALSE(ct.raw_type()); CHECK(ct.size() == sizeof(type)); @@ -129,7 +125,6 @@ TEST_CASE("features/types/class") { REQUIRE(type_db::get().is()); const class_type ct = type_db::get().as(); - CHECK(ct.id() == type_id{typename_arg>}); REQUIRE(ct.raw_type()); CHECK(ct.raw_type().id() == type_db::get().id()); diff --git a/untests/features/types/enum_type_tests.cpp b/untests/features/types/enum_type_tests.cpp index 52841c5..f54a278 100644 --- a/untests/features/types/enum_type_tests.cpp +++ b/untests/features/types/enum_type_tests.cpp @@ -29,7 +29,6 @@ TEST_CASE("features/types/enum") { REQUIRE(type_db::get().is()); const enum_type et = type_db::get().as(); - CHECK(et.id() == type_id{typename_arg>}); CHECK_FALSE(et.raw_type()); CHECK(et.underlying_type().id() == type_db::get().id()); @@ -45,7 +44,6 @@ TEST_CASE("features/types/enum") { REQUIRE(type_db::get().is()); const enum_type et = type_db::get().as(); - CHECK(et.id() == type_id{typename_arg>}); REQUIRE(et.raw_type()); CHECK(et.raw_type().id() == type_db::get().id()); diff --git a/untests/features/types/pointer_type_tests.cpp b/untests/features/types/pointer_type_tests.cpp index 60e95c4..6fbc619 100644 --- a/untests/features/types/pointer_type_tests.cpp +++ b/untests/features/types/pointer_type_tests.cpp @@ -28,7 +28,6 @@ TEST_CASE("features/types/pointer") { REQUIRE(type_db::get().is()); const pointer_type pt = type_db::get().as(); - CHECK(pt.id() == type_id{typename_arg>}); CHECK(pt.data_type().id() == type_db::get().id()); @@ -43,7 +42,6 @@ TEST_CASE("features/types/pointer") { REQUIRE(type_db::get().is()); const pointer_type pt = type_db::get().as(); - CHECK(pt.id() == type_id{typename_arg>}); CHECK(pt.data_type().id() == type_db::get().id()); @@ -58,7 +56,6 @@ TEST_CASE("features/types/pointer") { REQUIRE(type_db::get().is()); const pointer_type pt = type_db::get().as(); - CHECK(pt.id() == type_id{typename_arg>}); CHECK(pt.data_type().id() == type_db::get().id()); @@ -73,7 +70,6 @@ TEST_CASE("features/types/pointer") { REQUIRE(type_db::get().is()); const pointer_type pt = type_db::get().as(); - CHECK(pt.id() == type_id{typename_arg>}); CHECK(pt.data_type().id() == type_db::get().id()); diff --git a/untests/features/types/reference_type_tests.cpp b/untests/features/types/reference_type_tests.cpp index 49833d3..be5bf72 100644 --- a/untests/features/types/reference_type_tests.cpp +++ b/untests/features/types/reference_type_tests.cpp @@ -26,7 +26,6 @@ TEST_CASE("features/types/reference") { REQUIRE(type_db::get().is()); const reference_type rt = type_db::get().as(); - CHECK(rt.id() == type_id{typename_arg>}); CHECK(rt.data_type().id() == type_db::get().id()); @@ -41,7 +40,6 @@ TEST_CASE("features/types/reference") { REQUIRE(type_db::get().is()); const reference_type rt = type_db::get().as(); - CHECK(rt.id() == type_id{typename_arg>}); CHECK(rt.data_type().id() == type_db::get().id()); diff --git a/untests/features/types/void_type_tests.cpp b/untests/features/types/void_type_tests.cpp index b9740f8..a24fe5d 100644 --- a/untests/features/types/void_type_tests.cpp +++ b/untests/features/types/void_type_tests.cpp @@ -20,7 +20,6 @@ TEST_CASE("features/types/void") { REQUIRE(type_db::get().is()); const void_type vt = type_db::get().as(); - CHECK(vt.id() == type_id{typename_arg>}); CHECK_FALSE(vt.raw_type()); @@ -35,7 +34,6 @@ TEST_CASE("features/types/void") { REQUIRE(type_db::get().is()); const void_type vt = type_db::get().as(); - CHECK(vt.id() == type_id{typename_arg>}); REQUIRE(vt.raw_type()); CHECK(vt.raw_type().id() == type_db::get().id()); From 18ffff8ea092b95a244ccb3fdea8b9bdc808fded Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Tue, 10 Aug 2021 02:51:08 +0700 Subject: [PATCH 091/233] little fixes of types --- headers/meta.hpp/meta_fwd.hpp | 33 ++++++------------ headers/meta.hpp/meta_registry.hpp | 14 -------- .../meta.hpp/meta_registry/_registry_fwd.hpp | 1 - headers/meta.hpp/meta_types.hpp | 4 +-- headers/meta.hpp/meta_types/_types_fwd.hpp | 22 ++++++++++++ .../meta.hpp/meta_types/arithmetic_type.hpp | 9 +++-- headers/meta.hpp/meta_types/array_type.hpp | 28 +++++---------- headers/meta.hpp/meta_types/class_type.hpp | 9 +++-- headers/meta.hpp/meta_types/ctor_type.hpp | 11 +++--- headers/meta.hpp/meta_types/enum_type.hpp | 20 +++++++---- headers/meta.hpp/meta_types/function_type.hpp | 5 +-- headers/meta.hpp/meta_types/member_type.hpp | 5 +-- headers/meta.hpp/meta_types/method_type.hpp | 7 ++-- headers/meta.hpp/meta_types/pointer_type.hpp | 23 ++++--------- .../meta.hpp/meta_types/reference_type.hpp | 24 ++++--------- headers/meta.hpp/meta_types/void_type.hpp | 9 +++-- untests/features/types/array_type_tests.cpp | 34 +++++++++++++++++++ untests/features/types/enum_type_tests.cpp | 2 ++ 18 files changed, 134 insertions(+), 126 deletions(-) diff --git a/headers/meta.hpp/meta_fwd.hpp b/headers/meta.hpp/meta_fwd.hpp index 5c2234b..c8c1b25 100644 --- a/headers/meta.hpp/meta_fwd.hpp +++ b/headers/meta.hpp/meta_fwd.hpp @@ -109,40 +109,29 @@ namespace meta_hpp struct typename_arg_t {}; template < typename... Args > - inline typename_arg_t typename_arg; + inline constexpr typename_arg_t typename_arg; } -namespace meta_hpp +namespace meta_hpp::stdex { template < typename T > - struct add_ptr { - using type = std::add_pointer_t; - }; + struct is_bounded_array: std::false_type {}; + template < typename T, std::size_t N > + struct is_bounded_array: std::true_type {}; + template < typename T > + inline constexpr bool is_bounded_array_v = is_bounded_array::value; template < typename T > - struct remove_cv { - using type = std::remove_cv_t; - }; - + struct is_unbounded_array: std::false_type {}; template < typename T > - struct remove_ref { - using type = std::remove_reference_t; - }; + struct is_unbounded_array: std::true_type {}; + template < typename T > + inline constexpr bool is_unbounded_array_v = is_unbounded_array::value; template < typename T > struct remove_cvref { using type = std::remove_cv_t>; }; - - template < typename T > - using add_ptr_t = typename add_ptr::type; - - template < typename T > - using remove_cv_t = typename remove_cv::type; - - template < typename T > - using remove_ref_t = typename remove_ref::type; - template < typename T > using remove_cvref_t = typename remove_cvref::type; } diff --git a/headers/meta.hpp/meta_registry.hpp b/headers/meta.hpp/meta_registry.hpp index 0175acf..6b65af1 100644 --- a/headers/meta.hpp/meta_registry.hpp +++ b/headers/meta.hpp/meta_registry.hpp @@ -44,10 +44,6 @@ namespace meta_hpp void add_(const std::string& prefix, const enum_& internal); template < typename Function > void add_(const std::string& prefix, const function_& internal); - template < typename Member > - void add_(const std::string& prefix, const member_& internal); - template < typename Method > - void add_(const std::string& prefix, const method_& internal); void add_(const std::string& prefix, const namespace_& internal); void add_(const std::string& prefix, ...) = delete; private: @@ -139,16 +135,6 @@ namespace meta_hpp add_info_(prefix, internal.make_info()); } - template < typename Member > - inline void registry::add_(const std::string& prefix, const member_& internal) { - add_info_(prefix, internal.make_info()); - } - - template < typename Method > - inline void registry::add_(const std::string& prefix, const method_& internal) { - add_info_(prefix, internal.make_info()); - } - inline void registry::add_(const std::string& prefix, const namespace_& internal) { add_info_(prefix, internal.make_info()); } diff --git a/headers/meta.hpp/meta_registry/_registry_fwd.hpp b/headers/meta.hpp/meta_registry/_registry_fwd.hpp index 9cfa643..37e2a06 100644 --- a/headers/meta.hpp/meta_registry/_registry_fwd.hpp +++ b/headers/meta.hpp/meta_registry/_registry_fwd.hpp @@ -9,4 +9,3 @@ #include "../meta_fwd.hpp" #include "../meta_infos.hpp" #include "../meta_utilities.hpp" - diff --git a/headers/meta.hpp/meta_types.hpp b/headers/meta.hpp/meta_types.hpp index 00db3db..5369ff7 100644 --- a/headers/meta.hpp/meta_types.hpp +++ b/headers/meta.hpp/meta_types.hpp @@ -70,13 +70,13 @@ namespace meta_hpp } template < typename T > - inline any_type type_db::get() { + any_type type_db::get() { static const auto raw_type = detail::make_any_type(); return any_type{raw_type}; } template < typename Tuple > - inline std::vector type_db::multi_get() { + std::vector type_db::multi_get() { return detail::multi_get_impl::get(); } } diff --git a/headers/meta.hpp/meta_types/_types_fwd.hpp b/headers/meta.hpp/meta_types/_types_fwd.hpp index eb00b20..175b6c6 100644 --- a/headers/meta.hpp/meta_types/_types_fwd.hpp +++ b/headers/meta.hpp/meta_types/_types_fwd.hpp @@ -158,6 +158,28 @@ namespace meta_hpp const reference_type*, const void_type*> type_; }; + + inline bool operator<(const any_type& l, const any_type& r) noexcept { + return l.id() < r.id(); + } + + inline bool operator==(const any_type& l, const any_type& r) noexcept { + return l.id() == r.id(); + } + + inline bool operator!=(const any_type& l, const any_type& r) noexcept { + return l.id() != r.id(); + } +} + +namespace std +{ + template <> + struct hash { + size_t operator()(const meta_hpp::any_type& type) const noexcept { + return type.id().hash(); + } + }; } namespace meta_hpp diff --git a/headers/meta.hpp/meta_types/arithmetic_type.hpp b/headers/meta.hpp/meta_types/arithmetic_type.hpp index af36656..660a669 100644 --- a/headers/meta.hpp/meta_types/arithmetic_type.hpp +++ b/headers/meta.hpp/meta_types/arithmetic_type.hpp @@ -50,15 +50,14 @@ namespace meta_hpp namespace meta_hpp::detail { - template < typename T, typename = void > - struct arithmetic_traits; - template < typename T > - struct arithmetic_traits>> { + struct arithmetic_traits { + static_assert(std::is_arithmetic_v); static constexpr std::size_t size{sizeof(T)}; + using raw_type = std::remove_const_t; + static any_type make_raw_type() { - using raw_type = std::remove_const_t; return std::is_same_v ? any_type{} : type_db::get(); diff --git a/headers/meta.hpp/meta_types/array_type.hpp b/headers/meta.hpp/meta_types/array_type.hpp index 74dfc30..0869842 100644 --- a/headers/meta.hpp/meta_types/array_type.hpp +++ b/headers/meta.hpp/meta_types/array_type.hpp @@ -54,33 +54,21 @@ namespace meta_hpp namespace meta_hpp::detail { template < typename T > - struct array_traits; + struct array_traits { + static_assert(std::is_array_v); + static constexpr std::size_t extent{std::extent_v}; - template < typename T > - struct array_traits { - static constexpr std::size_t extent{0}; + using data_type = std::remove_extent_t; static any_type make_data_type() { - using data_type = T; return type_db::get(); } static bitflags make_flags() noexcept { - return array_flags::is_unbounded; - } - }; - - template < typename T, std::size_t N > - struct array_traits { - static constexpr std::size_t extent{N}; - - static any_type make_data_type() { - using data_type = T; - return type_db::get(); - } - - static bitflags make_flags() noexcept { - return array_flags::is_bounded; + bitflags flags; + if ( stdex::is_bounded_array_v ) flags.set(array_flags::is_bounded); + if ( stdex::is_unbounded_array_v ) flags.set(array_flags::is_unbounded); + return flags; } }; } diff --git a/headers/meta.hpp/meta_types/class_type.hpp b/headers/meta.hpp/meta_types/class_type.hpp index e6c6321..31c4b20 100644 --- a/headers/meta.hpp/meta_types/class_type.hpp +++ b/headers/meta.hpp/meta_types/class_type.hpp @@ -50,15 +50,14 @@ namespace meta_hpp namespace meta_hpp::detail { - template < typename T, typename = void > - struct class_traits; - template < typename T > - struct class_traits>> { + struct class_traits { + static_assert(std::is_class_v); static constexpr std::size_t size{sizeof(T)}; + using raw_type = std::remove_const_t; + static any_type make_raw_type() { - using raw_type = std::remove_const_t; return std::is_same_v ? any_type{} : type_db::get(); diff --git a/headers/meta.hpp/meta_types/ctor_type.hpp b/headers/meta.hpp/meta_types/ctor_type.hpp index 69eae28..939ebd5 100644 --- a/headers/meta.hpp/meta_types/ctor_type.hpp +++ b/headers/meta.hpp/meta_types/ctor_type.hpp @@ -44,24 +44,25 @@ namespace meta_hpp namespace meta_hpp::detail { - template < typename C, typename... Args > + template < typename Class, typename... Args > struct ctor_traits { - static_assert(std::is_constructible_v); + static_assert(std::is_constructible_v); static constexpr std::size_t arity{sizeof...(Args)}; + using class_type = Class; + using argument_types = std::tuple; + static any_type make_class_type() { - using class_type = C; return type_db::get(); } static std::vector make_argument_types() { - using argument_types = std::tuple; return type_db::multi_get(); } static bitflags make_flags() noexcept { bitflags flags; - if ( std::is_nothrow_constructible_v ) flags.set(ctor_flags::is_noexcept); + if ( std::is_nothrow_constructible_v ) flags.set(ctor_flags::is_noexcept); return flags; } }; diff --git a/headers/meta.hpp/meta_types/enum_type.hpp b/headers/meta.hpp/meta_types/enum_type.hpp index dba99d1..af0d710 100644 --- a/headers/meta.hpp/meta_types/enum_type.hpp +++ b/headers/meta.hpp/meta_types/enum_type.hpp @@ -29,6 +29,7 @@ namespace meta_hpp template < typename T > explicit enum_type(typename_arg_t); + std::size_t size() const noexcept; any_type raw_type() const noexcept; any_type underlying_type() const noexcept; @@ -42,20 +43,21 @@ namespace meta_hpp namespace meta_hpp::detail { - template < typename T, typename = void > - struct enum_traits; - template < typename T > - struct enum_traits>> { + struct enum_traits { + static_assert(std::is_enum_v); + static constexpr std::size_t size{sizeof(T)}; + + using raw_type = std::remove_const_t; + using underlying_type = std::underlying_type_t; + static any_type make_raw_type() { - using raw_type = std::remove_const_t; return std::is_same_v ? any_type{} : type_db::get(); } static any_type make_underlying_type() { - using underlying_type = std::underlying_type_t; return type_db::get(); } @@ -70,6 +72,7 @@ namespace meta_hpp::detail namespace meta_hpp { struct enum_type::state final { + const std::size_t size; const any_type raw_type; const any_type underlying_type; const bitflags flags; @@ -79,6 +82,7 @@ namespace meta_hpp enum_type::enum_type(typename_arg_t) : type_base{typename_arg} , state_{std::make_shared(state{ + detail::enum_traits::size, detail::enum_traits::make_raw_type(), detail::enum_traits::make_underlying_type(), detail::enum_traits::make_flags(), @@ -86,6 +90,10 @@ namespace meta_hpp static_assert(std::is_enum_v); } + inline std::size_t enum_type::size() const noexcept { + return state_->size; + } + inline any_type enum_type::raw_type() const noexcept { return state_->raw_type; } diff --git a/headers/meta.hpp/meta_types/function_type.hpp b/headers/meta.hpp/meta_types/function_type.hpp index 3473322..1bc8fc3 100644 --- a/headers/meta.hpp/meta_types/function_type.hpp +++ b/headers/meta.hpp/meta_types/function_type.hpp @@ -51,13 +51,14 @@ namespace meta_hpp::detail struct function_pointer_traits { static constexpr std::size_t arity{sizeof...(Args)}; + using return_type = R; + using argument_types = std::tuple; + static any_type make_return_type() { - using return_type = R; return type_db::get(); } static std::vector make_argument_types() { - using argument_types = std::tuple; return type_db::multi_get(); } diff --git a/headers/meta.hpp/meta_types/member_type.hpp b/headers/meta.hpp/meta_types/member_type.hpp index e8a5b3a..5c3b28b 100644 --- a/headers/meta.hpp/meta_types/member_type.hpp +++ b/headers/meta.hpp/meta_types/member_type.hpp @@ -46,13 +46,14 @@ namespace meta_hpp::detail template < typename V, typename C > struct member_pointer_traits { + using class_type = C; + using value_type = V; + static any_type make_class_type() { - using class_type = C; return type_db::get(); } static any_type make_value_type() { - using value_type = V; return type_db::get(); } }; diff --git a/headers/meta.hpp/meta_types/method_type.hpp b/headers/meta.hpp/meta_types/method_type.hpp index e4263b6..15c80ff 100644 --- a/headers/meta.hpp/meta_types/method_type.hpp +++ b/headers/meta.hpp/meta_types/method_type.hpp @@ -54,18 +54,19 @@ namespace meta_hpp::detail struct method_pointer_traits { static constexpr std::size_t arity{sizeof...(Args)}; + using class_type = C; + using return_type = R; + using argument_types = std::tuple; + static any_type make_class_type() { - using class_type = C; return type_db::get(); } static any_type make_return_type() { - using return_type = R; return type_db::get(); } static std::vector make_argument_types() { - using argument_types = std::tuple; return type_db::multi_get(); } diff --git a/headers/meta.hpp/meta_types/pointer_type.hpp b/headers/meta.hpp/meta_types/pointer_type.hpp index 5026724..269ed2e 100644 --- a/headers/meta.hpp/meta_types/pointer_type.hpp +++ b/headers/meta.hpp/meta_types/pointer_type.hpp @@ -40,29 +40,18 @@ namespace meta_hpp namespace meta_hpp::detail { template < typename T > - struct pointer_traits; + struct pointer_traits { + static_assert(std::is_pointer_v); + using data_type = std::remove_pointer_t; - template < typename T > - struct pointer_traits { static any_type make_data_type() { - using data_type = T; return type_db::get(); } static bitflags make_flags() noexcept { - return bitflags{}; - } - }; - - template < typename T > - struct pointer_traits { - static any_type make_data_type() { - using data_type = T; - return type_db::get(); - } - - static bitflags make_flags() noexcept { - return pointer_flags::is_const; + bitflags flags; + if ( std::is_const_v ) flags.set(pointer_flags::is_const); + return flags; } }; } diff --git a/headers/meta.hpp/meta_types/reference_type.hpp b/headers/meta.hpp/meta_types/reference_type.hpp index 51add95..5351f5d 100644 --- a/headers/meta.hpp/meta_types/reference_type.hpp +++ b/headers/meta.hpp/meta_types/reference_type.hpp @@ -44,29 +44,19 @@ namespace meta_hpp namespace meta_hpp::detail { template < typename T > - struct reference_traits; + struct reference_traits { + static_assert(std::is_reference_v); + using data_type = std::remove_reference_t; - template < typename T > - struct reference_traits { static any_type make_data_type() { - using data_type = T; return type_db::get(); } static bitflags make_flags() noexcept { - return reference_flags::is_lvalue; - } - }; - - template < typename T > - struct reference_traits { - static any_type make_data_type() { - using data_type = T; - return type_db::get(); - } - - static bitflags make_flags() noexcept { - return reference_flags::is_rvalue; + bitflags flags; + if ( std::is_lvalue_reference_v ) flags.set(reference_flags::is_lvalue); + if ( std::is_rvalue_reference_v ) flags.set(reference_flags::is_rvalue); + return flags; } }; } diff --git a/headers/meta.hpp/meta_types/void_type.hpp b/headers/meta.hpp/meta_types/void_type.hpp index d788a1f..2911b58 100644 --- a/headers/meta.hpp/meta_types/void_type.hpp +++ b/headers/meta.hpp/meta_types/void_type.hpp @@ -49,13 +49,12 @@ namespace meta_hpp namespace meta_hpp::detail { - template < typename T, typename = void > - struct void_traits; - template < typename T > - struct void_traits>> { + struct void_traits { + static_assert(std::is_void_v); + using raw_type = std::remove_const_t; + static any_type make_raw_type() { - using raw_type = std::remove_const_t; return std::is_same_v ? any_type{} : type_db::get(); diff --git a/untests/features/types/array_type_tests.cpp b/untests/features/types/array_type_tests.cpp index c4fe394..c695cc2 100644 --- a/untests/features/types/array_type_tests.cpp +++ b/untests/features/types/array_type_tests.cpp @@ -30,6 +30,40 @@ TEST_CASE("features/types/array") { CHECK(at.is_unbounded()); } + SUBCASE("unsigned[42][]") { + using type = unsigned[][42]; + + REQUIRE(type_db::get()); + REQUIRE(type_db::get().is()); + + const array_type at = type_db::get().as(); + + CHECK(at.data_type().id() == type_db::get().id()); + CHECK(at.extent() == 0); + + CHECK(at.flags() == (array_flags::is_unbounded)); + + CHECK_FALSE(at.is_bounded()); + CHECK(at.is_unbounded()); + } + + SUBCASE("const int[42][21]") { + using type = const int[42][21]; + + REQUIRE(type_db::get()); + REQUIRE(type_db::get().is()); + + const array_type at = type_db::get().as(); + + CHECK(at.data_type().id() == type_db::get().id()); + CHECK(at.extent() == 42); + + CHECK(at.flags() == (array_flags::is_bounded)); + + CHECK(at.is_bounded()); + CHECK_FALSE(at.is_unbounded()); + } + SUBCASE("const unsigned[42]") { using type = const unsigned[42]; diff --git a/untests/features/types/enum_type_tests.cpp b/untests/features/types/enum_type_tests.cpp index f54a278..f96eb6f 100644 --- a/untests/features/types/enum_type_tests.cpp +++ b/untests/features/types/enum_type_tests.cpp @@ -30,6 +30,7 @@ TEST_CASE("features/types/enum") { const enum_type et = type_db::get().as(); + CHECK(et.size() == sizeof(type)); CHECK_FALSE(et.raw_type()); CHECK(et.underlying_type().id() == type_db::get().id()); @@ -45,6 +46,7 @@ TEST_CASE("features/types/enum") { const enum_type et = type_db::get().as(); + CHECK(et.size() == sizeof(type)); REQUIRE(et.raw_type()); CHECK(et.raw_type().id() == type_db::get().id()); CHECK(et.underlying_type().id() == type_db::get().id()); From 2f4d33d24a6453bf05092be94697f228fdb8be6c Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Tue, 10 Aug 2021 03:38:39 +0700 Subject: [PATCH 092/233] base type for classes --- headers/meta.hpp/meta_fwd.hpp | 4 + headers/meta.hpp/meta_infos.hpp | 1 + headers/meta.hpp/meta_infos/base_info.hpp | 93 +++++++++++++++++ headers/meta.hpp/meta_infos/class_info.hpp | 74 +++++++++++++- headers/meta.hpp/meta_registry.hpp | 7 ++ headers/meta.hpp/meta_registry/base_.hpp | 58 +++++++++++ headers/meta.hpp/meta_registry/class_.hpp | 12 +++ headers/meta.hpp/meta_types.hpp | 1 + headers/meta.hpp/meta_types/_types_fwd.hpp | 1 + headers/meta.hpp/meta_types/base_type.hpp | 77 ++++++++++++++ headers/meta.hpp/meta_utilities/arg.hpp | 38 +++---- untests/features/infos/base_info_tests.cpp | 45 +++++++++ untests/features/infos/class_info_tests.cpp | 80 +++++++++++++++ untests/features/infos/ctor_info_tests.cpp | 106 ++++++++++++++++++++ untests/features/types/base_type_tests.cpp | 30 ++++++ 15 files changed, 607 insertions(+), 20 deletions(-) create mode 100644 headers/meta.hpp/meta_infos/base_info.hpp create mode 100644 headers/meta.hpp/meta_registry/base_.hpp create mode 100644 headers/meta.hpp/meta_types/base_type.hpp create mode 100644 untests/features/infos/base_info_tests.cpp create mode 100644 untests/features/types/base_type_tests.cpp diff --git a/headers/meta.hpp/meta_fwd.hpp b/headers/meta.hpp/meta_fwd.hpp index c8c1b25..34981a0 100644 --- a/headers/meta.hpp/meta_fwd.hpp +++ b/headers/meta.hpp/meta_fwd.hpp @@ -40,6 +40,7 @@ namespace meta_hpp namespace meta_hpp { + class base_info; class class_info; class ctor_info; class data_info; @@ -53,6 +54,7 @@ namespace meta_hpp namespace meta_hpp { + template < typename Base > class base_; template < typename Class > class class_; template < typename... Args > class ctor_; class data_; @@ -70,6 +72,7 @@ namespace meta_hpp class arithmetic_type; class array_type; + class base_type; class class_type; class ctor_type; class enum_type; @@ -92,6 +95,7 @@ namespace meta_hpp template < typename K, typename V > using info_map = std::map>; + using base_info_map = info_map; using class_info_map = info_map; using ctor_info_map = info_map; using data_info_map = info_map; diff --git a/headers/meta.hpp/meta_infos.hpp b/headers/meta.hpp/meta_infos.hpp index 9ac7f25..d4be547 100644 --- a/headers/meta.hpp/meta_infos.hpp +++ b/headers/meta.hpp/meta_infos.hpp @@ -8,6 +8,7 @@ #include "meta_fwd.hpp" +#include "meta_infos/base_info.hpp" #include "meta_infos/class_info.hpp" #include "meta_infos/ctor_info.hpp" #include "meta_infos/data_info.hpp" diff --git a/headers/meta.hpp/meta_infos/base_info.hpp b/headers/meta.hpp/meta_infos/base_info.hpp new file mode 100644 index 0000000..9f812b5 --- /dev/null +++ b/headers/meta.hpp/meta_infos/base_info.hpp @@ -0,0 +1,93 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "_infos_fwd.hpp" + +#include "data_info.hpp" + +namespace meta_hpp +{ + class base_info final { + public: + base_info() = default; + + void merge(const base_info& other); + explicit operator bool() const noexcept; + + const base_type& type() const noexcept; + public: + template < typename F > + void visit(F&& f) const; + + template < typename F > + void each_data(F&& f) const; + + data_info get_data_by_name(std::string_view name) const noexcept; + private: + template < typename Base > friend class base_; + + template < typename Base, typename Derived > + explicit base_info(typename_arg_t, typename_arg_t); + private: + struct state; + std::shared_ptr state_; + }; +} + +namespace meta_hpp +{ + struct base_info::state final { + base_type type; + data_info_map datas; + }; +} + +namespace meta_hpp +{ + inline void base_info::merge(const base_info& other) { + (void)other; + ///TODO: implme + } + + inline base_info::operator bool() const noexcept { + return !!state_; + } + + inline const base_type& base_info::type() const noexcept { + return state_->type; + } +} + +namespace meta_hpp +{ + template < typename F > + void base_info::visit(F&& f) const { + each_data(f); + } + + template < typename F > + void base_info::each_data(F&& f) const { + for ( auto&& name_info : state_->datas ) { + std::invoke(f, name_info.second); + } + } + + inline data_info base_info::get_data_by_name(std::string_view name) const noexcept { + return detail::find_or_default(state_->datas, name); + } +} + +namespace meta_hpp +{ + template < typename Base, typename Derived > + base_info::base_info(typename_arg_t, typename_arg_t) + : state_{std::make_shared(state{ + base_type{typename_arg, typename_arg}, + {} + })} {} +} diff --git a/headers/meta.hpp/meta_infos/class_info.hpp b/headers/meta.hpp/meta_infos/class_info.hpp index 00d9e49..90d2af6 100644 --- a/headers/meta.hpp/meta_infos/class_info.hpp +++ b/headers/meta.hpp/meta_infos/class_info.hpp @@ -8,6 +8,7 @@ #include "_infos_fwd.hpp" +#include "base_info.hpp" #include "ctor_info.hpp" #include "data_info.hpp" #include "enum_info.hpp" @@ -26,10 +27,23 @@ namespace meta_hpp const std::string& name() const noexcept; const class_type& type() const noexcept; + + template < typename Base > + bool is_derived_from() const; + bool is_derived_from(any_type base) const noexcept; + + template < typename... Args > + ctor_info get_ctor_by_args() const noexcept; + template < std::size_t Args > + ctor_info get_ctor_by_args(const std::array& args) const noexcept; + ctor_info get_ctor_by_args(const std::vector& args) const noexcept; public: template < typename F > void visit(F&& f) const; + template < typename F > + void each_base(F&& f) const; + template < typename F > void each_class(F&& f) const; @@ -73,6 +87,7 @@ namespace meta_hpp struct class_info::state final { std::string name; class_type type; + base_info_map bases; class_info_map classes; ctor_info_map ctors; data_info_map datas; @@ -101,12 +116,62 @@ namespace meta_hpp inline const class_type& class_info::type() const noexcept { return state_->type; } + + template < typename Base > + bool class_info::is_derived_from() const { + return class_info::is_derived_from(type_db::get()); + } + + inline bool class_info::is_derived_from(any_type base) const noexcept { + for ( auto&& id_info : state_->bases ) { + if ( base.id() == id_info.second.type().base_class_type().id() ) { + return true; + } + } + return false; + } + + template < typename... Args > + ctor_info class_info::get_ctor_by_args() const noexcept { + std::array args{type_db::get()...}; + return get_ctor_by_args(args); + } + + template < std::size_t Args > + ctor_info class_info::get_ctor_by_args(const std::array& args) const noexcept { + for ( auto&& id_info : state_->ctors ) { + const std::vector& ctor_args = + id_info.second.type().argument_types(); + + if ( args.size() == ctor_args.size() + && std::equal(args.begin(), args.end(), ctor_args.begin()) ) + { + return id_info.second; + } + } + return ctor_info{}; + } + + inline ctor_info class_info::get_ctor_by_args(const std::vector& args) const noexcept { + for ( auto&& id_info : state_->ctors ) { + const std::vector& ctor_args = + id_info.second.type().argument_types(); + + if ( args.size() == ctor_args.size() + && std::equal(args.begin(), args.end(), ctor_args.begin()) ) + { + return id_info.second; + } + } + return ctor_info{}; + } } namespace meta_hpp { template < typename F > void class_info::visit(F&& f) const { + each_base(f); each_class(f); each_ctor(f); each_data(f); @@ -116,6 +181,13 @@ namespace meta_hpp each_method(f); } + template < typename F > + void class_info::each_base(F&& f) const { + for ( auto&& id_info : state_->bases ) { + std::invoke(f, id_info.second); + } + } + template < typename F > void class_info::each_class(F&& f) const { for ( auto&& name_info : state_->classes ) { @@ -197,6 +269,6 @@ namespace meta_hpp : state_{std::make_shared(state{ std::move(name), type_db::get().template as(), - {}, {}, {}, {}, {}, {}, {} + {}, {}, {}, {}, {}, {}, {}, {} })} {} } diff --git a/headers/meta.hpp/meta_registry.hpp b/headers/meta.hpp/meta_registry.hpp index 6b65af1..4cefc0c 100644 --- a/headers/meta.hpp/meta_registry.hpp +++ b/headers/meta.hpp/meta_registry.hpp @@ -9,6 +9,7 @@ #include "meta_fwd.hpp" #include "meta_infos.hpp" +#include "meta_registry/base_.hpp" #include "meta_registry/class_.hpp" #include "meta_registry/ctor_.hpp" #include "meta_registry/data_.hpp" @@ -48,6 +49,7 @@ namespace meta_hpp void add_(const std::string& prefix, ...) = delete; private: struct add_info_f; + void add_info_(const std::string& prefix, const base_info& info); void add_info_(const std::string& prefix, const class_info& info); void add_info_(const std::string& prefix, const ctor_info& info); void add_info_(const std::string& prefix, const data_info& info); @@ -149,6 +151,11 @@ namespace meta_hpp } }; + inline void registry::add_info_(const std::string& prefix, const base_info& info) { + (void)prefix; + (void)info; + } + inline void registry::add_info_(const std::string& prefix, const class_info& info) { std::string name = prefix.empty() ? info.name() : prefix + "::" + info.name(); info.visit(kari_hpp::curry(add_info_f{}, std::ref(*this), name)); diff --git a/headers/meta.hpp/meta_registry/base_.hpp b/headers/meta.hpp/meta_registry/base_.hpp new file mode 100644 index 0000000..bca1673 --- /dev/null +++ b/headers/meta.hpp/meta_registry/base_.hpp @@ -0,0 +1,58 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "_registry_fwd.hpp" + +#include "data_.hpp" + +namespace meta_hpp +{ + template < typename Base > + class base_ final { + public: + explicit base_() = default; + + template < typename Derived > + base_info make_info() const; + public: + template < typename... Internals > + base_& operator()(Internals&&...internals); + private: + void add_(const data_& internal); + void add_(...) = delete; + private: + data_info_map datas_; + }; +} + +namespace meta_hpp +{ + template < typename Base > + template < typename Derived > + base_info base_::make_info() const { + base_info info{typename_arg, typename_arg}; + info.state_->datas.insert(datas_.begin(), datas_.end()); + return info; + } + + template < typename Base > + template < typename... Internals > + base_& base_::operator()(Internals&&...internals) { + (add_(std::forward(internals)), ...); + return *this; + } +} + +namespace meta_hpp +{ + template < typename Base > + void base_::add_(const data_& internal) { + auto info = internal.make_info(); + detail::merge_with(datas_, info.name(), info, &data_info::merge); + } +} diff --git a/headers/meta.hpp/meta_registry/class_.hpp b/headers/meta.hpp/meta_registry/class_.hpp index cbf131c..581cbf9 100644 --- a/headers/meta.hpp/meta_registry/class_.hpp +++ b/headers/meta.hpp/meta_registry/class_.hpp @@ -8,6 +8,7 @@ #include "_registry_fwd.hpp" +#include "base_.hpp" #include "ctor_.hpp" #include "data_.hpp" #include "enum_.hpp" @@ -27,6 +28,8 @@ namespace meta_hpp template < typename... Internals > class_& operator()(Internals&&...internals); private: + template < typename Base > + void add_(const base_& internal); template < typename Class2 > void add_(const class_& internal); template < typename... Args > @@ -43,6 +46,7 @@ namespace meta_hpp void add_(...) = delete; private: std::string name_; + base_info_map bases_; class_info_map classes_; ctor_info_map ctors_; data_info_map datas_; @@ -62,6 +66,7 @@ namespace meta_hpp template < typename Class > class_info class_::make_info() const { class_info info{typename_arg, name_}; + info.state_->bases.insert(bases_.begin(), bases_.end()); info.state_->classes.insert(classes_.begin(), classes_.end()); info.state_->ctors.insert(ctors_.begin(), ctors_.end()); info.state_->datas.insert(datas_.begin(), datas_.end()); @@ -82,6 +87,13 @@ namespace meta_hpp namespace meta_hpp { + template < typename Class > + template < typename Base > + void class_::add_(const base_& internal) { + auto info = internal.template make_info(); + detail::merge_with(bases_, info.type().id(), info, &base_info::merge); + } + template < typename Class > template < typename Class2 > void class_::add_(const class_& internal) { diff --git a/headers/meta.hpp/meta_types.hpp b/headers/meta.hpp/meta_types.hpp index 5369ff7..5265966 100644 --- a/headers/meta.hpp/meta_types.hpp +++ b/headers/meta.hpp/meta_types.hpp @@ -10,6 +10,7 @@ #include "meta_types/arithmetic_type.hpp" #include "meta_types/array_type.hpp" +#include "meta_types/base_type.hpp" #include "meta_types/class_type.hpp" #include "meta_types/ctor_type.hpp" #include "meta_types/enum_type.hpp" diff --git a/headers/meta.hpp/meta_types/_types_fwd.hpp b/headers/meta.hpp/meta_types/_types_fwd.hpp index 175b6c6..a533419 100644 --- a/headers/meta.hpp/meta_types/_types_fwd.hpp +++ b/headers/meta.hpp/meta_types/_types_fwd.hpp @@ -148,6 +148,7 @@ namespace meta_hpp std::variant< const arithmetic_type*, const array_type*, + const base_type*, const class_type*, const ctor_type*, const enum_type*, diff --git a/headers/meta.hpp/meta_types/base_type.hpp b/headers/meta.hpp/meta_types/base_type.hpp new file mode 100644 index 0000000..5d7fcf4 --- /dev/null +++ b/headers/meta.hpp/meta_types/base_type.hpp @@ -0,0 +1,77 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "_types_fwd.hpp" + +namespace meta_hpp +{ + class base_type final : public type_base { + public: + base_type() = default; + + base_type(base_type&&) = default; + base_type& operator=(base_type&&) = default; + + base_type(const base_type&) = default; + base_type& operator=(const base_type&) = default; + + template < typename Base, typename Derived > + explicit base_type(typename_arg_t, typename_arg_t); + + any_type base_class_type() const noexcept; + any_type derived_class_type() const noexcept; + private: + struct state; + std::shared_ptr state_; + }; +} + +namespace meta_hpp::detail +{ + template < typename Base, typename Derived > + struct base_traits { + static_assert(std::is_base_of_v); + + using base_class_type = Base; + using derived_class_type = Derived; + + static any_type make_base_class_type() { + return type_db::get(); + } + + static any_type make_derived_class_type() { + return type_db::get(); + } + }; +} + +namespace meta_hpp +{ + struct base_type::state final { + const any_type base_class_type; + const any_type derived_class_type; + }; + + template < typename Base, typename Derived > + base_type::base_type(typename_arg_t, typename_arg_t) + : type_base{typename_arg} + , state_{std::make_shared(state{ + detail::base_traits::make_base_class_type(), + detail::base_traits::make_derived_class_type(), + })} { + static_assert(std::is_base_of_v); + } + + inline any_type base_type::base_class_type() const noexcept { + return state_->base_class_type; + } + + inline any_type base_type::derived_class_type() const noexcept { + return state_->derived_class_type; + } +} diff --git a/headers/meta.hpp/meta_utilities/arg.hpp b/headers/meta.hpp/meta_utilities/arg.hpp index 291a56d..45cc6ed 100644 --- a/headers/meta.hpp/meta_utilities/arg.hpp +++ b/headers/meta.hpp/meta_utilities/arg.hpp @@ -59,16 +59,16 @@ namespace meta_hpp template < typename T , std::enable_if_t, int> > inline arg::arg(T&& v) - : data_{const_cast>>(std::addressof(v))} - , raw_type_{type_db::get>()} + : data_{const_cast>>(std::addressof(v))} + , raw_type_{type_db::get>()} , ref_type_{std::is_const_v ? ref_types::crref : ref_types::rref} {} template < typename T , std::enable_if_t, int> > inline arg::arg(T&& v) - : data_{const_cast>>(std::addressof(v))} - , raw_type_{type_db::get>()} - , ref_type_{std::is_const_v> ? ref_types::cref : ref_types::ref} {} + : data_{const_cast>>(std::addressof(v))} + , raw_type_{type_db::get>()} + , ref_type_{std::is_const_v> ? ref_types::cref : ref_types::ref} {} template < typename To > inline To arg::cast() const { @@ -81,7 +81,7 @@ namespace meta_hpp } if constexpr ( std::is_reference_v ) { - using raw_type = remove_cvref_t; + using raw_type = stdex::remove_cvref_t; if constexpr ( std::is_lvalue_reference_v ) { return *static_cast(data_); @@ -93,7 +93,7 @@ namespace meta_hpp } if constexpr ( !std::is_pointer_v && !std::is_reference_v ) { - using raw_type = remove_cvref_t; + using raw_type = stdex::remove_cvref_t; if ( ref_type() == ref_types::ref ) { if constexpr ( std::is_constructible_v ) { @@ -126,14 +126,14 @@ namespace meta_hpp template < typename To > inline bool arg::can_cast() const noexcept { if constexpr ( std::is_pointer_v ) { - using to_raw_type = remove_cv_t; - using to_raw_ptr_type = remove_cv_t>; + using to_raw_type = std::remove_cv_t; + using to_raw_ptr_type = std::remove_cv_t>; return raw_type().id() == type_db::get().id() - || raw_type().id() == type_db::get>().id(); + || raw_type().id() == type_db::get>().id(); } if constexpr ( std::is_lvalue_reference_v ) { - constexpr bool to_const = std::is_const_v>; + constexpr bool to_const = std::is_const_v>; if ( !to_const && is_rvalue() ) { return false; @@ -143,21 +143,21 @@ namespace meta_hpp return false; } - using to_raw_type = remove_cvref_t; + using to_raw_type = stdex::remove_cvref_t; if ( raw_type().id() == type_db::get().id() ) { return true; } if constexpr ( to_const && std::is_pointer_v ) { - using to_raw_ptr_type = remove_cv_t>; - return raw_type().id() == type_db::get>().id(); + using to_raw_ptr_type = std::remove_cv_t>; + return raw_type().id() == type_db::get>().id(); } return false; } if constexpr ( std::is_rvalue_reference_v ) { - constexpr bool to_const = std::is_const_v>; + constexpr bool to_const = std::is_const_v>; if ( !is_rvalue() ) { return false; @@ -167,21 +167,21 @@ namespace meta_hpp return false; } - using to_raw_type = remove_cvref_t; + using to_raw_type = stdex::remove_cvref_t; if ( raw_type().id() == type_db::get().id() ) { return true; } if constexpr ( to_const && std::is_pointer_v ) { - using to_raw_ptr_type = remove_cv_t>; - return raw_type().id() == type_db::get>().id(); + using to_raw_ptr_type = std::remove_cv_t>; + return raw_type().id() == type_db::get>().id(); } return false; } if constexpr ( !std::is_pointer_v && !std::is_reference_v ) { - using to_raw_type = remove_cv_t; + using to_raw_type = std::remove_cv_t; if ( raw_type().id() != type_db::get().id() ) { return false; } diff --git a/untests/features/infos/base_info_tests.cpp b/untests/features/infos/base_info_tests.cpp new file mode 100644 index 0000000..032560b --- /dev/null +++ b/untests/features/infos/base_info_tests.cpp @@ -0,0 +1,45 @@ +/******************************************************************************* + * 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 "_infos_fwd.hpp" + +namespace +{ + using namespace meta_hpp; + using namespace std::string_literals; +} + +namespace +{ + class base { + public: + virtual ~base() {} + }; + + class derived final : public base { + public: + derived() = default; + }; + + struct empty final {}; +} + +TEST_CASE("features/infos/base") { + registry db; + + db( + class_{"base"}, + class_{"derived"}( + base_{} + ) + ); + + REQUIRE(db.get_class_by_path("derived")); + const class_info derived_info = db.get_class_by_path("derived"); + + CHECK(derived_info.is_derived_from()); + CHECK_FALSE(derived_info.is_derived_from()); +} diff --git a/untests/features/infos/class_info_tests.cpp b/untests/features/infos/class_info_tests.cpp index de7996a..b0a1a99 100644 --- a/untests/features/infos/class_info_tests.cpp +++ b/untests/features/infos/class_info_tests.cpp @@ -8,7 +8,87 @@ namespace { + using namespace meta_hpp; + using namespace std::string_literals; +} + +namespace +{ + class shape { + public: + virtual ~shape() {} + virtual int area() const = 0; + }; + + class rectangle : public shape { + public: + rectangle(const rectangle& other) { + width_ = other.width_; + height_ = other.height_; + } + + rectangle& operator=(const rectangle& other) { + if ( this != &other ) { + return *this; + } + width_ = other.width_; + height_ = other.height_; + return *this; + } + + rectangle(int width, int height) + : width_{width} + , height_{height} {} + + int area() const override { + return width_ * height_; + } + + int width() const noexcept { + return width_; + } + + int height() const noexcept { + return height_; + } + private: + int width_{}; + int height_{}; + }; } TEST_CASE("features/infos/class") { + registry db; + + db( + class_{"shape"}( + method_{"area", &shape::area} + ), + class_{"rectangle"}( + base_{}, + ctor_{}, + method_{"width", &rectangle::width}, + method_{"height", &rectangle::height} + ) + ); + + SUBCASE("base") { + REQUIRE(db.get_class_by_path("shape")); + const class_info shape_info = db.get_class_by_path("shape"); + CHECK(shape_info.name() == "shape"); + CHECK(shape_info.type().id() == type_db::get().id()); + + CHECK_FALSE(shape_info.is_derived_from()); + CHECK_FALSE(shape_info.is_derived_from()); + } + + SUBCASE("derived") { + REQUIRE(db.get_class_by_path("rectangle")); + const class_info rectangle_info = db.get_class_by_path("rectangle"); + CHECK(rectangle_info.name() == "rectangle"); + CHECK(rectangle_info.type().id() == type_db::get().id()); + + CHECK(rectangle_info.is_derived_from()); + CHECK_FALSE(rectangle_info.is_derived_from()); + } } diff --git a/untests/features/infos/ctor_info_tests.cpp b/untests/features/infos/ctor_info_tests.cpp index 57fe560..3a91965 100644 --- a/untests/features/infos/ctor_info_tests.cpp +++ b/untests/features/infos/ctor_info_tests.cpp @@ -8,7 +8,113 @@ namespace { + using namespace meta_hpp; + using namespace std::string_literals; +} + +namespace +{ + struct ivec2 { + int x{}; + int y{}; + + [[maybe_unused]] ivec2() = default; + [[maybe_unused]] ivec2(const ivec2& other) = default; + [[maybe_unused]] explicit ivec2(int v): x{v}, y{v} {} + [[maybe_unused]] ivec2(int x, int y): x{x}, y{y} {} + }; } TEST_CASE("features/infos/ctor") { + registry db; + + db( + namespace_{"vmath"}( + class_{"ivec2"}( + ctor_<>{}(data_{"info", "void ctor"s}), + ctor_{}(data_{"info", "copy ctor"s}), + ctor_{}(data_{"info", "int ctor"s}), + ctor_{}(data_{"info", "int,int ctor"s}) + ) + ) + ); + + const class_info ivec2_info = db.get_class_by_path("vmath::ivec2"); + REQUIRE(ivec2_info); + + SUBCASE("void") { + const ctor_info ci = ivec2_info.get_ctor_by_args(); + REQUIRE(ci); + + REQUIRE(ci.get_data_by_name("info")); + CHECK(ci.get_data_by_name("info").value().equals("void ctor"s)); + + { + const ctor_info ci2 = ivec2_info.get_ctor_by_args(std::array{}); + const ctor_info ci3 = ivec2_info.get_ctor_by_args(std::vector{}); + REQUIRE(ci2); + REQUIRE(ci3); + CHECK(ci.type().id() == ci2.type().id()); + CHECK(ci.type().id() == ci2.type().id()); + } + } + + SUBCASE("int") { + const ctor_info ci = ivec2_info.get_ctor_by_args(); + REQUIRE(ci); + + REQUIRE(ci.get_data_by_name("info")); + CHECK(ci.get_data_by_name("info").value().equals("int ctor"s)); + + { + const ctor_info ci2 = ivec2_info.get_ctor_by_args(std::array{ + type_db::get()}); + const ctor_info ci3 = ivec2_info.get_ctor_by_args(std::vector{ + type_db::get()}); + REQUIRE(ci2); + REQUIRE(ci3); + CHECK(ci.type().id() == ci2.type().id()); + CHECK(ci.type().id() == ci2.type().id()); + } + } + + SUBCASE("const ivec2&") { + const ctor_info ci = ivec2_info.get_ctor_by_args(); + REQUIRE(ci); + + REQUIRE(ci.get_data_by_name("info")); + CHECK(ci.get_data_by_name("info").value().equals("copy ctor"s)); + + { + const ctor_info ci2 = ivec2_info.get_ctor_by_args(std::array{ + type_db::get()}); + const ctor_info ci3 = ivec2_info.get_ctor_by_args(std::vector{ + type_db::get()}); + REQUIRE(ci2); + REQUIRE(ci3); + CHECK(ci.type().id() == ci2.type().id()); + CHECK(ci.type().id() == ci2.type().id()); + } + } + + SUBCASE("int,int") { + const ctor_info ci = ivec2_info.get_ctor_by_args(); + REQUIRE(ci); + + REQUIRE(ci.get_data_by_name("info")); + CHECK(ci.get_data_by_name("info").value().equals("int,int ctor"s)); + + { + const ctor_info ci2 = ivec2_info.get_ctor_by_args(std::array{ + type_db::get(), + type_db::get()}); + const ctor_info ci3 = ivec2_info.get_ctor_by_args(std::vector{ + type_db::get(), + type_db::get()}); + REQUIRE(ci2); + REQUIRE(ci3); + CHECK(ci.type().id() == ci2.type().id()); + CHECK(ci.type().id() == ci2.type().id()); + } + } } diff --git a/untests/features/types/base_type_tests.cpp b/untests/features/types/base_type_tests.cpp new file mode 100644 index 0000000..d7ae407 --- /dev/null +++ b/untests/features/types/base_type_tests.cpp @@ -0,0 +1,30 @@ +/******************************************************************************* + * 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 "_types_fwd.hpp" + +namespace +{ + using namespace meta_hpp; + using namespace std::string_literals; +} + +namespace +{ + struct base { + virtual ~base() = 0; + }; + + struct derived final : base { + }; +} + +TEST_CASE("features/types/base") { + base_type bt{typename_arg, typename_arg}; + + CHECK(bt.base_class_type().id() == type_db::get().id()); + CHECK(bt.derived_class_type().id() == type_db::get().id()); +} From c0ad3347fe2b56ee85f9145dae9bf790f1366a65 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Wed, 11 Aug 2021 02:15:26 +0700 Subject: [PATCH 093/233] arg_base for argument cast checking --- headers/meta.hpp/meta_utilities/arg.hpp | 220 ++++---- untests/features/utilities/arg_base_tests.cpp | 184 +++++++ untests/features/utilities/arg_tests.cpp | 514 +++++++++--------- 3 files changed, 560 insertions(+), 358 deletions(-) create mode 100644 untests/features/utilities/arg_base_tests.cpp diff --git a/headers/meta.hpp/meta_utilities/arg.hpp b/headers/meta.hpp/meta_utilities/arg.hpp index 45cc6ed..0aad3a6 100644 --- a/headers/meta.hpp/meta_utilities/arg.hpp +++ b/headers/meta.hpp/meta_utilities/arg.hpp @@ -10,7 +10,7 @@ namespace meta_hpp { - class arg final { + class arg_base { public: enum class ref_types { ref, @@ -19,36 +19,38 @@ namespace meta_hpp crref, }; public: - arg() = delete; + arg_base() = delete; - arg(arg&&) = delete; - arg& operator=(arg&&) = delete; + arg_base(arg_base&&) = delete; + arg_base& operator=(arg_base&&) = delete; - arg(const arg&) = delete; - arg& operator=(const arg&) = delete; + arg_base(const arg_base&) = delete; + arg_base& operator=(const arg_base&) = delete; - template < typename T - , std::enable_if_t, int> = 0 > - explicit arg(T&& v); + template < typename T, std::enable_if_t< + std::is_pointer_v || + std::is_lvalue_reference_v, int> = 0 > + explicit arg_base(typename_arg_t) + : raw_type_{type_db::get>()} + , ref_type_{std::is_const_v> ? ref_types::cref : ref_types::ref} {} - template < typename T - , std::enable_if_t, int> = 0 > - explicit arg(T&& v); - - template < typename To > - To cast() const; - - template < typename To > - bool can_cast() const noexcept; - - any_type raw_type() const noexcept; - ref_types ref_type() const noexcept; + template < typename T, std::enable_if_t< + std::is_rvalue_reference_v || + (!std::is_pointer_v && !std::is_reference_v), int> = 0 > + explicit arg_base(typename_arg_t) + : raw_type_{type_db::get>()} + , ref_type_{std::is_const_v> ? ref_types::crref : ref_types::rref} {} bool is_const() const noexcept; bool is_lvalue() const noexcept; bool is_rvalue() const noexcept; + + any_type raw_type() const noexcept; + ref_types ref_type() const noexcept; + + template < typename To > + bool can_cast_to() const noexcept; private: - void* data_{}; any_type raw_type_{}; ref_types ref_type_{}; }; @@ -56,75 +58,31 @@ namespace meta_hpp namespace meta_hpp { - template < typename T - , std::enable_if_t, int> > - inline arg::arg(T&& v) - : data_{const_cast>>(std::addressof(v))} - , raw_type_{type_db::get>()} - , ref_type_{std::is_const_v ? ref_types::crref : ref_types::rref} {} + inline bool arg_base::is_const() const noexcept { + return ref_type_ == ref_types::cref + || ref_type_ == ref_types::crref; + } - template < typename T - , std::enable_if_t, int> > - inline arg::arg(T&& v) - : data_{const_cast>>(std::addressof(v))} - , raw_type_{type_db::get>()} - , ref_type_{std::is_const_v> ? ref_types::cref : ref_types::ref} {} + inline bool arg_base::is_lvalue() const noexcept { + return ref_type_ == ref_types::ref + || ref_type_ == ref_types::cref; + } - template < typename To > - inline To arg::cast() const { - if ( !can_cast() ) { - throw std::logic_error("bad argument cast"); - } + inline bool arg_base::is_rvalue() const noexcept { + return ref_type_ == ref_types::rref + || ref_type_ == ref_types::crref; + } - if constexpr ( std::is_pointer_v ) { - return *static_cast(data_); - } + inline any_type arg_base::raw_type() const noexcept { + return raw_type_; + } - if constexpr ( std::is_reference_v ) { - using raw_type = stdex::remove_cvref_t; - - if constexpr ( std::is_lvalue_reference_v ) { - return *static_cast(data_); - } - - if constexpr ( std::is_rvalue_reference_v ) { - return std::move(*static_cast(data_)); - } - } - - if constexpr ( !std::is_pointer_v && !std::is_reference_v ) { - using raw_type = stdex::remove_cvref_t; - - if ( ref_type() == ref_types::ref ) { - if constexpr ( std::is_constructible_v ) { - return To{*static_cast(data_)}; - } - } - - if ( ref_type() == ref_types::cref ) { - if constexpr ( std::is_constructible_v ) { - return To{std::as_const(*static_cast(data_))}; - } - } - - if ( ref_type() == ref_types::rref ) { - if constexpr ( std::is_constructible_v ) { - return To{std::move(*static_cast(data_))}; - } - } - - if ( ref_type() == ref_types::crref ) { - if constexpr ( std::is_constructible_v ) { - return To{std::move(std::as_const(*static_cast(data_)))}; - } - } - } - - throw std::logic_error("bad argument cast"); + inline arg_base::ref_types arg_base::ref_type() const noexcept { + return ref_type_; } template < typename To > - inline bool arg::can_cast() const noexcept { + bool arg_base::can_cast_to() const noexcept { if constexpr ( std::is_pointer_v ) { using to_raw_type = std::remove_cv_t; using to_raw_ptr_type = std::remove_cv_t>; @@ -192,27 +150,87 @@ namespace meta_hpp || (ref_type() == ref_types::crref && std::is_constructible_v); } } +} - inline any_type arg::raw_type() const noexcept { - return raw_type_; - } +namespace meta_hpp +{ + class arg final : public arg_base { + public: + arg() = delete; - inline arg::ref_types arg::ref_type() const noexcept { - return ref_type_; - } + arg(arg&&) = delete; + arg& operator=(arg&&) = delete; - inline bool arg::is_const() const noexcept { - return ref_type_ == ref_types::cref - || ref_type_ == ref_types::crref; - } + arg(const arg&) = delete; + arg& operator=(const arg&) = delete; - inline bool arg::is_lvalue() const noexcept { - return ref_type_ == ref_types::ref - || ref_type_ == ref_types::cref; - } + template < typename T > + explicit arg(T&& v); - inline bool arg::is_rvalue() const noexcept { - return ref_type_ == ref_types::rref - || ref_type_ == ref_types::crref; + template < typename To > + To cast() const; + private: + void* data_{}; + }; +} + +namespace meta_hpp +{ + template < typename T > + arg::arg(T&& v) + : arg_base{typename_arg} + , data_{const_cast>>(std::addressof(v))} {} + + template < typename To > + To arg::cast() const { + if ( !can_cast_to() ) { + throw std::logic_error("bad argument cast"); + } + + if constexpr ( std::is_pointer_v ) { + return *static_cast(data_); + } + + if constexpr ( std::is_reference_v ) { + using raw_type = stdex::remove_cvref_t; + + if constexpr ( std::is_lvalue_reference_v ) { + return *static_cast(data_); + } + + if constexpr ( std::is_rvalue_reference_v ) { + return std::move(*static_cast(data_)); + } + } + + if constexpr ( !std::is_pointer_v && !std::is_reference_v ) { + using raw_type = stdex::remove_cvref_t; + + if ( ref_type() == ref_types::ref ) { + if constexpr ( std::is_constructible_v ) { + return To{*static_cast(data_)}; + } + } + + if ( ref_type() == ref_types::cref ) { + if constexpr ( std::is_constructible_v ) { + return To{std::as_const(*static_cast(data_))}; + } + } + + if ( ref_type() == ref_types::rref ) { + if constexpr ( std::is_constructible_v ) { + return To{std::move(*static_cast(data_))}; + } + } + + if ( ref_type() == ref_types::crref ) { + if constexpr ( std::is_constructible_v ) { + return To{std::move(std::as_const(*static_cast(data_)))}; + } + } + } + + throw std::logic_error("bad argument cast"); } } diff --git a/untests/features/utilities/arg_base_tests.cpp b/untests/features/utilities/arg_base_tests.cpp new file mode 100644 index 0000000..0e538f6 --- /dev/null +++ b/untests/features/utilities/arg_base_tests.cpp @@ -0,0 +1,184 @@ +/******************************************************************************* + * 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 "_utilities_fwd.hpp" + +namespace +{ + using namespace meta_hpp; + using namespace std::string_literals; +} + +namespace +{ + struct ivec2 { + int x{}; + int y{}; + + [[maybe_unused]] ivec2() = default; + [[maybe_unused]] explicit ivec2(int v): x{v}, y{v} {} + [[maybe_unused]] ivec2(int x, int y): x{x}, y{y} {} + + [[maybe_unused]] ivec2(ivec2&& other) noexcept { + x = other.x; + y = other.y; + other.x = 0; + other.y = 0; + } + + [[maybe_unused]] ivec2(const ivec2& other) noexcept { + x = other.x; + y = other.y; + } + + ivec2& operator=(ivec2&&) = delete; + ivec2& operator=(const ivec2&) = delete; + }; + + struct ivec3 { + int x{}; + int y{}; + int z{}; + + [[maybe_unused]] ivec3() = default; + [[maybe_unused]] explicit ivec3(int v): x{v}, y{v}, z{v} {} + [[maybe_unused]] ivec3(int x, int y, int z): x{x}, y{y}, z{z} {} + + [[maybe_unused]] ivec3(ivec3&& other) noexcept { + x = other.x; + y = other.y; + z = other.z; + other.x = 0; + other.y = 0; + other.z = 0; + } + + [[maybe_unused]] ivec3(const ivec3& other) noexcept { + x = other.x; + y = other.y; + z = other.z; + } + + ivec3& operator=(ivec3&&) = delete; + ivec3& operator=(const ivec3&) = delete; + }; + + [[maybe_unused]] bool operator==(const ivec2& l, const ivec2& r) noexcept { + return l.x == r.x && l.y == r.y; + } + + [[maybe_unused]] bool operator==(const ivec3& l, const ivec3& r) noexcept { + return l.x == r.x && l.y == r.y && l.z == r.z; + } +} + +TEST_CASE("features/utilities/arg_base/type") { + SUBCASE("ptr") { + ivec2 v{1,2}; + ivec2* vp = &v; + arg_base a{typename_arg}; + + CHECK(a.raw_type().id() == type_db::get().id()); + CHECK(a.ref_type() == arg_base::ref_types::ref); + } + + SUBCASE("rptr") { + ivec2 v{1,2}; + ivec2* vp = &v; + arg_base a{typename_arg}; + + CHECK(a.raw_type().id() == type_db::get().id()); + CHECK(a.ref_type() == arg_base::ref_types::rref); + } + + SUBCASE("ptr_c") { + ivec2 v{1,2}; + ivec2* const vp = &v; + arg_base a{typename_arg}; + + CHECK(a.raw_type().id() == type_db::get().id()); + CHECK(a.ref_type() == arg_base::ref_types::cref); + } + + SUBCASE("rptr_c") { + ivec2 v{1,2}; + ivec2* const vp = &v; + arg_base a{typename_arg}; + + CHECK(a.raw_type().id() == type_db::get().id()); + CHECK(a.ref_type() == arg_base::ref_types::crref); + } + + SUBCASE("cptr") { + const ivec2 v{1,2}; + const ivec2* vp = &v; + arg_base a{typename_arg}; + + CHECK(a.raw_type().id() == type_db::get().id()); + CHECK(a.ref_type() == arg_base::ref_types::ref); + } + + SUBCASE("crptr") { + const ivec2 v{1,2}; + const ivec2* vp = &v; + arg_base a{typename_arg}; + + CHECK(a.raw_type().id() == type_db::get().id()); + CHECK(a.ref_type() == arg_base::ref_types::rref); + } + + SUBCASE("cptr_c") { + const ivec2 v{1,2}; + const ivec2* const vp = &v; + arg_base a{typename_arg}; + + CHECK(a.raw_type().id() == type_db::get().id()); + CHECK(a.ref_type() == arg_base::ref_types::cref); + } + + SUBCASE("crptr_c") { + const ivec2 v{1,2}; + const ivec2* const vp = &v; + arg_base a{typename_arg}; + + CHECK(a.raw_type().id() == type_db::get().id()); + CHECK(a.ref_type() == arg_base::ref_types::crref); + } + + SUBCASE("ref") { + ivec2 v{1,2}; + ivec2& vr = v; + arg_base a{typename_arg}; + + CHECK(a.raw_type().id() == type_db::get().id()); + CHECK(a.ref_type() == arg_base::ref_types::ref); + } + + SUBCASE("cref") { + const ivec2 v{1,2}; + const ivec2& vr = v; + arg_base a{typename_arg}; + + CHECK(a.raw_type().id() == type_db::get().id()); + CHECK(a.ref_type() == arg_base::ref_types::cref); + } + + SUBCASE("rref") { + ivec2 v{1,2}; + arg_base a{typename_arg}; + + CHECK(a.raw_type().id() == type_db::get().id()); + CHECK(a.ref_type() == arg_base::ref_types::rref); + } + + SUBCASE("crref") { + const ivec2 v{1,2}; + arg_base a{typename_arg}; + + CHECK(a.raw_type().id() == type_db::get().id()); + CHECK(a.ref_type() == arg_base::ref_types::crref); + } +} diff --git a/untests/features/utilities/arg_tests.cpp b/untests/features/utilities/arg_tests.cpp index 4043821..8829235 100644 --- a/untests/features/utilities/arg_tests.cpp +++ b/untests/features/utilities/arg_tests.cpp @@ -183,42 +183,42 @@ TEST_CASE("features/utilities/arg/type") { } } -TEST_CASE("features/utilities/arg/can_cast") { +TEST_CASE("features/utilities/arg/can_cast_to") { SUBCASE("ptr") { ivec2 v{1,2}; ivec2* vp = &v; arg a{vp}; - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast()); - CHECK(a.can_cast()); - CHECK(a.can_cast()); - CHECK(a.can_cast()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); { - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); } { - CHECK(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK(a.can_cast()); - CHECK(a.can_cast()); + CHECK(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); []([[maybe_unused]] ivec2 *&){}(vp); //[]([[maybe_unused]] const ivec2 *&){}(vp); @@ -237,36 +237,36 @@ TEST_CASE("features/utilities/arg/can_cast") { ivec2* vp = &v; arg a{std::move(vp)}; - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast()); - CHECK(a.can_cast()); - CHECK(a.can_cast()); - CHECK(a.can_cast()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); { - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); } { - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK(a.can_cast()); - CHECK(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); - CHECK(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK(a.can_cast()); - CHECK(a.can_cast()); + CHECK(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); //[]([[maybe_unused]] ivec2 *&){}(std::move(vp)); //[]([[maybe_unused]] const ivec2 *&){}(std::move(vp)); @@ -285,36 +285,36 @@ TEST_CASE("features/utilities/arg/can_cast") { ivec2* const vp = &v; arg a{vp}; - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast()); - CHECK(a.can_cast()); - CHECK(a.can_cast()); - CHECK(a.can_cast()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); { - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); } { - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK(a.can_cast()); - CHECK(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); // []([[maybe_unused]] ivec2 *&){}(vp); // []([[maybe_unused]] const ivec2 *&){}(vp); @@ -333,36 +333,36 @@ TEST_CASE("features/utilities/arg/can_cast") { ivec2* const vp = &v; arg a{std::move(vp)}; - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast()); - CHECK(a.can_cast()); - CHECK(a.can_cast()); - CHECK(a.can_cast()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); { - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); } { - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK(a.can_cast()); - CHECK(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK(a.can_cast()); - CHECK(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); //[]([[maybe_unused]] ivec2 *&){}(std::move(vp)); //[]([[maybe_unused]] const ivec2 *&){}(std::move(vp)); @@ -381,34 +381,34 @@ TEST_CASE("features/utilities/arg/can_cast") { const ivec2* vp = &v; arg a{vp}; - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast()); - CHECK(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); { - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); } { - CHECK_FALSE(a.can_cast()); - CHECK(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); //[]([[maybe_unused]] ivec2 *&){}(vp); []([[maybe_unused]] const ivec2 *&){}(vp); @@ -427,34 +427,34 @@ TEST_CASE("features/utilities/arg/can_cast") { const ivec2* vp = &v; arg a{std::move(vp)}; - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast()); - CHECK(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); { - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); } { - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast()); - CHECK(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); //[]([[maybe_unused]] ivec2 *&){}(std::move(vp)); //[]([[maybe_unused]] const ivec2 *&){}(std::move(vp)); @@ -473,34 +473,34 @@ TEST_CASE("features/utilities/arg/can_cast") { const ivec2* const vp = &v; arg a{vp}; - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast()); - CHECK(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); { - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); } { - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); //[]([[maybe_unused]] ivec2 *&){}(vp); //[]([[maybe_unused]] const ivec2 *&){}(vp); @@ -519,34 +519,34 @@ TEST_CASE("features/utilities/arg/can_cast") { const ivec2* const vp = &v; arg a{std::move(vp)}; - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast()); - CHECK(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); { - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); } { - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); //[]([[maybe_unused]] ivec2 *&){}(std::move(vp)); //[]([[maybe_unused]] const ivec2 *&){}(std::move(vp)); @@ -565,36 +565,36 @@ TEST_CASE("features/utilities/arg/can_cast") { ivec2& vr = v; arg a{vr}; - CHECK(a.can_cast()); - CHECK(a.can_cast()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast()); - CHECK(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); { - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); } { - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); } } @@ -603,35 +603,35 @@ TEST_CASE("features/utilities/arg/can_cast") { const ivec2& vr = v; arg a{vr}; - CHECK(a.can_cast()); - CHECK(a.can_cast()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast()); - CHECK(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); { - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); } { - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); } } @@ -639,37 +639,37 @@ TEST_CASE("features/utilities/arg/can_cast") { ivec2 v{1,2}; arg a{std::move(v)}; - CHECK(a.can_cast()); - CHECK(a.can_cast()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast()); - CHECK(a.can_cast()); - CHECK(a.can_cast()); - CHECK(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); { - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); } { - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); } } @@ -677,36 +677,36 @@ TEST_CASE("features/utilities/arg/can_cast") { const ivec2 v{1,2}; arg a{std::move(v)}; - CHECK(a.can_cast()); - CHECK(a.can_cast()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast()); - CHECK(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); { - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); } { - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); - CHECK_FALSE(a.can_cast()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); } } } From c0708cd8771947255a90b703006d2a81c1d7059c Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Wed, 11 Aug 2021 18:05:19 +0700 Subject: [PATCH 094/233] value impl --- headers/meta.hpp/meta_fwd.hpp | 1 + headers/meta.hpp/meta_types.hpp | 5 +- headers/meta.hpp/meta_types/_types_fwd.hpp | 2 +- headers/meta.hpp/meta_utilities/arg.hpp | 22 +- headers/meta.hpp/meta_utilities/value.hpp | 241 ++++++++++++++++++-- untests/features/utilities/value_tests.cpp | 243 +++++++++++++++++++++ 6 files changed, 489 insertions(+), 25 deletions(-) diff --git a/headers/meta.hpp/meta_fwd.hpp b/headers/meta.hpp/meta_fwd.hpp index 34981a0..b015a9e 100644 --- a/headers/meta.hpp/meta_fwd.hpp +++ b/headers/meta.hpp/meta_fwd.hpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include diff --git a/headers/meta.hpp/meta_types.hpp b/headers/meta.hpp/meta_types.hpp index 5265966..82a782e 100644 --- a/headers/meta.hpp/meta_types.hpp +++ b/headers/meta.hpp/meta_types.hpp @@ -71,9 +71,10 @@ namespace meta_hpp } template < typename T > - any_type type_db::get() { + const any_type& type_db::get() { static const auto raw_type = detail::make_any_type(); - return any_type{raw_type}; + static const auto type = any_type{raw_type}; + return type; } template < typename Tuple > diff --git a/headers/meta.hpp/meta_types/_types_fwd.hpp b/headers/meta.hpp/meta_types/_types_fwd.hpp index a533419..316f868 100644 --- a/headers/meta.hpp/meta_types/_types_fwd.hpp +++ b/headers/meta.hpp/meta_types/_types_fwd.hpp @@ -190,7 +190,7 @@ namespace meta_hpp type_db() = delete; template < typename T > - static any_type get(); + static const any_type& get(); template < typename Tuple > static std::vector multi_get(); diff --git a/headers/meta.hpp/meta_utilities/arg.hpp b/headers/meta.hpp/meta_utilities/arg.hpp index 0aad3a6..e75fb15 100644 --- a/headers/meta.hpp/meta_utilities/arg.hpp +++ b/headers/meta.hpp/meta_utilities/arg.hpp @@ -30,16 +30,12 @@ namespace meta_hpp template < typename T, std::enable_if_t< std::is_pointer_v || std::is_lvalue_reference_v, int> = 0 > - explicit arg_base(typename_arg_t) - : raw_type_{type_db::get>()} - , ref_type_{std::is_const_v> ? ref_types::cref : ref_types::ref} {} + explicit arg_base(typename_arg_t); template < typename T, std::enable_if_t< std::is_rvalue_reference_v || (!std::is_pointer_v && !std::is_reference_v), int> = 0 > - explicit arg_base(typename_arg_t) - : raw_type_{type_db::get>()} - , ref_type_{std::is_const_v> ? ref_types::crref : ref_types::rref} {} + explicit arg_base(typename_arg_t); bool is_const() const noexcept; bool is_lvalue() const noexcept; @@ -58,6 +54,20 @@ namespace meta_hpp namespace meta_hpp { + template < typename T, std::enable_if_t< + std::is_pointer_v || + std::is_lvalue_reference_v, int> > + arg_base::arg_base(typename_arg_t) + : raw_type_{type_db::get>()} + , ref_type_{std::is_const_v> ? ref_types::cref : ref_types::ref} {} + + template < typename T, std::enable_if_t< + std::is_rvalue_reference_v || + (!std::is_pointer_v && !std::is_reference_v), int> > + arg_base::arg_base(typename_arg_t) + : raw_type_{type_db::get>()} + , ref_type_{std::is_const_v> ? ref_types::crref : ref_types::rref} {} + inline bool arg_base::is_const() const noexcept { return ref_type_ == ref_types::cref || ref_type_ == ref_types::crref; diff --git a/headers/meta.hpp/meta_utilities/value.hpp b/headers/meta.hpp/meta_utilities/value.hpp index 1926e55..db32a16 100644 --- a/headers/meta.hpp/meta_utilities/value.hpp +++ b/headers/meta.hpp/meta_utilities/value.hpp @@ -14,33 +14,242 @@ namespace meta_hpp public: value() = delete; - value(value&&) = default; - value& operator=(value&&) = default; + value(value&& other); + value(const value& other); - value(const value&) = default; - value& operator=(const value&) = default; + value& operator=(value&& other); + value& operator=(const value& other); - template < typename T, typename Tp = std::decay_t + template < typename T + , typename Tp = std::decay_t , std::enable_if_t, int> = 0 > - value(T&& val) - : raw_{std::forward(val)} {} + value(T&& val); - template < typename T, typename Tp = std::decay_t + template < typename T + , typename Tp = std::decay_t , std::enable_if_t, int> = 0 > - value& operator=(T&& val) { - value{std::forward(val)}.swap(*this); - return *this; - } + value& operator=(T&& val); - void swap(value& other) noexcept { - using std::swap; - swap(raw_, other.raw_); - } + void swap(value& other) noexcept; + + const any_type& type() const noexcept; + + void* data() noexcept; + const void* data() const noexcept; + const void* cdata() const noexcept; + + template < typename T > + bool equals(const T& other) const; + bool equals(const value& other) const; + + template < typename T, typename Tp = std::decay_t > + Tp& cast() &; + + template < typename T, typename Tp = std::decay_t > + Tp&& cast() &&; + + template < typename T, typename Tp = std::decay_t > + const Tp& cast() const &; + + template < typename T, typename Tp = std::decay_t > + const Tp&& cast() const &&; + + template < typename T, typename Tp = std::decay_t > + Tp* try_cast() noexcept; + + template < typename T, typename Tp = std::decay_t > + const Tp* try_cast() const noexcept; private: + struct traits; std::any raw_{}; + const traits* traits_{}; }; inline void swap(value& l, value& r) noexcept { l.swap(r); } } + +namespace meta_hpp +{ + struct value::traits final { + const any_type type; + + void* (*const data)(value&) noexcept; + const void* (*const cdata)(const value&) noexcept; + + bool (*const equals)(const value&, const value&); + + void (*const move_ctor)(std::any&, value&&); + void (*const copy_ctor)(std::any&, const value&); + + template < typename T > + static const traits* get() noexcept; + }; + + template < typename T > + const value::traits* value::traits::get() noexcept { + static const traits traits{ + // type + type_db::get(), + + // data + +[](value& v) noexcept -> void* { + return v.try_cast(); + }, + + // cdata + +[](const value& v) noexcept -> const void* { + return v.try_cast(); + }, + + // equals + +[](const value& l, const value& r) -> bool { + if ( l.type() != r.type() ) { + return false; + } + if constexpr ( std::is_invocable_v, const T&, const T&> ) { + return std::equal_to<>{}(l.cast(), r.cast()); + } else { + throw std::logic_error("value type doesn't have equality operator"); + } + }, + + // move_ctor + +[](std::any& dst, value&& src) { + if constexpr ( std::is_move_constructible_v ) { + dst.emplace(std::move(src).cast()); + } else { + throw std::logic_error("value type is not move constructible"); + } + }, + + // copy_ctor + +[](std::any& dst, const value& src) { + if constexpr ( std::is_copy_constructible_v ) { + dst.emplace(src.cast()); + } else { + throw std::logic_error("value type is not copy constructible"); + } + }, + }; + return &traits; + } +} + +namespace meta_hpp +{ + inline value::value(value&& other) { + traits_ = other.traits_; + traits_->move_ctor(raw_, std::move(other)); + } + + inline value::value(const value& other) { + traits_ = other.traits_; + traits_->copy_ctor(raw_, other); + } + + inline value& value::operator=(value&& other) { + if ( this != &other ) { + traits_ = other.traits_; + traits_->move_ctor(raw_, std::move(other)); + } + return *this; + } + + inline value& value::operator=(const value& other) { + if ( this != &other ) { + traits_ = other.traits_; + traits_->copy_ctor(raw_, other); + } + return *this; + } + + template < typename T, typename Tp + , std::enable_if_t, int> > + value::value(T&& val) + : raw_{std::forward(val)} + , traits_{traits::get()} {} + + template < typename T, typename Tp + , std::enable_if_t, int> > + value& value::operator=(T&& val) { + raw_ = std::forward(val); + traits_ = type_db::get(); + return *this; + } + + inline void value::swap(value& other) noexcept { + using std::swap; + swap(raw_, other.raw_); + swap(traits_, other.traits_); + } + + inline const any_type& value::type() const noexcept { + return traits_->type; + } + + inline void* value::data() noexcept { + return traits_->data(*this); + } + + inline const void* value::data() const noexcept { + return traits_->cdata(*this); + } + + inline const void* value::cdata() const noexcept { + return traits_->cdata(*this); + } + + template < typename T > + bool value::equals(const T& other) const { + return type() == type_db::get() + && std::equal_to<>{}(cast(), other); + } + + inline bool value::equals(const value& other) const { + return traits_->equals(*this, other); + } + + template < typename T, typename Tp > + Tp& value::cast() & { + if ( type() != type_db::get() ) { + throw std::logic_error("bad value cast"); + } + return std::any_cast(raw_); + } + + template < typename T, typename Tp > + Tp&& value::cast() && { + if ( type() != type_db::get() ) { + throw std::logic_error("bad value cast"); + } + return std::move(std::any_cast(raw_)); + } + + template < typename T, typename Tp > + const Tp& value::cast() const & { + if ( type() != type_db::get() ) { + throw std::logic_error("bad value cast"); + } + return std::any_cast(raw_); + } + + template < typename T, typename Tp > + const Tp&& value::cast() const && { + if ( type() != type_db::get() ) { + throw std::logic_error("bad value cast"); + } + return std::move(std::any_cast(raw_)); + } + + template < typename T, typename Tp > + Tp* value::try_cast() noexcept { + return std::any_cast(&raw_); + } + + template < typename T, typename Tp > + const Tp* value::try_cast() const noexcept { + return std::any_cast(&raw_); + } +} diff --git a/untests/features/utilities/value_tests.cpp b/untests/features/utilities/value_tests.cpp index 6613699..6d75029 100644 --- a/untests/features/utilities/value_tests.cpp +++ b/untests/features/utilities/value_tests.cpp @@ -8,7 +8,250 @@ namespace { + using namespace meta_hpp; + using namespace std::string_literals; + + struct ivec2 { + int x{}; + int y{}; + + ivec2() = default; + explicit ivec2(int v): x{v}, y{v} {} + ivec2(int x, int y): x{x}, y{y} {} + + ivec2(ivec2&& other) noexcept + : x{other.x} + , y{other.y} { + other.x = 0; + other.y = 0; + ++move_ctor_counter; + } + + ivec2(const ivec2& other) noexcept + : x{other.x} + , y{other.y} { + ++copy_ctor_counter; + } + + ivec2& operator=(ivec2&& other) = delete; + ivec2& operator=(const ivec2& other) = delete; + public: + static int move_ctor_counter; + static int copy_ctor_counter; + }; + + int ivec2::move_ctor_counter{0}; + int ivec2::copy_ctor_counter{0}; + + bool operator==(const ivec2& l, const ivec2& r) noexcept { + return l.x == r.x && l.y == r.y; + } } TEST_CASE("features/utilities/value") { + ivec2::move_ctor_counter = 0; + ivec2::copy_ctor_counter = 0; + + SUBCASE("cast types") { + static_assert(std::is_same_v< + decltype(std::declval().cast()), + ivec2&>); + static_assert(std::is_same_v< + decltype(std::declval().cast()), + ivec2&&>); + static_assert(std::is_same_v< + decltype(std::declval().cast()), + const ivec2&>); + static_assert(std::is_same_v< + decltype(std::declval().cast()), + const ivec2&&>); + } + + SUBCASE("try_cast types") { + static_assert(std::is_same_v< + decltype(std::declval().try_cast()), + ivec2*>); + static_assert(std::is_same_v< + decltype(std::declval().try_cast()), + const ivec2*>); + } + + SUBCASE("ivec2&") { + ivec2 v{1,2}; + ivec2& vr = v; + + value val{vr}; + CHECK(ivec2::move_ctor_counter == 0); + CHECK(ivec2::copy_ctor_counter == 1); + + CHECK(val.type() == type_db::get()); + + CHECK(!std::memcmp(val.data(), &vr, sizeof(ivec2))); + CHECK(!std::memcmp(val.cdata(), &vr, sizeof(ivec2))); + CHECK(!std::memcmp(std::as_const(val).data(), &vr, sizeof(ivec2))); + CHECK(!std::memcmp(std::as_const(val).cdata(), &vr, sizeof(ivec2))); + + CHECK(val.equals(ivec2{1,2})); + CHECK(val.equals(value{ivec2{1,2}})); + + CHECK(val.cast() == ivec2{1,2}); + CHECK(std::as_const(val).cast() == ivec2{1,2}); + + CHECK(*val.try_cast() == ivec2{1,2}); + CHECK(*std::as_const(val).try_cast() == ivec2{1,2}); + } + + SUBCASE("const ivec2&") { + const ivec2 v{1,2}; + const ivec2& vr = v; + + value val{vr}; + CHECK(ivec2::move_ctor_counter == 0); + CHECK(ivec2::copy_ctor_counter == 1); + + CHECK(val.type() == type_db::get()); + + CHECK(!std::memcmp(val.data(), &vr, sizeof(ivec2))); + CHECK(!std::memcmp(val.cdata(), &vr, sizeof(ivec2))); + CHECK(!std::memcmp(std::as_const(val).data(), &vr, sizeof(ivec2))); + CHECK(!std::memcmp(std::as_const(val).cdata(), &vr, sizeof(ivec2))); + + CHECK(val.equals(ivec2{1,2})); + CHECK(val.equals(value{ivec2{1,2}})); + + CHECK(val.cast() == ivec2{1,2}); + CHECK(std::as_const(val).cast() == ivec2{1,2}); + + CHECK(*val.try_cast() == ivec2{1,2}); + CHECK(*std::as_const(val).try_cast() == ivec2{1,2}); + } + + SUBCASE("ivec2&&") { + ivec2 v{1,2}; + + value val{std::move(v)}; + CHECK(ivec2::move_ctor_counter == 1); + CHECK(ivec2::copy_ctor_counter == 0); + + CHECK(val.type() == type_db::get()); + + CHECK(val.equals(ivec2{1,2})); + CHECK(val.equals(value{ivec2{1,2}})); + + CHECK(val.cast() == ivec2{1,2}); + CHECK(std::as_const(val).cast() == ivec2{1,2}); + + CHECK(*val.try_cast() == ivec2{1,2}); + CHECK(*std::as_const(val).try_cast() == ivec2{1,2}); + } + + SUBCASE("const ivec2&&") { + const ivec2 v{1,2}; + + value val{std::move(v)}; + CHECK(ivec2::move_ctor_counter == 0); + CHECK(ivec2::copy_ctor_counter == 1); + + CHECK(val.type() == type_db::get()); + + CHECK(val.equals(ivec2{1,2})); + CHECK(val.equals(value{ivec2{1,2}})); + + CHECK(val.cast() == ivec2{1,2}); + CHECK(std::as_const(val).cast() == ivec2{1,2}); + + CHECK(*val.try_cast() == ivec2{1,2}); + CHECK(*std::as_const(val).try_cast() == ivec2{1,2}); + } + + SUBCASE("value(value&&)") { + ivec2 v{1,2}; + value val_src{std::move(v)}; + CHECK(ivec2::move_ctor_counter == 1); + CHECK(ivec2::copy_ctor_counter == 0); + + value val_dst{std::move(val_src)}; + CHECK(val_dst.equals(ivec2{1,2})); + CHECK(ivec2::move_ctor_counter == 2); + CHECK(ivec2::copy_ctor_counter == 0); + + CHECK(val_src.equals(ivec2{0,0})); + CHECK(val_src.data() != val_dst.data()); + } + + SUBCASE("value(const value&)") { + const ivec2 v{1,2}; + value val_src{v}; + CHECK(ivec2::move_ctor_counter == 0); + CHECK(ivec2::copy_ctor_counter == 1); + + value val_dst{val_src}; + CHECK(val_dst.equals(ivec2{1,2})); + CHECK(ivec2::move_ctor_counter == 0); + CHECK(ivec2::copy_ctor_counter == 2); + + CHECK(val_src.equals(ivec2{1,2})); + CHECK(val_src.data() != val_dst.data()); + } + + SUBCASE("value& operator=(value&&)") { + value val_src1{"world"s}; + value val_src2{ivec2{1,2}}; + CHECK(ivec2::move_ctor_counter == 1); + CHECK(ivec2::copy_ctor_counter == 0); + + value val_dst{"hello"s}; + + val_dst = std::move(val_src1); + CHECK(val_dst.equals("world"s)); + CHECK(ivec2::move_ctor_counter == 1); + CHECK(ivec2::copy_ctor_counter == 0); + + val_dst = std::move(val_src2); + CHECK(val_dst.equals(ivec2{1,2})); + CHECK(ivec2::move_ctor_counter == 2); + CHECK(ivec2::copy_ctor_counter == 0); + + CHECK(val_src2.equals(ivec2{0,0})); + CHECK(val_src2.data() != val_dst.data()); + } + + SUBCASE("value& operator=(const value&)") { + value val_src1{"world"s}; + value val_src2{ivec2{1,2}}; + CHECK(ivec2::move_ctor_counter == 1); + CHECK(ivec2::copy_ctor_counter == 0); + + value val_dst{"hello"s}; + + val_dst = val_src1; + CHECK(val_dst.equals("world"s)); + CHECK(ivec2::move_ctor_counter == 1); + CHECK(ivec2::copy_ctor_counter == 0); + + val_dst = val_src2; + CHECK(val_dst.equals(ivec2{1,2})); + CHECK(ivec2::move_ctor_counter == 1); + CHECK(ivec2::copy_ctor_counter == 1); + + CHECK(val_src2.equals(ivec2{1,2})); + CHECK(val_src2.data() != val_dst.data()); + } + + SUBCASE("swap") { + value val1{"world"s}; + value val2{ivec2{1,2}}; + CHECK(ivec2::move_ctor_counter == 1); + CHECK(ivec2::copy_ctor_counter == 0); + + val1.swap(val2); + CHECK(val1.equals(ivec2{1,2})); + CHECK(val2.equals("world"s)); + CHECK(ivec2::move_ctor_counter == 3); + CHECK(ivec2::copy_ctor_counter == 0); + + swap(val1, val2); + CHECK(val1.equals("world"s)); + CHECK(val2.equals(ivec2{1,2})); + } } From 4d400af7a062960ad0215872dae365271000c6c9 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 13 Aug 2021 10:52:45 +0700 Subject: [PATCH 095/233] more arg tests --- headers/meta.hpp/meta_utilities/arg.hpp | 70 ++- untests/features/utilities/arg_base_tests.cpp | 184 ------- untests/features/utilities/arg_tests.cpp | 472 +++++++++++------- 3 files changed, 328 insertions(+), 398 deletions(-) delete mode 100644 untests/features/utilities/arg_base_tests.cpp diff --git a/headers/meta.hpp/meta_utilities/arg.hpp b/headers/meta.hpp/meta_utilities/arg.hpp index e75fb15..e943fee 100644 --- a/headers/meta.hpp/meta_utilities/arg.hpp +++ b/headers/meta.hpp/meta_utilities/arg.hpp @@ -28,13 +28,14 @@ namespace meta_hpp arg_base& operator=(const arg_base&) = delete; template < typename T, std::enable_if_t< - std::is_pointer_v || - std::is_lvalue_reference_v, int> = 0 > + std::is_pointer_v || std::is_lvalue_reference_v + , int> = 0 > explicit arg_base(typename_arg_t); template < typename T, std::enable_if_t< std::is_rvalue_reference_v || - (!std::is_pointer_v && !std::is_reference_v), int> = 0 > + (!std::is_pointer_v && !std::is_reference_v) + , int> = 0 > explicit arg_base(typename_arg_t); bool is_const() const noexcept; @@ -55,15 +56,16 @@ namespace meta_hpp namespace meta_hpp { template < typename T, std::enable_if_t< - std::is_pointer_v || - std::is_lvalue_reference_v, int> > + std::is_pointer_v || std::is_lvalue_reference_v + , int> > arg_base::arg_base(typename_arg_t) : raw_type_{type_db::get>()} , ref_type_{std::is_const_v> ? ref_types::cref : ref_types::ref} {} template < typename T, std::enable_if_t< std::is_rvalue_reference_v || - (!std::is_pointer_v && !std::is_reference_v), int> > + (!std::is_pointer_v && !std::is_reference_v) + , int> > arg_base::arg_base(typename_arg_t) : raw_type_{type_db::get>()} , ref_type_{std::is_const_v> ? ref_types::crref : ref_types::rref} {} @@ -96,53 +98,37 @@ namespace meta_hpp if constexpr ( std::is_pointer_v ) { using to_raw_type = std::remove_cv_t; using to_raw_ptr_type = std::remove_cv_t>; - return raw_type().id() == type_db::get().id() - || raw_type().id() == type_db::get>().id(); + return raw_type() == type_db::get() + || raw_type() == type_db::get(); } - if constexpr ( std::is_lvalue_reference_v ) { + if constexpr ( std::is_reference_v ) { constexpr bool to_const = std::is_const_v>; - if ( !to_const && is_rvalue() ) { - return false; - } - if ( !to_const && is_const() ) { return false; } + if constexpr ( std::is_lvalue_reference_v ) { + if ( !to_const && is_rvalue() ) { + return false; + } + } + + if constexpr ( std::is_rvalue_reference_v ) { + if ( !is_rvalue() ) { + return false; + } + } + using to_raw_type = stdex::remove_cvref_t; - if ( raw_type().id() == type_db::get().id() ) { + if ( raw_type() == type_db::get() ) { return true; } if constexpr ( to_const && std::is_pointer_v ) { using to_raw_ptr_type = std::remove_cv_t>; - return raw_type().id() == type_db::get>().id(); - } - - return false; - } - - if constexpr ( std::is_rvalue_reference_v ) { - constexpr bool to_const = std::is_const_v>; - - if ( !is_rvalue() ) { - return false; - } - - if ( !to_const && is_const() ) { - return false; - } - - using to_raw_type = stdex::remove_cvref_t; - if ( raw_type().id() == type_db::get().id() ) { - return true; - } - - if constexpr ( to_const && std::is_pointer_v ) { - using to_raw_ptr_type = std::remove_cv_t>; - return raw_type().id() == type_db::get>().id(); + return raw_type() == type_db::get(); } return false; @@ -150,7 +136,7 @@ namespace meta_hpp if constexpr ( !std::is_pointer_v && !std::is_reference_v ) { using to_raw_type = std::remove_cv_t; - if ( raw_type().id() != type_db::get().id() ) { + if ( raw_type() != type_db::get() ) { return false; } @@ -189,7 +175,7 @@ namespace meta_hpp template < typename T > arg::arg(T&& v) : arg_base{typename_arg} - , data_{const_cast>>(std::addressof(v))} {} + , data_{const_cast*>(std::addressof(v))} {} template < typename To > To arg::cast() const { @@ -214,7 +200,7 @@ namespace meta_hpp } if constexpr ( !std::is_pointer_v && !std::is_reference_v ) { - using raw_type = stdex::remove_cvref_t; + using raw_type = std::remove_cv_t; if ( ref_type() == ref_types::ref ) { if constexpr ( std::is_constructible_v ) { diff --git a/untests/features/utilities/arg_base_tests.cpp b/untests/features/utilities/arg_base_tests.cpp deleted file mode 100644 index 0e538f6..0000000 --- a/untests/features/utilities/arg_base_tests.cpp +++ /dev/null @@ -1,184 +0,0 @@ -/******************************************************************************* - * 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 "_utilities_fwd.hpp" - -namespace -{ - using namespace meta_hpp; - using namespace std::string_literals; -} - -namespace -{ - struct ivec2 { - int x{}; - int y{}; - - [[maybe_unused]] ivec2() = default; - [[maybe_unused]] explicit ivec2(int v): x{v}, y{v} {} - [[maybe_unused]] ivec2(int x, int y): x{x}, y{y} {} - - [[maybe_unused]] ivec2(ivec2&& other) noexcept { - x = other.x; - y = other.y; - other.x = 0; - other.y = 0; - } - - [[maybe_unused]] ivec2(const ivec2& other) noexcept { - x = other.x; - y = other.y; - } - - ivec2& operator=(ivec2&&) = delete; - ivec2& operator=(const ivec2&) = delete; - }; - - struct ivec3 { - int x{}; - int y{}; - int z{}; - - [[maybe_unused]] ivec3() = default; - [[maybe_unused]] explicit ivec3(int v): x{v}, y{v}, z{v} {} - [[maybe_unused]] ivec3(int x, int y, int z): x{x}, y{y}, z{z} {} - - [[maybe_unused]] ivec3(ivec3&& other) noexcept { - x = other.x; - y = other.y; - z = other.z; - other.x = 0; - other.y = 0; - other.z = 0; - } - - [[maybe_unused]] ivec3(const ivec3& other) noexcept { - x = other.x; - y = other.y; - z = other.z; - } - - ivec3& operator=(ivec3&&) = delete; - ivec3& operator=(const ivec3&) = delete; - }; - - [[maybe_unused]] bool operator==(const ivec2& l, const ivec2& r) noexcept { - return l.x == r.x && l.y == r.y; - } - - [[maybe_unused]] bool operator==(const ivec3& l, const ivec3& r) noexcept { - return l.x == r.x && l.y == r.y && l.z == r.z; - } -} - -TEST_CASE("features/utilities/arg_base/type") { - SUBCASE("ptr") { - ivec2 v{1,2}; - ivec2* vp = &v; - arg_base a{typename_arg}; - - CHECK(a.raw_type().id() == type_db::get().id()); - CHECK(a.ref_type() == arg_base::ref_types::ref); - } - - SUBCASE("rptr") { - ivec2 v{1,2}; - ivec2* vp = &v; - arg_base a{typename_arg}; - - CHECK(a.raw_type().id() == type_db::get().id()); - CHECK(a.ref_type() == arg_base::ref_types::rref); - } - - SUBCASE("ptr_c") { - ivec2 v{1,2}; - ivec2* const vp = &v; - arg_base a{typename_arg}; - - CHECK(a.raw_type().id() == type_db::get().id()); - CHECK(a.ref_type() == arg_base::ref_types::cref); - } - - SUBCASE("rptr_c") { - ivec2 v{1,2}; - ivec2* const vp = &v; - arg_base a{typename_arg}; - - CHECK(a.raw_type().id() == type_db::get().id()); - CHECK(a.ref_type() == arg_base::ref_types::crref); - } - - SUBCASE("cptr") { - const ivec2 v{1,2}; - const ivec2* vp = &v; - arg_base a{typename_arg}; - - CHECK(a.raw_type().id() == type_db::get().id()); - CHECK(a.ref_type() == arg_base::ref_types::ref); - } - - SUBCASE("crptr") { - const ivec2 v{1,2}; - const ivec2* vp = &v; - arg_base a{typename_arg}; - - CHECK(a.raw_type().id() == type_db::get().id()); - CHECK(a.ref_type() == arg_base::ref_types::rref); - } - - SUBCASE("cptr_c") { - const ivec2 v{1,2}; - const ivec2* const vp = &v; - arg_base a{typename_arg}; - - CHECK(a.raw_type().id() == type_db::get().id()); - CHECK(a.ref_type() == arg_base::ref_types::cref); - } - - SUBCASE("crptr_c") { - const ivec2 v{1,2}; - const ivec2* const vp = &v; - arg_base a{typename_arg}; - - CHECK(a.raw_type().id() == type_db::get().id()); - CHECK(a.ref_type() == arg_base::ref_types::crref); - } - - SUBCASE("ref") { - ivec2 v{1,2}; - ivec2& vr = v; - arg_base a{typename_arg}; - - CHECK(a.raw_type().id() == type_db::get().id()); - CHECK(a.ref_type() == arg_base::ref_types::ref); - } - - SUBCASE("cref") { - const ivec2 v{1,2}; - const ivec2& vr = v; - arg_base a{typename_arg}; - - CHECK(a.raw_type().id() == type_db::get().id()); - CHECK(a.ref_type() == arg_base::ref_types::cref); - } - - SUBCASE("rref") { - ivec2 v{1,2}; - arg_base a{typename_arg}; - - CHECK(a.raw_type().id() == type_db::get().id()); - CHECK(a.ref_type() == arg_base::ref_types::rref); - } - - SUBCASE("crref") { - const ivec2 v{1,2}; - arg_base a{typename_arg}; - - CHECK(a.raw_type().id() == type_db::get().id()); - CHECK(a.ref_type() == arg_base::ref_types::crref); - } -} diff --git a/untests/features/utilities/arg_tests.cpp b/untests/features/utilities/arg_tests.cpp index 8829235..053b2ca 100644 --- a/untests/features/utilities/arg_tests.cpp +++ b/untests/features/utilities/arg_tests.cpp @@ -81,7 +81,7 @@ TEST_CASE("features/utilities/arg/type") { ivec2* vp = &v; arg a{vp}; - CHECK(a.raw_type().id() == type_db::get().id()); + CHECK(a.raw_type() == type_db::get()); CHECK(a.ref_type() == arg::ref_types::ref); } @@ -90,7 +90,7 @@ TEST_CASE("features/utilities/arg/type") { ivec2* vp = &v; arg a{std::move(vp)}; - CHECK(a.raw_type().id() == type_db::get().id()); + CHECK(a.raw_type() == type_db::get()); CHECK(a.ref_type() == arg::ref_types::rref); } @@ -99,7 +99,7 @@ TEST_CASE("features/utilities/arg/type") { ivec2* const vp = &v; arg a{vp}; - CHECK(a.raw_type().id() == type_db::get().id()); + CHECK(a.raw_type() == type_db::get()); CHECK(a.ref_type() == arg::ref_types::cref); } @@ -108,7 +108,7 @@ TEST_CASE("features/utilities/arg/type") { ivec2* const vp = &v; arg a{std::move(vp)}; - CHECK(a.raw_type().id() == type_db::get().id()); + CHECK(a.raw_type() == type_db::get()); CHECK(a.ref_type() == arg::ref_types::crref); } @@ -117,7 +117,7 @@ TEST_CASE("features/utilities/arg/type") { const ivec2* vp = &v; arg a{vp}; - CHECK(a.raw_type().id() == type_db::get().id()); + CHECK(a.raw_type() == type_db::get()); CHECK(a.ref_type() == arg::ref_types::ref); } @@ -126,7 +126,7 @@ TEST_CASE("features/utilities/arg/type") { const ivec2* vp = &v; arg a{std::move(vp)}; - CHECK(a.raw_type().id() == type_db::get().id()); + CHECK(a.raw_type() == type_db::get()); CHECK(a.ref_type() == arg::ref_types::rref); } @@ -135,7 +135,7 @@ TEST_CASE("features/utilities/arg/type") { const ivec2* const vp = &v; arg a{vp}; - CHECK(a.raw_type().id() == type_db::get().id()); + CHECK(a.raw_type() == type_db::get()); CHECK(a.ref_type() == arg::ref_types::cref); } @@ -144,7 +144,7 @@ TEST_CASE("features/utilities/arg/type") { const ivec2* const vp = &v; arg a{std::move(vp)}; - CHECK(a.raw_type().id() == type_db::get().id()); + CHECK(a.raw_type() == type_db::get()); CHECK(a.ref_type() == arg::ref_types::crref); } @@ -153,7 +153,7 @@ TEST_CASE("features/utilities/arg/type") { ivec2& vr = v; arg a{vr}; - CHECK(a.raw_type().id() == type_db::get().id()); + CHECK(a.raw_type() == type_db::get()); CHECK(a.ref_type() == arg::ref_types::ref); } @@ -162,7 +162,7 @@ TEST_CASE("features/utilities/arg/type") { const ivec2& vr = v; arg a{vr}; - CHECK(a.raw_type().id() == type_db::get().id()); + CHECK(a.raw_type() == type_db::get()); CHECK(a.ref_type() == arg::ref_types::cref); } @@ -170,7 +170,7 @@ TEST_CASE("features/utilities/arg/type") { ivec2 v{1,2}; arg a{std::move(v)}; - CHECK(a.raw_type().id() == type_db::get().id()); + CHECK(a.raw_type() == type_db::get()); CHECK(a.ref_type() == arg::ref_types::rref); } @@ -178,7 +178,7 @@ TEST_CASE("features/utilities/arg/type") { const ivec2 v{1,2}; arg a{std::move(v)}; - CHECK(a.raw_type().id() == type_db::get().id()); + CHECK(a.raw_type() == type_db::get()); CHECK(a.ref_type() == arg::ref_types::crref); } } @@ -191,12 +191,6 @@ TEST_CASE("features/utilities/arg/can_cast_to") { CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); - - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); @@ -210,6 +204,11 @@ TEST_CASE("features/utilities/arg/can_cast_to") { } { + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); CHECK(a.can_cast_to()); @@ -220,6 +219,11 @@ TEST_CASE("features/utilities/arg/can_cast_to") { CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); + []([[maybe_unused]] ivec2 *){}(vp); + []([[maybe_unused]] const ivec2 *){}(vp); + []([[maybe_unused]] ivec2 *const){}(vp); + []([[maybe_unused]] const ivec2 *const){}(vp); + []([[maybe_unused]] ivec2 *&){}(vp); //[]([[maybe_unused]] const ivec2 *&){}(vp); []([[maybe_unused]] ivec2 *const &){}(vp); @@ -239,12 +243,6 @@ TEST_CASE("features/utilities/arg/can_cast_to") { CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); - - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); @@ -258,6 +256,11 @@ TEST_CASE("features/utilities/arg/can_cast_to") { } { + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); CHECK(a.can_cast_to()); @@ -268,6 +271,11 @@ TEST_CASE("features/utilities/arg/can_cast_to") { CHECK(a.can_cast_to()); CHECK(a.can_cast_to()); + []([[maybe_unused]] ivec2 *){}(std::move(vp)); + []([[maybe_unused]] const ivec2 *){}(std::move(vp)); + []([[maybe_unused]] ivec2 *const){}(std::move(vp)); + []([[maybe_unused]] const ivec2 *const){}(std::move(vp)); + //[]([[maybe_unused]] ivec2 *&){}(std::move(vp)); //[]([[maybe_unused]] const ivec2 *&){}(std::move(vp)); []([[maybe_unused]] ivec2 *const &){}(std::move(vp)); @@ -287,12 +295,6 @@ TEST_CASE("features/utilities/arg/can_cast_to") { CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); - - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); @@ -306,6 +308,11 @@ TEST_CASE("features/utilities/arg/can_cast_to") { } { + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); CHECK(a.can_cast_to()); @@ -316,6 +323,11 @@ TEST_CASE("features/utilities/arg/can_cast_to") { CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); + []([[maybe_unused]] ivec2 *){}(vp); + []([[maybe_unused]] const ivec2 *){}(vp); + []([[maybe_unused]] ivec2 *const &){}(vp); + []([[maybe_unused]] const ivec2 *const &){}(vp); + // []([[maybe_unused]] ivec2 *&){}(vp); // []([[maybe_unused]] const ivec2 *&){}(vp); []([[maybe_unused]] ivec2 *const &){}(vp); @@ -335,12 +347,6 @@ TEST_CASE("features/utilities/arg/can_cast_to") { CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); - - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); @@ -354,6 +360,11 @@ TEST_CASE("features/utilities/arg/can_cast_to") { } { + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); CHECK(a.can_cast_to()); @@ -364,6 +375,11 @@ TEST_CASE("features/utilities/arg/can_cast_to") { CHECK(a.can_cast_to()); CHECK(a.can_cast_to()); + []([[maybe_unused]] ivec2 *){}(std::move(vp)); + []([[maybe_unused]] const ivec2 *){}(std::move(vp)); + []([[maybe_unused]] ivec2 *const){}(std::move(vp)); + []([[maybe_unused]] const ivec2 *const){}(std::move(vp)); + //[]([[maybe_unused]] ivec2 *&){}(std::move(vp)); //[]([[maybe_unused]] const ivec2 *&){}(std::move(vp)); []([[maybe_unused]] ivec2 *const &){}(std::move(vp)); @@ -383,23 +399,24 @@ TEST_CASE("features/utilities/arg/can_cast_to") { CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); - - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); { + CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); } { + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); CHECK(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); @@ -410,6 +427,11 @@ TEST_CASE("features/utilities/arg/can_cast_to") { CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); + //[]([[maybe_unused]] ivec2 *){}(vp); + []([[maybe_unused]] const ivec2 *){}(vp); + //[]([[maybe_unused]] ivec2 *const){}(vp); + []([[maybe_unused]] const ivec2 *const){}(vp); + //[]([[maybe_unused]] ivec2 *&){}(vp); []([[maybe_unused]] const ivec2 *&){}(vp); //[]([[maybe_unused]] ivec2 *const &){}(vp); @@ -429,23 +451,24 @@ TEST_CASE("features/utilities/arg/can_cast_to") { CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); - - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); { + CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); } { + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); @@ -456,6 +479,11 @@ TEST_CASE("features/utilities/arg/can_cast_to") { CHECK_FALSE(a.can_cast_to()); CHECK(a.can_cast_to()); + //[]([[maybe_unused]] ivec2 *){}(std::move(vp)); + []([[maybe_unused]] const ivec2 *){}(std::move(vp)); + //[]([[maybe_unused]] ivec2 *const){}(std::move(vp)); + []([[maybe_unused]] const ivec2 *const){}(std::move(vp)); + //[]([[maybe_unused]] ivec2 *&){}(std::move(vp)); //[]([[maybe_unused]] const ivec2 *&){}(std::move(vp)); //[]([[maybe_unused]] ivec2 *const &){}(std::move(vp)); @@ -475,23 +503,24 @@ TEST_CASE("features/utilities/arg/can_cast_to") { CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); { + CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); } { + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); @@ -502,6 +531,11 @@ TEST_CASE("features/utilities/arg/can_cast_to") { CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); + //[]([[maybe_unused]] ivec2 *){}(vp); + []([[maybe_unused]] const ivec2 *){}(vp); + //[]([[maybe_unused]] ivec2 *const){}(vp); + []([[maybe_unused]] const ivec2 *const){}(vp); + //[]([[maybe_unused]] ivec2 *&){}(vp); //[]([[maybe_unused]] const ivec2 *&){}(vp); //[]([[maybe_unused]] ivec2 *const &){}(vp); @@ -521,23 +555,24 @@ TEST_CASE("features/utilities/arg/can_cast_to") { CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); - - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); { + CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); } { + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); @@ -548,6 +583,11 @@ TEST_CASE("features/utilities/arg/can_cast_to") { CHECK_FALSE(a.can_cast_to()); CHECK(a.can_cast_to()); + //[]([[maybe_unused]] ivec2 *){}(std::move(vp)); + []([[maybe_unused]] const ivec2 *){}(std::move(vp)); + //[]([[maybe_unused]] ivec2 *const){}(std::move(vp)); + []([[maybe_unused]] const ivec2 *const){}(std::move(vp)); + //[]([[maybe_unused]] ivec2 *&){}(std::move(vp)); //[]([[maybe_unused]] const ivec2 *&){}(std::move(vp)); //[]([[maybe_unused]] ivec2 *const &){}(std::move(vp)); @@ -565,27 +605,37 @@ TEST_CASE("features/utilities/arg/can_cast_to") { ivec2& vr = v; arg a{vr}; - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); + { + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); + []([[maybe_unused]] ivec2){}(vr); + []([[maybe_unused]] const ivec2){}(vr); + []([[maybe_unused]] ivec2&){}(vr); + []([[maybe_unused]] const ivec2&){}(vr); + //[]([[maybe_unused]] ivec2&&){}(vr); + //[]([[maybe_unused]] const ivec2&&){}(vr); + } { CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); } { + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); @@ -595,6 +645,21 @@ TEST_CASE("features/utilities/arg/can_cast_to") { CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); + + //[]([[maybe_unused]] ivec2*){}(vr); + //[]([[maybe_unused]] const ivec2*){}(vr); + //[]([[maybe_unused]] ivec2* const){}(vr); + //[]([[maybe_unused]] const ivec2* const){}(vr); + + //[]([[maybe_unused]] ivec2 *&){}(vr); + //[]([[maybe_unused]] const ivec2 *&){}(vr); + //[]([[maybe_unused]] ivec2 *const &){}(vr); + //[]([[maybe_unused]] const ivec2 *const &){}(vr); + + //[]([[maybe_unused]] ivec2 *&&){}(vr); + //[]([[maybe_unused]] const ivec2 *&&){}(vr); + //[]([[maybe_unused]] ivec2 *const &&){}(vr); + //[]([[maybe_unused]] const ivec2 *const &&){}(vr); } } @@ -603,26 +668,37 @@ TEST_CASE("features/utilities/arg/can_cast_to") { const ivec2& vr = v; arg a{vr}; - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); + { + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); + []([[maybe_unused]] ivec2){}(vr); + []([[maybe_unused]] const ivec2){}(vr); + //[]([[maybe_unused]] ivec2&){}(vr); + []([[maybe_unused]] const ivec2&){}(vr); + //[]([[maybe_unused]] ivec2&&){}(vr); + //[]([[maybe_unused]] const ivec2&&){}(vr); + } { CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); } { + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); @@ -632,6 +708,21 @@ TEST_CASE("features/utilities/arg/can_cast_to") { CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); + + //[]([[maybe_unused]] ivec2*){}(vr); + //[]([[maybe_unused]] const ivec2*){}(vr); + //[]([[maybe_unused]] ivec2* const){}(vr); + //[]([[maybe_unused]] const ivec2* const){}(vr); + + //[]([[maybe_unused]] ivec2 *&){}(vr); + //[]([[maybe_unused]] const ivec2 *&){}(vr); + //[]([[maybe_unused]] ivec2 *const &){}(vr); + //[]([[maybe_unused]] const ivec2 *const &){}(vr); + + //[]([[maybe_unused]] ivec2 *&&){}(vr); + //[]([[maybe_unused]] const ivec2 *&&){}(vr); + //[]([[maybe_unused]] ivec2 *const &&){}(vr); + //[]([[maybe_unused]] const ivec2 *const &&){}(vr); } } @@ -639,28 +730,37 @@ TEST_CASE("features/utilities/arg/can_cast_to") { ivec2 v{1,2}; arg a{std::move(v)}; - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); + { + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); + []([[maybe_unused]] ivec2){}(std::move(v)); + []([[maybe_unused]] const ivec2){}(std::move(v)); + //[]([[maybe_unused]] ivec2&){}(std::move(v)); + []([[maybe_unused]] const ivec2&){}(std::move(v)); + []([[maybe_unused]] ivec2&&){}(std::move(v)); + []([[maybe_unused]] const ivec2&&){}(std::move(v)); + } { CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); } { + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); @@ -670,6 +770,21 @@ TEST_CASE("features/utilities/arg/can_cast_to") { CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); + + //[]([[maybe_unused]] ivec2*){}(std::move(v)); + //[]([[maybe_unused]] const ivec2*){}(std::move(v)); + //[]([[maybe_unused]] ivec2* const){}(std::move(v)); + //[]([[maybe_unused]] const ivec2* const){}(std::move(v)); + + //[]([[maybe_unused]] ivec2 *&){}(std::move(v)); + //[]([[maybe_unused]] const ivec2 *&){}(std::move(v)); + //[]([[maybe_unused]] ivec2 *const &){}(std::move(v)); + //[]([[maybe_unused]] const ivec2 *const &){}(std::move(v)); + + //[]([[maybe_unused]] ivec2 *&&){}(std::move(v)); + //[]([[maybe_unused]] const ivec2 *&&){}(std::move(v)); + //[]([[maybe_unused]] ivec2 *const &&){}(std::move(v)); + //[]([[maybe_unused]] const ivec2 *const &&){}(std::move(v)); } } @@ -677,27 +792,37 @@ TEST_CASE("features/utilities/arg/can_cast_to") { const ivec2 v{1,2}; arg a{std::move(v)}; - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); + { + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); + []([[maybe_unused]] ivec2){}(std::move(v)); + []([[maybe_unused]] const ivec2){}(std::move(v)); + //[]([[maybe_unused]] ivec2&){}(std::move(v)); + []([[maybe_unused]] const ivec2&){}(std::move(v)); + //[]([[maybe_unused]] ivec2&&){}(std::move(v)); + []([[maybe_unused]] const ivec2&&){}(std::move(v)); + } { CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); } { + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); @@ -707,6 +832,21 @@ TEST_CASE("features/utilities/arg/can_cast_to") { CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); CHECK_FALSE(a.can_cast_to()); + + //[]([[maybe_unused]] ivec2*){}(std::move(v)); + //[]([[maybe_unused]] const ivec2*){}(std::move(v)); + //[]([[maybe_unused]] ivec2* const){}(std::move(v)); + //[]([[maybe_unused]] const ivec2* const){}(std::move(v)); + + //[]([[maybe_unused]] ivec2 *&){}(std::move(v)); + //[]([[maybe_unused]] const ivec2 *&){}(std::move(v)); + //[]([[maybe_unused]] ivec2 *const &){}(std::move(v)); + //[]([[maybe_unused]] const ivec2 *const &){}(std::move(v)); + + //[]([[maybe_unused]] ivec2 *&&){}(std::move(v)); + //[]([[maybe_unused]] const ivec2 *&&){}(std::move(v)); + //[]([[maybe_unused]] ivec2 *const &&){}(std::move(v)); + //[]([[maybe_unused]] const ivec2 *const &&){}(std::move(v)); } } } @@ -719,18 +859,17 @@ TEST_CASE("features/utilities/arg/cast") { CHECK_THROWS(a.cast()); CHECK_THROWS(a.cast()); - - CHECK(a.cast() == vp); - CHECK(a.cast() == vp); - CHECK(a.cast() == vp); - CHECK(a.cast() == vp); - CHECK_THROWS(a.cast()); CHECK_THROWS(a.cast()); CHECK_THROWS(a.cast()); CHECK_THROWS(a.cast()); { + CHECK(a.cast() == vp); + CHECK(a.cast() == vp); + CHECK(a.cast() == vp); + CHECK(a.cast() == vp); + CHECK(a.cast() == vp); CHECK_THROWS(a.cast()); CHECK(a.cast() == vp); @@ -749,18 +888,17 @@ TEST_CASE("features/utilities/arg/cast") { CHECK_THROWS(arg{std::move(vp)}.cast()); CHECK_THROWS(arg{std::move(vp)}.cast()); - - CHECK(arg{std::move(vp)}.cast() == vp); - CHECK(arg{std::move(vp)}.cast() == vp); - CHECK(arg{std::move(vp)}.cast() == vp); - CHECK(arg{std::move(vp)}.cast() == vp); - CHECK_THROWS(arg{std::move(vp)}.cast()); CHECK_THROWS(arg{std::move(vp)}.cast()); CHECK_THROWS(arg{std::move(vp)}.cast()); CHECK_THROWS(arg{std::move(vp)}.cast()); { + CHECK(arg{std::move(vp)}.cast() == vp); + CHECK(arg{std::move(vp)}.cast() == vp); + CHECK(arg{std::move(vp)}.cast() == vp); + CHECK(arg{std::move(vp)}.cast() == vp); + CHECK_THROWS(arg{std::move(vp)}.cast()); CHECK_THROWS(arg{std::move(vp)}.cast()); CHECK(arg{std::move(vp)}.cast() == vp); @@ -780,18 +918,17 @@ TEST_CASE("features/utilities/arg/cast") { CHECK_THROWS(a.cast()); CHECK_THROWS(a.cast()); - - CHECK(a.cast() == vp); - CHECK(a.cast() == vp); - CHECK(a.cast() == vp); - CHECK(a.cast() == vp); - CHECK_THROWS(a.cast()); CHECK_THROWS(a.cast()); CHECK_THROWS(a.cast()); CHECK_THROWS(a.cast()); { + CHECK(a.cast() == vp); + CHECK(a.cast() == vp); + CHECK(a.cast() == vp); + CHECK(a.cast() == vp); + CHECK_THROWS(a.cast()); CHECK_THROWS(a.cast()); CHECK(a.cast() == vp); @@ -810,18 +947,17 @@ TEST_CASE("features/utilities/arg/cast") { CHECK_THROWS(arg{std::move(vp)}.cast()); CHECK_THROWS(arg{std::move(vp)}.cast()); - - CHECK(arg{std::move(vp)}.cast() == vp); - CHECK(arg{std::move(vp)}.cast() == vp); - CHECK(arg{std::move(vp)}.cast() == vp); - CHECK(arg{std::move(vp)}.cast() == vp); - CHECK_THROWS(arg{std::move(vp)}.cast()); CHECK_THROWS(arg{std::move(vp)}.cast()); CHECK_THROWS(arg{std::move(vp)}.cast()); CHECK_THROWS(arg{std::move(vp)}.cast()); { + CHECK(arg{std::move(vp)}.cast() == vp); + CHECK(arg{std::move(vp)}.cast() == vp); + CHECK(arg{std::move(vp)}.cast() == vp); + CHECK(arg{std::move(vp)}.cast() == vp); + CHECK_THROWS(arg{std::move(vp)}.cast()); CHECK_THROWS(arg{std::move(vp)}.cast()); CHECK(arg{std::move(vp)}.cast() == vp); @@ -841,18 +977,17 @@ TEST_CASE("features/utilities/arg/cast") { CHECK_THROWS(a.cast()); CHECK_THROWS(a.cast()); - - CHECK_THROWS(a.cast()); - CHECK(a.cast() == vp); - CHECK_THROWS(a.cast()); - CHECK(a.cast() == vp); - CHECK_THROWS(a.cast()); CHECK_THROWS(a.cast()); CHECK_THROWS(a.cast()); CHECK_THROWS(a.cast()); { + CHECK_THROWS(a.cast()); + CHECK(a.cast() == vp); + CHECK_THROWS(a.cast()); + CHECK(a.cast() == vp); + CHECK_THROWS(a.cast()); CHECK(a.cast() == vp); CHECK_THROWS(a.cast()); @@ -871,18 +1006,17 @@ TEST_CASE("features/utilities/arg/cast") { CHECK_THROWS(arg{std::move(vp)}.cast()); CHECK_THROWS(arg{std::move(vp)}.cast()); - - CHECK_THROWS(arg{std::move(vp)}.cast()); - CHECK(arg{std::move(vp)}.cast() == vp); - CHECK_THROWS(arg{std::move(vp)}.cast()); - CHECK(arg{std::move(vp)}.cast() == vp); - CHECK_THROWS(arg{std::move(vp)}.cast()); CHECK_THROWS(arg{std::move(vp)}.cast()); CHECK_THROWS(arg{std::move(vp)}.cast()); CHECK_THROWS(arg{std::move(vp)}.cast()); { + CHECK_THROWS(arg{std::move(vp)}.cast()); + CHECK(arg{std::move(vp)}.cast() == vp); + CHECK_THROWS(arg{std::move(vp)}.cast()); + CHECK(arg{std::move(vp)}.cast() == vp); + CHECK_THROWS(arg{std::move(vp)}.cast()); CHECK_THROWS(arg{std::move(vp)}.cast()); CHECK_THROWS(arg{std::move(vp)}.cast()); @@ -902,18 +1036,17 @@ TEST_CASE("features/utilities/arg/cast") { CHECK_THROWS(a.cast()); CHECK_THROWS(a.cast()); - - CHECK_THROWS(a.cast()); - CHECK(a.cast() == vp); - CHECK_THROWS(a.cast()); - CHECK(a.cast() == vp); - CHECK_THROWS(a.cast()); CHECK_THROWS(a.cast()); CHECK_THROWS(a.cast()); CHECK_THROWS(a.cast()); { + CHECK_THROWS(a.cast()); + CHECK(a.cast() == vp); + CHECK_THROWS(a.cast()); + CHECK(a.cast() == vp); + CHECK_THROWS(a.cast()); CHECK_THROWS(a.cast()); CHECK_THROWS(a.cast()); @@ -932,18 +1065,17 @@ TEST_CASE("features/utilities/arg/cast") { CHECK_THROWS(arg{std::move(vp)}.cast()); CHECK_THROWS(arg{std::move(vp)}.cast()); - - CHECK_THROWS(arg{std::move(vp)}.cast()); - CHECK(arg{std::move(vp)}.cast() == vp); - CHECK_THROWS(arg{std::move(vp)}.cast()); - CHECK(arg{std::move(vp)}.cast() == vp); - CHECK_THROWS(arg{std::move(vp)}.cast()); CHECK_THROWS(arg{std::move(vp)}.cast()); CHECK_THROWS(arg{std::move(vp)}.cast()); CHECK_THROWS(arg{std::move(vp)}.cast()); { + CHECK_THROWS(arg{std::move(vp)}.cast()); + CHECK(arg{std::move(vp)}.cast() == vp); + CHECK_THROWS(arg{std::move(vp)}.cast()); + CHECK(arg{std::move(vp)}.cast() == vp); + CHECK_THROWS(arg{std::move(vp)}.cast()); CHECK_THROWS(arg{std::move(vp)}.cast()); CHECK_THROWS(arg{std::move(vp)}.cast()); @@ -963,16 +1095,15 @@ TEST_CASE("features/utilities/arg/cast") { CHECK(a.cast() == ivec2{1,2}); CHECK(a.cast() == ivec2{1,2}); + CHECK(&a.cast() == &v); + CHECK(&a.cast() == &vr); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); CHECK_THROWS(a.cast()); CHECK_THROWS(a.cast()); CHECK_THROWS(a.cast()); CHECK_THROWS(a.cast()); - - CHECK(&a.cast() == &v); - CHECK(&a.cast() == &vr); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); } SUBCASE("cref") { @@ -982,31 +1113,29 @@ TEST_CASE("features/utilities/arg/cast") { CHECK(a.cast() == v); CHECK(a.cast() == v); + CHECK_THROWS(a.cast()); + CHECK(&a.cast() == &vr); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); CHECK_THROWS(a.cast()); CHECK_THROWS(a.cast()); CHECK_THROWS(a.cast()); CHECK_THROWS(a.cast()); - - CHECK_THROWS(a.cast()); - CHECK(&a.cast() == &vr); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); } SUBCASE("rref") { CHECK(arg{ivec2{1,2}}.cast() == ivec2{1,2}); CHECK(arg{ivec2{1,2}}.cast() == ivec2{1,2}); + CHECK_THROWS(arg{ivec2{1,2}}.cast()); + CHECK(arg{ivec2{1,2}}.cast() == ivec2{1,2}); + CHECK(arg{ivec2{1,2}}.cast() == ivec2{1,2}); + CHECK(arg{ivec2{1,2}}.cast() == ivec2{1,2}); CHECK_THROWS(arg{ivec2{1,2}}.cast()); CHECK_THROWS(arg{ivec2{1,2}}.cast()); CHECK_THROWS(arg{ivec2{1,2}}.cast()); CHECK_THROWS(arg{ivec2{1,2}}.cast()); - - CHECK_THROWS(arg{ivec2{1,2}}.cast()); - CHECK(arg{ivec2{1,2}}.cast() == ivec2{1,2}); - CHECK(arg{ivec2{1,2}}.cast() == ivec2{1,2}); - CHECK(arg{ivec2{1,2}}.cast() == ivec2{1,2}); } SUBCASE("crref") { @@ -1015,15 +1144,14 @@ TEST_CASE("features/utilities/arg/cast") { CHECK(a.cast() == ivec2{1,2}); CHECK(a.cast() == ivec2{1,2}); + CHECK_THROWS(a.cast()); + CHECK(&a.cast() == &v); + CHECK_THROWS(a.cast()); + CHECK(a.cast() == v); CHECK_THROWS(a.cast()); CHECK_THROWS(a.cast()); CHECK_THROWS(a.cast()); CHECK_THROWS(a.cast()); - - CHECK_THROWS(a.cast()); - CHECK(&a.cast() == &v); - CHECK_THROWS(a.cast()); - CHECK(a.cast() == v); } } From 442c80ffb914ae6f7c1bd099294d5eff54150114 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 13 Aug 2021 13:10:33 +0700 Subject: [PATCH 096/233] invoke functions, methods and ctors with static arguments --- headers/meta.hpp/meta_fwd.hpp | 1 + headers/meta.hpp/meta_infos/ctor_info.hpp | 105 ++- headers/meta.hpp/meta_infos/function_info.hpp | 123 ++- headers/meta.hpp/meta_infos/method_info.hpp | 139 +++- headers/meta.hpp/meta_types/method_type.hpp | 184 +++++ headers/meta.hpp/meta_utilities.hpp | 1 + headers/meta.hpp/meta_utilities/inst.hpp | 183 +++++ untests/features/infos/base_info_tests.cpp | 1 - untests/features/infos/ctor_info_tests.cpp | 81 ++ .../features/infos/function_info_tests.cpp | 81 ++ untests/features/infos/method_info_tests.cpp | 772 ++++++++++++++++++ untests/features/utilities/inst_tests.cpp | 76 ++ untests/features/utilities/value_tests.cpp | 9 +- 13 files changed, 1739 insertions(+), 17 deletions(-) create mode 100644 headers/meta.hpp/meta_utilities/inst.hpp create mode 100644 untests/features/utilities/inst_tests.cpp diff --git a/headers/meta.hpp/meta_fwd.hpp b/headers/meta.hpp/meta_fwd.hpp index b015a9e..56d9acc 100644 --- a/headers/meta.hpp/meta_fwd.hpp +++ b/headers/meta.hpp/meta_fwd.hpp @@ -88,6 +88,7 @@ namespace meta_hpp namespace meta_hpp { class arg; + class inst; class value; } diff --git a/headers/meta.hpp/meta_infos/ctor_info.hpp b/headers/meta.hpp/meta_infos/ctor_info.hpp index 5e6069f..b294216 100644 --- a/headers/meta.hpp/meta_infos/ctor_info.hpp +++ b/headers/meta.hpp/meta_infos/ctor_info.hpp @@ -20,6 +20,12 @@ namespace meta_hpp explicit operator bool() const noexcept; const ctor_type& type() const noexcept; + + template < typename... Args > + value invoke(Args&&... args) const; + + template < typename... Args > + bool is_invocable_with() const noexcept; public: template < typename F > void visit(F&& f) const; @@ -39,11 +45,94 @@ namespace meta_hpp }; } +namespace meta_hpp::detail +{ + using ctor_invoke = std::function; + + template < typename Class, typename... Args, std::size_t... Is > + value raw_ctor_invoke_impl( + const arg* args, + std::index_sequence) + { + using ct = ctor_traits; + using class_type = typename ct::class_type; + using argument_types = typename ct::argument_types; + + if ( !(... && (args + Is)->can_cast_to>()) ) { + throw std::logic_error("an attempt to call a ctor with an incorrect argument types"); + } + + class_type class_value{(args + Is)->cast>()...}; + return value{std::forward(class_value)}; + } + + template < typename Class, typename... Args > + value raw_ctor_invoke( + const arg* args, + std::size_t arg_count) + { + using ct = ctor_traits; + + if ( arg_count != ct::arity ) { + throw std::logic_error("an attempt to call a ctor with an incorrect arity"); + } + + return raw_ctor_invoke_impl( + args, + std::make_index_sequence()); + } + + template < typename Class, typename... Args > + ctor_invoke make_ctor_invoke() { + using namespace std::placeholders; + return std::bind(&raw_ctor_invoke, _1, _2); + } +} + +namespace meta_hpp::detail +{ + using ctor_is_invocable_with = std::function; + + template < typename Class, typename... Args, std::size_t... Is > + bool raw_ctor_is_invocable_with_impl( + const arg_base* arg_bases, + std::index_sequence) + { + using ct = ctor_traits; + using argument_types = typename ct::argument_types; + return (... && (arg_bases + Is)->can_cast_to>() ); + } + + template < typename Class, typename... Args > + bool raw_ctor_is_invocable_with( + const arg_base* arg_bases, + std::size_t arg_count) + { + using ct = ctor_traits; + + if ( arg_count != ct::arity ) { + return false; + } + + return raw_ctor_is_invocable_with_impl( + arg_bases, + std::make_index_sequence()); + } + + template < typename Class, typename... Args > + ctor_is_invocable_with make_ctor_is_invocable_with() { + using namespace std::placeholders; + return std::bind(&raw_ctor_is_invocable_with, _1, _2); + } +} + namespace meta_hpp { struct ctor_info::state final { ctor_type type; data_info_map datas; + detail::ctor_invoke invoke; + detail::ctor_is_invocable_with is_invocable_with; }; } @@ -61,6 +150,18 @@ namespace meta_hpp inline const ctor_type& ctor_info::type() const noexcept { return state_->type; } + + template < typename... Args > + value ctor_info::invoke(Args&&... args) const { + std::array vargs{arg{std::forward(args)}...}; + return state_->invoke(vargs.data(), vargs.size()); + } + + template < typename... Args > + bool ctor_info::is_invocable_with() const noexcept { + std::array arg_bases{arg_base{typename_arg}...}; + return state_->is_invocable_with(arg_bases.data(), arg_bases.size()); + } } namespace meta_hpp @@ -88,6 +189,8 @@ namespace meta_hpp ctor_info::ctor_info(typename_arg_t, typename_arg_t) : state_{std::make_shared(state{ ctor_type{typename_arg, typename_arg}, - {} + {}, + detail::make_ctor_invoke(), + detail::make_ctor_is_invocable_with(), })} {} } diff --git a/headers/meta.hpp/meta_infos/function_info.hpp b/headers/meta.hpp/meta_infos/function_info.hpp index 3b12110..065409c 100644 --- a/headers/meta.hpp/meta_infos/function_info.hpp +++ b/headers/meta.hpp/meta_infos/function_info.hpp @@ -21,6 +21,12 @@ namespace meta_hpp const std::string& name() const noexcept; const function_type& type() const noexcept; + + template < typename... Args > + std::optional invoke(Args&&... args) const; + + template < typename... Args > + bool is_invocable_with() const noexcept; public: template < typename F > void visit(F&& f) const; @@ -33,19 +39,112 @@ namespace meta_hpp template < typename Function > friend class function_; template < typename Function > - explicit function_info(std::string name, Function instance); + explicit function_info(std::string name, Function function); private: struct state; std::shared_ptr state_; }; } +namespace meta_hpp::detail +{ + using function_invoke = std::function(const arg*, std::size_t)>; + + template < typename Function, std::size_t... Is > + std::optional raw_function_invoke_impl( + Function function, + const arg* args, + std::index_sequence) + { + using ft = function_pointer_traits; + using return_type = typename ft::return_type; + using argument_types = typename ft::argument_types; + + if ( !(... && (args + Is)->can_cast_to>()) ) { + throw std::logic_error("an attempt to call a function with an incorrect argument types"); + } + + if constexpr ( std::is_void_v ) { + std::invoke(function, + (args + Is)->cast>()...); + return std::nullopt; + } else { + return_type return_value{std::invoke(function, + (args + Is)->cast>()...)}; + return value{std::forward(return_value)}; + } + } + + template < typename Function > + std::optional raw_function_invoke( + Function function, + const arg* args, + std::size_t arg_count) + { + using ft = function_pointer_traits; + + if ( arg_count != ft::arity ) { + throw std::logic_error("an attempt to call a function with an incorrect arity"); + } + + return raw_function_invoke_impl( + function, + args, + std::make_index_sequence()); + } + + template < typename Function > + function_invoke make_function_invoke(Function function) { + using namespace std::placeholders; + return std::bind(&raw_function_invoke, function, _1, _2); + } +} + +namespace meta_hpp::detail +{ + using function_is_invocable_with = std::function; + + template < typename Function, std::size_t... Is > + bool raw_function_is_invocable_with_impl( + const arg_base* arg_bases, + std::index_sequence) + { + using ft = function_pointer_traits; + using argument_types = typename ft::argument_types; + return (... && (arg_bases + Is)->can_cast_to>() ); + } + + template < typename Function > + bool raw_function_is_invocable_with( + const arg_base* arg_bases, + std::size_t arg_count) + { + using ft = function_pointer_traits; + + if ( arg_count != ft::arity ) { + return false; + } + + return raw_function_is_invocable_with_impl( + arg_bases, + std::make_index_sequence()); + } + + template < typename Function > + function_is_invocable_with make_function_is_invocable_with() { + using namespace std::placeholders; + return std::bind(&raw_function_is_invocable_with, _1, _2); + } +} + namespace meta_hpp { struct function_info::state final { std::string name; function_type type; data_info_map datas; + detail::function_invoke invoke; + detail::function_is_invocable_with is_invocable_with; }; } @@ -67,6 +166,18 @@ namespace meta_hpp inline const function_type& function_info::type() const noexcept { return state_->type; } + + template < typename... Args > + std::optional function_info::invoke(Args&&... args) const { + std::array vargs{arg{std::forward(args)}...}; + return state_->invoke(vargs.data(), vargs.size()); + } + + template < typename... Args > + bool function_info::is_invocable_with() const noexcept { + std::array arg_bases{arg_base{typename_arg}...}; + return state_->is_invocable_with(arg_bases.data(), arg_bases.size()); + } } namespace meta_hpp @@ -91,12 +202,12 @@ namespace meta_hpp namespace meta_hpp { template < typename Function > - function_info::function_info(std::string name, Function instance) + function_info::function_info(std::string name, Function function) : state_{std::make_shared(state{ std::move(name), type_db::get().template as(), - {} - })} { - (void)instance; - } + {}, + detail::make_function_invoke(function), + detail::make_function_is_invocable_with(), + })} {} } diff --git a/headers/meta.hpp/meta_infos/method_info.hpp b/headers/meta.hpp/meta_infos/method_info.hpp index b3f812b..c266a7e 100644 --- a/headers/meta.hpp/meta_infos/method_info.hpp +++ b/headers/meta.hpp/meta_infos/method_info.hpp @@ -21,6 +21,12 @@ namespace meta_hpp const std::string& name() const noexcept; const method_type& type() const noexcept; + + template < typename Instance, typename... Args > + std::optional invoke(Instance&& instance, Args&&... args) const; + + template < typename Inst, typename... Args > + bool is_invocable_with() const noexcept; public: template < typename F > void visit(F&& f) const; @@ -33,19 +39,128 @@ namespace meta_hpp template < typename Method > friend class method_; template < typename Method > - explicit method_info(std::string name, Method instance); + explicit method_info(std::string name, Method method); private: struct state; std::shared_ptr state_; }; } +namespace meta_hpp::detail +{ + using method_invoke = std::function(const inst&, const arg*, std::size_t)>; + + template < typename Method, std::size_t... Is > + std::optional raw_method_invoke_impl( + Method method, + const inst& inst, + const arg* args, + std::index_sequence) + { + using mt = method_pointer_traits; + using return_type = typename mt::return_type; + using qualified_type = typename mt::qualified_type; + using argument_types = typename mt::argument_types; + + if ( !inst.can_cast_to() ) { + throw std::logic_error("an attempt to call a method with an incorrect instance type"); + } + + if ( !(... && (args + Is)->can_cast_to>()) ) { + throw std::logic_error("an attempt to call a method with an incorrect argument types"); + } + + if constexpr ( std::is_void_v ) { + std::invoke(method, + inst.cast(), + (args + Is)->cast>()...); + return std::nullopt; + } else { + return_type return_value{std::invoke(method, + inst.cast(), + (args + Is)->cast>()...)}; + return value{std::forward(return_value)}; + } + } + + template < typename Method > + std::optional raw_method_invoke( + Method method, + const inst& inst, + const arg* args, + std::size_t arg_count) + { + using mt = method_pointer_traits; + + if ( arg_count != mt::arity ) { + throw std::logic_error("an attempt to call a method with an incorrect arity"); + } + + return raw_method_invoke_impl( + method, + inst, + args, + std::make_index_sequence()); + } + + template < typename Method > + method_invoke make_method_invoke(Method method) { + using namespace std::placeholders; + return std::bind(&raw_method_invoke, method, _1, _2, _3); + } +} + +namespace meta_hpp::detail +{ + using method_is_invocable_with = std::function; + + template < typename Method, std::size_t... Is > + bool raw_method_is_invocable_with_impl( + const inst_base& inst_base, + const arg_base* arg_bases, + std::index_sequence) + { + using mt = method_pointer_traits; + using qualified_type = typename mt::qualified_type; + using argument_types = typename mt::argument_types; + + return inst_base.can_cast_to() + && (... && (arg_bases + Is)->can_cast_to>() ); + } + + template < typename Method > + bool raw_method_is_invocable_with( + const inst_base& inst_base, + const arg_base* arg_bases, + std::size_t arg_count) + { + using mt = method_pointer_traits; + + if ( arg_count != mt::arity ) { + return false; + } + + return raw_method_is_invocable_with_impl( + inst_base, + arg_bases, + std::make_index_sequence()); + } + + template < typename Method > + method_is_invocable_with make_method_is_invocable_with() { + using namespace std::placeholders; + return std::bind(&raw_method_is_invocable_with, _1, _2, _3); + } +} + namespace meta_hpp { struct method_info::state final { std::string name; method_type type; data_info_map datas; + detail::method_invoke invoke; + detail::method_is_invocable_with is_invocable_with; }; } @@ -67,6 +182,18 @@ namespace meta_hpp inline const method_type& method_info::type() const noexcept { return state_->type; } + + template < typename Instance, typename... Args > + std::optional method_info::invoke(Instance&& instance, Args&&... args) const { + std::array vargs{arg{std::forward(args)}...}; + return state_->invoke(inst{std::forward(instance)}, vargs.data(), vargs.size()); + } + + template < typename Inst, typename... Args > + bool method_info::is_invocable_with() const noexcept { + std::array arg_bases{arg_base{typename_arg}...}; + return state_->is_invocable_with(inst_base{typename_arg}, arg_bases.data(), arg_bases.size()); + } } namespace meta_hpp @@ -91,12 +218,12 @@ namespace meta_hpp namespace meta_hpp { template < typename Method > - method_info::method_info(std::string name, Method instance) + method_info::method_info(std::string name, Method method) : state_{std::make_shared(state{ std::move(name), type_db::get().template as(), - {} - })} { - (void)instance; - } + {}, + detail::make_method_invoke(method), + detail::make_method_is_invocable_with(), + })} {} } diff --git a/headers/meta.hpp/meta_types/method_type.hpp b/headers/meta.hpp/meta_types/method_type.hpp index 15c80ff..75996f5 100644 --- a/headers/meta.hpp/meta_types/method_type.hpp +++ b/headers/meta.hpp/meta_types/method_type.hpp @@ -13,6 +13,9 @@ namespace meta_hpp enum class method_flags : unsigned { is_const = 1 << 0, is_noexcept = 1 << 1, + is_volatile = 1 << 2, + is_lvalue_qualified = 1 << 3, + is_rvalue_qualified = 1 << 4, }; ENUM_HPP_OPERATORS_DECL(method_flags) @@ -39,6 +42,9 @@ namespace meta_hpp bitflags flags() const noexcept; bool is_const() const noexcept; bool is_noexcept() const noexcept; + bool is_volatile() const noexcept; + bool is_lvalue_qualified() const noexcept; + bool is_rvalue_qualified() const noexcept; private: struct state; std::shared_ptr state_; @@ -56,6 +62,7 @@ namespace meta_hpp::detail using class_type = C; using return_type = R; + using qualified_type = C; using argument_types = std::tuple; static any_type make_class_type() { @@ -77,6 +84,7 @@ namespace meta_hpp::detail template < typename R, typename C, typename... Args > struct method_pointer_traits : method_pointer_traits { + using qualified_type = const C; static bitflags make_flags() noexcept { return method_flags::is_const; } @@ -84,6 +92,7 @@ namespace meta_hpp::detail template < typename R, typename C, typename... Args > struct method_pointer_traits : method_pointer_traits { + using qualified_type = C; static bitflags make_flags() noexcept { return method_flags::is_noexcept; } @@ -91,10 +100,173 @@ namespace meta_hpp::detail template < typename R, typename C, typename... Args > struct method_pointer_traits : method_pointer_traits { + using qualified_type = const C; static bitflags make_flags() noexcept { return method_flags::is_const | method_flags::is_noexcept; } }; + + template < typename R, typename C, typename... Args > + struct method_pointer_traits : method_pointer_traits { + using qualified_type = C&; + static bitflags make_flags() noexcept { + return method_flags::is_lvalue_qualified; + } + }; + + template < typename R, typename C, typename... Args > + struct method_pointer_traits : method_pointer_traits { + using qualified_type = C&; + static bitflags make_flags() noexcept { + return method_flags::is_noexcept | method_flags::is_lvalue_qualified; + } + }; + + template < typename R, typename C, typename... Args > + struct method_pointer_traits : method_pointer_traits { + using qualified_type = const C&; + static bitflags make_flags() noexcept { + return method_flags::is_const | method_flags::is_lvalue_qualified; + } + }; + + template < typename R, typename C, typename... Args > + struct method_pointer_traits : method_pointer_traits { + using qualified_type = const C&; + static bitflags make_flags() noexcept { + return method_flags::is_const | method_flags::is_noexcept | method_flags::is_lvalue_qualified; + } + }; + + template < typename R, typename C, typename... Args > + struct method_pointer_traits : method_pointer_traits { + using qualified_type = C&&; + static bitflags make_flags() noexcept { + return method_flags::is_rvalue_qualified; + } + }; + + template < typename R, typename C, typename... Args > + struct method_pointer_traits : method_pointer_traits { + using qualified_type = C&&; + static bitflags make_flags() noexcept { + return method_flags::is_noexcept | method_flags::is_rvalue_qualified; + } + }; + + template < typename R, typename C, typename... Args > + struct method_pointer_traits : method_pointer_traits { + using qualified_type = const C&&; + static bitflags make_flags() noexcept { + return method_flags::is_const | method_flags::is_rvalue_qualified; + } + }; + + template < typename R, typename C, typename... Args > + struct method_pointer_traits : method_pointer_traits { + using qualified_type = const C&&; + static bitflags make_flags() noexcept { + return method_flags::is_const | method_flags::is_noexcept | method_flags::is_rvalue_qualified; + } + }; + + // + + template < typename R, typename C, typename... Args > + struct method_pointer_traits : method_pointer_traits { + using qualified_type = C; + static bitflags make_flags() noexcept { + return method_flags::is_volatile; + } + }; + + template < typename R, typename C, typename... Args > + struct method_pointer_traits : method_pointer_traits { + using qualified_type = const C; + static bitflags make_flags() noexcept { + return method_flags::is_volatile | method_flags::is_const; + } + }; + + template < typename R, typename C, typename... Args > + struct method_pointer_traits : method_pointer_traits { + using qualified_type = C; + static bitflags make_flags() noexcept { + return method_flags::is_volatile | method_flags::is_noexcept; + } + }; + + template < typename R, typename C, typename... Args > + struct method_pointer_traits : method_pointer_traits { + using qualified_type = const C; + static bitflags make_flags() noexcept { + return method_flags::is_volatile | method_flags::is_const | method_flags::is_noexcept; + } + }; + + template < typename R, typename C, typename... Args > + struct method_pointer_traits : method_pointer_traits { + using qualified_type = C&; + static bitflags make_flags() noexcept { + return method_flags::is_volatile | method_flags::is_lvalue_qualified; + } + }; + + template < typename R, typename C, typename... Args > + struct method_pointer_traits : method_pointer_traits { + using qualified_type = C&; + static bitflags make_flags() noexcept { + return method_flags::is_volatile | method_flags::is_noexcept | method_flags::is_lvalue_qualified; + } + }; + + template < typename R, typename C, typename... Args > + struct method_pointer_traits : method_pointer_traits { + using qualified_type = const C&; + static bitflags make_flags() noexcept { + return method_flags::is_volatile | method_flags::is_const | method_flags::is_lvalue_qualified; + } + }; + + template < typename R, typename C, typename... Args > + struct method_pointer_traits : method_pointer_traits { + using qualified_type = const C&; + static bitflags make_flags() noexcept { + return method_flags::is_volatile | method_flags::is_const | method_flags::is_noexcept | method_flags::is_lvalue_qualified; + } + }; + + template < typename R, typename C, typename... Args > + struct method_pointer_traits : method_pointer_traits { + using qualified_type = C&&; + static bitflags make_flags() noexcept { + return method_flags::is_volatile | method_flags::is_rvalue_qualified; + } + }; + + template < typename R, typename C, typename... Args > + struct method_pointer_traits : method_pointer_traits { + using qualified_type = C&&; + static bitflags make_flags() noexcept { + return method_flags::is_volatile | method_flags::is_noexcept | method_flags::is_rvalue_qualified; + } + }; + + template < typename R, typename C, typename... Args > + struct method_pointer_traits : method_pointer_traits { + using qualified_type = const C&&; + static bitflags make_flags() noexcept { + return method_flags::is_volatile | method_flags::is_const | method_flags::is_rvalue_qualified; + } + }; + + template < typename R, typename C, typename... Args > + struct method_pointer_traits : method_pointer_traits { + using qualified_type = const C&&; + static bitflags make_flags() noexcept { + return method_flags::is_volatile | method_flags::is_const | method_flags::is_noexcept | method_flags::is_rvalue_qualified; + } + }; } namespace meta_hpp @@ -153,4 +325,16 @@ namespace meta_hpp inline bool method_type::is_noexcept() const noexcept { return state_->flags.has(method_flags::is_noexcept); } + + inline bool method_type::is_volatile() const noexcept { + return state_->flags.has(method_flags::is_volatile); + } + + inline bool method_type::is_lvalue_qualified() const noexcept { + return state_->flags.has(method_flags::is_lvalue_qualified); + } + + inline bool method_type::is_rvalue_qualified() const noexcept { + return state_->flags.has(method_flags::is_rvalue_qualified); + } } diff --git a/headers/meta.hpp/meta_utilities.hpp b/headers/meta.hpp/meta_utilities.hpp index be54873..f553ef8 100644 --- a/headers/meta.hpp/meta_utilities.hpp +++ b/headers/meta.hpp/meta_utilities.hpp @@ -9,4 +9,5 @@ #include "meta_fwd.hpp" #include "meta_utilities/arg.hpp" +#include "meta_utilities/inst.hpp" #include "meta_utilities/value.hpp" diff --git a/headers/meta.hpp/meta_utilities/inst.hpp b/headers/meta.hpp/meta_utilities/inst.hpp new file mode 100644 index 0000000..b6f6557 --- /dev/null +++ b/headers/meta.hpp/meta_utilities/inst.hpp @@ -0,0 +1,183 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_fwd.hpp" + +namespace meta_hpp +{ + class inst_base { + public: + enum class ref_types { + ref, + rref, + cref, + crref, + }; + public: + inst_base() = delete; + + inst_base(inst_base&&) = delete; + inst_base& operator=(inst_base&&) = delete; + + inst_base(const inst_base&) = delete; + inst_base& operator=(const inst_base&) = delete; + + template < typename T, std::enable_if_t< + std::is_lvalue_reference_v && std::is_class_v> + , int> = 0> + explicit inst_base(typename_arg_t); + + template < typename T, std::enable_if_t< + std::is_class_v || + (std::is_rvalue_reference_v && std::is_class_v>) + , int> = 0> + explicit inst_base(typename_arg_t); + + bool is_const() const noexcept; + bool is_lvalue() const noexcept; + bool is_rvalue() const noexcept; + + any_type raw_type() const noexcept; + ref_types ref_type() const noexcept; + + template < typename To > + bool can_cast_to() const noexcept; + private: + any_type raw_type_{}; + ref_types ref_type_{}; + }; +} + +namespace meta_hpp +{ + template < typename T, std::enable_if_t< + std::is_lvalue_reference_v && std::is_class_v> + , int> > + inst_base::inst_base(typename_arg_t) + : raw_type_{type_db::get>()} + , ref_type_{std::is_const_v> ? ref_types::cref : ref_types::ref} {} + + template < typename T, std::enable_if_t< + std::is_class_v || + (std::is_rvalue_reference_v && std::is_class_v>) + , int> > + inst_base::inst_base(typename_arg_t) + : raw_type_{type_db::get>()} + , ref_type_{std::is_const_v> ? ref_types::crref : ref_types::rref} {} + + inline bool inst_base::is_const() const noexcept { + return ref_type_ == ref_types::cref + || ref_type_ == ref_types::crref; + } + + inline bool inst_base::is_lvalue() const noexcept { + return ref_type_ == ref_types::ref + || ref_type_ == ref_types::cref; + } + + inline bool inst_base::is_rvalue() const noexcept { + return ref_type_ == ref_types::rref + || ref_type_ == ref_types::crref; + } + + inline any_type inst_base::raw_type() const noexcept { + return raw_type_; + } + + inline inst_base::ref_types inst_base::ref_type() const noexcept { + return ref_type_; + } + + template < typename To > + bool inst_base::can_cast_to() const noexcept { + static_assert( + std::is_class_v || + (std::is_reference_v && std::is_class_v>)); + + constexpr bool to_const = std::is_const_v>; + + if ( !to_const && is_const() ) { + return false; + } + + if constexpr ( std::is_lvalue_reference_v ) { + if ( !is_lvalue() ) { + return false; + } + } + + if constexpr ( std::is_rvalue_reference_v ) { + if ( !is_rvalue() ) { + return false; + } + } + + using to_raw_type = stdex::remove_cvref_t; + return raw_type() == type_db::get(); + } +} + +namespace meta_hpp +{ + class inst final : public inst_base { + public: + inst() = delete; + + inst(inst&&) = delete; + inst& operator=(inst&&) = delete; + + inst(const inst&) = delete; + inst& operator=(const inst&) = delete; + + template < typename T, std::enable_if_t< + std::is_class_v || + (std::is_reference_v && std::is_class_v>) + , int> = 0 > + explicit inst(T&& v); + + template < typename To > + decltype(auto) cast() const; + private: + void* data_{}; + }; +} + +namespace meta_hpp +{ + template < typename T, std::enable_if_t< + std::is_class_v || + (std::is_reference_v && std::is_class_v>) + , int> > + inst::inst(T&& v) + : inst_base{typename_arg} + , data_{const_cast*>(std::addressof(v))} {} + + template < typename To > + decltype(auto) inst::cast() const { + if ( !can_cast_to() ) { + throw std::logic_error("bad inst cast"); + } + + if constexpr ( std::is_reference_v ) { + using raw_type_with_cv = std::remove_reference_t; + + if constexpr ( std::is_lvalue_reference_v ) { + return *static_cast(data_); + } + + if constexpr ( std::is_rvalue_reference_v ) { + return std::move(*static_cast(data_)); + } + } + + if constexpr ( !std::is_reference_v) { + using raw_type_with_cv = To; + return *static_cast(data_); + } + } +} diff --git a/untests/features/infos/base_info_tests.cpp b/untests/features/infos/base_info_tests.cpp index 032560b..d90da07 100644 --- a/untests/features/infos/base_info_tests.cpp +++ b/untests/features/infos/base_info_tests.cpp @@ -21,7 +21,6 @@ namespace class derived final : public base { public: - derived() = default; }; struct empty final {}; diff --git a/untests/features/infos/ctor_info_tests.cpp b/untests/features/infos/ctor_info_tests.cpp index 3a91965..5fa4e57 100644 --- a/untests/features/infos/ctor_info_tests.cpp +++ b/untests/features/infos/ctor_info_tests.cpp @@ -23,6 +23,10 @@ namespace [[maybe_unused]] explicit ivec2(int v): x{v}, y{v} {} [[maybe_unused]] ivec2(int x, int y): x{x}, y{y} {} }; + + [[maybe_unused]] bool operator==(const ivec2& l, const ivec2& r) noexcept { + return l.x == r.x && l.y == r.y; + } } TEST_CASE("features/infos/ctor") { @@ -57,6 +61,22 @@ TEST_CASE("features/infos/ctor") { CHECK(ci.type().id() == ci2.type().id()); CHECK(ci.type().id() == ci2.type().id()); } + + { + CHECK(ci.is_invocable_with<>()); + + CHECK_FALSE(ci.is_invocable_with()); + CHECK_FALSE(ci.is_invocable_with()); + CHECK_FALSE(ci.is_invocable_with()); + CHECK_FALSE(ci.is_invocable_with()); + CHECK_FALSE(ci.is_invocable_with()); + CHECK_FALSE(ci.is_invocable_with()); + } + + { + CHECK(ci.invoke().equals(ivec2{})); + CHECK_THROWS(ci.invoke(42)); + } } SUBCASE("int") { @@ -76,6 +96,22 @@ TEST_CASE("features/infos/ctor") { CHECK(ci.type().id() == ci2.type().id()); CHECK(ci.type().id() == ci2.type().id()); } + + { + CHECK_FALSE(ci.is_invocable_with<>()); + + CHECK(ci.is_invocable_with()); + CHECK(ci.is_invocable_with()); + CHECK(ci.is_invocable_with()); + CHECK(ci.is_invocable_with()); + CHECK(ci.is_invocable_with()); + CHECK(ci.is_invocable_with()); + } + + { + CHECK_THROWS(ci.invoke()); + CHECK(ci.invoke(42).equals(ivec2{42})); + } } SUBCASE("const ivec2&") { @@ -95,6 +131,29 @@ TEST_CASE("features/infos/ctor") { CHECK(ci.type().id() == ci2.type().id()); CHECK(ci.type().id() == ci2.type().id()); } + + { + CHECK_FALSE(ci.is_invocable_with<>()); + + CHECK_FALSE(ci.is_invocable_with()); + CHECK_FALSE(ci.is_invocable_with()); + CHECK_FALSE(ci.is_invocable_with()); + CHECK_FALSE(ci.is_invocable_with()); + CHECK_FALSE(ci.is_invocable_with()); + CHECK_FALSE(ci.is_invocable_with()); + + CHECK(ci.is_invocable_with()); + CHECK(ci.is_invocable_with()); + CHECK(ci.is_invocable_with()); + CHECK(ci.is_invocable_with()); + CHECK(ci.is_invocable_with()); + } + + { + CHECK_THROWS(ci.invoke()); + CHECK_THROWS(ci.invoke(42)); + CHECK(ci.invoke(ivec2{21,42}).equals(ivec2{21,42})); + } } SUBCASE("int,int") { @@ -116,5 +175,27 @@ TEST_CASE("features/infos/ctor") { CHECK(ci.type().id() == ci2.type().id()); CHECK(ci.type().id() == ci2.type().id()); } + + { + CHECK_FALSE(ci.is_invocable_with<>()); + + CHECK_FALSE(ci.is_invocable_with()); + CHECK_FALSE(ci.is_invocable_with()); + CHECK_FALSE(ci.is_invocable_with()); + CHECK_FALSE(ci.is_invocable_with()); + CHECK_FALSE(ci.is_invocable_with()); + CHECK_FALSE(ci.is_invocable_with()); + + CHECK(ci.is_invocable_with()); + CHECK(ci.is_invocable_with()); + CHECK(ci.is_invocable_with()); + } + + { + CHECK_THROWS(ci.invoke()); + CHECK_THROWS(ci.invoke(42)); + CHECK_THROWS(ci.invoke(ivec2{21,42})); + CHECK(ci.invoke(21,42).equals(ivec2{21,42})); + } } } diff --git a/untests/features/infos/function_info_tests.cpp b/untests/features/infos/function_info_tests.cpp index 83baf40..dc1b25e 100644 --- a/untests/features/infos/function_info_tests.cpp +++ b/untests/features/infos/function_info_tests.cpp @@ -8,7 +8,88 @@ namespace { + using namespace meta_hpp; + using namespace std::string_literals; +} + +namespace +{ + struct ivec2 { + int x{}; + int y{}; + + [[maybe_unused]] ivec2() = default; + [[maybe_unused]] ivec2(const ivec2& other) = default; + [[maybe_unused]] explicit ivec2(int v): x{v}, y{v} {} + [[maybe_unused]] ivec2(int x, int y): x{x}, y{y} {} + }; + + bool operator==(const ivec2& l, const ivec2& r) noexcept { + return l.x == r.x && l.y == r.y; + } + + ivec2 iadd(const ivec2& l, const ivec2& r) noexcept { + return {l.x + r.x, l.y + r.y}; + } + + int ilength2(const ivec2& v) noexcept { + return v.x * v.x + v.y * v.y; + } } TEST_CASE("features/infos/function") { + registry db; + + db( + namespace_{"vmath"}( + class_{"ivec2"}, + function_{"iadd", &iadd}(data_{"info", "iadd function"s}), + function_{"ilength2", &ilength2}(data_{"info", "ilength2 function"s}) + ) + ); + + SUBCASE("iadd") { + const function_info fi = db.get_function_by_path("vmath::iadd"); + REQUIRE(fi); + + REQUIRE(fi.get_data_by_name("info")); + CHECK(fi.get_data_by_name("info").value().equals("iadd function"s)); + + CHECK_FALSE(fi.is_invocable_with()); + CHECK_FALSE(fi.is_invocable_with()); + CHECK_FALSE(fi.is_invocable_with()); + CHECK_FALSE(fi.is_invocable_with()); + + CHECK(fi.is_invocable_with()); + CHECK(fi.is_invocable_with()); + + CHECK_THROWS(fi.invoke()); + CHECK_THROWS(fi.invoke(42)); + CHECK_THROWS(fi.invoke(ivec2{}, 42)); + + CHECK(fi.invoke(ivec2{1,2},ivec2{3,4})); + CHECK(fi.invoke(ivec2{1,2},ivec2{3,4})->equals(ivec2{4,6})); + } + + SUBCASE("ilength2") { + const function_info fi = db.get_function_by_path("vmath::ilength2"); + REQUIRE(fi); + + REQUIRE(fi.get_data_by_name("info")); + CHECK(fi.get_data_by_name("info").value().equals("ilength2 function"s)); + + CHECK_FALSE(fi.is_invocable_with()); + CHECK_FALSE(fi.is_invocable_with()); + CHECK_FALSE(fi.is_invocable_with()); + + CHECK(fi.is_invocable_with()); + CHECK(fi.is_invocable_with()); + + CHECK_THROWS(fi.invoke()); + CHECK_THROWS(fi.invoke(42)); + CHECK_THROWS(fi.invoke(ivec2{}, 42)); + + CHECK(fi.invoke(ivec2{2,3})); + CHECK(fi.invoke(ivec2{2,3})->equals(13)); + } } diff --git a/untests/features/infos/method_info_tests.cpp b/untests/features/infos/method_info_tests.cpp index 21bcea4..e8e9d49 100644 --- a/untests/features/infos/method_info_tests.cpp +++ b/untests/features/infos/method_info_tests.cpp @@ -8,7 +8,779 @@ namespace { + using namespace meta_hpp; + using namespace std::string_literals; +} + +namespace +{ + struct clazz { + clazz() = default; + + clazz(clazz&&) = delete; + clazz(const clazz&) = delete; + + clazz& operator=(clazz&&) = delete; + clazz& operator=(const clazz&) = delete; + + // + + int non_const_method() { return 1; } + int non_const_method_noexcept() noexcept { return 2; } + + int const_method() const { return 3; } + int const_method_noexcept() const noexcept { return 4; } + + int non_const_method_ref() & { return 5; } + int non_const_method_noexcept_ref() & noexcept { return 6; } + + int const_method_ref() const & { return 7; } + int const_method_noexcept_ref() const & noexcept { return 8; } + + int non_const_method_rref() && { return 9; } + int non_const_method_noexcept_rref() && noexcept { return 10; } + + int const_method_rref() const && { return 11; } + int const_method_noexcept_rref() const && noexcept { return 12; } + + // + + int non_const_method_volatile() volatile { return 1; } + int non_const_method_noexcept_volatile() volatile noexcept { return 2; } + + int const_method_volatile() volatile const { return 3; } + int const_method_noexcept_volatile() volatile const noexcept { return 4; } + + int non_const_method_ref_volatile() volatile & { return 5; } + int non_const_method_noexcept_ref_volatile() volatile & noexcept { return 6; } + + int const_method_ref_volatile() volatile const & { return 7; } + int const_method_noexcept_ref_volatile() volatile const & noexcept { return 8; } + + int non_const_method_rref_volatile() volatile && { return 9; } + int non_const_method_noexcept_rref_volatile() volatile && noexcept { return 10; } + + int const_method_rref_volatile() volatile const && { return 11; } + int const_method_noexcept_rref_volatile() volatile const && noexcept { return 12; } + }; + + struct clazz2 {}; } TEST_CASE("features/infos/method") { + registry db; + + db( + class_{"clazz"}( + method_{"non_const_method", &clazz::non_const_method}, + method_{"non_const_method_noexcept", &clazz::non_const_method_noexcept}, + + method_{"const_method", &clazz::const_method}, + method_{"const_method_noexcept", &clazz::const_method_noexcept}, + + method_{"non_const_method_ref", &clazz::non_const_method_ref}, + method_{"non_const_method_noexcept_ref", &clazz::non_const_method_noexcept_ref}, + + method_{"const_method_ref", &clazz::const_method_ref}, + method_{"const_method_noexcept_ref", &clazz::const_method_noexcept_ref}, + + method_{"non_const_method_rref", &clazz::non_const_method_rref}, + method_{"non_const_method_noexcept_rref", &clazz::non_const_method_noexcept_rref}, + + method_{"const_method_rref", &clazz::const_method_rref}, + method_{"const_method_noexcept_rref", &clazz::const_method_noexcept_rref}, + + // + + method_{"non_const_method_volatile", &clazz::non_const_method_volatile}, + method_{"non_const_method_noexcept_volatile", &clazz::non_const_method_noexcept_volatile}, + + method_{"const_method_volatile", &clazz::const_method_volatile}, + method_{"const_method_noexcept_volatile", &clazz::const_method_noexcept_volatile}, + + method_{"non_const_method_ref_volatile", &clazz::non_const_method_ref_volatile}, + method_{"non_const_method_noexcept_ref_volatile", &clazz::non_const_method_noexcept_ref_volatile}, + + method_{"const_method_ref_volatile", &clazz::const_method_ref_volatile}, + method_{"const_method_noexcept_ref_volatile", &clazz::const_method_noexcept_ref_volatile}, + + method_{"non_const_method_rref_volatile", &clazz::non_const_method_rref_volatile}, + method_{"non_const_method_noexcept_rref_volatile", &clazz::non_const_method_noexcept_rref_volatile}, + + method_{"const_method_rref_volatile", &clazz::const_method_rref_volatile}, + method_{"const_method_noexcept_rref_volatile", &clazz::const_method_noexcept_rref_volatile} + ) + ); + + SUBCASE("non_const_method") { + const method_info mi = db.get_method_by_path("clazz::non_const_method"); + REQUIRE(mi); + + const method_info mi2 = db.get_method_by_path("clazz::non_const_method_volatile"); + REQUIRE(mi2); + + { + CHECK(mi.type().arity() == 0); + CHECK(mi.type().class_type() == type_db::get()); + CHECK(mi.type().return_type() == type_db::get()); + CHECK(mi.type().flags() == method_flags{}); + + CHECK(mi2.type().arity() == 0); + CHECK(mi2.type().class_type() == type_db::get()); + CHECK(mi2.type().return_type() == type_db::get()); + CHECK(mi2.type().flags() == method_flags::is_volatile); + } + + { + CHECK(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + CHECK(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + + CHECK(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); + CHECK(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); + } + + { + clazz cl; + + CHECK(mi.invoke(cl)->equals(1)); + CHECK_THROWS(mi.invoke(std::as_const(cl))); + CHECK(mi.invoke(std::move(cl))->equals(1)); + CHECK_THROWS(mi.invoke(std::move(std::as_const(cl)))); + + CHECK(mi2.invoke(cl)->equals(1)); + CHECK_THROWS(mi2.invoke(std::as_const(cl))); + CHECK(mi2.invoke(std::move(cl))->equals(1)); + CHECK_THROWS(mi2.invoke(std::move(std::as_const(cl)))); + } + + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + } + + SUBCASE("non_const_method_noexcept") { + const method_info mi = db.get_method_by_path("clazz::non_const_method_noexcept"); + REQUIRE(mi); + + const method_info mi2 = db.get_method_by_path("clazz::non_const_method_noexcept_volatile"); + REQUIRE(mi2); + + { + CHECK(mi.type().arity() == 0); + CHECK(mi.type().class_type() == type_db::get()); + CHECK(mi.type().return_type() == type_db::get()); + CHECK(mi.type().flags() == method_flags::is_noexcept); + + CHECK(mi2.type().arity() == 0); + CHECK(mi2.type().class_type() == type_db::get()); + CHECK(mi2.type().return_type() == type_db::get()); + CHECK(mi2.type().flags() == (method_flags::is_noexcept | method_flags::is_volatile)); + } + + { + CHECK(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + CHECK(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + + CHECK(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); + CHECK(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); + } + + { + clazz cl; + + CHECK(mi.invoke(cl)->equals(2)); + CHECK_THROWS(mi.invoke(std::as_const(cl))); + CHECK(mi.invoke(std::move(cl))->equals(2)); + CHECK_THROWS(mi.invoke(std::move(std::as_const(cl)))); + + CHECK(mi2.invoke(cl)->equals(2)); + CHECK_THROWS(mi2.invoke(std::as_const(cl))); + CHECK(mi2.invoke(std::move(cl))->equals(2)); + CHECK_THROWS(mi2.invoke(std::move(std::as_const(cl)))); + } + + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + } + + SUBCASE("const_method") { + const method_info mi = db.get_method_by_path("clazz::const_method"); + REQUIRE(mi); + + const method_info mi2 = db.get_method_by_path("clazz::const_method_volatile"); + REQUIRE(mi2); + + { + CHECK(mi.type().arity() == 0); + CHECK(mi.type().class_type() == type_db::get()); + CHECK(mi.type().return_type() == type_db::get()); + CHECK(mi.type().flags() == method_flags::is_const); + + CHECK(mi2.type().arity() == 0); + CHECK(mi2.type().class_type() == type_db::get()); + CHECK(mi2.type().return_type() == type_db::get()); + CHECK(mi2.type().flags() == (method_flags::is_const | method_flags::is_volatile)); + } + + { + CHECK(mi.is_invocable_with()); + CHECK(mi.is_invocable_with()); + CHECK(mi.is_invocable_with()); + CHECK(mi.is_invocable_with()); + + CHECK(mi2.is_invocable_with()); + CHECK(mi2.is_invocable_with()); + CHECK(mi2.is_invocable_with()); + CHECK(mi2.is_invocable_with()); + } + + { + clazz cl; + + CHECK(mi.invoke(cl)->equals(3)); + CHECK(mi.invoke(std::as_const(cl))->equals(3)); + CHECK(mi.invoke(std::move(cl))->equals(3)); + CHECK(mi.invoke(std::move(std::as_const(cl)))->equals(3)); + + CHECK(mi2.invoke(cl)->equals(3)); + CHECK(mi2.invoke(std::as_const(cl))->equals(3)); + CHECK(mi2.invoke(std::move(cl))->equals(3)); + CHECK(mi2.invoke(std::move(std::as_const(cl)))->equals(3)); + } + + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + } + + SUBCASE("const_method_noexcept") { + const method_info mi = db.get_method_by_path("clazz::const_method_noexcept"); + REQUIRE(mi); + + const method_info mi2 = db.get_method_by_path("clazz::const_method_noexcept_volatile"); + REQUIRE(mi2); + + { + CHECK(mi.type().arity() == 0); + CHECK(mi.type().class_type() == type_db::get()); + CHECK(mi.type().return_type() == type_db::get()); + CHECK(mi.type().flags() == (method_flags::is_const | method_flags::is_noexcept)); + + CHECK(mi2.type().arity() == 0); + CHECK(mi2.type().class_type() == type_db::get()); + CHECK(mi2.type().return_type() == type_db::get()); + CHECK(mi2.type().flags() == (method_flags::is_const | method_flags::is_noexcept | method_flags::is_volatile)); + } + + { + CHECK(mi.is_invocable_with()); + CHECK(mi.is_invocable_with()); + CHECK(mi.is_invocable_with()); + CHECK(mi.is_invocable_with()); + + CHECK(mi2.is_invocable_with()); + CHECK(mi2.is_invocable_with()); + CHECK(mi2.is_invocable_with()); + CHECK(mi2.is_invocable_with()); + } + + { + clazz cl; + + CHECK(mi.invoke(cl)->equals(4)); + CHECK(mi.invoke(std::as_const(cl))->equals(4)); + CHECK(mi.invoke(std::move(cl))->equals(4)); + CHECK(mi.invoke(std::move(std::as_const(cl)))->equals(4)); + + CHECK(mi2.invoke(cl)->equals(4)); + CHECK(mi2.invoke(std::as_const(cl))->equals(4)); + CHECK(mi2.invoke(std::move(cl))->equals(4)); + CHECK(mi2.invoke(std::move(std::as_const(cl)))->equals(4)); + } + + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + } + + SUBCASE("non_const_method_ref") { + const method_info mi = db.get_method_by_path("clazz::non_const_method_ref"); + REQUIRE(mi); + + const method_info mi2 = db.get_method_by_path("clazz::non_const_method_ref_volatile"); + REQUIRE(mi2); + + { + CHECK(mi.type().arity() == 0); + CHECK(mi.type().class_type() == type_db::get()); + CHECK(mi.type().return_type() == type_db::get()); + CHECK(mi.type().flags() == method_flags::is_lvalue_qualified); + + CHECK(mi2.type().arity() == 0); + CHECK(mi2.type().class_type() == type_db::get()); + CHECK(mi2.type().return_type() == type_db::get()); + CHECK(mi2.type().flags() == (method_flags::is_volatile | method_flags::is_lvalue_qualified)); + } + + { + CHECK(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + + CHECK(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); + } + + { + clazz cl; + + CHECK(mi.invoke(cl)->equals(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(mi2.invoke(cl)->equals(5)); + CHECK_THROWS(mi2.invoke(std::as_const(cl))); + CHECK_THROWS(mi2.invoke(std::move(cl))); + CHECK_THROWS(mi2.invoke(std::move(std::as_const(cl)))); + } + + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); + + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); + } + + SUBCASE("non_const_method_noexcept_ref") { + const method_info mi = db.get_method_by_path("clazz::non_const_method_noexcept_ref"); + REQUIRE(mi); + + const method_info mi2 = db.get_method_by_path("clazz::non_const_method_noexcept_ref_volatile"); + REQUIRE(mi2); + + { + CHECK(mi.type().arity() == 0); + CHECK(mi.type().class_type() == type_db::get()); + CHECK(mi.type().return_type() == type_db::get()); + CHECK(mi.type().flags() == (method_flags::is_noexcept | method_flags::is_lvalue_qualified)); + + CHECK(mi2.type().arity() == 0); + CHECK(mi2.type().class_type() == type_db::get()); + CHECK(mi2.type().return_type() == type_db::get()); + CHECK(mi2.type().flags() == (method_flags::is_noexcept | method_flags::is_volatile | method_flags::is_lvalue_qualified)); + } + + { + CHECK(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + + CHECK(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); + } + + { + clazz cl; + + CHECK(mi.invoke(cl)->equals(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(mi2.invoke(cl)->equals(6)); + CHECK_THROWS(mi2.invoke(std::as_const(cl))); + CHECK_THROWS(mi2.invoke(std::move(cl))); + CHECK_THROWS(mi2.invoke(std::move(std::as_const(cl)))); + } + + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); + + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); + } + + SUBCASE("const_method_ref") { + const method_info mi = db.get_method_by_path("clazz::const_method_ref"); + REQUIRE(mi); + + const method_info mi2 = db.get_method_by_path("clazz::const_method_ref_volatile"); + REQUIRE(mi2); + + { + CHECK(mi.type().arity() == 0); + CHECK(mi.type().class_type() == type_db::get()); + CHECK(mi.type().return_type() == type_db::get()); + CHECK(mi.type().flags() == (method_flags::is_const | method_flags::is_lvalue_qualified)); + + CHECK(mi2.type().arity() == 0); + CHECK(mi2.type().class_type() == type_db::get()); + CHECK(mi2.type().return_type() == type_db::get()); + CHECK(mi2.type().flags() == (method_flags::is_const | method_flags::is_volatile | method_flags::is_lvalue_qualified)); + } + + { + CHECK(mi.is_invocable_with()); + CHECK(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + + CHECK(mi2.is_invocable_with()); + CHECK(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); + } + + { + clazz cl; + + CHECK(mi.invoke(cl)->equals(7)); + CHECK(mi.invoke(std::as_const(cl))->equals(7)); + CHECK_THROWS(mi.invoke(std::move(cl))); + CHECK_THROWS(mi.invoke(std::move(std::as_const(cl)))); + + CHECK(mi2.invoke(cl)->equals(7)); + CHECK(mi2.invoke(std::as_const(cl))->equals(7)); + CHECK_THROWS(mi2.invoke(std::move(cl))); + CHECK_THROWS(mi2.invoke(std::move(std::as_const(cl)))); + } + + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); + + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); + } + + SUBCASE("const_method_noexcept_ref") { + const method_info mi = db.get_method_by_path("clazz::const_method_noexcept_ref"); + REQUIRE(mi); + + const method_info mi2 = db.get_method_by_path("clazz::const_method_noexcept_ref_volatile"); + REQUIRE(mi2); + + { + CHECK(mi.type().arity() == 0); + CHECK(mi.type().class_type() == type_db::get()); + CHECK(mi.type().return_type() == type_db::get()); + CHECK(mi.type().flags() == (method_flags::is_const | method_flags::is_noexcept | method_flags::is_lvalue_qualified)); + + CHECK(mi2.type().arity() == 0); + CHECK(mi2.type().class_type() == type_db::get()); + CHECK(mi2.type().return_type() == type_db::get()); + CHECK(mi2.type().flags() == (method_flags::is_const | method_flags::is_noexcept | method_flags::is_volatile | method_flags::is_lvalue_qualified)); + } + + { + CHECK(mi.is_invocable_with()); + CHECK(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + + CHECK(mi2.is_invocable_with()); + CHECK(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); + } + + { + clazz cl; + + CHECK(mi.invoke(cl)->equals(8)); + CHECK(mi.invoke(std::as_const(cl))->equals(8)); + CHECK_THROWS(mi.invoke(std::move(cl))); + CHECK_THROWS(mi.invoke(std::move(std::as_const(cl)))); + + CHECK(mi2.invoke(cl)->equals(8)); + CHECK(mi2.invoke(std::as_const(cl))->equals(8)); + CHECK_THROWS(mi2.invoke(std::move(cl))); + CHECK_THROWS(mi2.invoke(std::move(std::as_const(cl)))); + } + + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); + + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); + } + + SUBCASE("non_const_method_rref") { + const method_info mi = db.get_method_by_path("clazz::non_const_method_rref"); + REQUIRE(mi); + + const method_info mi2 = db.get_method_by_path("clazz::non_const_method_rref_volatile"); + REQUIRE(mi2); + + { + CHECK(mi.type().arity() == 0); + CHECK(mi.type().class_type() == type_db::get()); + CHECK(mi.type().return_type() == type_db::get()); + CHECK(mi.type().flags() == method_flags::is_rvalue_qualified); + + CHECK(mi2.type().arity() == 0); + CHECK(mi2.type().class_type() == type_db::get()); + CHECK(mi2.type().return_type() == type_db::get()); + CHECK(mi2.type().flags() == (method_flags::is_volatile | method_flags::is_rvalue_qualified)); + } + + { + CHECK_FALSE(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + CHECK(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + + CHECK_FALSE(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); + CHECK(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); + } + + { + clazz cl; + + CHECK_THROWS(mi.invoke(cl)); + CHECK_THROWS(mi.invoke(std::as_const(cl))); + CHECK(mi.invoke(std::move(cl))->equals(9)); + CHECK_THROWS(mi.invoke(std::move(std::as_const(cl)))); + + CHECK_THROWS(mi2.invoke(cl)); + CHECK_THROWS(mi2.invoke(std::as_const(cl))); + CHECK(mi2.invoke(std::move(cl))->equals(9)); + CHECK_THROWS(mi2.invoke(std::move(std::as_const(cl)))); + } + + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + } + + SUBCASE("non_const_method_noexcept_rref") { + const method_info mi = db.get_method_by_path("clazz::non_const_method_noexcept_rref"); + REQUIRE(mi); + + const method_info mi2 = db.get_method_by_path("clazz::non_const_method_noexcept_rref_volatile"); + REQUIRE(mi2); + + { + CHECK(mi.type().arity() == 0); + CHECK(mi.type().class_type() == type_db::get()); + CHECK(mi.type().return_type() == type_db::get()); + CHECK(mi.type().flags() == (method_flags::is_noexcept | method_flags::is_rvalue_qualified)); + + CHECK(mi2.type().arity() == 0); + CHECK(mi2.type().class_type() == type_db::get()); + CHECK(mi2.type().return_type() == type_db::get()); + CHECK(mi2.type().flags() == (method_flags::is_noexcept | method_flags::is_volatile | method_flags::is_rvalue_qualified)); + } + + { + CHECK_FALSE(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + CHECK(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + + CHECK_FALSE(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); + CHECK(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); + } + + { + clazz cl; + + CHECK_THROWS(mi.invoke(cl)); + CHECK_THROWS(mi.invoke(std::as_const(cl))); + CHECK(mi.invoke(std::move(cl))->equals(10)); + CHECK_THROWS(mi.invoke(std::move(std::as_const(cl)))); + + CHECK_THROWS(mi2.invoke(cl)); + CHECK_THROWS(mi2.invoke(std::as_const(cl))); + CHECK(mi2.invoke(std::move(cl))->equals(10)); + CHECK_THROWS(mi2.invoke(std::move(std::as_const(cl)))); + } + + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + } + + SUBCASE("const_method_rref") { + const method_info mi = db.get_method_by_path("clazz::const_method_rref"); + REQUIRE(mi); + + const method_info mi2 = db.get_method_by_path("clazz::const_method_rref_volatile"); + REQUIRE(mi2); + + { + CHECK(mi.type().arity() == 0); + CHECK(mi.type().class_type() == type_db::get()); + CHECK(mi.type().return_type() == type_db::get()); + CHECK(mi.type().flags() == (method_flags::is_const | method_flags::is_rvalue_qualified)); + + CHECK(mi2.type().arity() == 0); + CHECK(mi2.type().class_type() == type_db::get()); + CHECK(mi2.type().return_type() == type_db::get()); + CHECK(mi2.type().flags() == (method_flags::is_const | method_flags::is_volatile | method_flags::is_rvalue_qualified)); + } + + { + CHECK_FALSE(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + CHECK(mi.is_invocable_with()); + CHECK(mi.is_invocable_with()); + + CHECK_FALSE(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); + CHECK(mi2.is_invocable_with()); + CHECK(mi2.is_invocable_with()); + } + + { + clazz cl; + + CHECK_THROWS(mi.invoke(cl)); + CHECK_THROWS(mi.invoke(std::as_const(cl))); + CHECK(mi.invoke(std::move(cl))->equals(11)); + CHECK(mi.invoke(std::move(std::as_const(cl)))->equals(11)); + + CHECK_THROWS(mi2.invoke(cl)); + CHECK_THROWS(mi2.invoke(std::as_const(cl))); + CHECK(mi2.invoke(std::move(cl))->equals(11)); + CHECK(mi2.invoke(std::move(std::as_const(cl)))->equals(11)); + } + + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + } + + SUBCASE("const_method_noexcept_rref") { + const method_info mi = db.get_method_by_path("clazz::const_method_noexcept_rref"); + REQUIRE(mi); + + const method_info mi2 = db.get_method_by_path("clazz::const_method_noexcept_rref_volatile"); + REQUIRE(mi2); + + { + CHECK(mi.type().arity() == 0); + CHECK(mi.type().class_type() == type_db::get()); + CHECK(mi.type().return_type() == type_db::get()); + CHECK(mi.type().flags() == (method_flags::is_const | method_flags::is_noexcept | method_flags::is_rvalue_qualified)); + + CHECK(mi2.type().arity() == 0); + CHECK(mi2.type().class_type() == type_db::get()); + CHECK(mi2.type().return_type() == type_db::get()); + CHECK(mi2.type().flags() == (method_flags::is_const | method_flags::is_noexcept | method_flags::is_volatile | method_flags::is_rvalue_qualified)); + } + + { + CHECK_FALSE(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + CHECK(mi.is_invocable_with()); + CHECK(mi.is_invocable_with()); + + CHECK_FALSE(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); + CHECK(mi2.is_invocable_with()); + CHECK(mi2.is_invocable_with()); + } + + { + clazz cl; + + CHECK_THROWS(mi.invoke(cl)); + CHECK_THROWS(mi.invoke(std::as_const(cl))); + CHECK(mi.invoke(std::move(cl))->equals(12)); + CHECK(mi.invoke(std::move(std::as_const(cl)))->equals(12)); + + CHECK_THROWS(mi2.invoke(cl)); + CHECK_THROWS(mi2.invoke(std::as_const(cl))); + CHECK(mi2.invoke(std::move(cl))->equals(12)); + CHECK(mi2.invoke(std::move(std::as_const(cl)))->equals(12)); + } + + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + } } diff --git a/untests/features/utilities/inst_tests.cpp b/untests/features/utilities/inst_tests.cpp new file mode 100644 index 0000000..a260ac5 --- /dev/null +++ b/untests/features/utilities/inst_tests.cpp @@ -0,0 +1,76 @@ +/******************************************************************************* + * 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 "_utilities_fwd.hpp" + +namespace +{ + using namespace meta_hpp; + using namespace std::string_literals; +} + +namespace +{ + struct ivec2 { + int x{}; + int y{}; + + [[maybe_unused]] ivec2() = default; + [[maybe_unused]] explicit ivec2(int v): x{v}, y{v} {} + [[maybe_unused]] ivec2(int x, int y): x{x}, y{y} {} + + [[maybe_unused]] ivec2(ivec2&& other) noexcept { + x = other.x; + y = other.y; + other.x = 0; + other.y = 0; + } + + [[maybe_unused]] ivec2(const ivec2& other) noexcept { + x = other.x; + y = other.y; + } + + ivec2& operator=(ivec2&&) = delete; + ivec2& operator=(const ivec2&) = delete; + }; +} + +TEST_CASE("features/utilities/inst/type") { + SUBCASE("ref") { + ivec2 v{1,2}; + ivec2& vr = v; + inst a{vr}; + + CHECK(a.raw_type() == type_db::get()); + CHECK(a.ref_type() == inst::ref_types::ref); + } + + SUBCASE("cref") { + const ivec2 v{1,2}; + const ivec2& vr = v; + inst a{vr}; + + CHECK(a.raw_type() == type_db::get()); + CHECK(a.ref_type() == inst::ref_types::cref); + } + + SUBCASE("rref") { + ivec2 v{1,2}; + inst a{std::move(v)}; + + CHECK(a.raw_type() == type_db::get()); + CHECK(a.ref_type() == inst::ref_types::rref); + } + + SUBCASE("crref") { + const ivec2 v{1,2}; + inst a{std::move(v)}; + + CHECK(a.raw_type() == type_db::get()); + CHECK(a.ref_type() == inst::ref_types::crref); + } +} diff --git a/untests/features/utilities/value_tests.cpp b/untests/features/utilities/value_tests.cpp index 6d75029..cf33cb0 100644 --- a/untests/features/utilities/value_tests.cpp +++ b/untests/features/utilities/value_tests.cpp @@ -10,14 +10,17 @@ namespace { using namespace meta_hpp; using namespace std::string_literals; +} +namespace +{ struct ivec2 { int x{}; int y{}; - ivec2() = default; - explicit ivec2(int v): x{v}, y{v} {} - ivec2(int x, int y): x{x}, y{y} {} + [[maybe_unused]] ivec2() = default; + [[maybe_unused]] explicit ivec2(int v): x{v}, y{v} {} + [[maybe_unused]] ivec2(int x, int y): x{x}, y{y} {} ivec2(ivec2&& other) noexcept : x{other.x} From beef317a591e8b872aa08271fa938e86fad40e35 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 13 Aug 2021 14:00:11 +0700 Subject: [PATCH 097/233] msvc fixes --- CMakeLists.txt | 3 +++ headers/meta.hpp/meta_infos/ctor_info.hpp | 16 ++++++++++++---- headers/meta.hpp/meta_infos/function_info.hpp | 16 ++++++++++++---- headers/meta.hpp/meta_infos/method_info.hpp | 16 ++++++++++++---- headers/meta.hpp/meta_utilities/arg.hpp | 12 ++++++++---- headers/meta.hpp/meta_utilities/inst.hpp | 6 ++++-- untests/features/infos/method_info_tests.cpp | 8 ++++---- untests/features/utilities/value_tests.cpp | 2 +- 8 files changed, 56 insertions(+), 23 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fd019e6..eccb5c1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,6 +19,9 @@ target_include_directories(${PROJECT_NAME} INTERFACE headers) target_compile_options(${PROJECT_NAME} INTERFACE + $<$: + /wd4702> + INTERFACE $<$,$>: -Wno-c++98-compat-pedantic -Wno-covered-switch-default diff --git a/headers/meta.hpp/meta_infos/ctor_info.hpp b/headers/meta.hpp/meta_infos/ctor_info.hpp index b294216..c0d237d 100644 --- a/headers/meta.hpp/meta_infos/ctor_info.hpp +++ b/headers/meta.hpp/meta_infos/ctor_info.hpp @@ -153,14 +153,22 @@ namespace meta_hpp template < typename... Args > value ctor_info::invoke(Args&&... args) const { - std::array vargs{arg{std::forward(args)}...}; - return state_->invoke(vargs.data(), vargs.size()); + if constexpr ( sizeof...(Args) > 0 ) { + std::array vargs{arg{std::forward(args)}...}; + return state_->invoke(vargs.data(), vargs.size()); + } else { + return state_->invoke(nullptr, 0); + } } template < typename... Args > bool ctor_info::is_invocable_with() const noexcept { - std::array arg_bases{arg_base{typename_arg}...}; - return state_->is_invocable_with(arg_bases.data(), arg_bases.size()); + if constexpr ( sizeof...(Args) > 0 ) { + std::array arg_bases{arg_base{typename_arg}...}; + return state_->is_invocable_with(arg_bases.data(), arg_bases.size()); + } else { + return state_->is_invocable_with(nullptr, 0); + } } } diff --git a/headers/meta.hpp/meta_infos/function_info.hpp b/headers/meta.hpp/meta_infos/function_info.hpp index 065409c..1303050 100644 --- a/headers/meta.hpp/meta_infos/function_info.hpp +++ b/headers/meta.hpp/meta_infos/function_info.hpp @@ -169,14 +169,22 @@ namespace meta_hpp template < typename... Args > std::optional function_info::invoke(Args&&... args) const { - std::array vargs{arg{std::forward(args)}...}; - return state_->invoke(vargs.data(), vargs.size()); + if constexpr ( sizeof...(Args) > 0 ) { + std::array vargs{arg{std::forward(args)}...}; + return state_->invoke(vargs.data(), vargs.size()); + } else { + return state_->invoke(nullptr, 0); + } } template < typename... Args > bool function_info::is_invocable_with() const noexcept { - std::array arg_bases{arg_base{typename_arg}...}; - return state_->is_invocable_with(arg_bases.data(), arg_bases.size()); + if constexpr ( sizeof...(Args) > 0 ) { + std::array arg_bases{arg_base{typename_arg}...}; + return state_->is_invocable_with(arg_bases.data(), arg_bases.size()); + } else { + return state_->is_invocable_with(nullptr, 0); + } } } diff --git a/headers/meta.hpp/meta_infos/method_info.hpp b/headers/meta.hpp/meta_infos/method_info.hpp index c266a7e..c2cf42f 100644 --- a/headers/meta.hpp/meta_infos/method_info.hpp +++ b/headers/meta.hpp/meta_infos/method_info.hpp @@ -185,14 +185,22 @@ namespace meta_hpp template < typename Instance, typename... Args > std::optional method_info::invoke(Instance&& instance, Args&&... args) const { - std::array vargs{arg{std::forward(args)}...}; - return state_->invoke(inst{std::forward(instance)}, vargs.data(), vargs.size()); + if constexpr ( sizeof...(Args) > 0 ) { + std::array vargs{arg{std::forward(args)}...}; + return state_->invoke(inst{std::forward(instance)}, vargs.data(), vargs.size()); + } else { + return state_->invoke(inst{std::forward(instance)}, nullptr, 0); + } } template < typename Inst, typename... Args > bool method_info::is_invocable_with() const noexcept { - std::array arg_bases{arg_base{typename_arg}...}; - return state_->is_invocable_with(inst_base{typename_arg}, arg_bases.data(), arg_bases.size()); + if constexpr ( sizeof...(Args) > 0 ) { + std::array arg_bases{arg_base{typename_arg}...}; + return state_->is_invocable_with(inst_base{typename_arg}, arg_bases.data(), arg_bases.size()); + } else { + return state_->is_invocable_with(inst_base{typename_arg}, nullptr, 0); + } } } diff --git a/headers/meta.hpp/meta_utilities/arg.hpp b/headers/meta.hpp/meta_utilities/arg.hpp index e943fee..4cedebf 100644 --- a/headers/meta.hpp/meta_utilities/arg.hpp +++ b/headers/meta.hpp/meta_utilities/arg.hpp @@ -105,13 +105,17 @@ namespace meta_hpp if constexpr ( std::is_reference_v ) { constexpr bool to_const = std::is_const_v>; - if ( !to_const && is_const() ) { - return false; + if constexpr ( !to_const ) { + if ( is_const() ) { + return false; + } } if constexpr ( std::is_lvalue_reference_v ) { - if ( !to_const && is_rvalue() ) { - return false; + if constexpr ( !to_const ) { + if ( is_rvalue() ) { + return false; + } } } diff --git a/headers/meta.hpp/meta_utilities/inst.hpp b/headers/meta.hpp/meta_utilities/inst.hpp index b6f6557..7d68a5a 100644 --- a/headers/meta.hpp/meta_utilities/inst.hpp +++ b/headers/meta.hpp/meta_utilities/inst.hpp @@ -101,8 +101,10 @@ namespace meta_hpp constexpr bool to_const = std::is_const_v>; - if ( !to_const && is_const() ) { - return false; + if constexpr ( !to_const ) { + if ( is_const() ) { + return false; + } } if constexpr ( std::is_lvalue_reference_v ) { diff --git a/untests/features/infos/method_info_tests.cpp b/untests/features/infos/method_info_tests.cpp index e8e9d49..0c8030b 100644 --- a/untests/features/infos/method_info_tests.cpp +++ b/untests/features/infos/method_info_tests.cpp @@ -495,8 +495,8 @@ TEST_CASE("features/infos/method") { static_assert(std::is_invocable_v); static_assert(std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(!std::is_invocable_v); + //static_assert(!std::is_invocable_v); // msvc issue + //static_assert(!std::is_invocable_v); // msvc issue static_assert(std::is_invocable_v); static_assert(std::is_invocable_v); @@ -551,8 +551,8 @@ TEST_CASE("features/infos/method") { static_assert(std::is_invocable_v); static_assert(std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(!std::is_invocable_v); + //static_assert(!std::is_invocable_v); // msvc issue + //static_assert(!std::is_invocable_v); // msvc issue static_assert(std::is_invocable_v); static_assert(std::is_invocable_v); diff --git a/untests/features/utilities/value_tests.cpp b/untests/features/utilities/value_tests.cpp index cf33cb0..515755f 100644 --- a/untests/features/utilities/value_tests.cpp +++ b/untests/features/utilities/value_tests.cpp @@ -250,7 +250,7 @@ TEST_CASE("features/utilities/value") { val1.swap(val2); CHECK(val1.equals(ivec2{1,2})); CHECK(val2.equals("world"s)); - CHECK(ivec2::move_ctor_counter == 3); + CHECK((ivec2::move_ctor_counter == 2 || ivec2::move_ctor_counter == 3)); CHECK(ivec2::copy_ctor_counter == 0); swap(val1, val2); From 3f5a579bfaa031dde7071151524c783a77158057 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 13 Aug 2021 16:40:29 +0700 Subject: [PATCH 098/233] fix msvc 2017 --- headers/meta.hpp/meta_fwd.hpp | 2 +- headers/meta.hpp/meta_utilities/value.hpp | 45 ++++++++++++++++++----- 2 files changed, 36 insertions(+), 11 deletions(-) diff --git a/headers/meta.hpp/meta_fwd.hpp b/headers/meta.hpp/meta_fwd.hpp index 56d9acc..6dae7dc 100644 --- a/headers/meta.hpp/meta_fwd.hpp +++ b/headers/meta.hpp/meta_fwd.hpp @@ -115,7 +115,7 @@ namespace meta_hpp struct typename_arg_t {}; template < typename... Args > - inline constexpr typename_arg_t typename_arg; + inline constexpr typename_arg_t typename_arg{}; } namespace meta_hpp::stdex diff --git a/headers/meta.hpp/meta_utilities/value.hpp b/headers/meta.hpp/meta_utilities/value.hpp index db32a16..a0c9ad9 100644 --- a/headers/meta.hpp/meta_utilities/value.hpp +++ b/headers/meta.hpp/meta_utilities/value.hpp @@ -8,6 +8,39 @@ #include "../meta_fwd.hpp" +namespace meta_hpp::detail +{ + template < typename T, typename = void > + struct has_value_type_equality_operator + : std::false_type {}; + + template < typename T > + struct has_value_type_equality_operator().cast() == std::declval().cast() + )>> : std::true_type {}; + + template < typename T > + inline constexpr bool has_value_type_equality_operator_v = has_value_type_equality_operator::value; + + template < typename T, std::enable_if_t< + has_value_type_equality_operator_v + , int> = 0 > + bool value_equality_function(const value& l, const value& r) { + return l.type() == r.type() + && l.cast() == r.cast(); + } + + template < typename T, std::enable_if_t< + !has_value_type_equality_operator_v + , int> = 0 > + bool value_equality_function(const value& l, const value& r) { + if ( l.type() != r.type() ) { + return false; + } + throw std::logic_error("value type doesn't have equality operator"); + } +} + namespace meta_hpp { class value final { @@ -104,16 +137,8 @@ namespace meta_hpp }, // equals - +[](const value& l, const value& r) -> bool { - if ( l.type() != r.type() ) { - return false; - } - if constexpr ( std::is_invocable_v, const T&, const T&> ) { - return std::equal_to<>{}(l.cast(), r.cast()); - } else { - throw std::logic_error("value type doesn't have equality operator"); - } - }, + + &detail::value_equality_function, // move_ctor +[](std::any& dst, value&& src) { From f229d992dfb09ff4f193a9a9544882cd0f2e0406 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 13 Aug 2021 16:47:01 +0700 Subject: [PATCH 099/233] fix clang --- headers/meta.hpp/meta_utilities/value.hpp | 66 +++++++++++------------ 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/headers/meta.hpp/meta_utilities/value.hpp b/headers/meta.hpp/meta_utilities/value.hpp index a0c9ad9..956091d 100644 --- a/headers/meta.hpp/meta_utilities/value.hpp +++ b/headers/meta.hpp/meta_utilities/value.hpp @@ -8,39 +8,6 @@ #include "../meta_fwd.hpp" -namespace meta_hpp::detail -{ - template < typename T, typename = void > - struct has_value_type_equality_operator - : std::false_type {}; - - template < typename T > - struct has_value_type_equality_operator().cast() == std::declval().cast() - )>> : std::true_type {}; - - template < typename T > - inline constexpr bool has_value_type_equality_operator_v = has_value_type_equality_operator::value; - - template < typename T, std::enable_if_t< - has_value_type_equality_operator_v - , int> = 0 > - bool value_equality_function(const value& l, const value& r) { - return l.type() == r.type() - && l.cast() == r.cast(); - } - - template < typename T, std::enable_if_t< - !has_value_type_equality_operator_v - , int> = 0 > - bool value_equality_function(const value& l, const value& r) { - if ( l.type() != r.type() ) { - return false; - } - throw std::logic_error("value type doesn't have equality operator"); - } -} - namespace meta_hpp { class value final { @@ -103,6 +70,39 @@ namespace meta_hpp } } +namespace meta_hpp::detail +{ + template < typename T, typename = void > + struct has_value_type_equality_operator + : std::false_type {}; + + template < typename T > + struct has_value_type_equality_operator().cast() == std::declval().cast() + )>> : std::true_type {}; + + template < typename T > + inline constexpr bool has_value_type_equality_operator_v = has_value_type_equality_operator::value; + + template < typename T, std::enable_if_t< + has_value_type_equality_operator_v + , int> = 0 > + bool value_equality_function(const value& l, const value& r) { + return l.type() == r.type() + && l.cast() == r.cast(); + } + + template < typename T, std::enable_if_t< + !has_value_type_equality_operator_v + , int> = 0 > + bool value_equality_function(const value& l, const value& r) { + if ( l.type() != r.type() ) { + return false; + } + throw std::logic_error("value type doesn't have equality operator"); + } +} + namespace meta_hpp { struct value::traits final { From beb9e6dea3d859886bff9c23c65e172a655fa254 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Mon, 16 Aug 2021 07:34:41 +0700 Subject: [PATCH 100/233] set and get member with static arguments --- headers/meta.hpp/meta_infos/member_info.hpp | 85 ++++++++++- untests/features/infos/member_info_tests.cpp | 149 +++++++++++++++++++ 2 files changed, 229 insertions(+), 5 deletions(-) diff --git a/headers/meta.hpp/meta_infos/member_info.hpp b/headers/meta.hpp/meta_infos/member_info.hpp index a3d1a7d..a1413e9 100644 --- a/headers/meta.hpp/meta_infos/member_info.hpp +++ b/headers/meta.hpp/meta_infos/member_info.hpp @@ -21,6 +21,12 @@ namespace meta_hpp const std::string& name() const noexcept; const member_type& type() const noexcept; + + template < typename Instance > + value get(Instance&& instance) const; + + template < typename Instance, typename Value > + void set(Instance&& instance, Value&& value) const; public: template < typename F > void visit(F&& f) const; @@ -40,12 +46,71 @@ namespace meta_hpp }; } +namespace meta_hpp::detail +{ + using member_getter = std::function; + using member_setter = std::function; + + template < typename Member > + value raw_member_getter(Member member, const inst& inst) { + using mt = member_pointer_traits; + using class_type = typename mt::class_type; + using value_type = typename mt::value_type; + + using qualified_type = const class_type; + + 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(member, inst.cast())}; + return value{std::forward(return_value)}; + } + + template < typename Member > + void raw_member_setter(Member member, const inst& inst, const arg& arg) { + using mt = member_pointer_traits; + 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 ) { + if ( !inst.can_cast_to() ) { + throw std::logic_error("an attempt to set a member with an incorrect instance type"); + } + + if ( !arg.can_cast_to() ) { + throw std::logic_error("an attempt to set a member with an incorrect argument type"); + } + + std::invoke(member, inst.cast()) = arg.cast(); + } else { + throw std::logic_error("an attempt to set a constant member"); + } + } + + template < typename Member > + member_getter make_member_getter(Member member) { + using namespace std::placeholders; + return std::bind(&raw_member_getter, member, _1); + } + + template < typename Member > + member_setter make_member_setter(Member member) { + using namespace std::placeholders; + return std::bind(&raw_member_setter, member, _1, _2); + } +} + namespace meta_hpp { struct member_info::state final { std::string name; member_type type; data_info_map datas; + detail::member_getter getter; + detail::member_setter setter; }; } @@ -67,6 +132,16 @@ namespace meta_hpp inline const member_type& member_info::type() const noexcept { return state_->type; } + + template < typename Instance > + value member_info::get(Instance&& instance) const { + return state_->getter(inst{std::forward(instance)}); + } + + template < typename Instance, typename Value > + void member_info::set(Instance&& instance, Value&& value) const { + state_->setter(inst{std::forward(instance)}, arg{std::forward(value)}); + } } namespace meta_hpp @@ -91,12 +166,12 @@ namespace meta_hpp namespace meta_hpp { template < typename Member > - member_info::member_info(std::string name, Member instance) + member_info::member_info(std::string name, Member member) : state_{std::make_shared(state{ std::move(name), type_db::get().template as(), - {} - })} { - (void)instance; - } + {}, + detail::make_member_getter(member), + detail::make_member_setter(member), + })} {} } diff --git a/untests/features/infos/member_info_tests.cpp b/untests/features/infos/member_info_tests.cpp index 31db3d2..c43b170 100644 --- a/untests/features/infos/member_info_tests.cpp +++ b/untests/features/infos/member_info_tests.cpp @@ -8,7 +8,156 @@ namespace { + using namespace meta_hpp; + using namespace std::string_literals; +} + +namespace +{ + struct ivec2 { + int x{}; + int y{}; + + [[maybe_unused]] ivec2() = default; + [[maybe_unused]] explicit ivec2(int v): x{v}, y{v} {} + [[maybe_unused]] ivec2(int x, int y): x{x}, y{y} {} + }; + + struct ipnt2 { + const int x{}; + const int y{}; + + [[maybe_unused]] ipnt2() = default; + [[maybe_unused]] explicit ipnt2(int v): x{v}, y{v} {} + [[maybe_unused]] ipnt2(int x, int y): x{x}, y{y} {} + }; + + bool operator==(const ivec2& l, const ivec2& r) noexcept { + return l.x == r.x && l.y == r.y; + } + + bool operator==(const ipnt2& l, const ipnt2& r) noexcept { + return l.x == r.x && l.y == r.y; + } } TEST_CASE("features/infos/member") { + registry db; + + db( + namespace_{"vmath"}( + class_{"ivec2"}( + member_{"x", &ivec2::x}, + member_{"y", &ivec2::y} + ), + class_{"ipnt2"}( + member_{"x", &ipnt2::x}, + member_{"y", &ipnt2::y} + ) + ) + ); + + SUBCASE("non_const") { + const member_info x_mi = db.get_member_by_path("vmath::ivec2::x"); + const member_info y_mi = db.get_member_by_path("vmath::ivec2::y"); + REQUIRE(x_mi); + REQUIRE(y_mi); + + { + CHECK(x_mi.name() == "x"); + CHECK(x_mi.type().class_type() == type_db::get()); + CHECK(x_mi.type().value_type() == type_db::get()); + + CHECK(y_mi.name() == "y"); + CHECK(y_mi.type().class_type() == type_db::get()); + CHECK(y_mi.type().value_type() == type_db::get()); + } + + { + ivec2 v{1,2}; + + CHECK(x_mi.get(v).equals(1)); + CHECK(x_mi.get(std::as_const(v)).equals(1)); + CHECK(x_mi.get(std::move(v)).equals(1)); + CHECK(x_mi.get(std::move(std::as_const(v))).equals(1)); + + CHECK(y_mi.get(v).equals(2)); + CHECK(y_mi.get(std::as_const(v)).equals(2)); + CHECK(y_mi.get(std::move(v)).equals(2)); + CHECK(y_mi.get(std::move(std::as_const(v))).equals(2)); + + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + } + + { + ivec2 v{1,2}; + + CHECK_NOTHROW(x_mi.set(v, 10)); CHECK(v.x == 10); + CHECK_THROWS(x_mi.set(std::as_const(v), 11)); CHECK(v.x == 10); + CHECK_NOTHROW(x_mi.set(std::move(v), 12)); CHECK(v.x == 12); + CHECK_THROWS(x_mi.set(std::move(std::as_const(v)), 13)); CHECK(v.x == 12); + + CHECK_NOTHROW(y_mi.set(v, 20)); CHECK(v.y == 20); + CHECK_THROWS(y_mi.set(std::as_const(v), 21)); CHECK(v.y == 20); + CHECK_NOTHROW(y_mi.set(std::move(v), 22)); CHECK(v.y == 22); + CHECK_THROWS(y_mi.set(std::move(std::as_const(v)), 23)); CHECK(v.y == 22); + + CHECK(v == ivec2{12,22}); + } + } + + SUBCASE("const") { + const member_info x_mi = db.get_member_by_path("vmath::ipnt2::x"); + const member_info y_mi = db.get_member_by_path("vmath::ipnt2::y"); + REQUIRE(x_mi); + REQUIRE(y_mi); + + { + CHECK(x_mi.name() == "x"); + CHECK(x_mi.type().class_type() == type_db::get()); + CHECK(x_mi.type().value_type() == type_db::get()); + + CHECK(y_mi.name() == "y"); + CHECK(y_mi.type().class_type() == type_db::get()); + CHECK(y_mi.type().value_type() == type_db::get()); + } + + { + ipnt2 v{1,2}; + + CHECK(x_mi.get(v).equals(1)); + CHECK(x_mi.get(std::as_const(v)).equals(1)); + CHECK(x_mi.get(std::move(v)).equals(1)); + CHECK(x_mi.get(std::move(std::as_const(v))).equals(1)); + + CHECK(y_mi.get(v).equals(2)); + CHECK(y_mi.get(std::as_const(v)).equals(2)); + CHECK(y_mi.get(std::move(v)).equals(2)); + CHECK(y_mi.get(std::move(std::as_const(v))).equals(2)); + + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + } + + { + ipnt2 v{1,2}; + + CHECK_THROWS(x_mi.set(v, 10)); CHECK(v.x == 1); + CHECK_THROWS(x_mi.set(std::as_const(v), 11)); CHECK(v.x == 1); + CHECK_THROWS(x_mi.set(std::move(v), 12)); CHECK(v.x == 1); + CHECK_THROWS(x_mi.set(std::move(std::as_const(v)), 13)); CHECK(v.x == 1); + + CHECK_THROWS(y_mi.set(v, 20)); CHECK(v.y == 2); + CHECK_THROWS(y_mi.set(std::as_const(v), 21)); CHECK(v.y == 2); + CHECK_THROWS(y_mi.set(std::move(v), 22)); CHECK(v.y == 2); + CHECK_THROWS(y_mi.set(std::move(std::as_const(v)), 23)); CHECK(v.y == 2); + + CHECK(v == ipnt2{1,2}); + } + } } From 044590e782d3df38a3c52017c819280cb493fb16 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Mon, 16 Aug 2021 08:03:46 +0700 Subject: [PATCH 101/233] disable recursive wrapper types --- headers/meta.hpp/meta_utilities/arg.hpp | 10 ++++++++-- headers/meta.hpp/meta_utilities/inst.hpp | 16 ++++++++-------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/headers/meta.hpp/meta_utilities/arg.hpp b/headers/meta.hpp/meta_utilities/arg.hpp index 4cedebf..9364d60 100644 --- a/headers/meta.hpp/meta_utilities/arg.hpp +++ b/headers/meta.hpp/meta_utilities/arg.hpp @@ -164,7 +164,10 @@ namespace meta_hpp arg(const arg&) = delete; arg& operator=(const arg&) = delete; - template < typename T > + template < typename T + , std::enable_if_t, arg>, int> = 0 + , std::enable_if_t, inst>, int> = 0 + , std::enable_if_t, value>, int> = 0 > explicit arg(T&& v); template < typename To > @@ -176,7 +179,10 @@ namespace meta_hpp namespace meta_hpp { - template < typename T > + template < typename T + , std::enable_if_t, arg>, int> + , std::enable_if_t, inst>, int> + , std::enable_if_t, value>, int> > arg::arg(T&& v) : arg_base{typename_arg} , data_{const_cast*>(std::addressof(v))} {} diff --git a/headers/meta.hpp/meta_utilities/inst.hpp b/headers/meta.hpp/meta_utilities/inst.hpp index 7d68a5a..9e94ee5 100644 --- a/headers/meta.hpp/meta_utilities/inst.hpp +++ b/headers/meta.hpp/meta_utilities/inst.hpp @@ -136,10 +136,10 @@ namespace meta_hpp inst(const inst&) = delete; inst& operator=(const inst&) = delete; - template < typename T, std::enable_if_t< - std::is_class_v || - (std::is_reference_v && std::is_class_v>) - , int> = 0 > + template < typename T + , std::enable_if_t, arg>, int> = 0 + , std::enable_if_t, inst>, int> = 0 + , std::enable_if_t, value>, int> = 0 > explicit inst(T&& v); template < typename To > @@ -151,10 +151,10 @@ namespace meta_hpp namespace meta_hpp { - template < typename T, std::enable_if_t< - std::is_class_v || - (std::is_reference_v && std::is_class_v>) - , int> > + template < typename T + , std::enable_if_t, arg>, int> + , std::enable_if_t, inst>, int> + , std::enable_if_t, value>, int> > inst::inst(T&& v) : inst_base{typename_arg} , data_{const_cast*>(std::addressof(v))} {} From 0e15e522720d0b626d32f27f354eba3c7fea835f Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Mon, 16 Aug 2021 08:08:46 +0700 Subject: [PATCH 102/233] fix unused warning --- headers/meta.hpp/meta_infos/class_info.hpp | 23 +++++++++++++++++---- headers/meta.hpp/meta_infos/member_info.hpp | 2 +- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/headers/meta.hpp/meta_infos/class_info.hpp b/headers/meta.hpp/meta_infos/class_info.hpp index 90d2af6..7e861db 100644 --- a/headers/meta.hpp/meta_infos/class_info.hpp +++ b/headers/meta.hpp/meta_infos/class_info.hpp @@ -34,9 +34,10 @@ namespace meta_hpp template < typename... Args > ctor_info get_ctor_by_args() const noexcept; - template < std::size_t Args > - ctor_info get_ctor_by_args(const std::array& args) const noexcept; + template < std::size_t N > + ctor_info get_ctor_by_args(const std::array& args) const noexcept; ctor_info get_ctor_by_args(const std::vector& args) const noexcept; + ctor_info get_ctor_by_args(std::initializer_list args) const noexcept; public: template < typename F > void visit(F&& f) const; @@ -137,8 +138,8 @@ namespace meta_hpp return get_ctor_by_args(args); } - template < std::size_t Args > - ctor_info class_info::get_ctor_by_args(const std::array& args) const noexcept { + template < std::size_t N > + ctor_info class_info::get_ctor_by_args(const std::array& args) const noexcept { for ( auto&& id_info : state_->ctors ) { const std::vector& ctor_args = id_info.second.type().argument_types(); @@ -165,6 +166,20 @@ namespace meta_hpp } return ctor_info{}; } + + inline ctor_info class_info::get_ctor_by_args(std::initializer_list args) const noexcept { + for ( auto&& id_info : state_->ctors ) { + const std::vector& ctor_args = + id_info.second.type().argument_types(); + + if ( args.size() == ctor_args.size() + && std::equal(args.begin(), args.end(), ctor_args.begin()) ) + { + return id_info.second; + } + } + return ctor_info{}; + } } namespace meta_hpp diff --git a/headers/meta.hpp/meta_infos/member_info.hpp b/headers/meta.hpp/meta_infos/member_info.hpp index a1413e9..3d5a956 100644 --- a/headers/meta.hpp/meta_infos/member_info.hpp +++ b/headers/meta.hpp/meta_infos/member_info.hpp @@ -68,7 +68,7 @@ namespace meta_hpp::detail } template < typename Member > - void raw_member_setter(Member member, const inst& inst, const arg& arg) { + void raw_member_setter([[maybe_unused]] Member member, const inst& inst, const arg& arg) { using mt = member_pointer_traits; using class_type = typename mt::class_type; using value_type = typename mt::value_type; From b78ea6d0d4f18ec58ec215865f51b24ba97fa5db Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Mon, 16 Aug 2021 08:47:54 +0700 Subject: [PATCH 103/233] arg and inst from value --- headers/meta.hpp/meta_infos/member_info.hpp | 4 ++ headers/meta.hpp/meta_utilities/arg.hpp | 44 +++++++++++++++++++++ headers/meta.hpp/meta_utilities/inst.hpp | 44 +++++++++++++++++++++ headers/meta.hpp/meta_utilities/value.hpp | 8 ++++ 4 files changed, 100 insertions(+) diff --git a/headers/meta.hpp/meta_infos/member_info.hpp b/headers/meta.hpp/meta_infos/member_info.hpp index 3d5a956..613ba2a 100644 --- a/headers/meta.hpp/meta_infos/member_info.hpp +++ b/headers/meta.hpp/meta_infos/member_info.hpp @@ -76,6 +76,10 @@ namespace meta_hpp::detail using qualified_type = class_type; if constexpr ( !std::is_const_v ) { + if ( inst.is_const() ) { + throw std::logic_error("an attempt to set a member with an const instance type"); + } + if ( !inst.can_cast_to() ) { throw std::logic_error("an attempt to set a member with an incorrect instance type"); } diff --git a/headers/meta.hpp/meta_utilities/arg.hpp b/headers/meta.hpp/meta_utilities/arg.hpp index 9364d60..ebd63c0 100644 --- a/headers/meta.hpp/meta_utilities/arg.hpp +++ b/headers/meta.hpp/meta_utilities/arg.hpp @@ -8,6 +8,8 @@ #include "../meta_fwd.hpp" +#include "value.hpp" + namespace meta_hpp { class arg_base { @@ -38,6 +40,11 @@ namespace meta_hpp , int> = 0 > explicit arg_base(typename_arg_t); + explicit arg_base(value& v); + explicit arg_base(value&& v); + explicit arg_base(const value& v); + explicit arg_base(const value&& v); + bool is_const() const noexcept; bool is_lvalue() const noexcept; bool is_rvalue() const noexcept; @@ -70,6 +77,22 @@ namespace meta_hpp : raw_type_{type_db::get>()} , ref_type_{std::is_const_v> ? ref_types::crref : ref_types::rref} {} + inline arg_base::arg_base(value& v) + : raw_type_{v.type()} + , ref_type_{ref_types::ref} {} + + inline arg_base::arg_base(value&& v) + : raw_type_{v.type()} + , ref_type_{ref_types::rref} {} + + inline arg_base::arg_base(const value& v) + : raw_type_{v.type()} + , ref_type_{ref_types::cref} {} + + inline arg_base::arg_base(const value&& v) + : raw_type_{v.type()} + , ref_type_{ref_types::crref} {} + inline bool arg_base::is_const() const noexcept { return ref_type_ == ref_types::cref || ref_type_ == ref_types::crref; @@ -170,6 +193,11 @@ namespace meta_hpp , std::enable_if_t, value>, int> = 0 > explicit arg(T&& v); + explicit arg(value& v); + explicit arg(value&& v); + explicit arg(const value& v); + explicit arg(const value&& v); + template < typename To > To cast() const; private: @@ -187,6 +215,22 @@ namespace meta_hpp : arg_base{typename_arg} , data_{const_cast*>(std::addressof(v))} {} + inline arg::arg(value& v) + : arg_base{v} + , data_{const_cast(v.data())} {} + + inline arg::arg(value&& v) + : arg_base{v} + , data_{const_cast(v.data())} {} + + inline arg::arg(const value& v) + : arg_base{v} + , data_{const_cast(v.data())} {} + + inline arg::arg(const value&& v) + : arg_base{v} + , data_{const_cast(v.data())} {} + template < typename To > To arg::cast() const { if ( !can_cast_to() ) { diff --git a/headers/meta.hpp/meta_utilities/inst.hpp b/headers/meta.hpp/meta_utilities/inst.hpp index 9e94ee5..a3ca89b 100644 --- a/headers/meta.hpp/meta_utilities/inst.hpp +++ b/headers/meta.hpp/meta_utilities/inst.hpp @@ -8,6 +8,8 @@ #include "../meta_fwd.hpp" +#include "value.hpp" + namespace meta_hpp { class inst_base { @@ -38,6 +40,11 @@ namespace meta_hpp , int> = 0> explicit inst_base(typename_arg_t); + explicit inst_base(value& v); + explicit inst_base(value&& v); + explicit inst_base(const value& v); + explicit inst_base(const value&& v); + bool is_const() const noexcept; bool is_lvalue() const noexcept; bool is_rvalue() const noexcept; @@ -70,6 +77,22 @@ namespace meta_hpp : raw_type_{type_db::get>()} , ref_type_{std::is_const_v> ? ref_types::crref : ref_types::rref} {} + inline inst_base::inst_base(value& v) + : raw_type_{v.type()} + , ref_type_{ref_types::ref} {} + + inline inst_base::inst_base(value&& v) + : raw_type_{v.type()} + , ref_type_{ref_types::rref} {} + + inline inst_base::inst_base(const value& v) + : raw_type_{v.type()} + , ref_type_{ref_types::cref} {} + + inline inst_base::inst_base(const value&& v) + : raw_type_{v.type()} + , ref_type_{ref_types::crref} {} + inline bool inst_base::is_const() const noexcept { return ref_type_ == ref_types::cref || ref_type_ == ref_types::crref; @@ -142,6 +165,11 @@ namespace meta_hpp , std::enable_if_t, value>, int> = 0 > explicit inst(T&& v); + explicit inst(value& v); + explicit inst(value&& v); + explicit inst(const value& v); + explicit inst(const value&& v); + template < typename To > decltype(auto) cast() const; private: @@ -159,6 +187,22 @@ namespace meta_hpp : inst_base{typename_arg} , data_{const_cast*>(std::addressof(v))} {} + inline inst::inst(value& v) + : inst_base{v} + , data_{const_cast(v.data())} {} + + inline inst::inst(value&& v) + : inst_base{v} + , data_{const_cast(v.data())} {} + + inline inst::inst(const value& v) + : inst_base{v} + , data_{const_cast(v.data())} {} + + inline inst::inst(const value&& v) + : inst_base{v} + , data_{const_cast(v.data())} {} + template < typename To > decltype(auto) inst::cast() const { if ( !can_cast_to() ) { diff --git a/headers/meta.hpp/meta_utilities/value.hpp b/headers/meta.hpp/meta_utilities/value.hpp index 956091d..fd1bf33 100644 --- a/headers/meta.hpp/meta_utilities/value.hpp +++ b/headers/meta.hpp/meta_utilities/value.hpp @@ -22,11 +22,15 @@ namespace meta_hpp template < typename T , typename Tp = std::decay_t + , std::enable_if_t, int> = 0 + , std::enable_if_t, int> = 0 , std::enable_if_t, int> = 0 > value(T&& val); template < typename T , typename Tp = std::decay_t + , std::enable_if_t, int> = 0 + , std::enable_if_t, int> = 0 , std::enable_if_t, int> = 0 > value& operator=(T&& val); @@ -191,12 +195,16 @@ namespace meta_hpp } template < typename T, typename Tp + , std::enable_if_t, int> + , std::enable_if_t, int> , std::enable_if_t, int> > value::value(T&& val) : raw_{std::forward(val)} , traits_{traits::get()} {} template < typename T, typename Tp + , std::enable_if_t, int> + , std::enable_if_t, int> , std::enable_if_t, int> > value& value::operator=(T&& val) { raw_ = std::forward(val); From a5f999cad9b7c4abf86e584e0065b1e18f47212c Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Mon, 16 Aug 2021 14:10:16 +0700 Subject: [PATCH 104/233] istream and ostream value operators --- headers/meta.hpp/meta_fwd.hpp | 6 ++ headers/meta.hpp/meta_utilities/value.hpp | 92 ++++++++++++++++++++-- untests/features/utilities/value_tests.cpp | 20 +++++ untests/meta_tests.hpp | 2 +- 4 files changed, 114 insertions(+), 6 deletions(-) diff --git a/headers/meta.hpp/meta_fwd.hpp b/headers/meta.hpp/meta_fwd.hpp index 6dae7dc..4ae5f20 100644 --- a/headers/meta.hpp/meta_fwd.hpp +++ b/headers/meta.hpp/meta_fwd.hpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -140,6 +141,11 @@ namespace meta_hpp::stdex }; template < typename T > using remove_cvref_t = typename remove_cvref::type; + + template < typename Enum > + constexpr std::underlying_type_t to_underlying(Enum e) noexcept { + return static_cast>(e); + } } namespace meta_hpp::detail diff --git a/headers/meta.hpp/meta_utilities/value.hpp b/headers/meta.hpp/meta_utilities/value.hpp index fd1bf33..116b3ef 100644 --- a/headers/meta.hpp/meta_utilities/value.hpp +++ b/headers/meta.hpp/meta_utilities/value.hpp @@ -63,6 +63,9 @@ namespace meta_hpp template < typename T, typename Tp = std::decay_t > const Tp* try_cast() const noexcept; + + friend std::istream& operator>>(std::istream& os, value& v); + friend std::ostream& operator<<(std::ostream& os, const value& v); private: struct traits; std::any raw_{}; @@ -82,7 +85,7 @@ namespace meta_hpp::detail template < typename T > struct has_value_type_equality_operator().cast() == std::declval().cast() + std::declval() == std::declval() )>> : std::true_type {}; template < typename T > @@ -91,7 +94,7 @@ namespace meta_hpp::detail template < typename T, std::enable_if_t< has_value_type_equality_operator_v , int> = 0 > - bool value_equality_function(const value& l, const value& r) { + bool value_equals_function(const value& l, const value& r) { return l.type() == r.type() && l.cast() == r.cast(); } @@ -99,7 +102,7 @@ namespace meta_hpp::detail template < typename T, std::enable_if_t< !has_value_type_equality_operator_v , int> = 0 > - bool value_equality_function(const value& l, const value& r) { + bool value_equals_function(const value& l, const value& r) { if ( l.type() != r.type() ) { return false; } @@ -107,6 +110,64 @@ namespace meta_hpp::detail } } +namespace meta_hpp::detail +{ + template < typename T, typename = void > + struct has_value_type_istream_operator + : std::false_type {}; + + template < typename T > + struct has_value_type_istream_operator() >> std::declval() + )>> : std::true_type {}; + + template < typename T > + inline constexpr bool has_value_type_istream_operator_v = has_value_type_istream_operator::value; + + template < typename T, std::enable_if_t< + has_value_type_istream_operator_v + , int> = 0 > + void value_istream_function(std::istream& os, value& v) { + os >> v.cast(); + } + + template < typename T, std::enable_if_t< + !has_value_type_istream_operator_v + , int> = 0 > + void value_istream_function([[maybe_unused]] std::istream& os, [[maybe_unused]] value& v) { + throw std::logic_error("value type doesn't have istream operator"); + } +} + +namespace meta_hpp::detail +{ + template < typename T, typename = void > + struct has_value_type_ostream_operator + : std::false_type {}; + + template < typename T > + struct has_value_type_ostream_operator() << std::declval() + )>> : std::true_type {}; + + template < typename T > + inline constexpr bool has_value_type_ostream_operator_v = has_value_type_ostream_operator::value; + + template < typename T, std::enable_if_t< + has_value_type_ostream_operator_v + , int> = 0 > + void value_ostream_function(std::ostream& os, const value& v) { + os << v.cast(); + } + + template < typename T, std::enable_if_t< + !has_value_type_ostream_operator_v + , int> = 0 > + void value_ostream_function([[maybe_unused]] std::ostream& os, [[maybe_unused]] const value& v) { + throw std::logic_error("value type doesn't have ostream operator"); + } +} + namespace meta_hpp { struct value::traits final { @@ -120,6 +181,9 @@ namespace meta_hpp void (*const move_ctor)(std::any&, value&&); void (*const copy_ctor)(std::any&, const value&); + void (*const istream)(std::istream&, value&); + void (*const ostream)(std::ostream&, const value&); + template < typename T > static const traits* get() noexcept; }; @@ -141,8 +205,7 @@ namespace meta_hpp }, // equals - - &detail::value_equality_function, + &detail::value_equals_function, // move_ctor +[](std::any& dst, value&& src) { @@ -161,6 +224,12 @@ namespace meta_hpp throw std::logic_error("value type is not copy constructible"); } }, + + // istream + &detail::value_istream_function, + + // ostream + &detail::value_ostream_function, }; return &traits; } @@ -286,3 +355,16 @@ namespace meta_hpp return std::any_cast(&raw_); } } + +namespace meta_hpp +{ + inline std::istream& operator>>(std::istream& is, value& v) { + v.traits_->istream(is, v); + return is; + } + + inline std::ostream& operator<<(std::ostream& os, const value& v) { + v.traits_->ostream(os, v); + return os; + } +} diff --git a/untests/features/utilities/value_tests.cpp b/untests/features/utilities/value_tests.cpp index 515755f..0bce6ad 100644 --- a/untests/features/utilities/value_tests.cpp +++ b/untests/features/utilities/value_tests.cpp @@ -257,4 +257,24 @@ TEST_CASE("features/utilities/value") { CHECK(val1.equals("world"s)); CHECK(val2.equals(ivec2{1,2})); } + + SUBCASE("ostream") { + std::stringstream str_stream; + CHECK_NOTHROW(str_stream << value{21} << " " << value{42}); + CHECK_THROWS(str_stream << value{ivec2{1,2}}); + REQUIRE(str_stream.str() == "21 42"); + } + + SUBCASE("istream") { + std::stringstream str_stream{"21 42"}; + + value v{ivec2{1,2}}; + CHECK_THROWS(str_stream >> v); + + v = value{0}; + CHECK_NOTHROW(str_stream >> v); + CHECK(v.equals(21)); + CHECK_NOTHROW(str_stream >> v); + CHECK(v.equals(42)); + } } diff --git a/untests/meta_tests.hpp b/untests/meta_tests.hpp index 32f0e65..62be851 100644 --- a/untests/meta_tests.hpp +++ b/untests/meta_tests.hpp @@ -9,5 +9,5 @@ #include #include -// https://github.com/onqtam/doctest/issues/126 #include +#include From f6fe32e7eb9ce6be09f067d318fde40efbc92d3f Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Mon, 16 Aug 2021 14:37:45 +0700 Subject: [PATCH 105/233] explicit value ctor --- headers/meta.hpp/meta_registry/data_.hpp | 8 +++++--- headers/meta.hpp/meta_utilities/value.hpp | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/headers/meta.hpp/meta_registry/data_.hpp b/headers/meta.hpp/meta_registry/data_.hpp index e07bde2..a91a832 100644 --- a/headers/meta.hpp/meta_registry/data_.hpp +++ b/headers/meta.hpp/meta_registry/data_.hpp @@ -12,7 +12,8 @@ namespace meta_hpp { class data_ final { public: - explicit data_(std::string name, class value value); + template < typename T > + explicit data_(std::string name, T&& value); data_info make_info() const; public: @@ -30,9 +31,10 @@ namespace meta_hpp namespace meta_hpp { - inline data_::data_(std::string name, class value value) + template < typename T > + data_::data_(std::string name, T&& value) : name_{std::move(name)} - , value_{std::move(value)} {} + , value_{std::forward(value)} {} inline data_info data_::make_info() const { data_info info{name_, value_}; diff --git a/headers/meta.hpp/meta_utilities/value.hpp b/headers/meta.hpp/meta_utilities/value.hpp index 116b3ef..5f6f822 100644 --- a/headers/meta.hpp/meta_utilities/value.hpp +++ b/headers/meta.hpp/meta_utilities/value.hpp @@ -25,7 +25,7 @@ namespace meta_hpp , std::enable_if_t, int> = 0 , std::enable_if_t, int> = 0 , std::enable_if_t, int> = 0 > - value(T&& val); + explicit value(T&& val); template < typename T , typename Tp = std::decay_t From f11452ba10c0f6795beabcd6b3a38fc4b88467c1 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Mon, 16 Aug 2021 16:28:23 +0700 Subject: [PATCH 106/233] operator== instead equals function for value --- headers/meta.hpp/meta_utilities/value.hpp | 46 +++++---- untests/features/infos/ctor_info_tests.cpp | 16 ++-- .../features/infos/function_info_tests.cpp | 8 +- untests/features/infos/member_info_tests.cpp | 32 +++---- untests/features/infos/method_info_tests.cpp | 96 +++++++++---------- untests/features/utilities/value_tests.cpp | 66 ++++++++----- 6 files changed, 143 insertions(+), 121 deletions(-) diff --git a/headers/meta.hpp/meta_utilities/value.hpp b/headers/meta.hpp/meta_utilities/value.hpp index 5f6f822..92b49d6 100644 --- a/headers/meta.hpp/meta_utilities/value.hpp +++ b/headers/meta.hpp/meta_utilities/value.hpp @@ -42,10 +42,6 @@ namespace meta_hpp const void* data() const noexcept; const void* cdata() const noexcept; - template < typename T > - bool equals(const T& other) const; - bool equals(const value& other) const; - template < typename T, typename Tp = std::decay_t > Tp& cast() &; @@ -64,6 +60,12 @@ namespace meta_hpp template < typename T, typename Tp = std::decay_t > const Tp* try_cast() const noexcept; + template < typename T > + friend bool operator==(const value& l, const T& r); + template < typename T > + friend bool operator==(const T& l, const value& r); + friend bool operator==(const value& l, const value& r); + friend std::istream& operator>>(std::istream& os, value& v); friend std::ostream& operator<<(std::ostream& os, const value& v); private: @@ -95,17 +97,14 @@ namespace meta_hpp::detail has_value_type_equality_operator_v , int> = 0 > bool value_equals_function(const value& l, const value& r) { - return l.type() == r.type() - && l.cast() == r.cast(); + assert(l.type() == r.type()); + return l.cast() == r.cast(); } template < typename T, std::enable_if_t< !has_value_type_equality_operator_v , int> = 0 > - bool value_equals_function(const value& l, const value& r) { - if ( l.type() != r.type() ) { - return false; - } + bool value_equals_function([[maybe_unused]] const value& l, [[maybe_unused]] const value& r) { throw std::logic_error("value type doesn't have equality operator"); } } @@ -303,16 +302,6 @@ namespace meta_hpp return traits_->cdata(*this); } - template < typename T > - bool value::equals(const T& other) const { - return type() == type_db::get() - && std::equal_to<>{}(cast(), other); - } - - inline bool value::equals(const value& other) const { - return traits_->equals(*this, other); - } - template < typename T, typename Tp > Tp& value::cast() & { if ( type() != type_db::get() ) { @@ -358,6 +347,23 @@ namespace meta_hpp namespace meta_hpp { + template < typename T > + bool operator==(const value& l, const T& r) { + return l.type() == type_db::get() + && std::equal_to<>{}(l.cast(), r); + } + + template < typename T > + bool operator==(const T& l, const value& r) { + return type_db::get() == r.type() + && std::equal_to<>{}(l, r.cast()); + } + + inline bool operator==(const value& l, const value& r) { + return l.type() == r.type() + && l.traits_->equals(l, r); + } + inline std::istream& operator>>(std::istream& is, value& v) { v.traits_->istream(is, v); return is; diff --git a/untests/features/infos/ctor_info_tests.cpp b/untests/features/infos/ctor_info_tests.cpp index 5fa4e57..eb0a78b 100644 --- a/untests/features/infos/ctor_info_tests.cpp +++ b/untests/features/infos/ctor_info_tests.cpp @@ -51,7 +51,7 @@ TEST_CASE("features/infos/ctor") { REQUIRE(ci); REQUIRE(ci.get_data_by_name("info")); - CHECK(ci.get_data_by_name("info").value().equals("void ctor"s)); + CHECK(ci.get_data_by_name("info").value() == "void ctor"s); { const ctor_info ci2 = ivec2_info.get_ctor_by_args(std::array{}); @@ -74,7 +74,7 @@ TEST_CASE("features/infos/ctor") { } { - CHECK(ci.invoke().equals(ivec2{})); + CHECK(ci.invoke() == ivec2{}); CHECK_THROWS(ci.invoke(42)); } } @@ -84,7 +84,7 @@ TEST_CASE("features/infos/ctor") { REQUIRE(ci); REQUIRE(ci.get_data_by_name("info")); - CHECK(ci.get_data_by_name("info").value().equals("int ctor"s)); + CHECK(ci.get_data_by_name("info").value() == "int ctor"s); { const ctor_info ci2 = ivec2_info.get_ctor_by_args(std::array{ @@ -110,7 +110,7 @@ TEST_CASE("features/infos/ctor") { { CHECK_THROWS(ci.invoke()); - CHECK(ci.invoke(42).equals(ivec2{42})); + CHECK(ci.invoke(42) == ivec2{42}); } } @@ -119,7 +119,7 @@ TEST_CASE("features/infos/ctor") { REQUIRE(ci); REQUIRE(ci.get_data_by_name("info")); - CHECK(ci.get_data_by_name("info").value().equals("copy ctor"s)); + CHECK(ci.get_data_by_name("info").value() == "copy ctor"s); { const ctor_info ci2 = ivec2_info.get_ctor_by_args(std::array{ @@ -152,7 +152,7 @@ TEST_CASE("features/infos/ctor") { { CHECK_THROWS(ci.invoke()); CHECK_THROWS(ci.invoke(42)); - CHECK(ci.invoke(ivec2{21,42}).equals(ivec2{21,42})); + CHECK(ci.invoke(ivec2{21,42}) == ivec2{21,42}); } } @@ -161,7 +161,7 @@ TEST_CASE("features/infos/ctor") { REQUIRE(ci); REQUIRE(ci.get_data_by_name("info")); - CHECK(ci.get_data_by_name("info").value().equals("int,int ctor"s)); + CHECK(ci.get_data_by_name("info").value() == "int,int ctor"s); { const ctor_info ci2 = ivec2_info.get_ctor_by_args(std::array{ @@ -195,7 +195,7 @@ TEST_CASE("features/infos/ctor") { CHECK_THROWS(ci.invoke()); CHECK_THROWS(ci.invoke(42)); CHECK_THROWS(ci.invoke(ivec2{21,42})); - CHECK(ci.invoke(21,42).equals(ivec2{21,42})); + CHECK(ci.invoke(21,42) == ivec2{21,42}); } } } diff --git a/untests/features/infos/function_info_tests.cpp b/untests/features/infos/function_info_tests.cpp index dc1b25e..5d0d98e 100644 --- a/untests/features/infos/function_info_tests.cpp +++ b/untests/features/infos/function_info_tests.cpp @@ -53,7 +53,7 @@ TEST_CASE("features/infos/function") { REQUIRE(fi); REQUIRE(fi.get_data_by_name("info")); - CHECK(fi.get_data_by_name("info").value().equals("iadd function"s)); + CHECK(fi.get_data_by_name("info").value() == "iadd function"s); CHECK_FALSE(fi.is_invocable_with()); CHECK_FALSE(fi.is_invocable_with()); @@ -68,7 +68,7 @@ TEST_CASE("features/infos/function") { CHECK_THROWS(fi.invoke(ivec2{}, 42)); CHECK(fi.invoke(ivec2{1,2},ivec2{3,4})); - CHECK(fi.invoke(ivec2{1,2},ivec2{3,4})->equals(ivec2{4,6})); + CHECK(fi.invoke(ivec2{1,2},ivec2{3,4}).value() == ivec2{4,6}); } SUBCASE("ilength2") { @@ -76,7 +76,7 @@ TEST_CASE("features/infos/function") { REQUIRE(fi); REQUIRE(fi.get_data_by_name("info")); - CHECK(fi.get_data_by_name("info").value().equals("ilength2 function"s)); + CHECK(fi.get_data_by_name("info").value() == "ilength2 function"s); CHECK_FALSE(fi.is_invocable_with()); CHECK_FALSE(fi.is_invocable_with()); @@ -90,6 +90,6 @@ TEST_CASE("features/infos/function") { CHECK_THROWS(fi.invoke(ivec2{}, 42)); CHECK(fi.invoke(ivec2{2,3})); - CHECK(fi.invoke(ivec2{2,3})->equals(13)); + CHECK(fi.invoke(ivec2{2,3}).value() == 13); } } diff --git a/untests/features/infos/member_info_tests.cpp b/untests/features/infos/member_info_tests.cpp index c43b170..d4b9c54 100644 --- a/untests/features/infos/member_info_tests.cpp +++ b/untests/features/infos/member_info_tests.cpp @@ -76,15 +76,15 @@ TEST_CASE("features/infos/member") { { ivec2 v{1,2}; - CHECK(x_mi.get(v).equals(1)); - CHECK(x_mi.get(std::as_const(v)).equals(1)); - CHECK(x_mi.get(std::move(v)).equals(1)); - CHECK(x_mi.get(std::move(std::as_const(v))).equals(1)); + CHECK(x_mi.get(v) == 1); + CHECK(x_mi.get(std::as_const(v)) == 1); + CHECK(x_mi.get(std::move(v)) == 1); + CHECK(x_mi.get(std::move(std::as_const(v))) == 1); - CHECK(y_mi.get(v).equals(2)); - CHECK(y_mi.get(std::as_const(v)).equals(2)); - CHECK(y_mi.get(std::move(v)).equals(2)); - CHECK(y_mi.get(std::move(std::as_const(v))).equals(2)); + CHECK(y_mi.get(v) == 2); + CHECK(y_mi.get(std::as_const(v)) == 2); + CHECK(y_mi.get(std::move(v)) == 2); + CHECK(y_mi.get(std::move(std::as_const(v))) == 2); static_assert(std::is_invocable_v); static_assert(std::is_invocable_v); @@ -128,15 +128,15 @@ TEST_CASE("features/infos/member") { { ipnt2 v{1,2}; - CHECK(x_mi.get(v).equals(1)); - CHECK(x_mi.get(std::as_const(v)).equals(1)); - CHECK(x_mi.get(std::move(v)).equals(1)); - CHECK(x_mi.get(std::move(std::as_const(v))).equals(1)); + CHECK(x_mi.get(v) == 1); + CHECK(x_mi.get(std::as_const(v)) == 1); + CHECK(x_mi.get(std::move(v)) == 1); + CHECK(x_mi.get(std::move(std::as_const(v))) == 1); - CHECK(y_mi.get(v).equals(2)); - CHECK(y_mi.get(std::as_const(v)).equals(2)); - CHECK(y_mi.get(std::move(v)).equals(2)); - CHECK(y_mi.get(std::move(std::as_const(v))).equals(2)); + CHECK(y_mi.get(v) == 2); + CHECK(y_mi.get(std::as_const(v)) == 2); + CHECK(y_mi.get(std::move(v)) == 2); + CHECK(y_mi.get(std::move(std::as_const(v))) == 2); static_assert(std::is_invocable_v); static_assert(std::is_invocable_v); diff --git a/untests/features/infos/method_info_tests.cpp b/untests/features/infos/method_info_tests.cpp index 0c8030b..277443c 100644 --- a/untests/features/infos/method_info_tests.cpp +++ b/untests/features/infos/method_info_tests.cpp @@ -146,14 +146,14 @@ TEST_CASE("features/infos/method") { { clazz cl; - CHECK(mi.invoke(cl)->equals(1)); + CHECK(mi.invoke(cl).value() == 1); CHECK_THROWS(mi.invoke(std::as_const(cl))); - CHECK(mi.invoke(std::move(cl))->equals(1)); + CHECK(mi.invoke(std::move(cl)).value() == 1); CHECK_THROWS(mi.invoke(std::move(std::as_const(cl)))); - CHECK(mi2.invoke(cl)->equals(1)); + CHECK(mi2.invoke(cl).value() == 1); CHECK_THROWS(mi2.invoke(std::as_const(cl))); - CHECK(mi2.invoke(std::move(cl))->equals(1)); + CHECK(mi2.invoke(std::move(cl)).value() == 1); CHECK_THROWS(mi2.invoke(std::move(std::as_const(cl)))); } @@ -202,14 +202,14 @@ TEST_CASE("features/infos/method") { { clazz cl; - CHECK(mi.invoke(cl)->equals(2)); + CHECK(mi.invoke(cl).value() == 2); CHECK_THROWS(mi.invoke(std::as_const(cl))); - CHECK(mi.invoke(std::move(cl))->equals(2)); + CHECK(mi.invoke(std::move(cl)).value() == 2); CHECK_THROWS(mi.invoke(std::move(std::as_const(cl)))); - CHECK(mi2.invoke(cl)->equals(2)); + CHECK(mi2.invoke(cl).value() == 2); CHECK_THROWS(mi2.invoke(std::as_const(cl))); - CHECK(mi2.invoke(std::move(cl))->equals(2)); + CHECK(mi2.invoke(std::move(cl)).value() == 2); CHECK_THROWS(mi2.invoke(std::move(std::as_const(cl)))); } @@ -258,15 +258,15 @@ TEST_CASE("features/infos/method") { { clazz cl; - CHECK(mi.invoke(cl)->equals(3)); - CHECK(mi.invoke(std::as_const(cl))->equals(3)); - CHECK(mi.invoke(std::move(cl))->equals(3)); - CHECK(mi.invoke(std::move(std::as_const(cl)))->equals(3)); + CHECK(mi.invoke(cl).value() == 3); + CHECK(mi.invoke(std::as_const(cl)).value() == 3); + CHECK(mi.invoke(std::move(cl)).value() == 3); + CHECK(mi.invoke(std::move(std::as_const(cl))).value() == 3); - CHECK(mi2.invoke(cl)->equals(3)); - CHECK(mi2.invoke(std::as_const(cl))->equals(3)); - CHECK(mi2.invoke(std::move(cl))->equals(3)); - CHECK(mi2.invoke(std::move(std::as_const(cl)))->equals(3)); + CHECK(mi2.invoke(cl).value() == 3); + CHECK(mi2.invoke(std::as_const(cl)).value() == 3); + CHECK(mi2.invoke(std::move(cl)).value() == 3); + CHECK(mi2.invoke(std::move(std::as_const(cl))).value() == 3); } static_assert(std::is_invocable_v); @@ -314,15 +314,15 @@ TEST_CASE("features/infos/method") { { clazz cl; - CHECK(mi.invoke(cl)->equals(4)); - CHECK(mi.invoke(std::as_const(cl))->equals(4)); - CHECK(mi.invoke(std::move(cl))->equals(4)); - CHECK(mi.invoke(std::move(std::as_const(cl)))->equals(4)); + CHECK(mi.invoke(cl).value() == 4); + CHECK(mi.invoke(std::as_const(cl)).value() == 4); + CHECK(mi.invoke(std::move(cl)).value() == 4); + CHECK(mi.invoke(std::move(std::as_const(cl))).value() == 4); - CHECK(mi2.invoke(cl)->equals(4)); - CHECK(mi2.invoke(std::as_const(cl))->equals(4)); - CHECK(mi2.invoke(std::move(cl))->equals(4)); - CHECK(mi2.invoke(std::move(std::as_const(cl)))->equals(4)); + CHECK(mi2.invoke(cl).value() == 4); + CHECK(mi2.invoke(std::as_const(cl)).value() == 4); + CHECK(mi2.invoke(std::move(cl)).value() == 4); + CHECK(mi2.invoke(std::move(std::as_const(cl))).value() == 4); } static_assert(std::is_invocable_v); @@ -370,12 +370,12 @@ TEST_CASE("features/infos/method") { { clazz cl; - CHECK(mi.invoke(cl)->equals(5)); + CHECK(mi.invoke(cl).value() == 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(mi2.invoke(cl)->equals(5)); + CHECK(mi2.invoke(cl).value() == 5); CHECK_THROWS(mi2.invoke(std::as_const(cl))); CHECK_THROWS(mi2.invoke(std::move(cl))); CHECK_THROWS(mi2.invoke(std::move(std::as_const(cl)))); @@ -426,12 +426,12 @@ TEST_CASE("features/infos/method") { { clazz cl; - CHECK(mi.invoke(cl)->equals(6)); + CHECK(mi.invoke(cl).value() == 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(mi2.invoke(cl)->equals(6)); + CHECK(mi2.invoke(cl).value() == 6); CHECK_THROWS(mi2.invoke(std::as_const(cl))); CHECK_THROWS(mi2.invoke(std::move(cl))); CHECK_THROWS(mi2.invoke(std::move(std::as_const(cl)))); @@ -482,13 +482,13 @@ TEST_CASE("features/infos/method") { { clazz cl; - CHECK(mi.invoke(cl)->equals(7)); - CHECK(mi.invoke(std::as_const(cl))->equals(7)); + CHECK(mi.invoke(cl).value() == 7); + CHECK(mi.invoke(std::as_const(cl)).value() == 7); CHECK_THROWS(mi.invoke(std::move(cl))); CHECK_THROWS(mi.invoke(std::move(std::as_const(cl)))); - CHECK(mi2.invoke(cl)->equals(7)); - CHECK(mi2.invoke(std::as_const(cl))->equals(7)); + CHECK(mi2.invoke(cl).value() == 7); + CHECK(mi2.invoke(std::as_const(cl)).value() == 7); CHECK_THROWS(mi2.invoke(std::move(cl))); CHECK_THROWS(mi2.invoke(std::move(std::as_const(cl)))); } @@ -538,13 +538,13 @@ TEST_CASE("features/infos/method") { { clazz cl; - CHECK(mi.invoke(cl)->equals(8)); - CHECK(mi.invoke(std::as_const(cl))->equals(8)); + CHECK(mi.invoke(cl).value() == 8); + CHECK(mi.invoke(std::as_const(cl)).value() == 8); CHECK_THROWS(mi.invoke(std::move(cl))); CHECK_THROWS(mi.invoke(std::move(std::as_const(cl)))); - CHECK(mi2.invoke(cl)->equals(8)); - CHECK(mi2.invoke(std::as_const(cl))->equals(8)); + CHECK(mi2.invoke(cl).value() == 8); + CHECK(mi2.invoke(std::as_const(cl)).value() == 8); CHECK_THROWS(mi2.invoke(std::move(cl))); CHECK_THROWS(mi2.invoke(std::move(std::as_const(cl)))); } @@ -596,12 +596,12 @@ TEST_CASE("features/infos/method") { CHECK_THROWS(mi.invoke(cl)); CHECK_THROWS(mi.invoke(std::as_const(cl))); - CHECK(mi.invoke(std::move(cl))->equals(9)); + CHECK(mi.invoke(std::move(cl)).value() == 9); CHECK_THROWS(mi.invoke(std::move(std::as_const(cl)))); CHECK_THROWS(mi2.invoke(cl)); CHECK_THROWS(mi2.invoke(std::as_const(cl))); - CHECK(mi2.invoke(std::move(cl))->equals(9)); + CHECK(mi2.invoke(std::move(cl)).value() == 9); CHECK_THROWS(mi2.invoke(std::move(std::as_const(cl)))); } @@ -652,12 +652,12 @@ TEST_CASE("features/infos/method") { CHECK_THROWS(mi.invoke(cl)); CHECK_THROWS(mi.invoke(std::as_const(cl))); - CHECK(mi.invoke(std::move(cl))->equals(10)); + CHECK(mi.invoke(std::move(cl)).value() == 10); CHECK_THROWS(mi.invoke(std::move(std::as_const(cl)))); CHECK_THROWS(mi2.invoke(cl)); CHECK_THROWS(mi2.invoke(std::as_const(cl))); - CHECK(mi2.invoke(std::move(cl))->equals(10)); + CHECK(mi2.invoke(std::move(cl)).value() == 10); CHECK_THROWS(mi2.invoke(std::move(std::as_const(cl)))); } @@ -708,13 +708,13 @@ TEST_CASE("features/infos/method") { CHECK_THROWS(mi.invoke(cl)); CHECK_THROWS(mi.invoke(std::as_const(cl))); - CHECK(mi.invoke(std::move(cl))->equals(11)); - CHECK(mi.invoke(std::move(std::as_const(cl)))->equals(11)); + CHECK(mi.invoke(std::move(cl)).value() == 11); + CHECK(mi.invoke(std::move(std::as_const(cl))).value() == 11); CHECK_THROWS(mi2.invoke(cl)); CHECK_THROWS(mi2.invoke(std::as_const(cl))); - CHECK(mi2.invoke(std::move(cl))->equals(11)); - CHECK(mi2.invoke(std::move(std::as_const(cl)))->equals(11)); + CHECK(mi2.invoke(std::move(cl)).value() == 11); + CHECK(mi2.invoke(std::move(std::as_const(cl))).value() == 11); } static_assert(!std::is_invocable_v); @@ -764,13 +764,13 @@ TEST_CASE("features/infos/method") { CHECK_THROWS(mi.invoke(cl)); CHECK_THROWS(mi.invoke(std::as_const(cl))); - CHECK(mi.invoke(std::move(cl))->equals(12)); - CHECK(mi.invoke(std::move(std::as_const(cl)))->equals(12)); + CHECK(mi.invoke(std::move(cl)).value() == 12); + CHECK(mi.invoke(std::move(std::as_const(cl))).value() == 12); CHECK_THROWS(mi2.invoke(cl)); CHECK_THROWS(mi2.invoke(std::as_const(cl))); - CHECK(mi2.invoke(std::move(cl))->equals(12)); - CHECK(mi2.invoke(std::move(std::as_const(cl)))->equals(12)); + CHECK(mi2.invoke(std::move(cl)).value() == 12); + CHECK(mi2.invoke(std::move(std::as_const(cl))).value() == 12); } static_assert(!std::is_invocable_v); diff --git a/untests/features/utilities/value_tests.cpp b/untests/features/utilities/value_tests.cpp index 0bce6ad..650ff84 100644 --- a/untests/features/utilities/value_tests.cpp +++ b/untests/features/utilities/value_tests.cpp @@ -94,8 +94,8 @@ TEST_CASE("features/utilities/value") { CHECK(!std::memcmp(std::as_const(val).data(), &vr, sizeof(ivec2))); CHECK(!std::memcmp(std::as_const(val).cdata(), &vr, sizeof(ivec2))); - CHECK(val.equals(ivec2{1,2})); - CHECK(val.equals(value{ivec2{1,2}})); + CHECK(val == ivec2{1,2}); + CHECK(val == value{ivec2{1,2}}); CHECK(val.cast() == ivec2{1,2}); CHECK(std::as_const(val).cast() == ivec2{1,2}); @@ -119,8 +119,8 @@ TEST_CASE("features/utilities/value") { CHECK(!std::memcmp(std::as_const(val).data(), &vr, sizeof(ivec2))); CHECK(!std::memcmp(std::as_const(val).cdata(), &vr, sizeof(ivec2))); - CHECK(val.equals(ivec2{1,2})); - CHECK(val.equals(value{ivec2{1,2}})); + CHECK(val == ivec2{1,2}); + CHECK(val == value{ivec2{1,2}}); CHECK(val.cast() == ivec2{1,2}); CHECK(std::as_const(val).cast() == ivec2{1,2}); @@ -138,8 +138,8 @@ TEST_CASE("features/utilities/value") { CHECK(val.type() == type_db::get()); - CHECK(val.equals(ivec2{1,2})); - CHECK(val.equals(value{ivec2{1,2}})); + CHECK(val == ivec2{1,2}); + CHECK(val == value{ivec2{1,2}}); CHECK(val.cast() == ivec2{1,2}); CHECK(std::as_const(val).cast() == ivec2{1,2}); @@ -157,8 +157,8 @@ TEST_CASE("features/utilities/value") { CHECK(val.type() == type_db::get()); - CHECK(val.equals(ivec2{1,2})); - CHECK(val.equals(value{ivec2{1,2}})); + CHECK(val == ivec2{1,2}); + CHECK(val == value{ivec2{1,2}}); CHECK(val.cast() == ivec2{1,2}); CHECK(std::as_const(val).cast() == ivec2{1,2}); @@ -174,11 +174,11 @@ TEST_CASE("features/utilities/value") { CHECK(ivec2::copy_ctor_counter == 0); value val_dst{std::move(val_src)}; - CHECK(val_dst.equals(ivec2{1,2})); + CHECK(val_dst == ivec2{1,2}); CHECK(ivec2::move_ctor_counter == 2); CHECK(ivec2::copy_ctor_counter == 0); - CHECK(val_src.equals(ivec2{0,0})); + CHECK(val_src == ivec2{0,0}); CHECK(val_src.data() != val_dst.data()); } @@ -189,11 +189,11 @@ TEST_CASE("features/utilities/value") { CHECK(ivec2::copy_ctor_counter == 1); value val_dst{val_src}; - CHECK(val_dst.equals(ivec2{1,2})); + CHECK(val_dst == ivec2{1,2}); CHECK(ivec2::move_ctor_counter == 0); CHECK(ivec2::copy_ctor_counter == 2); - CHECK(val_src.equals(ivec2{1,2})); + CHECK(val_src == ivec2{1,2}); CHECK(val_src.data() != val_dst.data()); } @@ -206,16 +206,16 @@ TEST_CASE("features/utilities/value") { value val_dst{"hello"s}; val_dst = std::move(val_src1); - CHECK(val_dst.equals("world"s)); + CHECK(val_dst == "world"s); CHECK(ivec2::move_ctor_counter == 1); CHECK(ivec2::copy_ctor_counter == 0); val_dst = std::move(val_src2); - CHECK(val_dst.equals(ivec2{1,2})); + CHECK(val_dst == ivec2{1,2}); CHECK(ivec2::move_ctor_counter == 2); CHECK(ivec2::copy_ctor_counter == 0); - CHECK(val_src2.equals(ivec2{0,0})); + CHECK(val_src2 == ivec2{0,0}); CHECK(val_src2.data() != val_dst.data()); } @@ -228,16 +228,16 @@ TEST_CASE("features/utilities/value") { value val_dst{"hello"s}; val_dst = val_src1; - CHECK(val_dst.equals("world"s)); + CHECK(val_dst == "world"s); CHECK(ivec2::move_ctor_counter == 1); CHECK(ivec2::copy_ctor_counter == 0); val_dst = val_src2; - CHECK(val_dst.equals(ivec2{1,2})); + CHECK(val_dst == ivec2{1,2}); CHECK(ivec2::move_ctor_counter == 1); CHECK(ivec2::copy_ctor_counter == 1); - CHECK(val_src2.equals(ivec2{1,2})); + CHECK(val_src2 == ivec2{1,2}); CHECK(val_src2.data() != val_dst.data()); } @@ -248,20 +248,20 @@ TEST_CASE("features/utilities/value") { CHECK(ivec2::copy_ctor_counter == 0); val1.swap(val2); - CHECK(val1.equals(ivec2{1,2})); - CHECK(val2.equals("world"s)); + CHECK(val1 == ivec2{1,2}); + CHECK(val2 == "world"s); CHECK((ivec2::move_ctor_counter == 2 || ivec2::move_ctor_counter == 3)); CHECK(ivec2::copy_ctor_counter == 0); swap(val1, val2); - CHECK(val1.equals("world"s)); - CHECK(val2.equals(ivec2{1,2})); + CHECK(val1 == "world"s); + CHECK(val2 == ivec2{1,2}); } SUBCASE("ostream") { std::stringstream str_stream; CHECK_NOTHROW(str_stream << value{21} << " " << value{42}); - CHECK_THROWS(str_stream << value{ivec2{1,2}}); + CHECK_THROWS((str_stream << value{ivec2{1,2}})); REQUIRE(str_stream.str() == "21 42"); } @@ -273,8 +273,24 @@ TEST_CASE("features/utilities/value") { v = value{0}; CHECK_NOTHROW(str_stream >> v); - CHECK(v.equals(21)); + CHECK(v == 21); CHECK_NOTHROW(str_stream >> v); - CHECK(v.equals(42)); + CHECK(v == 42); + } + + SUBCASE("operator==") { + CHECK(value{ivec2{1,2}} == ivec2{1,2}); + CHECK_FALSE(value{ivec2{1,2}} == ivec2{1,3}); + + CHECK(ivec2{1,2} == value{ivec2{1,2}}); + CHECK_FALSE(ivec2{1,3} == value{ivec2{1,2}}); + + CHECK(value{ivec2{1,2}} == value{ivec2{1,2}}); + CHECK_FALSE(value{ivec2{1,2}} == value{ivec2{1,3}}); + + class empty_class1 {}; + class empty_class2 {}; + CHECK_FALSE(value{empty_class1{}} == value{empty_class2{}}); + CHECK_THROWS(value{empty_class1{}} == value{empty_class1{}}); } } From 7c2d999825534a8c9fc02adb9e77bda81fadab32 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Mon, 16 Aug 2021 16:34:52 +0700 Subject: [PATCH 107/233] fix clang warnings --- untests/features/utilities/value_tests.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/untests/features/utilities/value_tests.cpp b/untests/features/utilities/value_tests.cpp index 650ff84..96b37b4 100644 --- a/untests/features/utilities/value_tests.cpp +++ b/untests/features/utilities/value_tests.cpp @@ -288,9 +288,12 @@ TEST_CASE("features/utilities/value") { CHECK(value{ivec2{1,2}} == value{ivec2{1,2}}); CHECK_FALSE(value{ivec2{1,2}} == value{ivec2{1,3}}); - class empty_class1 {}; - class empty_class2 {}; - CHECK_FALSE(value{empty_class1{}} == value{empty_class2{}}); - CHECK_THROWS(value{empty_class1{}} == value{empty_class1{}}); + { + class empty_class1 {}; + class empty_class2 {}; + + CHECK_FALSE(operator==(value{empty_class1{}}, value{empty_class2{}})); + CHECK_THROWS(operator==(value{empty_class1{}}, value{empty_class1{}})); + } } } From a9cfa7774404abfd1e10f5a57d340d6bce23f807 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Mon, 16 Aug 2021 19:23:08 +0700 Subject: [PATCH 108/233] base type compare operators --- headers/meta.hpp/meta_infos/class_info.hpp | 2 +- headers/meta.hpp/meta_types/_types_fwd.hpp | 44 +++++++++++++++++++ untests/features/infos/class_info_tests.cpp | 4 +- untests/features/infos/ctor_info_tests.cpp | 16 +++---- .../features/types/arithmetic_type_tests.cpp | 4 +- untests/features/types/array_type_tests.cpp | 8 ++-- untests/features/types/base_type_tests.cpp | 4 +- untests/features/types/class_type_tests.cpp | 2 +- untests/features/types/ctor_type_tests.cpp | 12 ++--- untests/features/types/enum_type_tests.cpp | 6 +-- .../features/types/function_type_tests.cpp | 12 ++--- untests/features/types/member_type_tests.cpp | 8 ++-- untests/features/types/method_type_tests.cpp | 10 ++--- untests/features/types/pointer_type_tests.cpp | 8 ++-- .../features/types/reference_type_tests.cpp | 4 +- untests/features/types/void_type_tests.cpp | 2 +- 16 files changed, 95 insertions(+), 51 deletions(-) diff --git a/headers/meta.hpp/meta_infos/class_info.hpp b/headers/meta.hpp/meta_infos/class_info.hpp index 7e861db..fc0ec79 100644 --- a/headers/meta.hpp/meta_infos/class_info.hpp +++ b/headers/meta.hpp/meta_infos/class_info.hpp @@ -125,7 +125,7 @@ namespace meta_hpp inline bool class_info::is_derived_from(any_type base) const noexcept { for ( auto&& id_info : state_->bases ) { - if ( base.id() == id_info.second.type().base_class_type().id() ) { + if ( base == id_info.second.type().base_class_type() ) { return true; } } diff --git a/headers/meta.hpp/meta_types/_types_fwd.hpp b/headers/meta.hpp/meta_types/_types_fwd.hpp index 316f868..39e8327 100644 --- a/headers/meta.hpp/meta_types/_types_fwd.hpp +++ b/headers/meta.hpp/meta_types/_types_fwd.hpp @@ -102,6 +102,20 @@ namespace meta_hpp private: type_id id_; }; + + // + + inline bool operator<(const type_base& l, const type_base& r) noexcept { + return l.id() < r.id(); + } + + inline bool operator==(const type_base& l, const type_base& r) noexcept { + return l.id() == r.id(); + } + + inline bool operator!=(const type_base& l, const type_base& r) noexcept { + return l.id() != r.id(); + } } namespace meta_hpp @@ -160,6 +174,8 @@ namespace meta_hpp const void_type*> type_; }; + // + inline bool operator<(const any_type& l, const any_type& r) noexcept { return l.id() < r.id(); } @@ -171,6 +187,34 @@ namespace meta_hpp inline bool operator!=(const any_type& l, const any_type& r) noexcept { return l.id() != r.id(); } + + // + + inline bool operator<(const type_base& l, const any_type& r) noexcept { + return l.id() < r.id(); + } + + inline bool operator==(const type_base& l, const any_type& r) noexcept { + return l.id() == r.id(); + } + + inline bool operator!=(const type_base& l, const any_type& r) noexcept { + return l.id() != r.id(); + } + + // + + inline bool operator<(const any_type& l, const type_base& r) noexcept { + return l.id() < r.id(); + } + + inline bool operator==(const any_type& l, const type_base& r) noexcept { + return l.id() == r.id(); + } + + inline bool operator!=(const any_type& l, const type_base& r) noexcept { + return l.id() != r.id(); + } } namespace std diff --git a/untests/features/infos/class_info_tests.cpp b/untests/features/infos/class_info_tests.cpp index b0a1a99..59bc299 100644 --- a/untests/features/infos/class_info_tests.cpp +++ b/untests/features/infos/class_info_tests.cpp @@ -76,7 +76,7 @@ TEST_CASE("features/infos/class") { REQUIRE(db.get_class_by_path("shape")); const class_info shape_info = db.get_class_by_path("shape"); CHECK(shape_info.name() == "shape"); - CHECK(shape_info.type().id() == type_db::get().id()); + CHECK(shape_info.type() == type_db::get()); CHECK_FALSE(shape_info.is_derived_from()); CHECK_FALSE(shape_info.is_derived_from()); @@ -86,7 +86,7 @@ TEST_CASE("features/infos/class") { REQUIRE(db.get_class_by_path("rectangle")); const class_info rectangle_info = db.get_class_by_path("rectangle"); CHECK(rectangle_info.name() == "rectangle"); - CHECK(rectangle_info.type().id() == type_db::get().id()); + CHECK(rectangle_info.type() == type_db::get()); CHECK(rectangle_info.is_derived_from()); CHECK_FALSE(rectangle_info.is_derived_from()); diff --git a/untests/features/infos/ctor_info_tests.cpp b/untests/features/infos/ctor_info_tests.cpp index eb0a78b..aa2d571 100644 --- a/untests/features/infos/ctor_info_tests.cpp +++ b/untests/features/infos/ctor_info_tests.cpp @@ -58,8 +58,8 @@ TEST_CASE("features/infos/ctor") { const ctor_info ci3 = ivec2_info.get_ctor_by_args(std::vector{}); REQUIRE(ci2); REQUIRE(ci3); - CHECK(ci.type().id() == ci2.type().id()); - CHECK(ci.type().id() == ci2.type().id()); + CHECK(ci.type() == ci2.type()); + CHECK(ci.type() == ci2.type()); } { @@ -93,8 +93,8 @@ TEST_CASE("features/infos/ctor") { type_db::get()}); REQUIRE(ci2); REQUIRE(ci3); - CHECK(ci.type().id() == ci2.type().id()); - CHECK(ci.type().id() == ci2.type().id()); + CHECK(ci.type() == ci2.type()); + CHECK(ci.type() == ci2.type()); } { @@ -128,8 +128,8 @@ TEST_CASE("features/infos/ctor") { type_db::get()}); REQUIRE(ci2); REQUIRE(ci3); - CHECK(ci.type().id() == ci2.type().id()); - CHECK(ci.type().id() == ci2.type().id()); + CHECK(ci.type() == ci2.type()); + CHECK(ci.type() == ci2.type()); } { @@ -172,8 +172,8 @@ TEST_CASE("features/infos/ctor") { type_db::get()}); REQUIRE(ci2); REQUIRE(ci3); - CHECK(ci.type().id() == ci2.type().id()); - CHECK(ci.type().id() == ci2.type().id()); + CHECK(ci.type() == ci2.type()); + CHECK(ci.type() == ci2.type()); } { diff --git a/untests/features/types/arithmetic_type_tests.cpp b/untests/features/types/arithmetic_type_tests.cpp index 5815e8e..c407be1 100644 --- a/untests/features/types/arithmetic_type_tests.cpp +++ b/untests/features/types/arithmetic_type_tests.cpp @@ -43,7 +43,7 @@ TEST_CASE("features/types/arithmetic") { const arithmetic_type at = type_db::get().as(); - CHECK(at.raw_type().id() == type_db::get().id()); + CHECK(at.raw_type() == type_db::get()); CHECK(at.size() == sizeof(type)); CHECK(at.flags() == ( @@ -66,7 +66,7 @@ TEST_CASE("features/types/arithmetic") { const arithmetic_type at = type_db::get().as(); - CHECK(at.raw_type().id() == type_db::get().id()); + CHECK(at.raw_type() == type_db::get()); CHECK(at.size() == sizeof(type)); CHECK(at.flags() == ( diff --git a/untests/features/types/array_type_tests.cpp b/untests/features/types/array_type_tests.cpp index c695cc2..b2f6169 100644 --- a/untests/features/types/array_type_tests.cpp +++ b/untests/features/types/array_type_tests.cpp @@ -21,7 +21,7 @@ TEST_CASE("features/types/array") { const array_type at = type_db::get().as(); - CHECK(at.data_type().id() == type_db::get().id()); + CHECK(at.data_type() == type_db::get()); CHECK(at.extent() == 0); CHECK(at.flags() == (array_flags::is_unbounded)); @@ -38,7 +38,7 @@ TEST_CASE("features/types/array") { const array_type at = type_db::get().as(); - CHECK(at.data_type().id() == type_db::get().id()); + CHECK(at.data_type() == type_db::get()); CHECK(at.extent() == 0); CHECK(at.flags() == (array_flags::is_unbounded)); @@ -55,7 +55,7 @@ TEST_CASE("features/types/array") { const array_type at = type_db::get().as(); - CHECK(at.data_type().id() == type_db::get().id()); + CHECK(at.data_type() == type_db::get()); CHECK(at.extent() == 42); CHECK(at.flags() == (array_flags::is_bounded)); @@ -72,7 +72,7 @@ TEST_CASE("features/types/array") { const array_type at = type_db::get().as(); - CHECK(at.data_type().id() == type_db::get().id()); + CHECK(at.data_type() == type_db::get()); CHECK(at.extent() == 42); CHECK(at.flags() == (array_flags::is_bounded)); diff --git a/untests/features/types/base_type_tests.cpp b/untests/features/types/base_type_tests.cpp index d7ae407..0a84731 100644 --- a/untests/features/types/base_type_tests.cpp +++ b/untests/features/types/base_type_tests.cpp @@ -25,6 +25,6 @@ namespace TEST_CASE("features/types/base") { base_type bt{typename_arg, typename_arg}; - CHECK(bt.base_class_type().id() == type_db::get().id()); - CHECK(bt.derived_class_type().id() == type_db::get().id()); + CHECK(bt.base_class_type() == type_db::get()); + CHECK(bt.derived_class_type() == type_db::get()); } diff --git a/untests/features/types/class_type_tests.cpp b/untests/features/types/class_type_tests.cpp index 00db749..bf4bbbc 100644 --- a/untests/features/types/class_type_tests.cpp +++ b/untests/features/types/class_type_tests.cpp @@ -127,7 +127,7 @@ TEST_CASE("features/types/class") { const class_type ct = type_db::get().as(); REQUIRE(ct.raw_type()); - CHECK(ct.raw_type().id() == type_db::get().id()); + CHECK(ct.raw_type() == type_db::get()); CHECK(ct.size() == sizeof(type)); CHECK(ct.flags() == ( diff --git a/untests/features/types/ctor_type_tests.cpp b/untests/features/types/ctor_type_tests.cpp index 3cdc84d..8245684 100644 --- a/untests/features/types/ctor_type_tests.cpp +++ b/untests/features/types/ctor_type_tests.cpp @@ -28,7 +28,7 @@ TEST_CASE("features/types/ctor") { SUBCASE("ivec2_void") { ctor_type ct{typename_arg, typename_arg<>}; - CHECK(ct.class_type().id() == type_db::get().id()); + CHECK(ct.class_type() == type_db::get()); CHECK(ct.argument_types().size() == 0); CHECK(ct.arity() == 0); @@ -44,7 +44,7 @@ TEST_CASE("features/types/ctor") { ctor_type ct{typename_arg, typename_arg}; CHECK(ct.arity() == 1); - CHECK(ct.class_type().id() == type_db::get().id()); + CHECK(ct.class_type() == type_db::get()); CHECK(ct.argument_types().size() == 1); CHECK(ct.flags() == (ctor_flags{})); @@ -53,7 +53,7 @@ TEST_CASE("features/types/ctor") { { REQUIRE(ct.argument_type(0)); const any_type arg0 = ct.argument_type(0); - CHECK(arg0.id() == type_db::get().id()); + CHECK(arg0 == type_db::get()); } { @@ -64,7 +64,7 @@ TEST_CASE("features/types/ctor") { SUBCASE("ivec2_int_int") { ctor_type ct{typename_arg, typename_arg}; - CHECK(ct.class_type().id() == type_db::get().id()); + CHECK(ct.class_type() == type_db::get()); CHECK(ct.argument_types().size() == 2); CHECK(ct.arity() == 2); @@ -74,13 +74,13 @@ TEST_CASE("features/types/ctor") { { REQUIRE(ct.argument_type(0)); const any_type arg0 = ct.argument_type(0); - CHECK(arg0.id() == type_db::get().id()); + CHECK(arg0 == type_db::get()); } { REQUIRE(ct.argument_type(1)); const any_type arg1 = ct.argument_type(1); - CHECK(arg1.id() == type_db::get().id()); + CHECK(arg1 == type_db::get()); } { diff --git a/untests/features/types/enum_type_tests.cpp b/untests/features/types/enum_type_tests.cpp index f96eb6f..03be3a7 100644 --- a/untests/features/types/enum_type_tests.cpp +++ b/untests/features/types/enum_type_tests.cpp @@ -32,7 +32,7 @@ TEST_CASE("features/types/enum") { CHECK(et.size() == sizeof(type)); CHECK_FALSE(et.raw_type()); - CHECK(et.underlying_type().id() == type_db::get().id()); + CHECK(et.underlying_type() == type_db::get()); CHECK(et.flags() == (enum_flags{})); CHECK_FALSE(et.is_const()); @@ -48,8 +48,8 @@ TEST_CASE("features/types/enum") { CHECK(et.size() == sizeof(type)); REQUIRE(et.raw_type()); - CHECK(et.raw_type().id() == type_db::get().id()); - CHECK(et.underlying_type().id() == type_db::get().id()); + CHECK(et.raw_type() == type_db::get()); + CHECK(et.underlying_type() == type_db::get()); CHECK(et.flags() == (enum_flags::is_const)); CHECK(et.is_const()); diff --git a/untests/features/types/function_type_tests.cpp b/untests/features/types/function_type_tests.cpp index 38632ab..fb3ac00 100644 --- a/untests/features/types/function_type_tests.cpp +++ b/untests/features/types/function_type_tests.cpp @@ -32,7 +32,7 @@ TEST_CASE("features/types/function") { REQUIRE(type_db::get().is()); const function_type ft = type_db::get().as(); - CHECK(ft.return_type().id() == type_db::get().id()); + CHECK(ft.return_type() == type_db::get()); CHECK(ft.argument_types().size() == 1); CHECK(ft.arity() == 1); @@ -42,7 +42,7 @@ TEST_CASE("features/types/function") { { REQUIRE(ft.argument_type(0)); const any_type arg0 = ft.argument_type(0); - CHECK(arg0.id() == type_db::get().id()); + CHECK(arg0 == type_db::get()); } { @@ -57,7 +57,7 @@ TEST_CASE("features/types/function") { REQUIRE(type_db::get().is()); const function_type ft = type_db::get().as(); - CHECK(ft.return_type().id() == type_db::get().id()); + CHECK(ft.return_type() == type_db::get()); CHECK(ft.argument_types().size() == 1); CHECK(ft.arity() == 1); @@ -67,7 +67,7 @@ TEST_CASE("features/types/function") { { REQUIRE(ft.argument_type(0)); const any_type arg0 = ft.argument_type(0); - CHECK(arg0.id() == type_db::get().id()); + CHECK(arg0 == type_db::get()); } { @@ -82,7 +82,7 @@ TEST_CASE("features/types/function") { REQUIRE(type_db::get().is()); const function_type ft = type_db::get().as(); - CHECK(ft.return_type().id() == type_db::get().id()); + CHECK(ft.return_type() == type_db::get()); CHECK(ft.argument_types().size() == 1); CHECK(ft.arity() == 1); @@ -92,7 +92,7 @@ TEST_CASE("features/types/function") { { REQUIRE(ft.argument_type(0)); const any_type arg0 = ft.argument_type(0); - CHECK(arg0.id() == type_db::get().id()); + CHECK(arg0 == type_db::get()); } { diff --git a/untests/features/types/member_type_tests.cpp b/untests/features/types/member_type_tests.cpp index 3115124..e085801 100644 --- a/untests/features/types/member_type_tests.cpp +++ b/untests/features/types/member_type_tests.cpp @@ -28,8 +28,8 @@ TEST_CASE("features/types/member") { REQUIRE(type_db::get().is()); const member_type mt = type_db::get().as(); - CHECK(mt.class_type().id() == type_db::get().id()); - CHECK(mt.value_type().id() == type_db::get().id()); + CHECK(mt.class_type() == type_db::get()); + CHECK(mt.value_type() == type_db::get()); } SUBCASE("clazz::const_int_member") { @@ -39,7 +39,7 @@ TEST_CASE("features/types/member") { REQUIRE(type_db::get().is()); const member_type mt = type_db::get().as(); - CHECK(mt.class_type().id() == type_db::get().id()); - CHECK(mt.value_type().id() == type_db::get().id()); + CHECK(mt.class_type() == type_db::get()); + CHECK(mt.value_type() == type_db::get()); } } diff --git a/untests/features/types/method_type_tests.cpp b/untests/features/types/method_type_tests.cpp index 084db51..334946d 100644 --- a/untests/features/types/method_type_tests.cpp +++ b/untests/features/types/method_type_tests.cpp @@ -40,8 +40,8 @@ TEST_CASE("features/types/method") { REQUIRE(type_db::get().is()); const method_type mt = type_db::get().as(); - CHECK(mt.class_type().id() == type_db::get().id()); - CHECK(mt.return_type().id() == type_db::get().id()); + CHECK(mt.class_type() == type_db::get()); + CHECK(mt.return_type() == type_db::get()); CHECK(mt.argument_types().size() == 1); CHECK(mt.arity() == 1); @@ -53,7 +53,7 @@ TEST_CASE("features/types/method") { { REQUIRE(mt.argument_type(0)); const any_type arg0 = mt.argument_type(0); - CHECK(arg0.id() == type_db::get().id()); + CHECK(arg0 == type_db::get()); } { @@ -68,8 +68,8 @@ TEST_CASE("features/types/method") { REQUIRE(type_db::get().is()); const method_type mt = type_db::get().as(); - CHECK(mt.class_type().id() == type_db::get().id()); - CHECK(mt.return_type().id() == type_db::get().id()); + CHECK(mt.class_type() == type_db::get()); + CHECK(mt.return_type() == type_db::get()); CHECK(mt.argument_types().size() == 0); CHECK(mt.arity() == 0); diff --git a/untests/features/types/pointer_type_tests.cpp b/untests/features/types/pointer_type_tests.cpp index 6fbc619..f267734 100644 --- a/untests/features/types/pointer_type_tests.cpp +++ b/untests/features/types/pointer_type_tests.cpp @@ -29,7 +29,7 @@ TEST_CASE("features/types/pointer") { const pointer_type pt = type_db::get().as(); - CHECK(pt.data_type().id() == type_db::get().id()); + CHECK(pt.data_type() == type_db::get()); CHECK(pt.flags() == (pointer_flags{})); CHECK_FALSE(pt.is_const()); @@ -43,7 +43,7 @@ TEST_CASE("features/types/pointer") { const pointer_type pt = type_db::get().as(); - CHECK(pt.data_type().id() == type_db::get().id()); + CHECK(pt.data_type() == type_db::get()); CHECK(pt.flags() == (pointer_flags{})); CHECK_FALSE(pt.is_const()); @@ -57,7 +57,7 @@ TEST_CASE("features/types/pointer") { const pointer_type pt = type_db::get().as(); - CHECK(pt.data_type().id() == type_db::get().id()); + CHECK(pt.data_type() == type_db::get()); CHECK(pt.flags() == (pointer_flags::is_const)); CHECK(pt.is_const()); @@ -71,7 +71,7 @@ TEST_CASE("features/types/pointer") { const pointer_type pt = type_db::get().as(); - CHECK(pt.data_type().id() == type_db::get().id()); + CHECK(pt.data_type() == type_db::get()); CHECK(pt.flags() == (pointer_flags::is_const)); CHECK(pt.is_const()); diff --git a/untests/features/types/reference_type_tests.cpp b/untests/features/types/reference_type_tests.cpp index be5bf72..0bacb4a 100644 --- a/untests/features/types/reference_type_tests.cpp +++ b/untests/features/types/reference_type_tests.cpp @@ -27,7 +27,7 @@ TEST_CASE("features/types/reference") { const reference_type rt = type_db::get().as(); - CHECK(rt.data_type().id() == type_db::get().id()); + CHECK(rt.data_type() == type_db::get()); CHECK(rt.flags() == (reference_flags::is_lvalue)); @@ -41,7 +41,7 @@ TEST_CASE("features/types/reference") { const reference_type rt = type_db::get().as(); - CHECK(rt.data_type().id() == type_db::get().id()); + CHECK(rt.data_type() == type_db::get()); CHECK(rt.flags() == (reference_flags::is_rvalue)); diff --git a/untests/features/types/void_type_tests.cpp b/untests/features/types/void_type_tests.cpp index a24fe5d..e53afb2 100644 --- a/untests/features/types/void_type_tests.cpp +++ b/untests/features/types/void_type_tests.cpp @@ -36,7 +36,7 @@ TEST_CASE("features/types/void") { const void_type vt = type_db::get().as(); REQUIRE(vt.raw_type()); - CHECK(vt.raw_type().id() == type_db::get().id()); + CHECK(vt.raw_type() == type_db::get()); CHECK(vt.flags() == (void_flags::is_const)); CHECK(vt.is_const()); From 6edfa3437991b78c0ca3903d3b945ce4d9c81670 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 20 Aug 2021 15:17:31 +0700 Subject: [PATCH 109/233] start again from scratch --- CMakeLists.txt | 15 +- headers/meta.hpp/meta_all.hpp | 4 - headers/meta.hpp/meta_fwd.hpp | 163 --- headers/meta.hpp/meta_infos.hpp | 20 - headers/meta.hpp/meta_infos/_infos_fwd.hpp | 11 - headers/meta.hpp/meta_infos/base_info.hpp | 93 -- headers/meta.hpp/meta_infos/class_info.hpp | 289 ---- headers/meta.hpp/meta_infos/ctor_info.hpp | 204 --- headers/meta.hpp/meta_infos/data_info.hpp | 96 -- headers/meta.hpp/meta_infos/enum_info.hpp | 118 -- headers/meta.hpp/meta_infos/evalue_info.hpp | 100 -- headers/meta.hpp/meta_infos/function_info.hpp | 221 ---- headers/meta.hpp/meta_infos/member_info.hpp | 181 --- headers/meta.hpp/meta_infos/method_info.hpp | 237 ---- .../meta.hpp/meta_infos/namespace_info.hpp | 162 --- headers/meta.hpp/meta_registry.hpp | 211 --- .../meta.hpp/meta_registry/_registry_fwd.hpp | 11 - headers/meta.hpp/meta_registry/base_.hpp | 58 - headers/meta.hpp/meta_registry/class_.hpp | 144 -- headers/meta.hpp/meta_registry/ctor_.hpp | 58 - headers/meta.hpp/meta_registry/data_.hpp | 58 - headers/meta.hpp/meta_registry/enum_.hpp | 71 - headers/meta.hpp/meta_registry/evalue_.hpp | 63 - headers/meta.hpp/meta_registry/function_.hpp | 63 - headers/meta.hpp/meta_registry/member_.hpp | 63 - headers/meta.hpp/meta_registry/method_.hpp | 63 - headers/meta.hpp/meta_registry/namespace_.hpp | 97 -- headers/meta.hpp/meta_types.hpp | 84 -- headers/meta.hpp/meta_types/_types_fwd.hpp | 242 ---- .../meta.hpp/meta_types/arithmetic_type.hpp | 128 -- headers/meta.hpp/meta_types/array_type.hpp | 108 -- headers/meta.hpp/meta_types/base_type.hpp | 77 -- headers/meta.hpp/meta_types/class_type.hpp | 128 -- headers/meta.hpp/meta_types/ctor_type.hpp | 118 -- headers/meta.hpp/meta_types/enum_type.hpp | 112 -- headers/meta.hpp/meta_types/function_type.hpp | 125 -- headers/meta.hpp/meta_types/member_type.hpp | 81 -- headers/meta.hpp/meta_types/method_type.hpp | 340 ----- headers/meta.hpp/meta_types/pointer_type.hpp | 88 -- .../meta.hpp/meta_types/reference_type.hpp | 96 -- headers/meta.hpp/meta_types/void_type.hpp | 94 -- headers/meta.hpp/meta_utilities.hpp | 13 - .../meta_utilities/_utilities_fwd.hpp | 9 - headers/meta.hpp/meta_utilities/arg.hpp | 286 ---- headers/meta.hpp/meta_utilities/inst.hpp | 229 ---- headers/meta.hpp/meta_utilities/value.hpp | 376 ------ untests/features/infos/_infos_fwd.hpp | 9 - untests/features/infos/base_info_tests.cpp | 44 - untests/features/infos/class_info_tests.cpp | 94 -- untests/features/infos/ctor_info_tests.cpp | 201 --- untests/features/infos/data_info_tests.cpp | 14 - untests/features/infos/enum_info_tests.cpp | 14 - untests/features/infos/evalue_info_tests.cpp | 14 - .../features/infos/function_info_tests.cpp | 95 -- untests/features/infos/member_info_tests.cpp | 163 --- untests/features/infos/method_info_tests.cpp | 786 ----------- .../features/infos/namespace_info_tests.cpp | 14 - untests/features/registry/_registry_fwd.hpp | 9 - untests/features/registry/registry_tests.cpp | 70 - untests/features/types/_types_fwd.hpp | 9 - .../features/types/arithmetic_type_tests.cpp | 83 -- untests/features/types/array_type_tests.cpp | 83 -- untests/features/types/base_type_tests.cpp | 30 - untests/features/types/class_type_tests.cpp | 143 -- untests/features/types/ctor_type_tests.cpp | 90 -- untests/features/types/enum_type_tests.cpp | 57 - .../features/types/function_type_tests.cpp | 102 -- untests/features/types/member_type_tests.cpp | 45 - untests/features/types/method_type_tests.cpp | 87 -- untests/features/types/pointer_type_tests.cpp | 79 -- .../features/types/reference_type_tests.cpp | 51 - untests/features/types/void_type_tests.cpp | 44 - untests/features/utilities/_utilities_fwd.hpp | 9 - untests/features/utilities/arg_tests.cpp | 1157 ----------------- untests/features/utilities/inst_tests.cpp | 76 -- untests/features/utilities/value_tests.cpp | 299 ----- 76 files changed, 5 insertions(+), 9574 deletions(-) delete mode 100644 headers/meta.hpp/meta_infos.hpp delete mode 100644 headers/meta.hpp/meta_infos/_infos_fwd.hpp delete mode 100644 headers/meta.hpp/meta_infos/base_info.hpp delete mode 100644 headers/meta.hpp/meta_infos/class_info.hpp delete mode 100644 headers/meta.hpp/meta_infos/ctor_info.hpp delete mode 100644 headers/meta.hpp/meta_infos/data_info.hpp delete mode 100644 headers/meta.hpp/meta_infos/enum_info.hpp delete mode 100644 headers/meta.hpp/meta_infos/evalue_info.hpp delete mode 100644 headers/meta.hpp/meta_infos/function_info.hpp delete mode 100644 headers/meta.hpp/meta_infos/member_info.hpp delete mode 100644 headers/meta.hpp/meta_infos/method_info.hpp delete mode 100644 headers/meta.hpp/meta_infos/namespace_info.hpp delete mode 100644 headers/meta.hpp/meta_registry.hpp delete mode 100644 headers/meta.hpp/meta_registry/_registry_fwd.hpp delete mode 100644 headers/meta.hpp/meta_registry/base_.hpp delete mode 100644 headers/meta.hpp/meta_registry/class_.hpp delete mode 100644 headers/meta.hpp/meta_registry/ctor_.hpp delete mode 100644 headers/meta.hpp/meta_registry/data_.hpp delete mode 100644 headers/meta.hpp/meta_registry/enum_.hpp delete mode 100644 headers/meta.hpp/meta_registry/evalue_.hpp delete mode 100644 headers/meta.hpp/meta_registry/function_.hpp delete mode 100644 headers/meta.hpp/meta_registry/member_.hpp delete mode 100644 headers/meta.hpp/meta_registry/method_.hpp delete mode 100644 headers/meta.hpp/meta_registry/namespace_.hpp delete mode 100644 headers/meta.hpp/meta_types.hpp delete mode 100644 headers/meta.hpp/meta_types/_types_fwd.hpp delete mode 100644 headers/meta.hpp/meta_types/arithmetic_type.hpp delete mode 100644 headers/meta.hpp/meta_types/array_type.hpp delete mode 100644 headers/meta.hpp/meta_types/base_type.hpp delete mode 100644 headers/meta.hpp/meta_types/class_type.hpp delete mode 100644 headers/meta.hpp/meta_types/ctor_type.hpp delete mode 100644 headers/meta.hpp/meta_types/enum_type.hpp delete mode 100644 headers/meta.hpp/meta_types/function_type.hpp delete mode 100644 headers/meta.hpp/meta_types/member_type.hpp delete mode 100644 headers/meta.hpp/meta_types/method_type.hpp delete mode 100644 headers/meta.hpp/meta_types/pointer_type.hpp delete mode 100644 headers/meta.hpp/meta_types/reference_type.hpp delete mode 100644 headers/meta.hpp/meta_types/void_type.hpp delete mode 100644 headers/meta.hpp/meta_utilities.hpp delete mode 100644 headers/meta.hpp/meta_utilities/_utilities_fwd.hpp delete mode 100644 headers/meta.hpp/meta_utilities/arg.hpp delete mode 100644 headers/meta.hpp/meta_utilities/inst.hpp delete mode 100644 headers/meta.hpp/meta_utilities/value.hpp delete mode 100644 untests/features/infos/_infos_fwd.hpp delete mode 100644 untests/features/infos/base_info_tests.cpp delete mode 100644 untests/features/infos/class_info_tests.cpp delete mode 100644 untests/features/infos/ctor_info_tests.cpp delete mode 100644 untests/features/infos/data_info_tests.cpp delete mode 100644 untests/features/infos/enum_info_tests.cpp delete mode 100644 untests/features/infos/evalue_info_tests.cpp delete mode 100644 untests/features/infos/function_info_tests.cpp delete mode 100644 untests/features/infos/member_info_tests.cpp delete mode 100644 untests/features/infos/method_info_tests.cpp delete mode 100644 untests/features/infos/namespace_info_tests.cpp delete mode 100644 untests/features/registry/_registry_fwd.hpp delete mode 100644 untests/features/registry/registry_tests.cpp delete mode 100644 untests/features/types/_types_fwd.hpp delete mode 100644 untests/features/types/arithmetic_type_tests.cpp delete mode 100644 untests/features/types/array_type_tests.cpp delete mode 100644 untests/features/types/base_type_tests.cpp delete mode 100644 untests/features/types/class_type_tests.cpp delete mode 100644 untests/features/types/ctor_type_tests.cpp delete mode 100644 untests/features/types/enum_type_tests.cpp delete mode 100644 untests/features/types/function_type_tests.cpp delete mode 100644 untests/features/types/member_type_tests.cpp delete mode 100644 untests/features/types/method_type_tests.cpp delete mode 100644 untests/features/types/pointer_type_tests.cpp delete mode 100644 untests/features/types/reference_type_tests.cpp delete mode 100644 untests/features/types/void_type_tests.cpp delete mode 100644 untests/features/utilities/_utilities_fwd.hpp delete mode 100644 untests/features/utilities/arg_tests.cpp delete mode 100644 untests/features/utilities/inst_tests.cpp delete mode 100644 untests/features/utilities/value_tests.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index eccb5c1..b35fbd9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,18 +20,13 @@ target_include_directories(${PROJECT_NAME} INTERFACE headers) target_compile_options(${PROJECT_NAME} INTERFACE $<$: - /wd4702> + > + INTERFACE + $<$: + > INTERFACE $<$,$>: - -Wno-c++98-compat-pedantic - -Wno-covered-switch-default - -Wno-ctad-maybe-unsupported - -Wno-exit-time-destructors - -Wno-padded - -Wno-poison-system-directories - -Wno-shadow - -Wno-unknown-warning-option - -Wno-weak-vtables>) + >) if(BUILD_AS_STANDALONE) option(BUILD_WITH_UNTESTS "Build with unit tests" ON) diff --git a/headers/meta.hpp/meta_all.hpp b/headers/meta.hpp/meta_all.hpp index d31c920..f2adc16 100644 --- a/headers/meta.hpp/meta_all.hpp +++ b/headers/meta.hpp/meta_all.hpp @@ -7,7 +7,3 @@ #pragma once #include "meta_fwd.hpp" -#include "meta_infos.hpp" -#include "meta_registry.hpp" -#include "meta_types.hpp" -#include "meta_utilities.hpp" diff --git a/headers/meta.hpp/meta_fwd.hpp b/headers/meta.hpp/meta_fwd.hpp index 4ae5f20..bae8590 100644 --- a/headers/meta.hpp/meta_fwd.hpp +++ b/headers/meta.hpp/meta_fwd.hpp @@ -6,169 +6,6 @@ #pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - namespace meta_hpp { - template < typename Enum > - using bitflags = enum_hpp::bitflags::bitflags; -} - -namespace meta_hpp -{ - class base_info; - class class_info; - class ctor_info; - class data_info; - class enum_info; - class evalue_info; - class function_info; - class member_info; - class method_info; - class namespace_info; -} - -namespace meta_hpp -{ - template < typename Base > class base_; - template < typename Class > class class_; - template < typename... Args > class ctor_; - class data_; - template < typename Enum > class enum_; - template < typename Enum > class evalue_; - template < typename Function > class function_; - template < typename Member > class member_; - template < typename Method > class method_; - class namespace_; -} - -namespace meta_hpp -{ - class type_id; - - class arithmetic_type; - class array_type; - class base_type; - class class_type; - class ctor_type; - class enum_type; - class function_type; - class member_type; - class method_type; - class pointer_type; - class reference_type; - class void_type; -} - -namespace meta_hpp -{ - class arg; - class inst; - class value; -} - -namespace meta_hpp -{ - template < typename K, typename V > - using info_map = std::map>; - - using base_info_map = info_map; - using class_info_map = info_map; - using ctor_info_map = info_map; - using data_info_map = info_map; - using enum_info_map = info_map; - using evalue_info_map = info_map; - using function_info_map = info_map; - using member_info_map = info_map; - using method_info_map = info_map; - using namespace_info_map = info_map; -} - -namespace meta_hpp -{ - template < typename... Args > - struct typename_arg_t {}; - - template < typename... Args > - inline constexpr typename_arg_t typename_arg{}; -} - -namespace meta_hpp::stdex -{ - template < typename T > - struct is_bounded_array: std::false_type {}; - template < typename T, std::size_t N > - struct is_bounded_array: std::true_type {}; - template < typename T > - inline constexpr bool is_bounded_array_v = is_bounded_array::value; - - template < typename T > - struct is_unbounded_array: std::false_type {}; - template < typename T > - struct is_unbounded_array: std::true_type {}; - template < typename T > - inline constexpr bool is_unbounded_array_v = is_unbounded_array::value; - - template < typename T > - struct remove_cvref { - using type = std::remove_cv_t>; - }; - template < typename T > - using remove_cvref_t = typename remove_cvref::type; - - template < typename Enum > - constexpr std::underlying_type_t to_underlying(Enum e) noexcept { - return static_cast>(e); - } -} - -namespace meta_hpp::detail -{ - template < typename K, typename V, typename C, typename A, typename K2, typename U > - V find_or(const std::map& src, K2&& key, U&& def) { - if ( auto iter = src.find(std::forward(key)); iter != src.end() ) { - return iter->second; - } - return std::forward(def); - } - - template < typename K, typename V, typename C, typename A, typename K2 > - V find_or_default(const std::map& src, K2&& key) { - return find_or(src, std::forward(key), V{}); - } - - template < typename K, typename V, typename C, typename A, typename K2, typename V2, typename F > - void merge_with(std::map& dst, K2&& key, V2&& value, F&& f) { - if ( auto iter = dst.find(key); iter != dst.end() ) { - std::invoke(std::forward(f), iter->second, std::forward(value)); - } else { - dst.emplace(std::forward(key), std::forward(value)); - } - } } diff --git a/headers/meta.hpp/meta_infos.hpp b/headers/meta.hpp/meta_infos.hpp deleted file mode 100644 index d4be547..0000000 --- a/headers/meta.hpp/meta_infos.hpp +++ /dev/null @@ -1,20 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "meta_fwd.hpp" - -#include "meta_infos/base_info.hpp" -#include "meta_infos/class_info.hpp" -#include "meta_infos/ctor_info.hpp" -#include "meta_infos/data_info.hpp" -#include "meta_infos/enum_info.hpp" -#include "meta_infos/evalue_info.hpp" -#include "meta_infos/function_info.hpp" -#include "meta_infos/member_info.hpp" -#include "meta_infos/method_info.hpp" -#include "meta_infos/namespace_info.hpp" diff --git a/headers/meta.hpp/meta_infos/_infos_fwd.hpp b/headers/meta.hpp/meta_infos/_infos_fwd.hpp deleted file mode 100644 index 62999e5..0000000 --- a/headers/meta.hpp/meta_infos/_infos_fwd.hpp +++ /dev/null @@ -1,11 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "../meta_fwd.hpp" -#include "../meta_types.hpp" -#include "../meta_utilities.hpp" diff --git a/headers/meta.hpp/meta_infos/base_info.hpp b/headers/meta.hpp/meta_infos/base_info.hpp deleted file mode 100644 index 9f812b5..0000000 --- a/headers/meta.hpp/meta_infos/base_info.hpp +++ /dev/null @@ -1,93 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "_infos_fwd.hpp" - -#include "data_info.hpp" - -namespace meta_hpp -{ - class base_info final { - public: - base_info() = default; - - void merge(const base_info& other); - explicit operator bool() const noexcept; - - const base_type& type() const noexcept; - public: - template < typename F > - void visit(F&& f) const; - - template < typename F > - void each_data(F&& f) const; - - data_info get_data_by_name(std::string_view name) const noexcept; - private: - template < typename Base > friend class base_; - - template < typename Base, typename Derived > - explicit base_info(typename_arg_t, typename_arg_t); - private: - struct state; - std::shared_ptr state_; - }; -} - -namespace meta_hpp -{ - struct base_info::state final { - base_type type; - data_info_map datas; - }; -} - -namespace meta_hpp -{ - inline void base_info::merge(const base_info& other) { - (void)other; - ///TODO: implme - } - - inline base_info::operator bool() const noexcept { - return !!state_; - } - - inline const base_type& base_info::type() const noexcept { - return state_->type; - } -} - -namespace meta_hpp -{ - template < typename F > - void base_info::visit(F&& f) const { - each_data(f); - } - - template < typename F > - void base_info::each_data(F&& f) const { - for ( auto&& name_info : state_->datas ) { - std::invoke(f, name_info.second); - } - } - - inline data_info base_info::get_data_by_name(std::string_view name) const noexcept { - return detail::find_or_default(state_->datas, name); - } -} - -namespace meta_hpp -{ - template < typename Base, typename Derived > - base_info::base_info(typename_arg_t, typename_arg_t) - : state_{std::make_shared(state{ - base_type{typename_arg, typename_arg}, - {} - })} {} -} diff --git a/headers/meta.hpp/meta_infos/class_info.hpp b/headers/meta.hpp/meta_infos/class_info.hpp deleted file mode 100644 index fc0ec79..0000000 --- a/headers/meta.hpp/meta_infos/class_info.hpp +++ /dev/null @@ -1,289 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "_infos_fwd.hpp" - -#include "base_info.hpp" -#include "ctor_info.hpp" -#include "data_info.hpp" -#include "enum_info.hpp" -#include "function_info.hpp" -#include "member_info.hpp" -#include "method_info.hpp" - -namespace meta_hpp -{ - class class_info final { - public: - class_info() = default; - - void merge(const class_info& other); - explicit operator bool() const noexcept; - - const std::string& name() const noexcept; - const class_type& type() const noexcept; - - template < typename Base > - bool is_derived_from() const; - bool is_derived_from(any_type base) const noexcept; - - template < typename... Args > - ctor_info get_ctor_by_args() const noexcept; - template < std::size_t N > - ctor_info get_ctor_by_args(const std::array& args) const noexcept; - ctor_info get_ctor_by_args(const std::vector& args) const noexcept; - ctor_info get_ctor_by_args(std::initializer_list args) const noexcept; - public: - template < typename F > - void visit(F&& f) const; - - template < typename F > - void each_base(F&& f) const; - - template < typename F > - void each_class(F&& f) const; - - template < typename F > - void each_ctor(F&& f) const; - - template < typename F > - void each_data(F&& f) const; - - template < typename F > - void each_enum(F&& f) const; - - template < typename F > - void each_function(F&& f) const; - - template < typename F > - void each_member(F&& f) const; - - template < typename F > - void each_method(F&& f) const; - - class_info get_class_by_name(std::string_view name) const noexcept; - data_info get_data_by_name(std::string_view name) const noexcept; - enum_info get_enum_by_name(std::string_view name) const noexcept; - function_info get_function_by_name(std::string_view name) const noexcept; - member_info get_member_by_name(std::string_view name) const noexcept; - method_info get_method_by_name(std::string_view name) const noexcept; - private: - template < typename Class > friend class class_; - - template < typename Class > - explicit class_info(typename_arg_t, std::string name); - private: - struct state; - std::shared_ptr state_; - }; -} - -namespace meta_hpp -{ - struct class_info::state final { - std::string name; - class_type type; - base_info_map bases; - class_info_map classes; - ctor_info_map ctors; - data_info_map datas; - enum_info_map enums; - function_info_map functions; - member_info_map members; - method_info_map methods; - }; -} - -namespace meta_hpp -{ - inline void class_info::merge(const class_info& other) { - (void)other; - ///TODO: implme - } - - inline class_info::operator bool() const noexcept { - return !!state_; - } - - inline const std::string& class_info::name() const noexcept { - return state_->name; - } - - inline const class_type& class_info::type() const noexcept { - return state_->type; - } - - template < typename Base > - bool class_info::is_derived_from() const { - return class_info::is_derived_from(type_db::get()); - } - - inline bool class_info::is_derived_from(any_type base) const noexcept { - for ( auto&& id_info : state_->bases ) { - if ( base == id_info.second.type().base_class_type() ) { - return true; - } - } - return false; - } - - template < typename... Args > - ctor_info class_info::get_ctor_by_args() const noexcept { - std::array args{type_db::get()...}; - return get_ctor_by_args(args); - } - - template < std::size_t N > - ctor_info class_info::get_ctor_by_args(const std::array& args) const noexcept { - for ( auto&& id_info : state_->ctors ) { - const std::vector& ctor_args = - id_info.second.type().argument_types(); - - if ( args.size() == ctor_args.size() - && std::equal(args.begin(), args.end(), ctor_args.begin()) ) - { - return id_info.second; - } - } - return ctor_info{}; - } - - inline ctor_info class_info::get_ctor_by_args(const std::vector& args) const noexcept { - for ( auto&& id_info : state_->ctors ) { - const std::vector& ctor_args = - id_info.second.type().argument_types(); - - if ( args.size() == ctor_args.size() - && std::equal(args.begin(), args.end(), ctor_args.begin()) ) - { - return id_info.second; - } - } - return ctor_info{}; - } - - inline ctor_info class_info::get_ctor_by_args(std::initializer_list args) const noexcept { - for ( auto&& id_info : state_->ctors ) { - const std::vector& ctor_args = - id_info.second.type().argument_types(); - - if ( args.size() == ctor_args.size() - && std::equal(args.begin(), args.end(), ctor_args.begin()) ) - { - return id_info.second; - } - } - return ctor_info{}; - } -} - -namespace meta_hpp -{ - template < typename F > - void class_info::visit(F&& f) const { - each_base(f); - each_class(f); - each_ctor(f); - each_data(f); - each_enum(f); - each_function(f); - each_member(f); - each_method(f); - } - - template < typename F > - void class_info::each_base(F&& f) const { - for ( auto&& id_info : state_->bases ) { - std::invoke(f, id_info.second); - } - } - - template < typename F > - void class_info::each_class(F&& f) const { - for ( auto&& name_info : state_->classes ) { - std::invoke(f, name_info.second); - } - } - - template < typename F > - void class_info::each_ctor(F&& f) const { - for ( auto&& id_info : state_->ctors ) { - std::invoke(f, id_info.second); - } - } - - template < typename F > - void class_info::each_data(F&& f) const { - for ( auto&& name_info : state_->datas ) { - std::invoke(f, name_info.second); - } - } - - template < typename F > - void class_info::each_enum(F&& f) const { - for ( auto&& name_info : state_->enums ) { - std::invoke(f, name_info.second); - } - } - - template < typename F > - void class_info::each_function(F&& f) const { - for ( auto&& name_info : state_->functions ) { - std::invoke(f, name_info.second); - } - } - - template < typename F > - void class_info::each_member(F&& f) const { - for ( auto&& name_info : state_->members ) { - std::invoke(f, name_info.second); - } - } - - template < typename F > - void class_info::each_method(F&& f) const { - for ( auto&& name_info : state_->methods ) { - std::invoke(f, name_info.second); - } - } - - inline class_info class_info::get_class_by_name(std::string_view name) const noexcept { - return detail::find_or_default(state_->classes, name); - } - - inline data_info class_info::get_data_by_name(std::string_view name) const noexcept { - return detail::find_or_default(state_->datas, name); - } - - inline enum_info class_info::get_enum_by_name(std::string_view name) const noexcept { - return detail::find_or_default(state_->enums, name); - } - - inline function_info class_info::get_function_by_name(std::string_view name) const noexcept { - return detail::find_or_default(state_->functions, name); - } - - inline member_info class_info::get_member_by_name(std::string_view name) const noexcept { - return detail::find_or_default(state_->members, name); - } - - inline method_info class_info::get_method_by_name(std::string_view name) const noexcept { - return detail::find_or_default(state_->methods, name); - } -} - -namespace meta_hpp -{ - template < typename Class > - inline class_info::class_info(typename_arg_t, std::string name) - : state_{std::make_shared(state{ - std::move(name), - type_db::get().template as(), - {}, {}, {}, {}, {}, {}, {}, {} - })} {} -} diff --git a/headers/meta.hpp/meta_infos/ctor_info.hpp b/headers/meta.hpp/meta_infos/ctor_info.hpp deleted file mode 100644 index c0d237d..0000000 --- a/headers/meta.hpp/meta_infos/ctor_info.hpp +++ /dev/null @@ -1,204 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "_infos_fwd.hpp" - -#include "data_info.hpp" - -namespace meta_hpp -{ - class ctor_info final { - public: - ctor_info() = default; - - void merge(const ctor_info& other); - explicit operator bool() const noexcept; - - const ctor_type& type() const noexcept; - - template < typename... Args > - value invoke(Args&&... args) const; - - template < typename... Args > - bool is_invocable_with() const noexcept; - public: - template < typename F > - void visit(F&& f) const; - - template < typename F > - void each_data(F&& f) const; - - data_info get_data_by_name(std::string_view name) const noexcept; - private: - template < typename... Args > friend class ctor_; - - template < typename Class, typename... Args > - explicit ctor_info(typename_arg_t, typename_arg_t); - private: - struct state; - std::shared_ptr state_; - }; -} - -namespace meta_hpp::detail -{ - using ctor_invoke = std::function; - - template < typename Class, typename... Args, std::size_t... Is > - value raw_ctor_invoke_impl( - const arg* args, - std::index_sequence) - { - using ct = ctor_traits; - using class_type = typename ct::class_type; - using argument_types = typename ct::argument_types; - - if ( !(... && (args + Is)->can_cast_to>()) ) { - throw std::logic_error("an attempt to call a ctor with an incorrect argument types"); - } - - class_type class_value{(args + Is)->cast>()...}; - return value{std::forward(class_value)}; - } - - template < typename Class, typename... Args > - value raw_ctor_invoke( - const arg* args, - std::size_t arg_count) - { - using ct = ctor_traits; - - if ( arg_count != ct::arity ) { - throw std::logic_error("an attempt to call a ctor with an incorrect arity"); - } - - return raw_ctor_invoke_impl( - args, - std::make_index_sequence()); - } - - template < typename Class, typename... Args > - ctor_invoke make_ctor_invoke() { - using namespace std::placeholders; - return std::bind(&raw_ctor_invoke, _1, _2); - } -} - -namespace meta_hpp::detail -{ - using ctor_is_invocable_with = std::function; - - template < typename Class, typename... Args, std::size_t... Is > - bool raw_ctor_is_invocable_with_impl( - const arg_base* arg_bases, - std::index_sequence) - { - using ct = ctor_traits; - using argument_types = typename ct::argument_types; - return (... && (arg_bases + Is)->can_cast_to>() ); - } - - template < typename Class, typename... Args > - bool raw_ctor_is_invocable_with( - const arg_base* arg_bases, - std::size_t arg_count) - { - using ct = ctor_traits; - - if ( arg_count != ct::arity ) { - return false; - } - - return raw_ctor_is_invocable_with_impl( - arg_bases, - std::make_index_sequence()); - } - - template < typename Class, typename... Args > - ctor_is_invocable_with make_ctor_is_invocable_with() { - using namespace std::placeholders; - return std::bind(&raw_ctor_is_invocable_with, _1, _2); - } -} - -namespace meta_hpp -{ - struct ctor_info::state final { - ctor_type type; - data_info_map datas; - detail::ctor_invoke invoke; - detail::ctor_is_invocable_with is_invocable_with; - }; -} - -namespace meta_hpp -{ - inline void ctor_info::merge(const ctor_info& other) { - (void)other; - ///TODO: implme - } - - inline ctor_info::operator bool() const noexcept { - return !!state_; - } - - inline const ctor_type& ctor_info::type() const noexcept { - return state_->type; - } - - template < typename... Args > - value ctor_info::invoke(Args&&... args) const { - if constexpr ( sizeof...(Args) > 0 ) { - std::array vargs{arg{std::forward(args)}...}; - return state_->invoke(vargs.data(), vargs.size()); - } else { - return state_->invoke(nullptr, 0); - } - } - - template < typename... Args > - bool ctor_info::is_invocable_with() const noexcept { - if constexpr ( sizeof...(Args) > 0 ) { - std::array arg_bases{arg_base{typename_arg}...}; - return state_->is_invocable_with(arg_bases.data(), arg_bases.size()); - } else { - return state_->is_invocable_with(nullptr, 0); - } - } -} - -namespace meta_hpp -{ - template < typename F > - void ctor_info::visit(F&& f) const { - each_data(f); - } - - template < typename F > - void ctor_info::each_data(F&& f) const { - for ( auto&& name_info : state_->datas ) { - std::invoke(f, name_info.second); - } - } - - inline data_info ctor_info::get_data_by_name(std::string_view name) const noexcept { - return detail::find_or_default(state_->datas, name); - } -} - -namespace meta_hpp -{ - template < typename Class, typename... Args > - ctor_info::ctor_info(typename_arg_t, typename_arg_t) - : state_{std::make_shared(state{ - ctor_type{typename_arg, typename_arg}, - {}, - detail::make_ctor_invoke(), - detail::make_ctor_is_invocable_with(), - })} {} -} diff --git a/headers/meta.hpp/meta_infos/data_info.hpp b/headers/meta.hpp/meta_infos/data_info.hpp deleted file mode 100644 index e6554c8..0000000 --- a/headers/meta.hpp/meta_infos/data_info.hpp +++ /dev/null @@ -1,96 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "_infos_fwd.hpp" - -namespace meta_hpp -{ - class data_info final { - public: - data_info() = default; - - void merge(const data_info& other); - explicit operator bool() const noexcept; - - const std::string& name() const noexcept; - const class value& value() const noexcept; - public: - template < typename F > - void visit(F&& f) const; - - template < typename F > - void each_data(F&& f) const; - - data_info get_data_by_name(std::string_view name) const noexcept; - private: - friend class data_; - - explicit data_info(std::string name, class value value); - private: - struct state; - std::shared_ptr state_; - }; -} - -namespace meta_hpp -{ - struct data_info::state final { - std::string name; - class value value; - data_info_map datas; - }; -} - -namespace meta_hpp -{ - inline void data_info::merge(const data_info& other) { - (void)other; - ///TODO: implme - } - - inline data_info::operator bool() const noexcept { - return !!state_; - } - - inline const std::string& data_info::name() const noexcept { - return state_->name; - } - - inline const class value& data_info::value() const noexcept { - return state_->value; - } -} - -namespace meta_hpp -{ - template < typename F > - void data_info::visit(F&& f) const { - each_data(f); - } - - template < typename F > - void data_info::each_data(F&& f) const { - for ( auto&& name_info : state_->datas ) { - std::invoke(f, name_info.second); - } - } - - inline data_info data_info::get_data_by_name(std::string_view name) const noexcept { - return detail::find_or_default(state_->datas, name); - } -} - -namespace meta_hpp -{ - inline data_info::data_info(std::string name, class value value) - : state_{std::make_shared(state{ - std::move(name), - std::move(value), - {} - })} {} -} diff --git a/headers/meta.hpp/meta_infos/enum_info.hpp b/headers/meta.hpp/meta_infos/enum_info.hpp deleted file mode 100644 index 44ffb44..0000000 --- a/headers/meta.hpp/meta_infos/enum_info.hpp +++ /dev/null @@ -1,118 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "_infos_fwd.hpp" - -#include "data_info.hpp" -#include "evalue_info.hpp" - -namespace meta_hpp -{ - class enum_info final { - public: - enum_info() = default; - - void merge(const enum_info& other); - explicit operator bool() const noexcept; - - const std::string& name() const noexcept; - const enum_type& type() const noexcept; - public: - template < typename F > - void visit(F&& f) const; - - template < typename F > - void each_data(F&& f) const; - - template < typename F > - void each_evalue(F&& f) const; - - data_info get_data_by_name(std::string_view name) const noexcept; - evalue_info get_evalue_by_name(std::string_view name) const noexcept; - private: - template < typename Enum > friend class enum_; - - template < typename Enum > - explicit enum_info(typename_arg_t, std::string name); - private: - struct state; - std::shared_ptr state_; - }; -} - -namespace meta_hpp -{ - struct enum_info::state final { - std::string name; - enum_type type; - data_info_map datas; - evalue_info_map evalues; - }; -} - -namespace meta_hpp -{ - inline void enum_info::merge(const enum_info& other) { - (void)other; - ///TODO: implme - } - - inline enum_info::operator bool() const noexcept { - return !!state_; - } - - inline const std::string& enum_info::name() const noexcept { - return state_->name; - } - - inline const enum_type& enum_info::type() const noexcept { - return state_->type; - } -} - -namespace meta_hpp -{ - template < typename F > - void enum_info::visit(F&& f) const { - each_data(f); - each_evalue(f); - } - - template < typename F > - void enum_info::each_data(F&& f) const { - for ( auto&& name_info : state_->datas ) { - std::invoke(f, name_info.second); - } - } - - template < typename F > - void enum_info::each_evalue(F&& f) const { - for ( auto&& name_info : state_->evalues ) { - std::invoke(f, name_info.second); - } - } - - inline data_info enum_info::get_data_by_name(std::string_view name) const noexcept { - return detail::find_or_default(state_->datas, name); - } - - inline evalue_info enum_info::get_evalue_by_name(std::string_view name) const noexcept { - return detail::find_or_default(state_->evalues, name); - } -} - -namespace meta_hpp -{ - template < typename Enum > - enum_info::enum_info(typename_arg_t, std::string name) - : state_{std::make_shared(state{ - std::move(name), - type_db::get().template as(), - {}, {} - })} {} -} diff --git a/headers/meta.hpp/meta_infos/evalue_info.hpp b/headers/meta.hpp/meta_infos/evalue_info.hpp deleted file mode 100644 index e516f72..0000000 --- a/headers/meta.hpp/meta_infos/evalue_info.hpp +++ /dev/null @@ -1,100 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "_infos_fwd.hpp" - -#include "data_info.hpp" - -namespace meta_hpp -{ - class evalue_info final { - public: - evalue_info() = default; - - void merge(const evalue_info& other); - explicit operator bool() const noexcept; - - const std::string& name() const noexcept; - const class value& value() const noexcept; - public: - template < typename F > - void visit(F&& f) const; - - template < typename F > - void each_data(F&& f) const; - - data_info get_data_by_name(std::string_view name) const noexcept; - private: - template < typename Enum > friend class evalue_; - - template < typename Enum > - explicit evalue_info(std::string name, Enum value); - private: - struct state; - std::shared_ptr state_; - }; -} - -namespace meta_hpp -{ - struct evalue_info::state final { - std::string name; - class value value; - data_info_map datas; - }; -} - -namespace meta_hpp -{ - inline void evalue_info::merge(const evalue_info& other) { - (void)other; - ///TODO: implme - } - - inline evalue_info::operator bool() const noexcept { - return !!state_; - } - - inline const std::string& evalue_info::name() const noexcept { - return state_->name; - } - - inline const class value& evalue_info::value() const noexcept { - return state_->value; - } -} - -namespace meta_hpp -{ - template < typename F > - void evalue_info::visit(F&& f) const { - each_data(f); - } - - template < typename F > - void evalue_info::each_data(F&& f) const { - for ( auto&& name_info : state_->datas ) { - std::invoke(f, name_info.second); - } - } - - inline data_info evalue_info::get_data_by_name(std::string_view name) const noexcept { - return detail::find_or_default(state_->datas, name); - } -} - -namespace meta_hpp -{ - template < typename Enum > - evalue_info::evalue_info(std::string name, Enum value) - : state_{std::make_shared(state{ - std::move(name), - std::move(value), - {} - })} {} -} diff --git a/headers/meta.hpp/meta_infos/function_info.hpp b/headers/meta.hpp/meta_infos/function_info.hpp deleted file mode 100644 index 1303050..0000000 --- a/headers/meta.hpp/meta_infos/function_info.hpp +++ /dev/null @@ -1,221 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "_infos_fwd.hpp" - -#include "data_info.hpp" - -namespace meta_hpp -{ - class function_info final { - public: - function_info() = default; - - void merge(const function_info& other); - explicit operator bool() const noexcept; - - const std::string& name() const noexcept; - const function_type& type() const noexcept; - - template < typename... Args > - std::optional invoke(Args&&... args) const; - - template < typename... Args > - bool is_invocable_with() const noexcept; - public: - template < typename F > - void visit(F&& f) const; - - template < typename F > - void each_data(F&& f) const; - - data_info get_data_by_name(std::string_view name) const noexcept; - private: - template < typename Function > friend class function_; - - template < typename Function > - explicit function_info(std::string name, Function function); - private: - struct state; - std::shared_ptr state_; - }; -} - -namespace meta_hpp::detail -{ - using function_invoke = std::function(const arg*, std::size_t)>; - - template < typename Function, std::size_t... Is > - std::optional raw_function_invoke_impl( - Function function, - const arg* args, - std::index_sequence) - { - using ft = function_pointer_traits; - using return_type = typename ft::return_type; - using argument_types = typename ft::argument_types; - - if ( !(... && (args + Is)->can_cast_to>()) ) { - throw std::logic_error("an attempt to call a function with an incorrect argument types"); - } - - if constexpr ( std::is_void_v ) { - std::invoke(function, - (args + Is)->cast>()...); - return std::nullopt; - } else { - return_type return_value{std::invoke(function, - (args + Is)->cast>()...)}; - return value{std::forward(return_value)}; - } - } - - template < typename Function > - std::optional raw_function_invoke( - Function function, - const arg* args, - std::size_t arg_count) - { - using ft = function_pointer_traits; - - if ( arg_count != ft::arity ) { - throw std::logic_error("an attempt to call a function with an incorrect arity"); - } - - return raw_function_invoke_impl( - function, - args, - std::make_index_sequence()); - } - - template < typename Function > - function_invoke make_function_invoke(Function function) { - using namespace std::placeholders; - return std::bind(&raw_function_invoke, function, _1, _2); - } -} - -namespace meta_hpp::detail -{ - using function_is_invocable_with = std::function; - - template < typename Function, std::size_t... Is > - bool raw_function_is_invocable_with_impl( - const arg_base* arg_bases, - std::index_sequence) - { - using ft = function_pointer_traits; - using argument_types = typename ft::argument_types; - return (... && (arg_bases + Is)->can_cast_to>() ); - } - - template < typename Function > - bool raw_function_is_invocable_with( - const arg_base* arg_bases, - std::size_t arg_count) - { - using ft = function_pointer_traits; - - if ( arg_count != ft::arity ) { - return false; - } - - return raw_function_is_invocable_with_impl( - arg_bases, - std::make_index_sequence()); - } - - template < typename Function > - function_is_invocable_with make_function_is_invocable_with() { - using namespace std::placeholders; - return std::bind(&raw_function_is_invocable_with, _1, _2); - } -} - -namespace meta_hpp -{ - struct function_info::state final { - std::string name; - function_type type; - data_info_map datas; - detail::function_invoke invoke; - detail::function_is_invocable_with is_invocable_with; - }; -} - -namespace meta_hpp -{ - inline void function_info::merge(const function_info& other) { - (void)other; - ///TODO: implme - } - - inline function_info::operator bool() const noexcept { - return !!state_; - } - - inline const std::string& function_info::name() const noexcept { - return state_->name; - } - - inline const function_type& function_info::type() const noexcept { - return state_->type; - } - - template < typename... Args > - std::optional function_info::invoke(Args&&... args) const { - if constexpr ( sizeof...(Args) > 0 ) { - std::array vargs{arg{std::forward(args)}...}; - return state_->invoke(vargs.data(), vargs.size()); - } else { - return state_->invoke(nullptr, 0); - } - } - - template < typename... Args > - bool function_info::is_invocable_with() const noexcept { - if constexpr ( sizeof...(Args) > 0 ) { - std::array arg_bases{arg_base{typename_arg}...}; - return state_->is_invocable_with(arg_bases.data(), arg_bases.size()); - } else { - return state_->is_invocable_with(nullptr, 0); - } - } -} - -namespace meta_hpp -{ - template < typename F > - void function_info::visit(F&& f) const { - each_data(f); - } - - template < typename F > - void function_info::each_data(F&& f) const { - for ( auto&& name_info : state_->datas ) { - std::invoke(f, name_info.second); - } - } - - inline data_info function_info::get_data_by_name(std::string_view name) const noexcept { - return detail::find_or_default(state_->datas, name); - } -} - -namespace meta_hpp -{ - template < typename Function > - function_info::function_info(std::string name, Function function) - : state_{std::make_shared(state{ - std::move(name), - type_db::get().template as(), - {}, - detail::make_function_invoke(function), - detail::make_function_is_invocable_with(), - })} {} -} diff --git a/headers/meta.hpp/meta_infos/member_info.hpp b/headers/meta.hpp/meta_infos/member_info.hpp deleted file mode 100644 index 613ba2a..0000000 --- a/headers/meta.hpp/meta_infos/member_info.hpp +++ /dev/null @@ -1,181 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "_infos_fwd.hpp" - -#include "data_info.hpp" - -namespace meta_hpp -{ - class member_info final { - public: - member_info() = default; - - void merge(const member_info& other); - explicit operator bool() const noexcept; - - const std::string& name() const noexcept; - const member_type& type() const noexcept; - - template < typename Instance > - value get(Instance&& instance) const; - - template < typename Instance, typename Value > - void set(Instance&& instance, Value&& value) const; - public: - template < typename F > - void visit(F&& f) const; - - template < typename F > - void each_data(F&& f) const; - - data_info get_data_by_name(std::string_view name) const noexcept; - private: - template < typename Member > friend class member_; - - template < typename Member > - explicit member_info(std::string name, Member instance); - private: - struct state; - std::shared_ptr state_; - }; -} - -namespace meta_hpp::detail -{ - using member_getter = std::function; - using member_setter = std::function; - - template < typename Member > - value raw_member_getter(Member member, const inst& inst) { - using mt = member_pointer_traits; - using class_type = typename mt::class_type; - using value_type = typename mt::value_type; - - using qualified_type = const class_type; - - 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(member, inst.cast())}; - return value{std::forward(return_value)}; - } - - template < typename Member > - void raw_member_setter([[maybe_unused]] Member member, const inst& inst, const arg& arg) { - using mt = member_pointer_traits; - 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 ) { - if ( inst.is_const() ) { - throw std::logic_error("an attempt to set a member with an const instance type"); - } - - if ( !inst.can_cast_to() ) { - throw std::logic_error("an attempt to set a member with an incorrect instance type"); - } - - if ( !arg.can_cast_to() ) { - throw std::logic_error("an attempt to set a member with an incorrect argument type"); - } - - std::invoke(member, inst.cast()) = arg.cast(); - } else { - throw std::logic_error("an attempt to set a constant member"); - } - } - - template < typename Member > - member_getter make_member_getter(Member member) { - using namespace std::placeholders; - return std::bind(&raw_member_getter, member, _1); - } - - template < typename Member > - member_setter make_member_setter(Member member) { - using namespace std::placeholders; - return std::bind(&raw_member_setter, member, _1, _2); - } -} - -namespace meta_hpp -{ - struct member_info::state final { - std::string name; - member_type type; - data_info_map datas; - detail::member_getter getter; - detail::member_setter setter; - }; -} - -namespace meta_hpp -{ - inline void member_info::merge(const member_info& other) { - (void)other; - ///TODO: implme - } - - inline member_info::operator bool() const noexcept { - return !!state_; - } - - inline const std::string& member_info::name() const noexcept { - return state_->name; - } - - inline const member_type& member_info::type() const noexcept { - return state_->type; - } - - template < typename Instance > - value member_info::get(Instance&& instance) const { - return state_->getter(inst{std::forward(instance)}); - } - - template < typename Instance, typename Value > - void member_info::set(Instance&& instance, Value&& value) const { - state_->setter(inst{std::forward(instance)}, arg{std::forward(value)}); - } -} - -namespace meta_hpp -{ - template < typename F > - void member_info::visit(F&& f) const { - each_data(f); - } - - template < typename F > - void member_info::each_data(F&& f) const { - for ( auto&& name_info : state_->datas ) { - std::invoke(f, name_info.second); - } - } - - inline data_info member_info::get_data_by_name(std::string_view name) const noexcept { - return detail::find_or_default(state_->datas, name); - } -} - -namespace meta_hpp -{ - template < typename Member > - member_info::member_info(std::string name, Member member) - : state_{std::make_shared(state{ - std::move(name), - type_db::get().template as(), - {}, - detail::make_member_getter(member), - detail::make_member_setter(member), - })} {} -} diff --git a/headers/meta.hpp/meta_infos/method_info.hpp b/headers/meta.hpp/meta_infos/method_info.hpp deleted file mode 100644 index c2cf42f..0000000 --- a/headers/meta.hpp/meta_infos/method_info.hpp +++ /dev/null @@ -1,237 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "_infos_fwd.hpp" - -#include "data_info.hpp" - -namespace meta_hpp -{ - class method_info final { - public: - method_info() = default; - - void merge(const method_info& other); - explicit operator bool() const noexcept; - - const std::string& name() const noexcept; - const method_type& type() const noexcept; - - template < typename Instance, typename... Args > - std::optional invoke(Instance&& instance, Args&&... args) const; - - template < typename Inst, typename... Args > - bool is_invocable_with() const noexcept; - public: - template < typename F > - void visit(F&& f) const; - - template < typename F > - void each_data(F&& f) const; - - data_info get_data_by_name(std::string_view name) const noexcept; - private: - template < typename Method > friend class method_; - - template < typename Method > - explicit method_info(std::string name, Method method); - private: - struct state; - std::shared_ptr state_; - }; -} - -namespace meta_hpp::detail -{ - using method_invoke = std::function(const inst&, const arg*, std::size_t)>; - - template < typename Method, std::size_t... Is > - std::optional raw_method_invoke_impl( - Method method, - const inst& inst, - const arg* args, - std::index_sequence) - { - using mt = method_pointer_traits; - using return_type = typename mt::return_type; - using qualified_type = typename mt::qualified_type; - using argument_types = typename mt::argument_types; - - if ( !inst.can_cast_to() ) { - throw std::logic_error("an attempt to call a method with an incorrect instance type"); - } - - if ( !(... && (args + Is)->can_cast_to>()) ) { - throw std::logic_error("an attempt to call a method with an incorrect argument types"); - } - - if constexpr ( std::is_void_v ) { - std::invoke(method, - inst.cast(), - (args + Is)->cast>()...); - return std::nullopt; - } else { - return_type return_value{std::invoke(method, - inst.cast(), - (args + Is)->cast>()...)}; - return value{std::forward(return_value)}; - } - } - - template < typename Method > - std::optional raw_method_invoke( - Method method, - const inst& inst, - const arg* args, - std::size_t arg_count) - { - using mt = method_pointer_traits; - - if ( arg_count != mt::arity ) { - throw std::logic_error("an attempt to call a method with an incorrect arity"); - } - - return raw_method_invoke_impl( - method, - inst, - args, - std::make_index_sequence()); - } - - template < typename Method > - method_invoke make_method_invoke(Method method) { - using namespace std::placeholders; - return std::bind(&raw_method_invoke, method, _1, _2, _3); - } -} - -namespace meta_hpp::detail -{ - using method_is_invocable_with = std::function; - - template < typename Method, std::size_t... Is > - bool raw_method_is_invocable_with_impl( - const inst_base& inst_base, - const arg_base* arg_bases, - std::index_sequence) - { - using mt = method_pointer_traits; - using qualified_type = typename mt::qualified_type; - using argument_types = typename mt::argument_types; - - return inst_base.can_cast_to() - && (... && (arg_bases + Is)->can_cast_to>() ); - } - - template < typename Method > - bool raw_method_is_invocable_with( - const inst_base& inst_base, - const arg_base* arg_bases, - std::size_t arg_count) - { - using mt = method_pointer_traits; - - if ( arg_count != mt::arity ) { - return false; - } - - return raw_method_is_invocable_with_impl( - inst_base, - arg_bases, - std::make_index_sequence()); - } - - template < typename Method > - method_is_invocable_with make_method_is_invocable_with() { - using namespace std::placeholders; - return std::bind(&raw_method_is_invocable_with, _1, _2, _3); - } -} - -namespace meta_hpp -{ - struct method_info::state final { - std::string name; - method_type type; - data_info_map datas; - detail::method_invoke invoke; - detail::method_is_invocable_with is_invocable_with; - }; -} - -namespace meta_hpp -{ - inline void method_info::merge(const method_info& other) { - (void)other; - ///TODO: implme - } - - inline method_info::operator bool() const noexcept { - return !!state_; - } - - inline const std::string& method_info::name() const noexcept { - return state_->name; - } - - inline const method_type& method_info::type() const noexcept { - return state_->type; - } - - template < typename Instance, typename... Args > - std::optional method_info::invoke(Instance&& instance, Args&&... args) const { - if constexpr ( sizeof...(Args) > 0 ) { - std::array vargs{arg{std::forward(args)}...}; - return state_->invoke(inst{std::forward(instance)}, vargs.data(), vargs.size()); - } else { - return state_->invoke(inst{std::forward(instance)}, nullptr, 0); - } - } - - template < typename Inst, typename... Args > - bool method_info::is_invocable_with() const noexcept { - if constexpr ( sizeof...(Args) > 0 ) { - std::array arg_bases{arg_base{typename_arg}...}; - return state_->is_invocable_with(inst_base{typename_arg}, arg_bases.data(), arg_bases.size()); - } else { - return state_->is_invocable_with(inst_base{typename_arg}, nullptr, 0); - } - } -} - -namespace meta_hpp -{ - template < typename F > - void method_info::visit(F&& f) const { - each_data(f); - } - - template < typename F > - void method_info::each_data(F&& f) const { - for ( auto&& name_info : state_->datas ) { - std::invoke(f, name_info.second); - } - } - - inline data_info method_info::get_data_by_name(std::string_view name) const noexcept { - return detail::find_or_default(state_->datas, name); - } -} - -namespace meta_hpp -{ - template < typename Method > - method_info::method_info(std::string name, Method method) - : state_{std::make_shared(state{ - std::move(name), - type_db::get().template as(), - {}, - detail::make_method_invoke(method), - detail::make_method_is_invocable_with(), - })} {} -} diff --git a/headers/meta.hpp/meta_infos/namespace_info.hpp b/headers/meta.hpp/meta_infos/namespace_info.hpp deleted file mode 100644 index 0cb2ef5..0000000 --- a/headers/meta.hpp/meta_infos/namespace_info.hpp +++ /dev/null @@ -1,162 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "_infos_fwd.hpp" - -#include "class_info.hpp" -#include "data_info.hpp" -#include "enum_info.hpp" -#include "function_info.hpp" - -namespace meta_hpp -{ - class namespace_info final { - public: - namespace_info() = default; - - void merge(const namespace_info& other); - explicit operator bool() const noexcept; - - const std::string& name() const noexcept; - public: - template < typename F > - void visit(F&& f) const; - - template < typename F > - void each_class(F&& f) const; - - template < typename F > - void each_data(F&& f) const; - - template < typename F > - void each_enum(F&& f) const; - - template < typename F > - void each_function(F&& f) const; - - template < typename F > - void each_namespace(F&& f) const; - - class_info get_class_by_name(std::string_view name) const noexcept; - data_info get_data_by_name(std::string_view name) const noexcept; - enum_info get_enum_by_name(std::string_view name) const noexcept; - function_info get_function_by_name(std::string_view name) const noexcept; - namespace_info get_namespace_by_name(std::string_view name) const noexcept; - private: - friend class namespace_; - - explicit namespace_info(std::string name); - private: - struct state; - std::shared_ptr state_; - }; -} - -namespace meta_hpp -{ - struct namespace_info::state final { - std::string name; - class_info_map classes; - data_info_map datas; - enum_info_map enums; - function_info_map functions; - namespace_info_map namespaces; - }; -} - -namespace meta_hpp -{ - inline void namespace_info::merge(const namespace_info& other) { - (void)other; - ///TODO: implme - } - - inline namespace_info::operator bool() const noexcept { - return !!state_; - } - - inline const std::string& namespace_info::name() const noexcept { - return state_->name; - } -} - -namespace meta_hpp -{ - template < typename F > - void namespace_info::visit(F&& f) const { - each_class(f); - each_data(f); - each_enum(f); - each_function(f); - each_namespace(f); - } - - template < typename F > - void namespace_info::each_class(F&& f) const { - for ( auto&& name_info : state_->classes ) { - std::invoke(f, name_info.second); - } - } - - template < typename F > - void namespace_info::each_data(F&& f) const { - for ( auto&& name_info : state_->datas ) { - std::invoke(f, name_info.second); - } - } - - template < typename F > - void namespace_info::each_enum(F&& f) const { - for ( auto&& name_info : state_->enums ) { - std::invoke(f, name_info.second); - } - } - - template < typename F > - void namespace_info::each_function(F&& f) const { - for ( auto&& name_info : state_->functions ) { - std::invoke(f, name_info.second); - } - } - - template < typename F > - void namespace_info::each_namespace(F&& f) const { - for ( auto&& name_info : state_->namespaces ) { - std::invoke(f, name_info.second); - } - } - - inline class_info namespace_info::get_class_by_name(std::string_view name) const noexcept { - return detail::find_or_default(state_->classes, name); - } - - inline data_info namespace_info::get_data_by_name(std::string_view name) const noexcept { - return detail::find_or_default(state_->datas, name); - } - - inline enum_info namespace_info::get_enum_by_name(std::string_view name) const noexcept { - return detail::find_or_default(state_->enums, name); - } - - inline function_info namespace_info::get_function_by_name(std::string_view name) const noexcept { - return detail::find_or_default(state_->functions, name); - } - - inline namespace_info namespace_info::get_namespace_by_name(std::string_view name) const noexcept { - return detail::find_or_default(state_->namespaces, name); - } -} - -namespace meta_hpp -{ - inline namespace_info::namespace_info(std::string name) - : state_{std::make_shared(state{ - std::move(name), - {}, {}, {}, {}, {} - })} {} -} diff --git a/headers/meta.hpp/meta_registry.hpp b/headers/meta.hpp/meta_registry.hpp deleted file mode 100644 index 4cefc0c..0000000 --- a/headers/meta.hpp/meta_registry.hpp +++ /dev/null @@ -1,211 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "meta_fwd.hpp" -#include "meta_infos.hpp" - -#include "meta_registry/base_.hpp" -#include "meta_registry/class_.hpp" -#include "meta_registry/ctor_.hpp" -#include "meta_registry/data_.hpp" -#include "meta_registry/enum_.hpp" -#include "meta_registry/evalue_.hpp" -#include "meta_registry/function_.hpp" -#include "meta_registry/member_.hpp" -#include "meta_registry/method_.hpp" -#include "meta_registry/namespace_.hpp" - -namespace meta_hpp -{ - class registry final { - public: - registry() = default; - - class_info get_class_by_path(std::string_view path) const noexcept; - data_info get_data_by_path(std::string_view path) const noexcept; - enum_info get_enum_by_path(std::string_view path) const noexcept; - evalue_info get_evalue_by_path(std::string_view path) const noexcept; - function_info get_function_by_path(std::string_view path) const noexcept; - member_info get_member_by_path(std::string_view path) const noexcept; - method_info get_method_by_path(std::string_view path) const noexcept; - namespace_info get_namespace_by_path(std::string_view path) const noexcept; - public: - template < typename... Internals > - registry& operator()(Internals&&... internals); - private: - template < typename Class > - void add_(const std::string& prefix, const class_& internal); - void add_(const std::string& prefix, const data_& internal); - template < typename Enum > - void add_(const std::string& prefix, const enum_& internal); - template < typename Function > - void add_(const std::string& prefix, const function_& internal); - void add_(const std::string& prefix, const namespace_& internal); - void add_(const std::string& prefix, ...) = delete; - private: - struct add_info_f; - void add_info_(const std::string& prefix, const base_info& info); - void add_info_(const std::string& prefix, const class_info& info); - void add_info_(const std::string& prefix, const ctor_info& info); - void add_info_(const std::string& prefix, const data_info& info); - void add_info_(const std::string& prefix, const enum_info& info); - void add_info_(const std::string& prefix, const evalue_info& info); - void add_info_(const std::string& prefix, const function_info& info); - void add_info_(const std::string& prefix, const member_info& info); - void add_info_(const std::string& prefix, const method_info& info); - void add_info_(const std::string& prefix, const namespace_info& info); - void add_info_(const std::string& prefix, ...) = delete; - private: - class_info_map classes_; - data_info_map datas_; - enum_info_map enums_; - evalue_info_map evalues_; - function_info_map functions_; - member_info_map members_; - method_info_map methods_; - namespace_info_map namespaces_; - }; -} - -namespace meta_hpp -{ - inline class_info registry::get_class_by_path(std::string_view path) const noexcept { - return detail::find_or_default(classes_, path); - } - - inline data_info registry::get_data_by_path(std::string_view path) const noexcept { - return detail::find_or_default(datas_, path); - } - - inline enum_info registry::get_enum_by_path(std::string_view path) const noexcept { - return detail::find_or_default(enums_, path); - } - - inline evalue_info registry::get_evalue_by_path(std::string_view path) const noexcept { - return detail::find_or_default(evalues_, path); - } - - inline function_info registry::get_function_by_path(std::string_view path) const noexcept { - return detail::find_or_default(functions_, path); - } - - inline member_info registry::get_member_by_path(std::string_view path) const noexcept { - return detail::find_or_default(members_, path); - } - - inline method_info registry::get_method_by_path(std::string_view path) const noexcept { - return detail::find_or_default(methods_, path); - } - - inline namespace_info registry::get_namespace_by_path(std::string_view path) const noexcept { - return detail::find_or_default(namespaces_, path); - } -} - -namespace meta_hpp -{ - template < typename... Internals > - inline registry& registry::operator()(Internals&&... internals) { - (add_(std::string{}, std::forward(internals)), ...); - return *this; - } -} - -namespace meta_hpp -{ - template < typename Class > - inline void registry::add_(const std::string& prefix, const class_& internal) { - add_info_(prefix, internal.make_info()); - } - - inline void registry::add_(const std::string& prefix, const data_& internal) { - add_info_(prefix, internal.make_info()); - } - - template < typename Enum > - inline void registry::add_(const std::string& prefix, const enum_& internal) { - add_info_(prefix, internal.make_info()); - } - - template < typename Function > - inline void registry::add_(const std::string& prefix, const function_& internal) { - add_info_(prefix, internal.make_info()); - } - - inline void registry::add_(const std::string& prefix, const namespace_& internal) { - add_info_(prefix, internal.make_info()); - } -} - -namespace meta_hpp -{ - struct registry::add_info_f final { - template < typename Info > - void operator()(registry& self, const std::string& prefix, Info&& info) const { - self.add_info_(prefix, std::forward(info)); - } - }; - - inline void registry::add_info_(const std::string& prefix, const base_info& info) { - (void)prefix; - (void)info; - } - - inline void registry::add_info_(const std::string& prefix, const class_info& info) { - std::string name = prefix.empty() ? info.name() : prefix + "::" + info.name(); - info.visit(kari_hpp::curry(add_info_f{}, std::ref(*this), name)); - detail::merge_with(classes_, name, info, &class_info::merge); - } - - inline void registry::add_info_(const std::string& prefix, const ctor_info& info) { - (void)prefix; - (void)info; - } - - inline void registry::add_info_(const std::string& prefix, const data_info& info) { - std::string name = prefix.empty() ? info.name() : prefix + "::" + info.name(); - info.visit(kari_hpp::curry(add_info_f{}, std::ref(*this), name)); - detail::merge_with(datas_, name, info, &data_info::merge); - } - - inline void registry::add_info_(const std::string& prefix, const enum_info& info) { - std::string name = prefix.empty() ? info.name() : prefix + "::" + info.name(); - info.visit(kari_hpp::curry(add_info_f{}, std::ref(*this), name)); - detail::merge_with(enums_, name, info, &enum_info::merge); - } - - inline void registry::add_info_(const std::string& prefix, const evalue_info& info) { - std::string name = prefix.empty() ? info.name() : prefix + "::" + info.name(); - info.visit(kari_hpp::curry(add_info_f{}, std::ref(*this), name)); - detail::merge_with(evalues_, name, info, &evalue_info::merge); - } - - inline void registry::add_info_(const std::string& prefix, const function_info& info) { - std::string name = prefix.empty() ? info.name() : prefix + "::" + info.name(); - info.visit(kari_hpp::curry(add_info_f{}, std::ref(*this), name)); - detail::merge_with(functions_, name, info, &function_info::merge); - } - - inline void registry::add_info_(const std::string& prefix, const member_info& info) { - std::string name = prefix.empty() ? info.name() : prefix + "::" + info.name(); - info.visit(kari_hpp::curry(add_info_f{}, std::ref(*this), name)); - detail::merge_with(members_, name, info, &member_info::merge); - } - - inline void registry::add_info_(const std::string& prefix, const method_info& info) { - std::string name = prefix.empty() ? info.name() : prefix + "::" + info.name(); - info.visit(kari_hpp::curry(add_info_f{}, std::ref(*this), name)); - detail::merge_with(methods_, name, info, &method_info::merge); - } - - inline void registry::add_info_(const std::string& prefix, const namespace_info& info) { - std::string name = prefix.empty() ? info.name() : prefix + "::" + info.name(); - info.visit(kari_hpp::curry(add_info_f{}, std::ref(*this), name)); - detail::merge_with(namespaces_, name, info, &namespace_info::merge); - } -} diff --git a/headers/meta.hpp/meta_registry/_registry_fwd.hpp b/headers/meta.hpp/meta_registry/_registry_fwd.hpp deleted file mode 100644 index 37e2a06..0000000 --- a/headers/meta.hpp/meta_registry/_registry_fwd.hpp +++ /dev/null @@ -1,11 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "../meta_fwd.hpp" -#include "../meta_infos.hpp" -#include "../meta_utilities.hpp" diff --git a/headers/meta.hpp/meta_registry/base_.hpp b/headers/meta.hpp/meta_registry/base_.hpp deleted file mode 100644 index bca1673..0000000 --- a/headers/meta.hpp/meta_registry/base_.hpp +++ /dev/null @@ -1,58 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "_registry_fwd.hpp" - -#include "data_.hpp" - -namespace meta_hpp -{ - template < typename Base > - class base_ final { - public: - explicit base_() = default; - - template < typename Derived > - base_info make_info() const; - public: - template < typename... Internals > - base_& operator()(Internals&&...internals); - private: - void add_(const data_& internal); - void add_(...) = delete; - private: - data_info_map datas_; - }; -} - -namespace meta_hpp -{ - template < typename Base > - template < typename Derived > - base_info base_::make_info() const { - base_info info{typename_arg, typename_arg}; - info.state_->datas.insert(datas_.begin(), datas_.end()); - return info; - } - - template < typename Base > - template < typename... Internals > - base_& base_::operator()(Internals&&...internals) { - (add_(std::forward(internals)), ...); - return *this; - } -} - -namespace meta_hpp -{ - template < typename Base > - void base_::add_(const data_& internal) { - auto info = internal.make_info(); - detail::merge_with(datas_, info.name(), info, &data_info::merge); - } -} diff --git a/headers/meta.hpp/meta_registry/class_.hpp b/headers/meta.hpp/meta_registry/class_.hpp deleted file mode 100644 index 581cbf9..0000000 --- a/headers/meta.hpp/meta_registry/class_.hpp +++ /dev/null @@ -1,144 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "_registry_fwd.hpp" - -#include "base_.hpp" -#include "ctor_.hpp" -#include "data_.hpp" -#include "enum_.hpp" -#include "function_.hpp" -#include "member_.hpp" -#include "method_.hpp" - -namespace meta_hpp -{ - template < typename Class > - class class_ final { - public: - explicit class_(std::string name); - - class_info make_info() const; - public: - template < typename... Internals > - class_& operator()(Internals&&...internals); - private: - template < typename Base > - void add_(const base_& internal); - template < typename Class2 > - void add_(const class_& internal); - template < typename... Args > - void add_(const ctor_& internal); - void add_(const data_& internal); - template < typename Enum > - void add_(const enum_& internal); - template < typename Function > - void add_(const function_& internal); - template < typename Member > - void add_(const member_& internal); - template < typename Method > - void add_(const method_& internal); - void add_(...) = delete; - private: - std::string name_; - base_info_map bases_; - class_info_map classes_; - ctor_info_map ctors_; - data_info_map datas_; - enum_info_map enums_; - function_info_map functions_; - member_info_map members_; - method_info_map methods_; - }; -} - -namespace meta_hpp -{ - template < typename Class > - class_::class_(std::string name) - : name_{std::move(name)} {} - - template < typename Class > - class_info class_::make_info() const { - class_info info{typename_arg, name_}; - info.state_->bases.insert(bases_.begin(), bases_.end()); - info.state_->classes.insert(classes_.begin(), classes_.end()); - info.state_->ctors.insert(ctors_.begin(), ctors_.end()); - info.state_->datas.insert(datas_.begin(), datas_.end()); - info.state_->enums.insert(enums_.begin(), enums_.end()); - info.state_->functions.insert(functions_.begin(), functions_.end()); - info.state_->members.insert(members_.begin(), members_.end()); - info.state_->methods.insert(methods_.begin(), methods_.end()); - return info; - } - - template < typename Class > - template < typename... Internals > - class_& class_::operator()(Internals&&...internals) { - (add_(std::forward(internals)), ...); - return *this; - } -} - -namespace meta_hpp -{ - template < typename Class > - template < typename Base > - void class_::add_(const base_& internal) { - auto info = internal.template make_info(); - detail::merge_with(bases_, info.type().id(), info, &base_info::merge); - } - - template < typename Class > - template < typename Class2 > - void class_::add_(const class_& internal) { - auto info = internal.make_info(); - detail::merge_with(classes_, info.name(), info, &class_info::merge); - } - - template < typename Class > - template < typename... Args > - void class_::add_(const ctor_& internal) { - auto info = internal.template make_info(); - detail::merge_with(ctors_, info.type().id(), info, &ctor_info::merge); - } - - template < typename Class > - void class_::add_(const data_& internal) { - auto info = internal.make_info(); - detail::merge_with(datas_, info.name(), info, &data_info::merge); - } - - template < typename Class > - template < typename Enum > - void class_::add_(const enum_& internal) { - auto info = internal.make_info(); - detail::merge_with(enums_, info.name(), info, &enum_info::merge); - } - - template < typename Class > - template < typename Function > - void class_::add_(const function_& internal) { - auto info = internal.make_info(); - detail::merge_with(functions_, info.name(), info, &function_info::merge); - } - - template < typename Class > - template < typename Member > - void class_::add_(const member_& internal) { - auto info = internal.make_info(); - detail::merge_with(members_, info.name(), info, &member_info::merge); - } - - template < typename Class > - template < typename Method > - void class_::add_(const method_& internal) { - auto info = internal.make_info(); - detail::merge_with(methods_, info.name(), info, &method_info::merge); - } -} diff --git a/headers/meta.hpp/meta_registry/ctor_.hpp b/headers/meta.hpp/meta_registry/ctor_.hpp deleted file mode 100644 index 94046b4..0000000 --- a/headers/meta.hpp/meta_registry/ctor_.hpp +++ /dev/null @@ -1,58 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "_registry_fwd.hpp" - -#include "data_.hpp" - -namespace meta_hpp -{ - template < typename... Args > - class ctor_ final { - public: - explicit ctor_() = default; - - template < typename Class > - ctor_info make_info() const; - public: - template < typename... Internals > - ctor_& operator()(Internals&&...internals); - private: - void add_(const data_& internal); - void add_(...) = delete; - private: - data_info_map datas_; - }; -} - -namespace meta_hpp -{ - template < typename... Args > - template < typename Class > - ctor_info ctor_::make_info() const { - ctor_info info{typename_arg, typename_arg}; - info.state_->datas.insert(datas_.begin(), datas_.end()); - return info; - } - - template < typename... Args > - template < typename... Internals > - ctor_& ctor_::operator()(Internals&&...internals) { - (add_(std::forward(internals)), ...); - return *this; - } -} - -namespace meta_hpp -{ - template < typename... Args > - void ctor_::add_(const data_& internal) { - auto info = internal.make_info(); - detail::merge_with(datas_, info.name(), info, &data_info::merge); - } -} diff --git a/headers/meta.hpp/meta_registry/data_.hpp b/headers/meta.hpp/meta_registry/data_.hpp deleted file mode 100644 index a91a832..0000000 --- a/headers/meta.hpp/meta_registry/data_.hpp +++ /dev/null @@ -1,58 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "_registry_fwd.hpp" - -namespace meta_hpp -{ - class data_ final { - public: - template < typename T > - explicit data_(std::string name, T&& value); - - data_info make_info() const; - public: - template < typename... Internals > - data_& operator()(Internals&&...internals); - private: - void add_(const data_& internal); - void add_(...) = delete; - private: - std::string name_; - class value value_; - data_info_map datas_; - }; -} - -namespace meta_hpp -{ - template < typename T > - data_::data_(std::string name, T&& value) - : name_{std::move(name)} - , value_{std::forward(value)} {} - - inline data_info data_::make_info() const { - data_info info{name_, value_}; - info.state_->datas.insert(datas_.begin(), datas_.end()); - return info; - } - - template < typename... Internals > - data_& data_::operator()(Internals&&...internals) { - (add_(std::forward(internals)), ...); - return *this; - } -} - -namespace meta_hpp -{ - inline void data_::add_(const data_& internal) { - auto info = internal.make_info(); - detail::merge_with(datas_, info.name(), info, &data_info::merge); - } -} diff --git a/headers/meta.hpp/meta_registry/enum_.hpp b/headers/meta.hpp/meta_registry/enum_.hpp deleted file mode 100644 index b3a1ef0..0000000 --- a/headers/meta.hpp/meta_registry/enum_.hpp +++ /dev/null @@ -1,71 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "_registry_fwd.hpp" - -#include "data_.hpp" -#include "evalue_.hpp" - -namespace meta_hpp -{ - template < typename Enum > - class enum_ final { - public: - explicit enum_(std::string name); - - enum_info make_info() const; - public: - template < typename... Internals > - enum_& operator()(Internals&&...internals); - private: - void add_(const data_& internal); - void add_(const evalue_& internal); - void add_(...) = delete; - private: - std::string name_; - data_info_map datas_; - evalue_info_map evalues_; - }; -} - -namespace meta_hpp -{ - template < typename Enum > - enum_::enum_(std::string name) - : name_{std::move(name)} {} - - template < typename Enum > - enum_info enum_::make_info() const { - enum_info info{typename_arg, name_}; - info.state_->datas.insert(datas_.begin(), datas_.end()); - info.state_->evalues.insert(evalues_.begin(), evalues_.end()); - return info; - } - - template < typename Enum > - template < typename... Internals > - enum_& enum_::operator()(Internals&&...internals) { - (add_(std::forward(internals)), ...); - return *this; - } -} - -namespace meta_hpp -{ - template < typename Enum > - void enum_::add_(const data_& internal) { - auto info = internal.make_info(); - detail::merge_with(datas_, info.name(), info, &data_info::merge); - } - - template < typename Enum > - void enum_::add_(const evalue_& internal) { - auto info = internal.make_info(); - detail::merge_with(evalues_, info.name(), info, &evalue_info::merge); - } -} diff --git a/headers/meta.hpp/meta_registry/evalue_.hpp b/headers/meta.hpp/meta_registry/evalue_.hpp deleted file mode 100644 index 52ee112..0000000 --- a/headers/meta.hpp/meta_registry/evalue_.hpp +++ /dev/null @@ -1,63 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "_registry_fwd.hpp" - -#include "data_.hpp" - -namespace meta_hpp -{ - template < typename Enum > - class evalue_ final { - public: - explicit evalue_(std::string name, Enum value); - - evalue_info make_info() const; - public: - template < typename... Internals > - evalue_& operator()(Internals&&...internals); - private: - void add_(const data_& internal); - void add_(...) = delete; - private: - std::string name_; - Enum value_; - data_info_map datas_; - }; -} - -namespace meta_hpp -{ - template < typename Enum > - evalue_::evalue_(std::string name, Enum value) - : name_{std::move(name)} - , value_{std::move(value)} {} - - template < typename Enum > - evalue_info evalue_::make_info() const { - evalue_info info{name_, value_}; - info.state_->datas.insert(datas_.begin(), datas_.end()); - return info; - } - - template < typename Enum > - template < typename... Internals > - evalue_& evalue_::operator()(Internals&&...internals) { - (add_(std::forward(internals)), ...); - return *this; - } -} - -namespace meta_hpp -{ - template < typename Enum > - void evalue_::add_(const data_& internal) { - auto info = internal.make_info(); - detail::merge_with(datas_, info.name(), info, &data_info::merge); - } -} diff --git a/headers/meta.hpp/meta_registry/function_.hpp b/headers/meta.hpp/meta_registry/function_.hpp deleted file mode 100644 index 807b058..0000000 --- a/headers/meta.hpp/meta_registry/function_.hpp +++ /dev/null @@ -1,63 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "_registry_fwd.hpp" - -#include "data_.hpp" - -namespace meta_hpp -{ - template < typename Function > - class function_ final { - public: - explicit function_(std::string name, Function instance); - - function_info make_info() const; - public: - template < typename... Internals > - function_& operator()(Internals&&...internals); - private: - void add_(const data_& internal); - void add_(...) = delete; - private: - std::string name_; - Function instance_; - data_info_map datas_; - }; -} - -namespace meta_hpp -{ - template < typename Function > - function_::function_(std::string name, Function instance) - : name_{std::move(name)} - , instance_{std::move(instance)} {} - - template < typename Function > - function_info function_::make_info() const { - function_info info{name_, instance_}; - info.state_->datas.insert(datas_.begin(), datas_.end()); - return info; - } - - template < typename Function > - template < typename... Internals > - function_& function_::operator()(Internals&&...internals) { - (add_(std::forward(internals)), ...); - return *this; - } -} - -namespace meta_hpp -{ - template < typename Function > - void function_::add_(const data_& internal) { - auto info = internal.make_info(); - detail::merge_with(datas_, info.name(), info, &data_info::merge); - } -} diff --git a/headers/meta.hpp/meta_registry/member_.hpp b/headers/meta.hpp/meta_registry/member_.hpp deleted file mode 100644 index 4572a66..0000000 --- a/headers/meta.hpp/meta_registry/member_.hpp +++ /dev/null @@ -1,63 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "_registry_fwd.hpp" - -#include "data_.hpp" - -namespace meta_hpp -{ - template < typename Member > - class member_ final { - public: - explicit member_(std::string name, Member instance); - - member_info make_info() const; - public: - template < typename... Internals > - member_& operator()(Internals&&...internals); - private: - void add_(const data_& internal); - void add_(...) = delete; - private: - std::string name_; - Member instance_; - data_info_map datas_; - }; -} - -namespace meta_hpp -{ - template < typename Member > - member_::member_(std::string name, Member instance) - : name_{std::move(name)} - , instance_{std::move(instance)} {} - - template < typename Member > - member_info member_::make_info() const { - member_info info{name_, instance_}; - info.state_->datas.insert(datas_.begin(), datas_.end()); - return info; - } - - template < typename Member > - template < typename... Internals > - member_& member_::operator()(Internals&&...internals) { - (add_(std::forward(internals)), ...); - return *this; - } -} - -namespace meta_hpp -{ - template < typename Member > - void member_::add_(const data_& internal) { - auto info = internal.make_info(); - detail::merge_with(datas_, info.name(), info, &data_info::merge); - } -} diff --git a/headers/meta.hpp/meta_registry/method_.hpp b/headers/meta.hpp/meta_registry/method_.hpp deleted file mode 100644 index f85f9f5..0000000 --- a/headers/meta.hpp/meta_registry/method_.hpp +++ /dev/null @@ -1,63 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "_registry_fwd.hpp" - -#include "data_.hpp" - -namespace meta_hpp -{ - template < typename Method > - class method_ final { - public: - explicit method_(std::string name, Method instance); - - method_info make_info() const; - public: - template < typename... Internals > - method_& operator()(Internals&&...internals); - private: - void add_(const data_& internal); - void add_(...) = delete; - private: - std::string name_; - Method instance_; - data_info_map datas_; - }; -} - -namespace meta_hpp -{ - template < typename Method > - method_::method_(std::string name, Method instance) - : name_{std::move(name)} - , instance_{std::move(instance)} {} - - template < typename Method > - method_info method_::make_info() const { - method_info info{name_, instance_}; - info.state_->datas.insert(datas_.begin(), datas_.end()); - return info; - } - - template < typename Method > - template < typename... Internals > - method_& method_::operator()(Internals&&...internals) { - (add_(std::forward(internals)), ...); - return *this; - } -} - -namespace meta_hpp -{ - template < typename Method > - void method_::add_(const data_& internal) { - auto info = internal.make_info(); - detail::merge_with(datas_, info.name(), info, &data_info::merge); - } -} diff --git a/headers/meta.hpp/meta_registry/namespace_.hpp b/headers/meta.hpp/meta_registry/namespace_.hpp deleted file mode 100644 index b1c720b..0000000 --- a/headers/meta.hpp/meta_registry/namespace_.hpp +++ /dev/null @@ -1,97 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "_registry_fwd.hpp" - -#include "class_.hpp" -#include "data_.hpp" -#include "enum_.hpp" -#include "function_.hpp" - -namespace meta_hpp -{ - class namespace_ final { - public: - explicit namespace_(std::string name); - - namespace_info make_info() const; - public: - template < typename... Internals > - namespace_& operator()(Internals&&...internals); - private: - template < typename Class > - void add_(const class_& internal); - void add_(const data_& internal); - template < typename Enum > - void add_(const enum_& internal); - template < typename Function > - void add_(const function_& internal); - void add_(const namespace_& internal); - void add_(...) = delete; - private: - std::string name_; - class_info_map classes_; - data_info_map datas_; - enum_info_map enums_; - function_info_map functions_; - namespace_info_map namespaces_; - }; -} - -namespace meta_hpp -{ - inline namespace_::namespace_(std::string name) - : name_{std::move(name)} {} - - inline namespace_info namespace_::make_info() const { - namespace_info info{name_}; - info.state_->classes.insert(classes_.begin(), classes_.end()); - info.state_->datas.insert(datas_.begin(), datas_.end()); - info.state_->enums.insert(enums_.begin(), enums_.end()); - info.state_->functions.insert(functions_.begin(), functions_.end()); - info.state_->namespaces.insert(namespaces_.begin(), namespaces_.end()); - return info; - } - - template < typename... Internals > - namespace_& namespace_::operator()(Internals&&...internals) { - (add_(std::forward(internals)), ...); - return *this; - } -} - -namespace meta_hpp -{ - template < typename Class > - void namespace_::add_(const class_& internal) { - auto info = internal.make_info(); - detail::merge_with(classes_, info.name(), info, &class_info::merge); - } - - inline void namespace_::add_(const data_& internal) { - auto info = internal.make_info(); - detail::merge_with(datas_, info.name(), info, &data_info::merge); - } - - template < typename Enum > - void namespace_::add_(const enum_& internal) { - auto info = internal.make_info(); - detail::merge_with(enums_, info.name(), info, &enum_info::merge); - } - - template < typename Function > - void namespace_::add_(const function_& internal) { - auto info = internal.make_info(); - detail::merge_with(functions_, info.name(), info, &function_info::merge); - } - - inline void namespace_::add_(const namespace_& internal) { - auto info = internal.make_info(); - detail::merge_with(namespaces_, info.name(), info, &namespace_info::merge); - } -} diff --git a/headers/meta.hpp/meta_types.hpp b/headers/meta.hpp/meta_types.hpp deleted file mode 100644 index 82a782e..0000000 --- a/headers/meta.hpp/meta_types.hpp +++ /dev/null @@ -1,84 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "meta_fwd.hpp" - -#include "meta_types/arithmetic_type.hpp" -#include "meta_types/array_type.hpp" -#include "meta_types/base_type.hpp" -#include "meta_types/class_type.hpp" -#include "meta_types/ctor_type.hpp" -#include "meta_types/enum_type.hpp" -#include "meta_types/function_type.hpp" -#include "meta_types/member_type.hpp" -#include "meta_types/method_type.hpp" -#include "meta_types/pointer_type.hpp" -#include "meta_types/reference_type.hpp" -#include "meta_types/void_type.hpp" - -namespace meta_hpp -{ - namespace detail - { - template < typename Tuple > - struct multi_get_impl; - - template < typename... Ts > - struct multi_get_impl> { - static std::vector get() { - return { type_db::get()... }; - } - }; - - template < typename T > - auto make_any_type() { - if constexpr ( std::is_arithmetic_v ) { - return arithmetic_type{typename_arg}; - } - if constexpr ( std::is_array_v ) { - return array_type{typename_arg}; - } - if constexpr ( std::is_class_v ) { - return class_type{typename_arg}; - } - if constexpr ( std::is_enum_v ) { - return enum_type{typename_arg}; - } - if constexpr ( std::is_pointer_v && std::is_function_v> ) { - return function_type{typename_arg}; - } - if constexpr ( std::is_member_object_pointer_v ) { - return member_type{typename_arg}; - } - if constexpr ( std::is_member_function_pointer_v ) { - return method_type{typename_arg}; - } - if constexpr ( std::is_pointer_v && !std::is_function_v> ) { - return pointer_type{typename_arg}; - } - if constexpr ( std::is_reference_v ) { - return reference_type{typename_arg}; - } - if constexpr ( std::is_void_v ) { - return void_type{typename_arg}; - } - } - } - - template < typename T > - const any_type& type_db::get() { - static const auto raw_type = detail::make_any_type(); - static const auto type = any_type{raw_type}; - return type; - } - - template < typename Tuple > - std::vector type_db::multi_get() { - return detail::multi_get_impl::get(); - } -} diff --git a/headers/meta.hpp/meta_types/_types_fwd.hpp b/headers/meta.hpp/meta_types/_types_fwd.hpp deleted file mode 100644 index 39e8327..0000000 --- a/headers/meta.hpp/meta_types/_types_fwd.hpp +++ /dev/null @@ -1,242 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "../meta_fwd.hpp" - -namespace meta_hpp -{ - class type_id final { - public: - type_id() = default; - - type_id(type_id&&) = default; - type_id& operator=(type_id&&) = default; - - type_id(const type_id&) = default; - type_id& operator=(const type_id&) = default; - - explicit operator bool() const noexcept { - return !!id_; - } - - std::size_t hash() const noexcept { - return std::hash{}(id_); - } - - friend bool operator<(type_id l, type_id r) noexcept { - return l.id_ < r.id_; - } - - friend bool operator==(type_id l, type_id r) noexcept { - return l.id_ == r.id_; - } - - friend bool operator!=(type_id l, type_id r) noexcept { - return l.id_ != r.id_; - } - private: - using underlying_type = std::size_t; - underlying_type id_{0u}; - private: - friend class type_base; - - template < typename T > - explicit type_id(typename_arg_t) noexcept - : id_{type_to_id()} {} - - static underlying_type next() noexcept { - static std::atomic id{}; - return ++id; - } - - template < typename T > - static underlying_type type_to_id() noexcept { - static const underlying_type id{next()}; - return id; - } - }; -} - -namespace std -{ - template <> - struct hash { - size_t operator()(meta_hpp::type_id id) const noexcept { - return id.hash(); - } - }; -} - -namespace meta_hpp -{ - class type_base { - public: - template < typename... Ts > - struct tag {}; - public: - type_base() = default; - virtual ~type_base() = default; - - type_base(type_base&&) = default; - type_base& operator=(type_base&&) = default; - - type_base(const type_base&) = default; - type_base& operator=(const type_base&) = default; - - type_id id() const noexcept { - return id_; - } - - explicit operator bool() const noexcept { - return !!id_; - } - protected: - template < typename... Ts > - explicit type_base(typename_arg_t) - : id_{typename_arg>} {} - private: - type_id id_; - }; - - // - - inline bool operator<(const type_base& l, const type_base& r) noexcept { - return l.id() < r.id(); - } - - inline bool operator==(const type_base& l, const type_base& r) noexcept { - return l.id() == r.id(); - } - - inline bool operator!=(const type_base& l, const type_base& r) noexcept { - return l.id() != r.id(); - } -} - -namespace meta_hpp -{ - class any_type final { - public: - any_type() = default; - - any_type(any_type&&) = default; - any_type& operator=(any_type&&) = default; - - any_type(const any_type&) = default; - any_type& operator=(const any_type&) = default; - - type_id id() const noexcept { - return id_; - } - - explicit operator bool() const noexcept { - return !!id_; - } - - template < typename T > - std::enable_if_t, T> as() const noexcept { - using Tptr = std::add_pointer_t>; - return is() ? *std::get(type_) : T{}; - } - - template < typename T > - std::enable_if_t, bool> is() const noexcept { - using Tptr = std::add_pointer_t>; - return std::holds_alternative(type_); - } - private: - friend class type_db; - - template < typename T - , std::enable_if_t, int> = 0 > - explicit any_type(const T& type) - : id_{type.id()} - , type_{std::addressof(type)} {} - private: - type_id id_; - std::variant< - const arithmetic_type*, - const array_type*, - const base_type*, - const class_type*, - const ctor_type*, - const enum_type*, - const function_type*, - const member_type*, - const method_type*, - const pointer_type*, - const reference_type*, - const void_type*> type_; - }; - - // - - inline bool operator<(const any_type& l, const any_type& r) noexcept { - return l.id() < r.id(); - } - - inline bool operator==(const any_type& l, const any_type& r) noexcept { - return l.id() == r.id(); - } - - inline bool operator!=(const any_type& l, const any_type& r) noexcept { - return l.id() != r.id(); - } - - // - - inline bool operator<(const type_base& l, const any_type& r) noexcept { - return l.id() < r.id(); - } - - inline bool operator==(const type_base& l, const any_type& r) noexcept { - return l.id() == r.id(); - } - - inline bool operator!=(const type_base& l, const any_type& r) noexcept { - return l.id() != r.id(); - } - - // - - inline bool operator<(const any_type& l, const type_base& r) noexcept { - return l.id() < r.id(); - } - - inline bool operator==(const any_type& l, const type_base& r) noexcept { - return l.id() == r.id(); - } - - inline bool operator!=(const any_type& l, const type_base& r) noexcept { - return l.id() != r.id(); - } -} - -namespace std -{ - template <> - struct hash { - size_t operator()(const meta_hpp::any_type& type) const noexcept { - return type.id().hash(); - } - }; -} - -namespace meta_hpp -{ - class type_db final { - public: - type_db() = delete; - - template < typename T > - static const any_type& get(); - - template < typename Tuple > - static std::vector multi_get(); - }; -} diff --git a/headers/meta.hpp/meta_types/arithmetic_type.hpp b/headers/meta.hpp/meta_types/arithmetic_type.hpp deleted file mode 100644 index 660a669..0000000 --- a/headers/meta.hpp/meta_types/arithmetic_type.hpp +++ /dev/null @@ -1,128 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "_types_fwd.hpp" - -namespace meta_hpp -{ - enum class arithmetic_flags : unsigned { - is_const = 1 << 0, - is_signed = 1 << 1, - is_unsigned = 1 << 2, - is_integral = 1 << 3, - is_floating_point = 1 << 4, - }; - - ENUM_HPP_OPERATORS_DECL(arithmetic_flags) - - class arithmetic_type final : public type_base { - public: - arithmetic_type() = default; - - arithmetic_type(arithmetic_type&&) = default; - arithmetic_type& operator=(arithmetic_type&&) = default; - - arithmetic_type(const arithmetic_type&) = default; - arithmetic_type& operator=(const arithmetic_type&) = default; - - template < typename T > - explicit arithmetic_type(typename_arg_t); - - std::size_t size() const noexcept; - any_type raw_type() const noexcept; - - bitflags flags() const noexcept; - bool is_const() const noexcept; - bool is_signed() const noexcept; - bool is_unsigned() const noexcept; - bool is_integral() const noexcept; - bool is_floating_point() const noexcept; - private: - struct state; - std::shared_ptr state_; - }; -} - -namespace meta_hpp::detail -{ - template < typename T > - struct arithmetic_traits { - static_assert(std::is_arithmetic_v); - static constexpr std::size_t size{sizeof(T)}; - - using raw_type = std::remove_const_t; - - static any_type make_raw_type() { - return std::is_same_v - ? any_type{} - : type_db::get(); - } - - static bitflags make_flags() noexcept { - bitflags flags; - if ( std::is_const_v ) flags.set(arithmetic_flags::is_const); - if ( std::is_signed_v ) flags.set(arithmetic_flags::is_signed); - if ( std::is_unsigned_v ) flags.set(arithmetic_flags::is_unsigned); - if ( std::is_integral_v ) flags.set(arithmetic_flags::is_integral); - if ( std::is_floating_point_v ) flags.set(arithmetic_flags::is_floating_point); - return flags; - } - }; -} - -namespace meta_hpp -{ - struct arithmetic_type::state final { - const std::size_t size; - const any_type raw_type; - const bitflags flags; - }; - - template < typename T > - arithmetic_type::arithmetic_type(typename_arg_t) - : type_base{typename_arg} - , state_{std::make_shared(state{ - detail::arithmetic_traits::size, - detail::arithmetic_traits::make_raw_type(), - detail::arithmetic_traits::make_flags(), - })} { - static_assert(std::is_arithmetic_v); - } - - inline std::size_t arithmetic_type::size() const noexcept { - return state_->size; - } - - inline any_type arithmetic_type::raw_type() const noexcept { - return state_->raw_type; - } - - inline bitflags arithmetic_type::flags() const noexcept { - return state_->flags; - } - - inline bool arithmetic_type::is_const() const noexcept { - return state_->flags.has(arithmetic_flags::is_const); - } - - inline bool arithmetic_type::is_signed() const noexcept { - return state_->flags.has(arithmetic_flags::is_signed); - } - - inline bool arithmetic_type::is_unsigned() const noexcept { - return state_->flags.has(arithmetic_flags::is_unsigned); - } - - inline bool arithmetic_type::is_integral() const noexcept { - return state_->flags.has(arithmetic_flags::is_integral); - } - - inline bool arithmetic_type::is_floating_point() const noexcept { - return state_->flags.has(arithmetic_flags::is_floating_point); - } -} diff --git a/headers/meta.hpp/meta_types/array_type.hpp b/headers/meta.hpp/meta_types/array_type.hpp deleted file mode 100644 index 0869842..0000000 --- a/headers/meta.hpp/meta_types/array_type.hpp +++ /dev/null @@ -1,108 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "_types_fwd.hpp" - -namespace meta_hpp -{ - enum class array_flags : unsigned { - is_bounded = 1 << 0, - is_unbounded = 1 << 1, - }; - - ENUM_HPP_OPERATORS_DECL(array_flags) - - class array_type final : public type_base { - public: - array_type() = default; - - array_type(array_type&&) = default; - array_type& operator=(array_type&&) = default; - - array_type(const array_type&) = default; - array_type& operator=(const array_type&) = default; - - template < typename T > - explicit array_type(typename_arg_t); - - std::size_t extent() const noexcept; - any_type data_type() const noexcept; - - bitflags flags() const noexcept; - bool is_bounded() const noexcept; - bool is_unbounded() const noexcept; - private: - struct state; - std::shared_ptr state_; - }; -} - -namespace meta_hpp -{ - struct array_type::state final { - const std::size_t extent; - const any_type data_type; - const bitflags flags; - }; -} - -namespace meta_hpp::detail -{ - template < typename T > - struct array_traits { - static_assert(std::is_array_v); - static constexpr std::size_t extent{std::extent_v}; - - using data_type = std::remove_extent_t; - - static any_type make_data_type() { - return type_db::get(); - } - - static bitflags make_flags() noexcept { - bitflags flags; - if ( stdex::is_bounded_array_v ) flags.set(array_flags::is_bounded); - if ( stdex::is_unbounded_array_v ) flags.set(array_flags::is_unbounded); - return flags; - } - }; -} - -namespace meta_hpp -{ - template < typename T > - array_type::array_type(typename_arg_t) - : type_base{typename_arg} - , state_{std::make_shared(state{ - detail::array_traits::extent, - detail::array_traits::make_data_type(), - detail::array_traits::make_flags(), - })} { - static_assert(std::is_array_v); - } - - inline std::size_t array_type::extent() const noexcept { - return state_->extent; - } - - inline any_type array_type::data_type() const noexcept { - return state_->data_type; - } - - inline bitflags array_type::flags() const noexcept { - return state_->flags; - } - - inline bool array_type::is_bounded() const noexcept { - return state_->flags.has(array_flags::is_bounded); - } - - inline bool array_type::is_unbounded() const noexcept { - return state_->flags.has(array_flags::is_unbounded); - } -} diff --git a/headers/meta.hpp/meta_types/base_type.hpp b/headers/meta.hpp/meta_types/base_type.hpp deleted file mode 100644 index 5d7fcf4..0000000 --- a/headers/meta.hpp/meta_types/base_type.hpp +++ /dev/null @@ -1,77 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "_types_fwd.hpp" - -namespace meta_hpp -{ - class base_type final : public type_base { - public: - base_type() = default; - - base_type(base_type&&) = default; - base_type& operator=(base_type&&) = default; - - base_type(const base_type&) = default; - base_type& operator=(const base_type&) = default; - - template < typename Base, typename Derived > - explicit base_type(typename_arg_t, typename_arg_t); - - any_type base_class_type() const noexcept; - any_type derived_class_type() const noexcept; - private: - struct state; - std::shared_ptr state_; - }; -} - -namespace meta_hpp::detail -{ - template < typename Base, typename Derived > - struct base_traits { - static_assert(std::is_base_of_v); - - using base_class_type = Base; - using derived_class_type = Derived; - - static any_type make_base_class_type() { - return type_db::get(); - } - - static any_type make_derived_class_type() { - return type_db::get(); - } - }; -} - -namespace meta_hpp -{ - struct base_type::state final { - const any_type base_class_type; - const any_type derived_class_type; - }; - - template < typename Base, typename Derived > - base_type::base_type(typename_arg_t, typename_arg_t) - : type_base{typename_arg} - , state_{std::make_shared(state{ - detail::base_traits::make_base_class_type(), - detail::base_traits::make_derived_class_type(), - })} { - static_assert(std::is_base_of_v); - } - - inline any_type base_type::base_class_type() const noexcept { - return state_->base_class_type; - } - - inline any_type base_type::derived_class_type() const noexcept { - return state_->derived_class_type; - } -} diff --git a/headers/meta.hpp/meta_types/class_type.hpp b/headers/meta.hpp/meta_types/class_type.hpp deleted file mode 100644 index 31c4b20..0000000 --- a/headers/meta.hpp/meta_types/class_type.hpp +++ /dev/null @@ -1,128 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "_types_fwd.hpp" - -namespace meta_hpp -{ - enum class class_flags : unsigned { - is_const = 1 << 0, - is_empty = 1 << 1, - is_final = 1 << 2, - is_abstract = 1 << 3, - is_polymorphic = 1 << 4, - }; - - ENUM_HPP_OPERATORS_DECL(class_flags) - - class class_type final : public type_base { - public: - class_type() = default; - - class_type(class_type&&) = default; - class_type& operator=(class_type&&) = default; - - class_type(const class_type&) = default; - class_type& operator=(const class_type&) = default; - - template < typename T > - explicit class_type(typename_arg_t); - - std::size_t size() const noexcept; - any_type raw_type() const noexcept; - - bitflags flags() const noexcept; - bool is_const() const noexcept; - bool is_empty() const noexcept; - bool is_final() const noexcept; - bool is_abstract() const noexcept; - bool is_polymorphic() const noexcept; - private: - struct state; - std::shared_ptr state_; - }; -} - -namespace meta_hpp::detail -{ - template < typename T > - struct class_traits { - static_assert(std::is_class_v); - static constexpr std::size_t size{sizeof(T)}; - - using raw_type = std::remove_const_t; - - static any_type make_raw_type() { - return std::is_same_v - ? any_type{} - : type_db::get(); - } - - static bitflags make_flags() noexcept { - bitflags flags; - if ( std::is_const_v ) flags.set(class_flags::is_const); - if ( std::is_empty_v ) flags.set(class_flags::is_empty); - if ( std::is_final_v ) flags.set(class_flags::is_final); - if ( std::is_abstract_v ) flags.set(class_flags::is_abstract); - if ( std::is_polymorphic_v ) flags.set(class_flags::is_polymorphic); - return flags; - } - }; -} - -namespace meta_hpp -{ - struct class_type::state final { - const std::size_t size; - const any_type raw_type; - const bitflags flags; - }; - - template < typename T > - class_type::class_type(typename_arg_t) - : type_base{typename_arg} - , state_{std::make_shared(state{ - detail::class_traits::size, - detail::class_traits::make_raw_type(), - detail::class_traits::make_flags(), - })} { - static_assert(std::is_class_v); - } - - inline std::size_t class_type::size() const noexcept { - return state_->size; - } - - inline any_type class_type::raw_type() const noexcept { - return state_->raw_type; - } - - inline bitflags class_type::flags() const noexcept { - return state_->flags; - } - - inline bool class_type::is_const() const noexcept { - return state_->flags.has(class_flags::is_const); - } - - inline bool class_type::is_empty() const noexcept { - return state_->flags.has(class_flags::is_empty); - } - - inline bool class_type::is_final() const noexcept { - return state_->flags.has(class_flags::is_final); - } - - inline bool class_type::is_abstract() const noexcept { - return state_->flags.has(class_flags::is_abstract); - } - - inline bool class_type::is_polymorphic() const noexcept { - return state_->flags.has(class_flags::is_polymorphic); - } -} diff --git a/headers/meta.hpp/meta_types/ctor_type.hpp b/headers/meta.hpp/meta_types/ctor_type.hpp deleted file mode 100644 index 939ebd5..0000000 --- a/headers/meta.hpp/meta_types/ctor_type.hpp +++ /dev/null @@ -1,118 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "_types_fwd.hpp" - -namespace meta_hpp -{ - enum class ctor_flags : unsigned { - is_noexcept = 1 << 0, - }; - - ENUM_HPP_OPERATORS_DECL(ctor_flags) - - class ctor_type final : public type_base { - public: - ctor_type() = default; - - ctor_type(ctor_type&&) = default; - ctor_type& operator=(ctor_type&&) = default; - - ctor_type(const ctor_type&) = default; - ctor_type& operator=(const ctor_type&) = default; - - template < typename Class, typename... Args > - explicit ctor_type(typename_arg_t, typename_arg_t); - - std::size_t arity() const noexcept; - any_type class_type() const noexcept; - any_type argument_type(std::size_t i) const noexcept; - const std::vector& argument_types() const noexcept; - - bitflags flags() const noexcept; - bool is_noexcept() const noexcept; - private: - struct state; - std::shared_ptr state_; - }; -} - -namespace meta_hpp::detail -{ - template < typename Class, typename... Args > - struct ctor_traits { - static_assert(std::is_constructible_v); - static constexpr std::size_t arity{sizeof...(Args)}; - - using class_type = Class; - using argument_types = std::tuple; - - static any_type make_class_type() { - return type_db::get(); - } - - static std::vector make_argument_types() { - return type_db::multi_get(); - } - - static bitflags make_flags() noexcept { - bitflags flags; - if ( std::is_nothrow_constructible_v ) flags.set(ctor_flags::is_noexcept); - return flags; - } - }; -} - -namespace meta_hpp -{ - struct ctor_type::state final { - const std::size_t arity; - const any_type class_type; - const std::vector argument_types; - const bitflags flags; - }; - - template < typename Class, typename... Args > - ctor_type::ctor_type(typename_arg_t, typename_arg_t) - : type_base{typename_arg} - , state_{std::make_shared(state{ - detail::ctor_traits::arity, - detail::ctor_traits::make_class_type(), - detail::ctor_traits::make_argument_types(), - detail::ctor_traits::make_flags(), - })} { - static_assert(std::is_class_v); - static_assert(std::is_constructible_v); - } - - inline std::size_t ctor_type::arity() const noexcept { - return state_->arity; - } - - inline any_type ctor_type::class_type() const noexcept { - return state_->class_type; - } - - inline any_type ctor_type::argument_type(std::size_t i) const noexcept { - return i < state_->argument_types.size() - ? state_->argument_types[i] - : any_type{}; - } - - inline const std::vector& ctor_type::argument_types() const noexcept { - return state_->argument_types; - } - - inline bitflags ctor_type::flags() const noexcept { - return state_->flags; - } - - inline bool ctor_type::is_noexcept() const noexcept { - return state_->flags.has(ctor_flags::is_noexcept); - } -} diff --git a/headers/meta.hpp/meta_types/enum_type.hpp b/headers/meta.hpp/meta_types/enum_type.hpp deleted file mode 100644 index af0d710..0000000 --- a/headers/meta.hpp/meta_types/enum_type.hpp +++ /dev/null @@ -1,112 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "_types_fwd.hpp" - -namespace meta_hpp -{ - enum class enum_flags : unsigned { - is_const = 1 << 0, - }; - - ENUM_HPP_OPERATORS_DECL(enum_flags) - - class enum_type final : public type_base { - public: - enum_type() = default; - - enum_type(enum_type&&) = default; - enum_type& operator=(enum_type&&) = default; - - enum_type(const enum_type&) = default; - enum_type& operator=(const enum_type&) = default; - - template < typename T > - explicit enum_type(typename_arg_t); - - std::size_t size() const noexcept; - any_type raw_type() const noexcept; - any_type underlying_type() const noexcept; - - bitflags flags() const noexcept; - bool is_const() const noexcept; - private: - struct state; - std::shared_ptr state_; - }; -} - -namespace meta_hpp::detail -{ - template < typename T > - struct enum_traits { - static_assert(std::is_enum_v); - static constexpr std::size_t size{sizeof(T)}; - - using raw_type = std::remove_const_t; - using underlying_type = std::underlying_type_t; - - static any_type make_raw_type() { - return std::is_same_v - ? any_type{} - : type_db::get(); - } - - static any_type make_underlying_type() { - return type_db::get(); - } - - static bitflags make_flags() noexcept { - bitflags flags; - if ( std::is_const_v ) flags.set(enum_flags::is_const); - return flags; - } - }; -} - -namespace meta_hpp -{ - struct enum_type::state final { - const std::size_t size; - const any_type raw_type; - const any_type underlying_type; - const bitflags flags; - }; - - template < typename T > - enum_type::enum_type(typename_arg_t) - : type_base{typename_arg} - , state_{std::make_shared(state{ - detail::enum_traits::size, - detail::enum_traits::make_raw_type(), - detail::enum_traits::make_underlying_type(), - detail::enum_traits::make_flags(), - })} { - static_assert(std::is_enum_v); - } - - inline std::size_t enum_type::size() const noexcept { - return state_->size; - } - - inline any_type enum_type::raw_type() const noexcept { - return state_->raw_type; - } - - inline any_type enum_type::underlying_type() const noexcept { - return state_->underlying_type; - } - - inline bitflags enum_type::flags() const noexcept { - return state_->flags; - } - - inline bool enum_type::is_const() const noexcept { - return state_->flags.has(enum_flags::is_const); - } -} diff --git a/headers/meta.hpp/meta_types/function_type.hpp b/headers/meta.hpp/meta_types/function_type.hpp deleted file mode 100644 index 1bc8fc3..0000000 --- a/headers/meta.hpp/meta_types/function_type.hpp +++ /dev/null @@ -1,125 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "_types_fwd.hpp" - -namespace meta_hpp -{ - enum class function_flags : unsigned { - is_noexcept = 1 << 0, - }; - - ENUM_HPP_OPERATORS_DECL(function_flags) - - class function_type final : public type_base { - public: - function_type() = default; - - function_type(function_type&&) = default; - function_type& operator=(function_type&&) = default; - - function_type(const function_type&) = default; - function_type& operator=(const function_type&) = default; - - template < typename T > - explicit function_type(typename_arg_t); - - std::size_t arity() const noexcept; - any_type return_type() const noexcept; - any_type argument_type(std::size_t i) const noexcept; - const std::vector& argument_types() const noexcept; - - bitflags flags() const noexcept; - bool is_noexcept() const noexcept; - private: - struct state; - std::shared_ptr state_; - }; -} - -namespace meta_hpp::detail -{ - template < typename T > - struct function_pointer_traits; - - template < typename R, typename... Args > - struct function_pointer_traits { - static constexpr std::size_t arity{sizeof...(Args)}; - - using return_type = R; - using argument_types = std::tuple; - - static any_type make_return_type() { - return type_db::get(); - } - - static std::vector make_argument_types() { - return type_db::multi_get(); - } - - static bitflags make_flags() noexcept { - return bitflags{}; - } - }; - - template < typename R, typename... Args > - struct function_pointer_traits : function_pointer_traits { - static bitflags make_flags() noexcept { - return function_flags::is_noexcept; - } - }; -} - -namespace meta_hpp -{ - struct function_type::state final { - const std::size_t arity; - const any_type return_type; - const std::vector argument_types; - const bitflags flags; - }; - - template < typename T > - function_type::function_type(typename_arg_t) - : type_base{typename_arg} - , state_{std::make_shared(state{ - detail::function_pointer_traits::arity, - detail::function_pointer_traits::make_return_type(), - detail::function_pointer_traits::make_argument_types(), - detail::function_pointer_traits::make_flags(), - })} { - static_assert(std::is_pointer_v); - static_assert(std::is_function_v>); - } - - inline std::size_t function_type::arity() const noexcept { - return state_->arity; - } - - inline any_type function_type::return_type() const noexcept { - return state_->return_type; - } - - inline any_type function_type::argument_type(std::size_t i) const noexcept { - return i < state_->argument_types.size() - ? state_->argument_types[i] - : any_type{}; - } - - inline const std::vector& function_type::argument_types() const noexcept { - return state_->argument_types; - } - - inline bitflags function_type::flags() const noexcept { - return state_->flags; - } - - inline bool function_type::is_noexcept() const noexcept { - return state_->flags.has(function_flags::is_noexcept); - } -} diff --git a/headers/meta.hpp/meta_types/member_type.hpp b/headers/meta.hpp/meta_types/member_type.hpp deleted file mode 100644 index 5c3b28b..0000000 --- a/headers/meta.hpp/meta_types/member_type.hpp +++ /dev/null @@ -1,81 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "_types_fwd.hpp" - -namespace meta_hpp -{ - class member_type final : public type_base { - public: - member_type() = default; - - member_type(member_type&&) = default; - member_type& operator=(member_type&&) = default; - - member_type(const member_type&) = default; - member_type& operator=(const member_type&) = default; - - template < typename T > - explicit member_type(typename_arg_t); - - any_type class_type() const noexcept; - any_type value_type() const noexcept; - private: - struct state; - std::shared_ptr state_; - }; -} - -namespace meta_hpp -{ - struct member_type::state final { - const any_type class_type; - const any_type value_type; - }; -} - -namespace meta_hpp::detail -{ - template < typename T > - struct member_pointer_traits; - - template < typename V, typename C > - struct member_pointer_traits { - using class_type = C; - using value_type = V; - - static any_type make_class_type() { - return type_db::get(); - } - - static any_type make_value_type() { - return type_db::get(); - } - }; -} - -namespace meta_hpp -{ - template < typename T > - member_type::member_type(typename_arg_t) - : type_base{typename_arg} - , state_{std::make_shared(state{ - detail::member_pointer_traits::make_class_type(), - detail::member_pointer_traits::make_value_type(), - })} { - static_assert(std::is_member_object_pointer_v); - } - - inline any_type member_type::class_type() const noexcept { - return state_->class_type; - } - - inline any_type member_type::value_type() const noexcept { - return state_->value_type; - } -} diff --git a/headers/meta.hpp/meta_types/method_type.hpp b/headers/meta.hpp/meta_types/method_type.hpp deleted file mode 100644 index 75996f5..0000000 --- a/headers/meta.hpp/meta_types/method_type.hpp +++ /dev/null @@ -1,340 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "_types_fwd.hpp" - -namespace meta_hpp -{ - enum class method_flags : unsigned { - is_const = 1 << 0, - is_noexcept = 1 << 1, - is_volatile = 1 << 2, - is_lvalue_qualified = 1 << 3, - is_rvalue_qualified = 1 << 4, - }; - - ENUM_HPP_OPERATORS_DECL(method_flags) - - class method_type final : public type_base { - public: - method_type() = default; - - method_type(method_type&&) = default; - method_type& operator=(method_type&&) = default; - - method_type(const method_type&) = default; - method_type& operator=(const method_type&) = default; - - template < typename T > - explicit method_type(typename_arg_t); - - std::size_t arity() const noexcept; - any_type class_type() const noexcept; - any_type return_type() const noexcept; - any_type argument_type(std::size_t i) const noexcept; - const std::vector& argument_types() const noexcept; - - bitflags flags() const noexcept; - bool is_const() const noexcept; - bool is_noexcept() const noexcept; - bool is_volatile() const noexcept; - bool is_lvalue_qualified() const noexcept; - bool is_rvalue_qualified() const noexcept; - private: - struct state; - std::shared_ptr state_; - }; -} - -namespace meta_hpp::detail -{ - template < typename T > - struct method_pointer_traits; - - template < typename R, typename C, typename... Args > - struct method_pointer_traits { - static constexpr std::size_t arity{sizeof...(Args)}; - - using class_type = C; - using return_type = R; - using qualified_type = C; - using argument_types = std::tuple; - - static any_type make_class_type() { - return type_db::get(); - } - - static any_type make_return_type() { - return type_db::get(); - } - - static std::vector make_argument_types() { - return type_db::multi_get(); - } - - static bitflags make_flags() noexcept { - return bitflags{}; - } - }; - - template < typename R, typename C, typename... Args > - struct method_pointer_traits : method_pointer_traits { - using qualified_type = const C; - static bitflags make_flags() noexcept { - return method_flags::is_const; - } - }; - - template < typename R, typename C, typename... Args > - struct method_pointer_traits : method_pointer_traits { - using qualified_type = C; - static bitflags make_flags() noexcept { - return method_flags::is_noexcept; - } - }; - - template < typename R, typename C, typename... Args > - struct method_pointer_traits : method_pointer_traits { - using qualified_type = const C; - static bitflags make_flags() noexcept { - return method_flags::is_const | method_flags::is_noexcept; - } - }; - - template < typename R, typename C, typename... Args > - struct method_pointer_traits : method_pointer_traits { - using qualified_type = C&; - static bitflags make_flags() noexcept { - return method_flags::is_lvalue_qualified; - } - }; - - template < typename R, typename C, typename... Args > - struct method_pointer_traits : method_pointer_traits { - using qualified_type = C&; - static bitflags make_flags() noexcept { - return method_flags::is_noexcept | method_flags::is_lvalue_qualified; - } - }; - - template < typename R, typename C, typename... Args > - struct method_pointer_traits : method_pointer_traits { - using qualified_type = const C&; - static bitflags make_flags() noexcept { - return method_flags::is_const | method_flags::is_lvalue_qualified; - } - }; - - template < typename R, typename C, typename... Args > - struct method_pointer_traits : method_pointer_traits { - using qualified_type = const C&; - static bitflags make_flags() noexcept { - return method_flags::is_const | method_flags::is_noexcept | method_flags::is_lvalue_qualified; - } - }; - - template < typename R, typename C, typename... Args > - struct method_pointer_traits : method_pointer_traits { - using qualified_type = C&&; - static bitflags make_flags() noexcept { - return method_flags::is_rvalue_qualified; - } - }; - - template < typename R, typename C, typename... Args > - struct method_pointer_traits : method_pointer_traits { - using qualified_type = C&&; - static bitflags make_flags() noexcept { - return method_flags::is_noexcept | method_flags::is_rvalue_qualified; - } - }; - - template < typename R, typename C, typename... Args > - struct method_pointer_traits : method_pointer_traits { - using qualified_type = const C&&; - static bitflags make_flags() noexcept { - return method_flags::is_const | method_flags::is_rvalue_qualified; - } - }; - - template < typename R, typename C, typename... Args > - struct method_pointer_traits : method_pointer_traits { - using qualified_type = const C&&; - static bitflags make_flags() noexcept { - return method_flags::is_const | method_flags::is_noexcept | method_flags::is_rvalue_qualified; - } - }; - - // - - template < typename R, typename C, typename... Args > - struct method_pointer_traits : method_pointer_traits { - using qualified_type = C; - static bitflags make_flags() noexcept { - return method_flags::is_volatile; - } - }; - - template < typename R, typename C, typename... Args > - struct method_pointer_traits : method_pointer_traits { - using qualified_type = const C; - static bitflags make_flags() noexcept { - return method_flags::is_volatile | method_flags::is_const; - } - }; - - template < typename R, typename C, typename... Args > - struct method_pointer_traits : method_pointer_traits { - using qualified_type = C; - static bitflags make_flags() noexcept { - return method_flags::is_volatile | method_flags::is_noexcept; - } - }; - - template < typename R, typename C, typename... Args > - struct method_pointer_traits : method_pointer_traits { - using qualified_type = const C; - static bitflags make_flags() noexcept { - return method_flags::is_volatile | method_flags::is_const | method_flags::is_noexcept; - } - }; - - template < typename R, typename C, typename... Args > - struct method_pointer_traits : method_pointer_traits { - using qualified_type = C&; - static bitflags make_flags() noexcept { - return method_flags::is_volatile | method_flags::is_lvalue_qualified; - } - }; - - template < typename R, typename C, typename... Args > - struct method_pointer_traits : method_pointer_traits { - using qualified_type = C&; - static bitflags make_flags() noexcept { - return method_flags::is_volatile | method_flags::is_noexcept | method_flags::is_lvalue_qualified; - } - }; - - template < typename R, typename C, typename... Args > - struct method_pointer_traits : method_pointer_traits { - using qualified_type = const C&; - static bitflags make_flags() noexcept { - return method_flags::is_volatile | method_flags::is_const | method_flags::is_lvalue_qualified; - } - }; - - template < typename R, typename C, typename... Args > - struct method_pointer_traits : method_pointer_traits { - using qualified_type = const C&; - static bitflags make_flags() noexcept { - return method_flags::is_volatile | method_flags::is_const | method_flags::is_noexcept | method_flags::is_lvalue_qualified; - } - }; - - template < typename R, typename C, typename... Args > - struct method_pointer_traits : method_pointer_traits { - using qualified_type = C&&; - static bitflags make_flags() noexcept { - return method_flags::is_volatile | method_flags::is_rvalue_qualified; - } - }; - - template < typename R, typename C, typename... Args > - struct method_pointer_traits : method_pointer_traits { - using qualified_type = C&&; - static bitflags make_flags() noexcept { - return method_flags::is_volatile | method_flags::is_noexcept | method_flags::is_rvalue_qualified; - } - }; - - template < typename R, typename C, typename... Args > - struct method_pointer_traits : method_pointer_traits { - using qualified_type = const C&&; - static bitflags make_flags() noexcept { - return method_flags::is_volatile | method_flags::is_const | method_flags::is_rvalue_qualified; - } - }; - - template < typename R, typename C, typename... Args > - struct method_pointer_traits : method_pointer_traits { - using qualified_type = const C&&; - static bitflags make_flags() noexcept { - return method_flags::is_volatile | method_flags::is_const | method_flags::is_noexcept | method_flags::is_rvalue_qualified; - } - }; -} - -namespace meta_hpp -{ - struct method_type::state final { - const std::size_t arity; - const any_type class_type; - const any_type return_type; - const std::vector argument_types; - const bitflags flags; - }; - - template < typename T > - method_type::method_type(typename_arg_t) - : type_base{typename_arg} - , state_{std::make_shared(state{ - detail::method_pointer_traits::arity, - detail::method_pointer_traits::make_class_type(), - detail::method_pointer_traits::make_return_type(), - detail::method_pointer_traits::make_argument_types(), - detail::method_pointer_traits::make_flags(), - })} { - static_assert(std::is_member_function_pointer_v); - } - - inline std::size_t method_type::arity() const noexcept { - return state_->arity; - } - - inline any_type method_type::class_type() const noexcept { - return state_->class_type; - } - - inline any_type method_type::return_type() const noexcept { - return state_->return_type; - } - - inline any_type method_type::argument_type(std::size_t i) const noexcept { - return i < state_->argument_types.size() - ? state_->argument_types[i] - : any_type{}; - } - - inline const std::vector& method_type::argument_types() const noexcept { - return state_->argument_types; - } - - inline bitflags method_type::flags() const noexcept { - return state_->flags; - } - - inline bool method_type::is_const() const noexcept { - return state_->flags.has(method_flags::is_const); - } - - inline bool method_type::is_noexcept() const noexcept { - return state_->flags.has(method_flags::is_noexcept); - } - - inline bool method_type::is_volatile() const noexcept { - return state_->flags.has(method_flags::is_volatile); - } - - inline bool method_type::is_lvalue_qualified() const noexcept { - return state_->flags.has(method_flags::is_lvalue_qualified); - } - - inline bool method_type::is_rvalue_qualified() const noexcept { - return state_->flags.has(method_flags::is_rvalue_qualified); - } -} diff --git a/headers/meta.hpp/meta_types/pointer_type.hpp b/headers/meta.hpp/meta_types/pointer_type.hpp deleted file mode 100644 index 269ed2e..0000000 --- a/headers/meta.hpp/meta_types/pointer_type.hpp +++ /dev/null @@ -1,88 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "_types_fwd.hpp" - -namespace meta_hpp -{ - enum class pointer_flags : unsigned { - is_const = 1 << 0, - }; - - class pointer_type final : public type_base { - public: - pointer_type() = default; - - pointer_type(pointer_type&&) = default; - pointer_type& operator=(pointer_type&&) = default; - - pointer_type(const pointer_type&) = default; - pointer_type& operator=(const pointer_type&) = default; - - template < typename T > - explicit pointer_type(typename_arg_t); - - any_type data_type() const noexcept; - - bitflags flags() const noexcept; - bool is_const() const noexcept; - private: - struct state; - std::shared_ptr state_; - }; -} - -namespace meta_hpp::detail -{ - template < typename T > - struct pointer_traits { - static_assert(std::is_pointer_v); - using data_type = std::remove_pointer_t; - - static any_type make_data_type() { - return type_db::get(); - } - - static bitflags make_flags() noexcept { - bitflags flags; - if ( std::is_const_v ) flags.set(pointer_flags::is_const); - return flags; - } - }; -} - -namespace meta_hpp -{ - struct pointer_type::state final { - const any_type data_type; - const bitflags flags; - }; - - template < typename T > - pointer_type::pointer_type(typename_arg_t) - : type_base{typename_arg} - , state_{std::make_shared(state{ - detail::pointer_traits::make_data_type(), - detail::pointer_traits::make_flags(), - })} { - static_assert(std::is_pointer_v); - static_assert(!std::is_function_v>); - } - - inline any_type pointer_type::data_type() const noexcept { - return state_->data_type; - } - - inline bitflags pointer_type::flags() const noexcept { - return state_->flags; - } - - inline bool pointer_type::is_const() const noexcept { - return state_->flags.has(pointer_flags::is_const); - } -} diff --git a/headers/meta.hpp/meta_types/reference_type.hpp b/headers/meta.hpp/meta_types/reference_type.hpp deleted file mode 100644 index 5351f5d..0000000 --- a/headers/meta.hpp/meta_types/reference_type.hpp +++ /dev/null @@ -1,96 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "_types_fwd.hpp" - -namespace meta_hpp -{ - enum class reference_flags : unsigned { - is_lvalue = 1 << 0, - is_rvalue = 1 << 1, - }; - - ENUM_HPP_OPERATORS_DECL(reference_flags) - - class reference_type final : public type_base { - public: - reference_type() = default; - - reference_type(reference_type&&) = default; - reference_type& operator=(reference_type&&) = default; - - reference_type(const reference_type&) = default; - reference_type& operator=(const reference_type&) = default; - - template < typename T > - explicit reference_type(typename_arg_t); - - any_type data_type() const noexcept; - - bitflags flags() const noexcept; - bool is_lvalue() const noexcept; - bool is_rvalue() const noexcept; - private: - struct state; - std::shared_ptr state_; - }; -} - -namespace meta_hpp::detail -{ - template < typename T > - struct reference_traits { - static_assert(std::is_reference_v); - using data_type = std::remove_reference_t; - - static any_type make_data_type() { - return type_db::get(); - } - - static bitflags make_flags() noexcept { - bitflags flags; - if ( std::is_lvalue_reference_v ) flags.set(reference_flags::is_lvalue); - if ( std::is_rvalue_reference_v ) flags.set(reference_flags::is_rvalue); - return flags; - } - }; -} - -namespace meta_hpp -{ - struct reference_type::state final { - const any_type data_type; - const bitflags flags; - }; - - template < typename T > - reference_type::reference_type(typename_arg_t) - : type_base{typename_arg} - , state_{std::make_shared(state{ - detail::reference_traits::make_data_type(), - detail::reference_traits::make_flags(), - })} { - static_assert(std::is_reference_v); - } - - inline any_type reference_type::data_type() const noexcept { - return state_->data_type; - } - - inline bitflags reference_type::flags() const noexcept { - return state_->flags; - } - - inline bool reference_type::is_lvalue() const noexcept { - return state_->flags.has(reference_flags::is_lvalue); - } - - inline bool reference_type::is_rvalue() const noexcept { - return state_->flags.has(reference_flags::is_rvalue); - } -} diff --git a/headers/meta.hpp/meta_types/void_type.hpp b/headers/meta.hpp/meta_types/void_type.hpp deleted file mode 100644 index 2911b58..0000000 --- a/headers/meta.hpp/meta_types/void_type.hpp +++ /dev/null @@ -1,94 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "_types_fwd.hpp" - -namespace meta_hpp -{ - enum class void_flags : unsigned { - is_const = 1 << 0, - }; - - ENUM_HPP_OPERATORS_DECL(void_flags) - - class void_type final : public type_base { - public: - void_type() = default; - - void_type(void_type&&) = default; - void_type& operator=(void_type&&) = default; - - void_type(const void_type&) = default; - void_type& operator=(const void_type&) = default; - - template < typename T > - explicit void_type(typename_arg_t); - - any_type raw_type() const noexcept; - - bitflags flags() const noexcept; - bool is_const() const noexcept; - private: - struct state; - std::shared_ptr state_; - }; -} - -namespace meta_hpp -{ - struct void_type::state final { - const any_type raw_type; - const bitflags flags; - }; -} - -namespace meta_hpp::detail -{ - template < typename T > - struct void_traits { - static_assert(std::is_void_v); - using raw_type = std::remove_const_t; - - static any_type make_raw_type() { - return std::is_same_v - ? any_type{} - : type_db::get(); - } - - static bitflags make_flags() noexcept { - bitflags flags; - if ( std::is_const_v ) flags.set(void_flags::is_const); - return flags; - } - }; -} - -namespace meta_hpp -{ - template < typename T > - void_type::void_type(typename_arg_t) - : type_base{typename_arg} - , state_{std::make_shared(state{ - detail::void_traits::make_raw_type(), - detail::void_traits::make_flags(), - })} { - static_assert(std::is_void_v); - } - - inline any_type void_type::raw_type() const noexcept { - return state_->raw_type; - } - - inline bitflags void_type::flags() const noexcept { - return state_->flags; - } - - inline bool void_type::is_const() const noexcept { - return state_->flags.has(void_flags::is_const); - } -} diff --git a/headers/meta.hpp/meta_utilities.hpp b/headers/meta.hpp/meta_utilities.hpp deleted file mode 100644 index f553ef8..0000000 --- a/headers/meta.hpp/meta_utilities.hpp +++ /dev/null @@ -1,13 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "meta_fwd.hpp" - -#include "meta_utilities/arg.hpp" -#include "meta_utilities/inst.hpp" -#include "meta_utilities/value.hpp" diff --git a/headers/meta.hpp/meta_utilities/_utilities_fwd.hpp b/headers/meta.hpp/meta_utilities/_utilities_fwd.hpp deleted file mode 100644 index c4f416c..0000000 --- a/headers/meta.hpp/meta_utilities/_utilities_fwd.hpp +++ /dev/null @@ -1,9 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "../meta_fwd.hpp" diff --git a/headers/meta.hpp/meta_utilities/arg.hpp b/headers/meta.hpp/meta_utilities/arg.hpp deleted file mode 100644 index ebd63c0..0000000 --- a/headers/meta.hpp/meta_utilities/arg.hpp +++ /dev/null @@ -1,286 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "../meta_fwd.hpp" - -#include "value.hpp" - -namespace meta_hpp -{ - class arg_base { - public: - enum class ref_types { - ref, - rref, - cref, - crref, - }; - public: - arg_base() = delete; - - arg_base(arg_base&&) = delete; - arg_base& operator=(arg_base&&) = delete; - - arg_base(const arg_base&) = delete; - arg_base& operator=(const arg_base&) = delete; - - template < typename T, std::enable_if_t< - std::is_pointer_v || std::is_lvalue_reference_v - , int> = 0 > - explicit arg_base(typename_arg_t); - - template < typename T, std::enable_if_t< - std::is_rvalue_reference_v || - (!std::is_pointer_v && !std::is_reference_v) - , int> = 0 > - explicit arg_base(typename_arg_t); - - explicit arg_base(value& v); - explicit arg_base(value&& v); - explicit arg_base(const value& v); - explicit arg_base(const value&& v); - - bool is_const() const noexcept; - bool is_lvalue() const noexcept; - bool is_rvalue() const noexcept; - - any_type raw_type() const noexcept; - ref_types ref_type() const noexcept; - - template < typename To > - bool can_cast_to() const noexcept; - private: - any_type raw_type_{}; - ref_types ref_type_{}; - }; -} - -namespace meta_hpp -{ - template < typename T, std::enable_if_t< - std::is_pointer_v || std::is_lvalue_reference_v - , int> > - arg_base::arg_base(typename_arg_t) - : raw_type_{type_db::get>()} - , ref_type_{std::is_const_v> ? ref_types::cref : ref_types::ref} {} - - template < typename T, std::enable_if_t< - std::is_rvalue_reference_v || - (!std::is_pointer_v && !std::is_reference_v) - , int> > - arg_base::arg_base(typename_arg_t) - : raw_type_{type_db::get>()} - , ref_type_{std::is_const_v> ? ref_types::crref : ref_types::rref} {} - - inline arg_base::arg_base(value& v) - : raw_type_{v.type()} - , ref_type_{ref_types::ref} {} - - inline arg_base::arg_base(value&& v) - : raw_type_{v.type()} - , ref_type_{ref_types::rref} {} - - inline arg_base::arg_base(const value& v) - : raw_type_{v.type()} - , ref_type_{ref_types::cref} {} - - inline arg_base::arg_base(const value&& v) - : raw_type_{v.type()} - , ref_type_{ref_types::crref} {} - - inline bool arg_base::is_const() const noexcept { - return ref_type_ == ref_types::cref - || ref_type_ == ref_types::crref; - } - - inline bool arg_base::is_lvalue() const noexcept { - return ref_type_ == ref_types::ref - || ref_type_ == ref_types::cref; - } - - inline bool arg_base::is_rvalue() const noexcept { - return ref_type_ == ref_types::rref - || ref_type_ == ref_types::crref; - } - - inline any_type arg_base::raw_type() const noexcept { - return raw_type_; - } - - inline arg_base::ref_types arg_base::ref_type() const noexcept { - return ref_type_; - } - - template < typename To > - bool arg_base::can_cast_to() const noexcept { - if constexpr ( std::is_pointer_v ) { - using to_raw_type = std::remove_cv_t; - using to_raw_ptr_type = std::remove_cv_t>; - return raw_type() == type_db::get() - || raw_type() == type_db::get(); - } - - if constexpr ( std::is_reference_v ) { - constexpr bool to_const = std::is_const_v>; - - if constexpr ( !to_const ) { - if ( is_const() ) { - return false; - } - } - - if constexpr ( std::is_lvalue_reference_v ) { - if constexpr ( !to_const ) { - if ( is_rvalue() ) { - return false; - } - } - } - - if constexpr ( std::is_rvalue_reference_v ) { - if ( !is_rvalue() ) { - return false; - } - } - - using to_raw_type = stdex::remove_cvref_t; - if ( raw_type() == type_db::get() ) { - return true; - } - - if constexpr ( to_const && std::is_pointer_v ) { - using to_raw_ptr_type = std::remove_cv_t>; - return raw_type() == type_db::get(); - } - - return false; - } - - if constexpr ( !std::is_pointer_v && !std::is_reference_v ) { - using to_raw_type = std::remove_cv_t; - if ( raw_type() != type_db::get() ) { - return false; - } - - return (ref_type() == ref_types::ref && std::is_constructible_v) - || (ref_type() == ref_types::cref && std::is_constructible_v) - || (ref_type() == ref_types::rref && std::is_constructible_v) - || (ref_type() == ref_types::crref && std::is_constructible_v); - } - } -} - -namespace meta_hpp -{ - class arg final : public arg_base { - public: - arg() = delete; - - arg(arg&&) = delete; - arg& operator=(arg&&) = delete; - - arg(const arg&) = delete; - arg& operator=(const arg&) = delete; - - template < typename T - , std::enable_if_t, arg>, int> = 0 - , std::enable_if_t, inst>, int> = 0 - , std::enable_if_t, value>, int> = 0 > - explicit arg(T&& v); - - explicit arg(value& v); - explicit arg(value&& v); - explicit arg(const value& v); - explicit arg(const value&& v); - - template < typename To > - To cast() const; - private: - void* data_{}; - }; -} - -namespace meta_hpp -{ - template < typename T - , std::enable_if_t, arg>, int> - , std::enable_if_t, inst>, int> - , std::enable_if_t, value>, int> > - arg::arg(T&& v) - : arg_base{typename_arg} - , data_{const_cast*>(std::addressof(v))} {} - - inline arg::arg(value& v) - : arg_base{v} - , data_{const_cast(v.data())} {} - - inline arg::arg(value&& v) - : arg_base{v} - , data_{const_cast(v.data())} {} - - inline arg::arg(const value& v) - : arg_base{v} - , data_{const_cast(v.data())} {} - - inline arg::arg(const value&& v) - : arg_base{v} - , data_{const_cast(v.data())} {} - - template < typename To > - To arg::cast() const { - if ( !can_cast_to() ) { - throw std::logic_error("bad argument cast"); - } - - if constexpr ( std::is_pointer_v ) { - return *static_cast(data_); - } - - if constexpr ( std::is_reference_v ) { - using raw_type = stdex::remove_cvref_t; - - if constexpr ( std::is_lvalue_reference_v ) { - return *static_cast(data_); - } - - if constexpr ( std::is_rvalue_reference_v ) { - return std::move(*static_cast(data_)); - } - } - - if constexpr ( !std::is_pointer_v && !std::is_reference_v ) { - using raw_type = std::remove_cv_t; - - if ( ref_type() == ref_types::ref ) { - if constexpr ( std::is_constructible_v ) { - return To{*static_cast(data_)}; - } - } - - if ( ref_type() == ref_types::cref ) { - if constexpr ( std::is_constructible_v ) { - return To{std::as_const(*static_cast(data_))}; - } - } - - if ( ref_type() == ref_types::rref ) { - if constexpr ( std::is_constructible_v ) { - return To{std::move(*static_cast(data_))}; - } - } - - if ( ref_type() == ref_types::crref ) { - if constexpr ( std::is_constructible_v ) { - return To{std::move(std::as_const(*static_cast(data_)))}; - } - } - } - - throw std::logic_error("bad argument cast"); - } -} diff --git a/headers/meta.hpp/meta_utilities/inst.hpp b/headers/meta.hpp/meta_utilities/inst.hpp deleted file mode 100644 index a3ca89b..0000000 --- a/headers/meta.hpp/meta_utilities/inst.hpp +++ /dev/null @@ -1,229 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "../meta_fwd.hpp" - -#include "value.hpp" - -namespace meta_hpp -{ - class inst_base { - public: - enum class ref_types { - ref, - rref, - cref, - crref, - }; - public: - inst_base() = delete; - - inst_base(inst_base&&) = delete; - inst_base& operator=(inst_base&&) = delete; - - inst_base(const inst_base&) = delete; - inst_base& operator=(const inst_base&) = delete; - - template < typename T, std::enable_if_t< - std::is_lvalue_reference_v && std::is_class_v> - , int> = 0> - explicit inst_base(typename_arg_t); - - template < typename T, std::enable_if_t< - std::is_class_v || - (std::is_rvalue_reference_v && std::is_class_v>) - , int> = 0> - explicit inst_base(typename_arg_t); - - explicit inst_base(value& v); - explicit inst_base(value&& v); - explicit inst_base(const value& v); - explicit inst_base(const value&& v); - - bool is_const() const noexcept; - bool is_lvalue() const noexcept; - bool is_rvalue() const noexcept; - - any_type raw_type() const noexcept; - ref_types ref_type() const noexcept; - - template < typename To > - bool can_cast_to() const noexcept; - private: - any_type raw_type_{}; - ref_types ref_type_{}; - }; -} - -namespace meta_hpp -{ - template < typename T, std::enable_if_t< - std::is_lvalue_reference_v && std::is_class_v> - , int> > - inst_base::inst_base(typename_arg_t) - : raw_type_{type_db::get>()} - , ref_type_{std::is_const_v> ? ref_types::cref : ref_types::ref} {} - - template < typename T, std::enable_if_t< - std::is_class_v || - (std::is_rvalue_reference_v && std::is_class_v>) - , int> > - inst_base::inst_base(typename_arg_t) - : raw_type_{type_db::get>()} - , ref_type_{std::is_const_v> ? ref_types::crref : ref_types::rref} {} - - inline inst_base::inst_base(value& v) - : raw_type_{v.type()} - , ref_type_{ref_types::ref} {} - - inline inst_base::inst_base(value&& v) - : raw_type_{v.type()} - , ref_type_{ref_types::rref} {} - - inline inst_base::inst_base(const value& v) - : raw_type_{v.type()} - , ref_type_{ref_types::cref} {} - - inline inst_base::inst_base(const value&& v) - : raw_type_{v.type()} - , ref_type_{ref_types::crref} {} - - inline bool inst_base::is_const() const noexcept { - return ref_type_ == ref_types::cref - || ref_type_ == ref_types::crref; - } - - inline bool inst_base::is_lvalue() const noexcept { - return ref_type_ == ref_types::ref - || ref_type_ == ref_types::cref; - } - - inline bool inst_base::is_rvalue() const noexcept { - return ref_type_ == ref_types::rref - || ref_type_ == ref_types::crref; - } - - inline any_type inst_base::raw_type() const noexcept { - return raw_type_; - } - - inline inst_base::ref_types inst_base::ref_type() const noexcept { - return ref_type_; - } - - template < typename To > - bool inst_base::can_cast_to() const noexcept { - static_assert( - std::is_class_v || - (std::is_reference_v && std::is_class_v>)); - - constexpr bool to_const = std::is_const_v>; - - if constexpr ( !to_const ) { - if ( is_const() ) { - return false; - } - } - - if constexpr ( std::is_lvalue_reference_v ) { - if ( !is_lvalue() ) { - return false; - } - } - - if constexpr ( std::is_rvalue_reference_v ) { - if ( !is_rvalue() ) { - return false; - } - } - - using to_raw_type = stdex::remove_cvref_t; - return raw_type() == type_db::get(); - } -} - -namespace meta_hpp -{ - class inst final : public inst_base { - public: - inst() = delete; - - inst(inst&&) = delete; - inst& operator=(inst&&) = delete; - - inst(const inst&) = delete; - inst& operator=(const inst&) = delete; - - template < typename T - , std::enable_if_t, arg>, int> = 0 - , std::enable_if_t, inst>, int> = 0 - , std::enable_if_t, value>, int> = 0 > - explicit inst(T&& v); - - explicit inst(value& v); - explicit inst(value&& v); - explicit inst(const value& v); - explicit inst(const value&& v); - - template < typename To > - decltype(auto) cast() const; - private: - void* data_{}; - }; -} - -namespace meta_hpp -{ - template < typename T - , std::enable_if_t, arg>, int> - , std::enable_if_t, inst>, int> - , std::enable_if_t, value>, int> > - inst::inst(T&& v) - : inst_base{typename_arg} - , data_{const_cast*>(std::addressof(v))} {} - - inline inst::inst(value& v) - : inst_base{v} - , data_{const_cast(v.data())} {} - - inline inst::inst(value&& v) - : inst_base{v} - , data_{const_cast(v.data())} {} - - inline inst::inst(const value& v) - : inst_base{v} - , data_{const_cast(v.data())} {} - - inline inst::inst(const value&& v) - : inst_base{v} - , data_{const_cast(v.data())} {} - - template < typename To > - decltype(auto) inst::cast() const { - if ( !can_cast_to() ) { - throw std::logic_error("bad inst cast"); - } - - if constexpr ( std::is_reference_v ) { - using raw_type_with_cv = std::remove_reference_t; - - if constexpr ( std::is_lvalue_reference_v ) { - return *static_cast(data_); - } - - if constexpr ( std::is_rvalue_reference_v ) { - return std::move(*static_cast(data_)); - } - } - - if constexpr ( !std::is_reference_v) { - using raw_type_with_cv = To; - return *static_cast(data_); - } - } -} diff --git a/headers/meta.hpp/meta_utilities/value.hpp b/headers/meta.hpp/meta_utilities/value.hpp deleted file mode 100644 index 92b49d6..0000000 --- a/headers/meta.hpp/meta_utilities/value.hpp +++ /dev/null @@ -1,376 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "../meta_fwd.hpp" - -namespace meta_hpp -{ - class value final { - public: - value() = delete; - - value(value&& other); - value(const value& other); - - value& operator=(value&& other); - value& operator=(const value& other); - - template < typename T - , typename Tp = std::decay_t - , std::enable_if_t, int> = 0 - , std::enable_if_t, int> = 0 - , std::enable_if_t, int> = 0 > - explicit value(T&& val); - - template < typename T - , typename Tp = std::decay_t - , std::enable_if_t, int> = 0 - , std::enable_if_t, int> = 0 - , std::enable_if_t, int> = 0 > - value& operator=(T&& val); - - void swap(value& other) noexcept; - - const any_type& type() const noexcept; - - void* data() noexcept; - const void* data() const noexcept; - const void* cdata() const noexcept; - - template < typename T, typename Tp = std::decay_t > - Tp& cast() &; - - template < typename T, typename Tp = std::decay_t > - Tp&& cast() &&; - - template < typename T, typename Tp = std::decay_t > - const Tp& cast() const &; - - template < typename T, typename Tp = std::decay_t > - const Tp&& cast() const &&; - - template < typename T, typename Tp = std::decay_t > - Tp* try_cast() noexcept; - - template < typename T, typename Tp = std::decay_t > - const Tp* try_cast() const noexcept; - - template < typename T > - friend bool operator==(const value& l, const T& r); - template < typename T > - friend bool operator==(const T& l, const value& r); - friend bool operator==(const value& l, const value& r); - - friend std::istream& operator>>(std::istream& os, value& v); - friend std::ostream& operator<<(std::ostream& os, const value& v); - private: - struct traits; - std::any raw_{}; - const traits* traits_{}; - }; - - inline void swap(value& l, value& r) noexcept { - l.swap(r); - } -} - -namespace meta_hpp::detail -{ - template < typename T, typename = void > - struct has_value_type_equality_operator - : std::false_type {}; - - template < typename T > - struct has_value_type_equality_operator() == std::declval() - )>> : std::true_type {}; - - template < typename T > - inline constexpr bool has_value_type_equality_operator_v = has_value_type_equality_operator::value; - - template < typename T, std::enable_if_t< - has_value_type_equality_operator_v - , int> = 0 > - bool value_equals_function(const value& l, const value& r) { - assert(l.type() == r.type()); - return l.cast() == r.cast(); - } - - template < typename T, std::enable_if_t< - !has_value_type_equality_operator_v - , int> = 0 > - bool value_equals_function([[maybe_unused]] const value& l, [[maybe_unused]] const value& r) { - throw std::logic_error("value type doesn't have equality operator"); - } -} - -namespace meta_hpp::detail -{ - template < typename T, typename = void > - struct has_value_type_istream_operator - : std::false_type {}; - - template < typename T > - struct has_value_type_istream_operator() >> std::declval() - )>> : std::true_type {}; - - template < typename T > - inline constexpr bool has_value_type_istream_operator_v = has_value_type_istream_operator::value; - - template < typename T, std::enable_if_t< - has_value_type_istream_operator_v - , int> = 0 > - void value_istream_function(std::istream& os, value& v) { - os >> v.cast(); - } - - template < typename T, std::enable_if_t< - !has_value_type_istream_operator_v - , int> = 0 > - void value_istream_function([[maybe_unused]] std::istream& os, [[maybe_unused]] value& v) { - throw std::logic_error("value type doesn't have istream operator"); - } -} - -namespace meta_hpp::detail -{ - template < typename T, typename = void > - struct has_value_type_ostream_operator - : std::false_type {}; - - template < typename T > - struct has_value_type_ostream_operator() << std::declval() - )>> : std::true_type {}; - - template < typename T > - inline constexpr bool has_value_type_ostream_operator_v = has_value_type_ostream_operator::value; - - template < typename T, std::enable_if_t< - has_value_type_ostream_operator_v - , int> = 0 > - void value_ostream_function(std::ostream& os, const value& v) { - os << v.cast(); - } - - template < typename T, std::enable_if_t< - !has_value_type_ostream_operator_v - , int> = 0 > - void value_ostream_function([[maybe_unused]] std::ostream& os, [[maybe_unused]] const value& v) { - throw std::logic_error("value type doesn't have ostream operator"); - } -} - -namespace meta_hpp -{ - struct value::traits final { - const any_type type; - - void* (*const data)(value&) noexcept; - const void* (*const cdata)(const value&) noexcept; - - bool (*const equals)(const value&, const value&); - - void (*const move_ctor)(std::any&, value&&); - void (*const copy_ctor)(std::any&, const value&); - - void (*const istream)(std::istream&, value&); - void (*const ostream)(std::ostream&, const value&); - - template < typename T > - static const traits* get() noexcept; - }; - - template < typename T > - const value::traits* value::traits::get() noexcept { - static const traits traits{ - // type - type_db::get(), - - // data - +[](value& v) noexcept -> void* { - return v.try_cast(); - }, - - // cdata - +[](const value& v) noexcept -> const void* { - return v.try_cast(); - }, - - // equals - &detail::value_equals_function, - - // move_ctor - +[](std::any& dst, value&& src) { - if constexpr ( std::is_move_constructible_v ) { - dst.emplace(std::move(src).cast()); - } else { - throw std::logic_error("value type is not move constructible"); - } - }, - - // copy_ctor - +[](std::any& dst, const value& src) { - if constexpr ( std::is_copy_constructible_v ) { - dst.emplace(src.cast()); - } else { - throw std::logic_error("value type is not copy constructible"); - } - }, - - // istream - &detail::value_istream_function, - - // ostream - &detail::value_ostream_function, - }; - return &traits; - } -} - -namespace meta_hpp -{ - inline value::value(value&& other) { - traits_ = other.traits_; - traits_->move_ctor(raw_, std::move(other)); - } - - inline value::value(const value& other) { - traits_ = other.traits_; - traits_->copy_ctor(raw_, other); - } - - inline value& value::operator=(value&& other) { - if ( this != &other ) { - traits_ = other.traits_; - traits_->move_ctor(raw_, std::move(other)); - } - return *this; - } - - inline value& value::operator=(const value& other) { - if ( this != &other ) { - traits_ = other.traits_; - traits_->copy_ctor(raw_, other); - } - return *this; - } - - template < typename T, typename Tp - , std::enable_if_t, int> - , std::enable_if_t, int> - , std::enable_if_t, int> > - value::value(T&& val) - : raw_{std::forward(val)} - , traits_{traits::get()} {} - - template < typename T, typename Tp - , std::enable_if_t, int> - , std::enable_if_t, int> - , std::enable_if_t, int> > - value& value::operator=(T&& val) { - raw_ = std::forward(val); - traits_ = type_db::get(); - return *this; - } - - inline void value::swap(value& other) noexcept { - using std::swap; - swap(raw_, other.raw_); - swap(traits_, other.traits_); - } - - inline const any_type& value::type() const noexcept { - return traits_->type; - } - - inline void* value::data() noexcept { - return traits_->data(*this); - } - - inline const void* value::data() const noexcept { - return traits_->cdata(*this); - } - - inline const void* value::cdata() const noexcept { - return traits_->cdata(*this); - } - - template < typename T, typename Tp > - Tp& value::cast() & { - if ( type() != type_db::get() ) { - throw std::logic_error("bad value cast"); - } - return std::any_cast(raw_); - } - - template < typename T, typename Tp > - Tp&& value::cast() && { - if ( type() != type_db::get() ) { - throw std::logic_error("bad value cast"); - } - return std::move(std::any_cast(raw_)); - } - - template < typename T, typename Tp > - const Tp& value::cast() const & { - if ( type() != type_db::get() ) { - throw std::logic_error("bad value cast"); - } - return std::any_cast(raw_); - } - - template < typename T, typename Tp > - const Tp&& value::cast() const && { - if ( type() != type_db::get() ) { - throw std::logic_error("bad value cast"); - } - return std::move(std::any_cast(raw_)); - } - - template < typename T, typename Tp > - Tp* value::try_cast() noexcept { - return std::any_cast(&raw_); - } - - template < typename T, typename Tp > - const Tp* value::try_cast() const noexcept { - return std::any_cast(&raw_); - } -} - -namespace meta_hpp -{ - template < typename T > - bool operator==(const value& l, const T& r) { - return l.type() == type_db::get() - && std::equal_to<>{}(l.cast(), r); - } - - template < typename T > - bool operator==(const T& l, const value& r) { - return type_db::get() == r.type() - && std::equal_to<>{}(l, r.cast()); - } - - inline bool operator==(const value& l, const value& r) { - return l.type() == r.type() - && l.traits_->equals(l, r); - } - - inline std::istream& operator>>(std::istream& is, value& v) { - v.traits_->istream(is, v); - return is; - } - - inline std::ostream& operator<<(std::ostream& os, const value& v) { - v.traits_->ostream(os, v); - return os; - } -} diff --git a/untests/features/infos/_infos_fwd.hpp b/untests/features/infos/_infos_fwd.hpp deleted file mode 100644 index b826cce..0000000 --- a/untests/features/infos/_infos_fwd.hpp +++ /dev/null @@ -1,9 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "../../meta_tests.hpp" diff --git a/untests/features/infos/base_info_tests.cpp b/untests/features/infos/base_info_tests.cpp deleted file mode 100644 index d90da07..0000000 --- a/untests/features/infos/base_info_tests.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/******************************************************************************* - * 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 "_infos_fwd.hpp" - -namespace -{ - using namespace meta_hpp; - using namespace std::string_literals; -} - -namespace -{ - class base { - public: - virtual ~base() {} - }; - - class derived final : public base { - public: - }; - - struct empty final {}; -} - -TEST_CASE("features/infos/base") { - registry db; - - db( - class_{"base"}, - class_{"derived"}( - base_{} - ) - ); - - REQUIRE(db.get_class_by_path("derived")); - const class_info derived_info = db.get_class_by_path("derived"); - - CHECK(derived_info.is_derived_from()); - CHECK_FALSE(derived_info.is_derived_from()); -} diff --git a/untests/features/infos/class_info_tests.cpp b/untests/features/infos/class_info_tests.cpp deleted file mode 100644 index 59bc299..0000000 --- a/untests/features/infos/class_info_tests.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/******************************************************************************* - * 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 "_infos_fwd.hpp" - -namespace -{ - using namespace meta_hpp; - using namespace std::string_literals; -} - -namespace -{ - class shape { - public: - virtual ~shape() {} - virtual int area() const = 0; - }; - - class rectangle : public shape { - public: - rectangle(const rectangle& other) { - width_ = other.width_; - height_ = other.height_; - } - - rectangle& operator=(const rectangle& other) { - if ( this != &other ) { - return *this; - } - width_ = other.width_; - height_ = other.height_; - return *this; - } - - rectangle(int width, int height) - : width_{width} - , height_{height} {} - - int area() const override { - return width_ * height_; - } - - int width() const noexcept { - return width_; - } - - int height() const noexcept { - return height_; - } - private: - int width_{}; - int height_{}; - }; -} - -TEST_CASE("features/infos/class") { - registry db; - - db( - class_{"shape"}( - method_{"area", &shape::area} - ), - class_{"rectangle"}( - base_{}, - ctor_{}, - method_{"width", &rectangle::width}, - method_{"height", &rectangle::height} - ) - ); - - SUBCASE("base") { - REQUIRE(db.get_class_by_path("shape")); - const class_info shape_info = db.get_class_by_path("shape"); - CHECK(shape_info.name() == "shape"); - CHECK(shape_info.type() == type_db::get()); - - CHECK_FALSE(shape_info.is_derived_from()); - CHECK_FALSE(shape_info.is_derived_from()); - } - - SUBCASE("derived") { - REQUIRE(db.get_class_by_path("rectangle")); - const class_info rectangle_info = db.get_class_by_path("rectangle"); - CHECK(rectangle_info.name() == "rectangle"); - CHECK(rectangle_info.type() == type_db::get()); - - CHECK(rectangle_info.is_derived_from()); - CHECK_FALSE(rectangle_info.is_derived_from()); - } -} diff --git a/untests/features/infos/ctor_info_tests.cpp b/untests/features/infos/ctor_info_tests.cpp deleted file mode 100644 index aa2d571..0000000 --- a/untests/features/infos/ctor_info_tests.cpp +++ /dev/null @@ -1,201 +0,0 @@ -/******************************************************************************* - * 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 "_infos_fwd.hpp" - -namespace -{ - using namespace meta_hpp; - using namespace std::string_literals; -} - -namespace -{ - struct ivec2 { - int x{}; - int y{}; - - [[maybe_unused]] ivec2() = default; - [[maybe_unused]] ivec2(const ivec2& other) = default; - [[maybe_unused]] explicit ivec2(int v): x{v}, y{v} {} - [[maybe_unused]] ivec2(int x, int y): x{x}, y{y} {} - }; - - [[maybe_unused]] bool operator==(const ivec2& l, const ivec2& r) noexcept { - return l.x == r.x && l.y == r.y; - } -} - -TEST_CASE("features/infos/ctor") { - registry db; - - db( - namespace_{"vmath"}( - class_{"ivec2"}( - ctor_<>{}(data_{"info", "void ctor"s}), - ctor_{}(data_{"info", "copy ctor"s}), - ctor_{}(data_{"info", "int ctor"s}), - ctor_{}(data_{"info", "int,int ctor"s}) - ) - ) - ); - - const class_info ivec2_info = db.get_class_by_path("vmath::ivec2"); - REQUIRE(ivec2_info); - - SUBCASE("void") { - const ctor_info ci = ivec2_info.get_ctor_by_args(); - REQUIRE(ci); - - REQUIRE(ci.get_data_by_name("info")); - CHECK(ci.get_data_by_name("info").value() == "void ctor"s); - - { - const ctor_info ci2 = ivec2_info.get_ctor_by_args(std::array{}); - const ctor_info ci3 = ivec2_info.get_ctor_by_args(std::vector{}); - REQUIRE(ci2); - REQUIRE(ci3); - CHECK(ci.type() == ci2.type()); - CHECK(ci.type() == ci2.type()); - } - - { - CHECK(ci.is_invocable_with<>()); - - CHECK_FALSE(ci.is_invocable_with()); - CHECK_FALSE(ci.is_invocable_with()); - CHECK_FALSE(ci.is_invocable_with()); - CHECK_FALSE(ci.is_invocable_with()); - CHECK_FALSE(ci.is_invocable_with()); - CHECK_FALSE(ci.is_invocable_with()); - } - - { - CHECK(ci.invoke() == ivec2{}); - CHECK_THROWS(ci.invoke(42)); - } - } - - SUBCASE("int") { - const ctor_info ci = ivec2_info.get_ctor_by_args(); - REQUIRE(ci); - - REQUIRE(ci.get_data_by_name("info")); - CHECK(ci.get_data_by_name("info").value() == "int ctor"s); - - { - const ctor_info ci2 = ivec2_info.get_ctor_by_args(std::array{ - type_db::get()}); - const ctor_info ci3 = ivec2_info.get_ctor_by_args(std::vector{ - type_db::get()}); - REQUIRE(ci2); - REQUIRE(ci3); - CHECK(ci.type() == ci2.type()); - CHECK(ci.type() == ci2.type()); - } - - { - CHECK_FALSE(ci.is_invocable_with<>()); - - CHECK(ci.is_invocable_with()); - CHECK(ci.is_invocable_with()); - CHECK(ci.is_invocable_with()); - CHECK(ci.is_invocable_with()); - CHECK(ci.is_invocable_with()); - CHECK(ci.is_invocable_with()); - } - - { - CHECK_THROWS(ci.invoke()); - CHECK(ci.invoke(42) == ivec2{42}); - } - } - - SUBCASE("const ivec2&") { - const ctor_info ci = ivec2_info.get_ctor_by_args(); - REQUIRE(ci); - - REQUIRE(ci.get_data_by_name("info")); - CHECK(ci.get_data_by_name("info").value() == "copy ctor"s); - - { - const ctor_info ci2 = ivec2_info.get_ctor_by_args(std::array{ - type_db::get()}); - const ctor_info ci3 = ivec2_info.get_ctor_by_args(std::vector{ - type_db::get()}); - REQUIRE(ci2); - REQUIRE(ci3); - CHECK(ci.type() == ci2.type()); - CHECK(ci.type() == ci2.type()); - } - - { - CHECK_FALSE(ci.is_invocable_with<>()); - - CHECK_FALSE(ci.is_invocable_with()); - CHECK_FALSE(ci.is_invocable_with()); - CHECK_FALSE(ci.is_invocable_with()); - CHECK_FALSE(ci.is_invocable_with()); - CHECK_FALSE(ci.is_invocable_with()); - CHECK_FALSE(ci.is_invocable_with()); - - CHECK(ci.is_invocable_with()); - CHECK(ci.is_invocable_with()); - CHECK(ci.is_invocable_with()); - CHECK(ci.is_invocable_with()); - CHECK(ci.is_invocable_with()); - } - - { - CHECK_THROWS(ci.invoke()); - CHECK_THROWS(ci.invoke(42)); - CHECK(ci.invoke(ivec2{21,42}) == ivec2{21,42}); - } - } - - SUBCASE("int,int") { - const ctor_info ci = ivec2_info.get_ctor_by_args(); - REQUIRE(ci); - - REQUIRE(ci.get_data_by_name("info")); - CHECK(ci.get_data_by_name("info").value() == "int,int ctor"s); - - { - const ctor_info ci2 = ivec2_info.get_ctor_by_args(std::array{ - type_db::get(), - type_db::get()}); - const ctor_info ci3 = ivec2_info.get_ctor_by_args(std::vector{ - type_db::get(), - type_db::get()}); - REQUIRE(ci2); - REQUIRE(ci3); - CHECK(ci.type() == ci2.type()); - CHECK(ci.type() == ci2.type()); - } - - { - CHECK_FALSE(ci.is_invocable_with<>()); - - CHECK_FALSE(ci.is_invocable_with()); - CHECK_FALSE(ci.is_invocable_with()); - CHECK_FALSE(ci.is_invocable_with()); - CHECK_FALSE(ci.is_invocable_with()); - CHECK_FALSE(ci.is_invocable_with()); - CHECK_FALSE(ci.is_invocable_with()); - - CHECK(ci.is_invocable_with()); - CHECK(ci.is_invocable_with()); - CHECK(ci.is_invocable_with()); - } - - { - CHECK_THROWS(ci.invoke()); - CHECK_THROWS(ci.invoke(42)); - CHECK_THROWS(ci.invoke(ivec2{21,42})); - CHECK(ci.invoke(21,42) == ivec2{21,42}); - } - } -} diff --git a/untests/features/infos/data_info_tests.cpp b/untests/features/infos/data_info_tests.cpp deleted file mode 100644 index 1bc3e47..0000000 --- a/untests/features/infos/data_info_tests.cpp +++ /dev/null @@ -1,14 +0,0 @@ -/******************************************************************************* - * 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 "_infos_fwd.hpp" - -namespace -{ -} - -TEST_CASE("features/infos/data") { -} diff --git a/untests/features/infos/enum_info_tests.cpp b/untests/features/infos/enum_info_tests.cpp deleted file mode 100644 index 497af93..0000000 --- a/untests/features/infos/enum_info_tests.cpp +++ /dev/null @@ -1,14 +0,0 @@ -/******************************************************************************* - * 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 "_infos_fwd.hpp" - -namespace -{ -} - -TEST_CASE("features/infos/enum") { -} diff --git a/untests/features/infos/evalue_info_tests.cpp b/untests/features/infos/evalue_info_tests.cpp deleted file mode 100644 index 75e3355..0000000 --- a/untests/features/infos/evalue_info_tests.cpp +++ /dev/null @@ -1,14 +0,0 @@ -/******************************************************************************* - * 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 "_infos_fwd.hpp" - -namespace -{ -} - -TEST_CASE("features/infos/evalue") { -} diff --git a/untests/features/infos/function_info_tests.cpp b/untests/features/infos/function_info_tests.cpp deleted file mode 100644 index 5d0d98e..0000000 --- a/untests/features/infos/function_info_tests.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/******************************************************************************* - * 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 "_infos_fwd.hpp" - -namespace -{ - using namespace meta_hpp; - using namespace std::string_literals; -} - -namespace -{ - struct ivec2 { - int x{}; - int y{}; - - [[maybe_unused]] ivec2() = default; - [[maybe_unused]] ivec2(const ivec2& other) = default; - [[maybe_unused]] explicit ivec2(int v): x{v}, y{v} {} - [[maybe_unused]] ivec2(int x, int y): x{x}, y{y} {} - }; - - bool operator==(const ivec2& l, const ivec2& r) noexcept { - return l.x == r.x && l.y == r.y; - } - - ivec2 iadd(const ivec2& l, const ivec2& r) noexcept { - return {l.x + r.x, l.y + r.y}; - } - - int ilength2(const ivec2& v) noexcept { - return v.x * v.x + v.y * v.y; - } -} - -TEST_CASE("features/infos/function") { - registry db; - - db( - namespace_{"vmath"}( - class_{"ivec2"}, - function_{"iadd", &iadd}(data_{"info", "iadd function"s}), - function_{"ilength2", &ilength2}(data_{"info", "ilength2 function"s}) - ) - ); - - SUBCASE("iadd") { - const function_info fi = db.get_function_by_path("vmath::iadd"); - REQUIRE(fi); - - REQUIRE(fi.get_data_by_name("info")); - CHECK(fi.get_data_by_name("info").value() == "iadd function"s); - - CHECK_FALSE(fi.is_invocable_with()); - CHECK_FALSE(fi.is_invocable_with()); - CHECK_FALSE(fi.is_invocable_with()); - CHECK_FALSE(fi.is_invocable_with()); - - CHECK(fi.is_invocable_with()); - CHECK(fi.is_invocable_with()); - - CHECK_THROWS(fi.invoke()); - CHECK_THROWS(fi.invoke(42)); - CHECK_THROWS(fi.invoke(ivec2{}, 42)); - - CHECK(fi.invoke(ivec2{1,2},ivec2{3,4})); - CHECK(fi.invoke(ivec2{1,2},ivec2{3,4}).value() == ivec2{4,6}); - } - - SUBCASE("ilength2") { - const function_info fi = db.get_function_by_path("vmath::ilength2"); - REQUIRE(fi); - - REQUIRE(fi.get_data_by_name("info")); - CHECK(fi.get_data_by_name("info").value() == "ilength2 function"s); - - CHECK_FALSE(fi.is_invocable_with()); - CHECK_FALSE(fi.is_invocable_with()); - CHECK_FALSE(fi.is_invocable_with()); - - CHECK(fi.is_invocable_with()); - CHECK(fi.is_invocable_with()); - - CHECK_THROWS(fi.invoke()); - CHECK_THROWS(fi.invoke(42)); - CHECK_THROWS(fi.invoke(ivec2{}, 42)); - - CHECK(fi.invoke(ivec2{2,3})); - CHECK(fi.invoke(ivec2{2,3}).value() == 13); - } -} diff --git a/untests/features/infos/member_info_tests.cpp b/untests/features/infos/member_info_tests.cpp deleted file mode 100644 index d4b9c54..0000000 --- a/untests/features/infos/member_info_tests.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/******************************************************************************* - * 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 "_infos_fwd.hpp" - -namespace -{ - using namespace meta_hpp; - using namespace std::string_literals; -} - -namespace -{ - struct ivec2 { - int x{}; - int y{}; - - [[maybe_unused]] ivec2() = default; - [[maybe_unused]] explicit ivec2(int v): x{v}, y{v} {} - [[maybe_unused]] ivec2(int x, int y): x{x}, y{y} {} - }; - - struct ipnt2 { - const int x{}; - const int y{}; - - [[maybe_unused]] ipnt2() = default; - [[maybe_unused]] explicit ipnt2(int v): x{v}, y{v} {} - [[maybe_unused]] ipnt2(int x, int y): x{x}, y{y} {} - }; - - bool operator==(const ivec2& l, const ivec2& r) noexcept { - return l.x == r.x && l.y == r.y; - } - - bool operator==(const ipnt2& l, const ipnt2& r) noexcept { - return l.x == r.x && l.y == r.y; - } -} - -TEST_CASE("features/infos/member") { - registry db; - - db( - namespace_{"vmath"}( - class_{"ivec2"}( - member_{"x", &ivec2::x}, - member_{"y", &ivec2::y} - ), - class_{"ipnt2"}( - member_{"x", &ipnt2::x}, - member_{"y", &ipnt2::y} - ) - ) - ); - - SUBCASE("non_const") { - const member_info x_mi = db.get_member_by_path("vmath::ivec2::x"); - const member_info y_mi = db.get_member_by_path("vmath::ivec2::y"); - REQUIRE(x_mi); - REQUIRE(y_mi); - - { - CHECK(x_mi.name() == "x"); - CHECK(x_mi.type().class_type() == type_db::get()); - CHECK(x_mi.type().value_type() == type_db::get()); - - CHECK(y_mi.name() == "y"); - CHECK(y_mi.type().class_type() == type_db::get()); - CHECK(y_mi.type().value_type() == type_db::get()); - } - - { - ivec2 v{1,2}; - - CHECK(x_mi.get(v) == 1); - CHECK(x_mi.get(std::as_const(v)) == 1); - CHECK(x_mi.get(std::move(v)) == 1); - CHECK(x_mi.get(std::move(std::as_const(v))) == 1); - - CHECK(y_mi.get(v) == 2); - CHECK(y_mi.get(std::as_const(v)) == 2); - CHECK(y_mi.get(std::move(v)) == 2); - CHECK(y_mi.get(std::move(std::as_const(v))) == 2); - - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); - } - - { - ivec2 v{1,2}; - - CHECK_NOTHROW(x_mi.set(v, 10)); CHECK(v.x == 10); - CHECK_THROWS(x_mi.set(std::as_const(v), 11)); CHECK(v.x == 10); - CHECK_NOTHROW(x_mi.set(std::move(v), 12)); CHECK(v.x == 12); - CHECK_THROWS(x_mi.set(std::move(std::as_const(v)), 13)); CHECK(v.x == 12); - - CHECK_NOTHROW(y_mi.set(v, 20)); CHECK(v.y == 20); - CHECK_THROWS(y_mi.set(std::as_const(v), 21)); CHECK(v.y == 20); - CHECK_NOTHROW(y_mi.set(std::move(v), 22)); CHECK(v.y == 22); - CHECK_THROWS(y_mi.set(std::move(std::as_const(v)), 23)); CHECK(v.y == 22); - - CHECK(v == ivec2{12,22}); - } - } - - SUBCASE("const") { - const member_info x_mi = db.get_member_by_path("vmath::ipnt2::x"); - const member_info y_mi = db.get_member_by_path("vmath::ipnt2::y"); - REQUIRE(x_mi); - REQUIRE(y_mi); - - { - CHECK(x_mi.name() == "x"); - CHECK(x_mi.type().class_type() == type_db::get()); - CHECK(x_mi.type().value_type() == type_db::get()); - - CHECK(y_mi.name() == "y"); - CHECK(y_mi.type().class_type() == type_db::get()); - CHECK(y_mi.type().value_type() == type_db::get()); - } - - { - ipnt2 v{1,2}; - - CHECK(x_mi.get(v) == 1); - CHECK(x_mi.get(std::as_const(v)) == 1); - CHECK(x_mi.get(std::move(v)) == 1); - CHECK(x_mi.get(std::move(std::as_const(v))) == 1); - - CHECK(y_mi.get(v) == 2); - CHECK(y_mi.get(std::as_const(v)) == 2); - CHECK(y_mi.get(std::move(v)) == 2); - CHECK(y_mi.get(std::move(std::as_const(v))) == 2); - - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); - } - - { - ipnt2 v{1,2}; - - CHECK_THROWS(x_mi.set(v, 10)); CHECK(v.x == 1); - CHECK_THROWS(x_mi.set(std::as_const(v), 11)); CHECK(v.x == 1); - CHECK_THROWS(x_mi.set(std::move(v), 12)); CHECK(v.x == 1); - CHECK_THROWS(x_mi.set(std::move(std::as_const(v)), 13)); CHECK(v.x == 1); - - CHECK_THROWS(y_mi.set(v, 20)); CHECK(v.y == 2); - CHECK_THROWS(y_mi.set(std::as_const(v), 21)); CHECK(v.y == 2); - CHECK_THROWS(y_mi.set(std::move(v), 22)); CHECK(v.y == 2); - CHECK_THROWS(y_mi.set(std::move(std::as_const(v)), 23)); CHECK(v.y == 2); - - CHECK(v == ipnt2{1,2}); - } - } -} diff --git a/untests/features/infos/method_info_tests.cpp b/untests/features/infos/method_info_tests.cpp deleted file mode 100644 index 277443c..0000000 --- a/untests/features/infos/method_info_tests.cpp +++ /dev/null @@ -1,786 +0,0 @@ -/******************************************************************************* - * 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 "_infos_fwd.hpp" - -namespace -{ - using namespace meta_hpp; - using namespace std::string_literals; -} - -namespace -{ - struct clazz { - clazz() = default; - - clazz(clazz&&) = delete; - clazz(const clazz&) = delete; - - clazz& operator=(clazz&&) = delete; - clazz& operator=(const clazz&) = delete; - - // - - int non_const_method() { return 1; } - int non_const_method_noexcept() noexcept { return 2; } - - int const_method() const { return 3; } - int const_method_noexcept() const noexcept { return 4; } - - int non_const_method_ref() & { return 5; } - int non_const_method_noexcept_ref() & noexcept { return 6; } - - int const_method_ref() const & { return 7; } - int const_method_noexcept_ref() const & noexcept { return 8; } - - int non_const_method_rref() && { return 9; } - int non_const_method_noexcept_rref() && noexcept { return 10; } - - int const_method_rref() const && { return 11; } - int const_method_noexcept_rref() const && noexcept { return 12; } - - // - - int non_const_method_volatile() volatile { return 1; } - int non_const_method_noexcept_volatile() volatile noexcept { return 2; } - - int const_method_volatile() volatile const { return 3; } - int const_method_noexcept_volatile() volatile const noexcept { return 4; } - - int non_const_method_ref_volatile() volatile & { return 5; } - int non_const_method_noexcept_ref_volatile() volatile & noexcept { return 6; } - - int const_method_ref_volatile() volatile const & { return 7; } - int const_method_noexcept_ref_volatile() volatile const & noexcept { return 8; } - - int non_const_method_rref_volatile() volatile && { return 9; } - int non_const_method_noexcept_rref_volatile() volatile && noexcept { return 10; } - - int const_method_rref_volatile() volatile const && { return 11; } - int const_method_noexcept_rref_volatile() volatile const && noexcept { return 12; } - }; - - struct clazz2 {}; -} - -TEST_CASE("features/infos/method") { - registry db; - - db( - class_{"clazz"}( - method_{"non_const_method", &clazz::non_const_method}, - method_{"non_const_method_noexcept", &clazz::non_const_method_noexcept}, - - method_{"const_method", &clazz::const_method}, - method_{"const_method_noexcept", &clazz::const_method_noexcept}, - - method_{"non_const_method_ref", &clazz::non_const_method_ref}, - method_{"non_const_method_noexcept_ref", &clazz::non_const_method_noexcept_ref}, - - method_{"const_method_ref", &clazz::const_method_ref}, - method_{"const_method_noexcept_ref", &clazz::const_method_noexcept_ref}, - - method_{"non_const_method_rref", &clazz::non_const_method_rref}, - method_{"non_const_method_noexcept_rref", &clazz::non_const_method_noexcept_rref}, - - method_{"const_method_rref", &clazz::const_method_rref}, - method_{"const_method_noexcept_rref", &clazz::const_method_noexcept_rref}, - - // - - method_{"non_const_method_volatile", &clazz::non_const_method_volatile}, - method_{"non_const_method_noexcept_volatile", &clazz::non_const_method_noexcept_volatile}, - - method_{"const_method_volatile", &clazz::const_method_volatile}, - method_{"const_method_noexcept_volatile", &clazz::const_method_noexcept_volatile}, - - method_{"non_const_method_ref_volatile", &clazz::non_const_method_ref_volatile}, - method_{"non_const_method_noexcept_ref_volatile", &clazz::non_const_method_noexcept_ref_volatile}, - - method_{"const_method_ref_volatile", &clazz::const_method_ref_volatile}, - method_{"const_method_noexcept_ref_volatile", &clazz::const_method_noexcept_ref_volatile}, - - method_{"non_const_method_rref_volatile", &clazz::non_const_method_rref_volatile}, - method_{"non_const_method_noexcept_rref_volatile", &clazz::non_const_method_noexcept_rref_volatile}, - - method_{"const_method_rref_volatile", &clazz::const_method_rref_volatile}, - method_{"const_method_noexcept_rref_volatile", &clazz::const_method_noexcept_rref_volatile} - ) - ); - - SUBCASE("non_const_method") { - const method_info mi = db.get_method_by_path("clazz::non_const_method"); - REQUIRE(mi); - - const method_info mi2 = db.get_method_by_path("clazz::non_const_method_volatile"); - REQUIRE(mi2); - - { - CHECK(mi.type().arity() == 0); - CHECK(mi.type().class_type() == type_db::get()); - CHECK(mi.type().return_type() == type_db::get()); - CHECK(mi.type().flags() == method_flags{}); - - CHECK(mi2.type().arity() == 0); - CHECK(mi2.type().class_type() == type_db::get()); - CHECK(mi2.type().return_type() == type_db::get()); - CHECK(mi2.type().flags() == method_flags::is_volatile); - } - - { - CHECK(mi.is_invocable_with()); - CHECK_FALSE(mi.is_invocable_with()); - CHECK(mi.is_invocable_with()); - CHECK_FALSE(mi.is_invocable_with()); - - CHECK(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); - CHECK(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); - } - - { - clazz cl; - - CHECK(mi.invoke(cl).value() == 1); - CHECK_THROWS(mi.invoke(std::as_const(cl))); - CHECK(mi.invoke(std::move(cl)).value() == 1); - CHECK_THROWS(mi.invoke(std::move(std::as_const(cl)))); - - CHECK(mi2.invoke(cl).value() == 1); - CHECK_THROWS(mi2.invoke(std::as_const(cl))); - CHECK(mi2.invoke(std::move(cl)).value() == 1); - CHECK_THROWS(mi2.invoke(std::move(std::as_const(cl)))); - } - - static_assert(std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(!std::is_invocable_v); - - static_assert(std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(!std::is_invocable_v); - } - - SUBCASE("non_const_method_noexcept") { - const method_info mi = db.get_method_by_path("clazz::non_const_method_noexcept"); - REQUIRE(mi); - - const method_info mi2 = db.get_method_by_path("clazz::non_const_method_noexcept_volatile"); - REQUIRE(mi2); - - { - CHECK(mi.type().arity() == 0); - CHECK(mi.type().class_type() == type_db::get()); - CHECK(mi.type().return_type() == type_db::get()); - CHECK(mi.type().flags() == method_flags::is_noexcept); - - CHECK(mi2.type().arity() == 0); - CHECK(mi2.type().class_type() == type_db::get()); - CHECK(mi2.type().return_type() == type_db::get()); - CHECK(mi2.type().flags() == (method_flags::is_noexcept | method_flags::is_volatile)); - } - - { - CHECK(mi.is_invocable_with()); - CHECK_FALSE(mi.is_invocable_with()); - CHECK(mi.is_invocable_with()); - CHECK_FALSE(mi.is_invocable_with()); - - CHECK(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); - CHECK(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); - } - - { - clazz cl; - - CHECK(mi.invoke(cl).value() == 2); - CHECK_THROWS(mi.invoke(std::as_const(cl))); - CHECK(mi.invoke(std::move(cl)).value() == 2); - CHECK_THROWS(mi.invoke(std::move(std::as_const(cl)))); - - CHECK(mi2.invoke(cl).value() == 2); - CHECK_THROWS(mi2.invoke(std::as_const(cl))); - CHECK(mi2.invoke(std::move(cl)).value() == 2); - CHECK_THROWS(mi2.invoke(std::move(std::as_const(cl)))); - } - - static_assert(std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(!std::is_invocable_v); - - static_assert(std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(!std::is_invocable_v); - } - - SUBCASE("const_method") { - const method_info mi = db.get_method_by_path("clazz::const_method"); - REQUIRE(mi); - - const method_info mi2 = db.get_method_by_path("clazz::const_method_volatile"); - REQUIRE(mi2); - - { - CHECK(mi.type().arity() == 0); - CHECK(mi.type().class_type() == type_db::get()); - CHECK(mi.type().return_type() == type_db::get()); - CHECK(mi.type().flags() == method_flags::is_const); - - CHECK(mi2.type().arity() == 0); - CHECK(mi2.type().class_type() == type_db::get()); - CHECK(mi2.type().return_type() == type_db::get()); - CHECK(mi2.type().flags() == (method_flags::is_const | method_flags::is_volatile)); - } - - { - CHECK(mi.is_invocable_with()); - CHECK(mi.is_invocable_with()); - CHECK(mi.is_invocable_with()); - CHECK(mi.is_invocable_with()); - - CHECK(mi2.is_invocable_with()); - CHECK(mi2.is_invocable_with()); - CHECK(mi2.is_invocable_with()); - CHECK(mi2.is_invocable_with()); - } - - { - clazz cl; - - CHECK(mi.invoke(cl).value() == 3); - CHECK(mi.invoke(std::as_const(cl)).value() == 3); - CHECK(mi.invoke(std::move(cl)).value() == 3); - CHECK(mi.invoke(std::move(std::as_const(cl))).value() == 3); - - CHECK(mi2.invoke(cl).value() == 3); - CHECK(mi2.invoke(std::as_const(cl)).value() == 3); - CHECK(mi2.invoke(std::move(cl)).value() == 3); - CHECK(mi2.invoke(std::move(std::as_const(cl))).value() == 3); - } - - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); - - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); - } - - SUBCASE("const_method_noexcept") { - const method_info mi = db.get_method_by_path("clazz::const_method_noexcept"); - REQUIRE(mi); - - const method_info mi2 = db.get_method_by_path("clazz::const_method_noexcept_volatile"); - REQUIRE(mi2); - - { - CHECK(mi.type().arity() == 0); - CHECK(mi.type().class_type() == type_db::get()); - CHECK(mi.type().return_type() == type_db::get()); - CHECK(mi.type().flags() == (method_flags::is_const | method_flags::is_noexcept)); - - CHECK(mi2.type().arity() == 0); - CHECK(mi2.type().class_type() == type_db::get()); - CHECK(mi2.type().return_type() == type_db::get()); - CHECK(mi2.type().flags() == (method_flags::is_const | method_flags::is_noexcept | method_flags::is_volatile)); - } - - { - CHECK(mi.is_invocable_with()); - CHECK(mi.is_invocable_with()); - CHECK(mi.is_invocable_with()); - CHECK(mi.is_invocable_with()); - - CHECK(mi2.is_invocable_with()); - CHECK(mi2.is_invocable_with()); - CHECK(mi2.is_invocable_with()); - CHECK(mi2.is_invocable_with()); - } - - { - clazz cl; - - CHECK(mi.invoke(cl).value() == 4); - CHECK(mi.invoke(std::as_const(cl)).value() == 4); - CHECK(mi.invoke(std::move(cl)).value() == 4); - CHECK(mi.invoke(std::move(std::as_const(cl))).value() == 4); - - CHECK(mi2.invoke(cl).value() == 4); - CHECK(mi2.invoke(std::as_const(cl)).value() == 4); - CHECK(mi2.invoke(std::move(cl)).value() == 4); - CHECK(mi2.invoke(std::move(std::as_const(cl))).value() == 4); - } - - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); - - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); - } - - SUBCASE("non_const_method_ref") { - const method_info mi = db.get_method_by_path("clazz::non_const_method_ref"); - REQUIRE(mi); - - const method_info mi2 = db.get_method_by_path("clazz::non_const_method_ref_volatile"); - REQUIRE(mi2); - - { - CHECK(mi.type().arity() == 0); - CHECK(mi.type().class_type() == type_db::get()); - CHECK(mi.type().return_type() == type_db::get()); - CHECK(mi.type().flags() == method_flags::is_lvalue_qualified); - - CHECK(mi2.type().arity() == 0); - CHECK(mi2.type().class_type() == type_db::get()); - CHECK(mi2.type().return_type() == type_db::get()); - CHECK(mi2.type().flags() == (method_flags::is_volatile | method_flags::is_lvalue_qualified)); - } - - { - CHECK(mi.is_invocable_with()); - CHECK_FALSE(mi.is_invocable_with()); - CHECK_FALSE(mi.is_invocable_with()); - CHECK_FALSE(mi.is_invocable_with()); - - CHECK(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); - } - - { - clazz cl; - - CHECK(mi.invoke(cl).value() == 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(mi2.invoke(cl).value() == 5); - CHECK_THROWS(mi2.invoke(std::as_const(cl))); - CHECK_THROWS(mi2.invoke(std::move(cl))); - CHECK_THROWS(mi2.invoke(std::move(std::as_const(cl)))); - } - - static_assert(std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(!std::is_invocable_v); - - static_assert(std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(!std::is_invocable_v); - } - - SUBCASE("non_const_method_noexcept_ref") { - const method_info mi = db.get_method_by_path("clazz::non_const_method_noexcept_ref"); - REQUIRE(mi); - - const method_info mi2 = db.get_method_by_path("clazz::non_const_method_noexcept_ref_volatile"); - REQUIRE(mi2); - - { - CHECK(mi.type().arity() == 0); - CHECK(mi.type().class_type() == type_db::get()); - CHECK(mi.type().return_type() == type_db::get()); - CHECK(mi.type().flags() == (method_flags::is_noexcept | method_flags::is_lvalue_qualified)); - - CHECK(mi2.type().arity() == 0); - CHECK(mi2.type().class_type() == type_db::get()); - CHECK(mi2.type().return_type() == type_db::get()); - CHECK(mi2.type().flags() == (method_flags::is_noexcept | method_flags::is_volatile | method_flags::is_lvalue_qualified)); - } - - { - CHECK(mi.is_invocable_with()); - CHECK_FALSE(mi.is_invocable_with()); - CHECK_FALSE(mi.is_invocable_with()); - CHECK_FALSE(mi.is_invocable_with()); - - CHECK(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); - } - - { - clazz cl; - - CHECK(mi.invoke(cl).value() == 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(mi2.invoke(cl).value() == 6); - CHECK_THROWS(mi2.invoke(std::as_const(cl))); - CHECK_THROWS(mi2.invoke(std::move(cl))); - CHECK_THROWS(mi2.invoke(std::move(std::as_const(cl)))); - } - - static_assert(std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(!std::is_invocable_v); - - static_assert(std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(!std::is_invocable_v); - } - - SUBCASE("const_method_ref") { - const method_info mi = db.get_method_by_path("clazz::const_method_ref"); - REQUIRE(mi); - - const method_info mi2 = db.get_method_by_path("clazz::const_method_ref_volatile"); - REQUIRE(mi2); - - { - CHECK(mi.type().arity() == 0); - CHECK(mi.type().class_type() == type_db::get()); - CHECK(mi.type().return_type() == type_db::get()); - CHECK(mi.type().flags() == (method_flags::is_const | method_flags::is_lvalue_qualified)); - - CHECK(mi2.type().arity() == 0); - CHECK(mi2.type().class_type() == type_db::get()); - CHECK(mi2.type().return_type() == type_db::get()); - CHECK(mi2.type().flags() == (method_flags::is_const | method_flags::is_volatile | method_flags::is_lvalue_qualified)); - } - - { - CHECK(mi.is_invocable_with()); - CHECK(mi.is_invocable_with()); - CHECK_FALSE(mi.is_invocable_with()); - CHECK_FALSE(mi.is_invocable_with()); - - CHECK(mi2.is_invocable_with()); - CHECK(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); - } - - { - clazz cl; - - CHECK(mi.invoke(cl).value() == 7); - CHECK(mi.invoke(std::as_const(cl)).value() == 7); - CHECK_THROWS(mi.invoke(std::move(cl))); - CHECK_THROWS(mi.invoke(std::move(std::as_const(cl)))); - - CHECK(mi2.invoke(cl).value() == 7); - CHECK(mi2.invoke(std::as_const(cl)).value() == 7); - CHECK_THROWS(mi2.invoke(std::move(cl))); - CHECK_THROWS(mi2.invoke(std::move(std::as_const(cl)))); - } - - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); - //static_assert(!std::is_invocable_v); // msvc issue - //static_assert(!std::is_invocable_v); // msvc issue - - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(!std::is_invocable_v); - } - - SUBCASE("const_method_noexcept_ref") { - const method_info mi = db.get_method_by_path("clazz::const_method_noexcept_ref"); - REQUIRE(mi); - - const method_info mi2 = db.get_method_by_path("clazz::const_method_noexcept_ref_volatile"); - REQUIRE(mi2); - - { - CHECK(mi.type().arity() == 0); - CHECK(mi.type().class_type() == type_db::get()); - CHECK(mi.type().return_type() == type_db::get()); - CHECK(mi.type().flags() == (method_flags::is_const | method_flags::is_noexcept | method_flags::is_lvalue_qualified)); - - CHECK(mi2.type().arity() == 0); - CHECK(mi2.type().class_type() == type_db::get()); - CHECK(mi2.type().return_type() == type_db::get()); - CHECK(mi2.type().flags() == (method_flags::is_const | method_flags::is_noexcept | method_flags::is_volatile | method_flags::is_lvalue_qualified)); - } - - { - CHECK(mi.is_invocable_with()); - CHECK(mi.is_invocable_with()); - CHECK_FALSE(mi.is_invocable_with()); - CHECK_FALSE(mi.is_invocable_with()); - - CHECK(mi2.is_invocable_with()); - CHECK(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); - } - - { - clazz cl; - - CHECK(mi.invoke(cl).value() == 8); - CHECK(mi.invoke(std::as_const(cl)).value() == 8); - CHECK_THROWS(mi.invoke(std::move(cl))); - CHECK_THROWS(mi.invoke(std::move(std::as_const(cl)))); - - CHECK(mi2.invoke(cl).value() == 8); - CHECK(mi2.invoke(std::as_const(cl)).value() == 8); - CHECK_THROWS(mi2.invoke(std::move(cl))); - CHECK_THROWS(mi2.invoke(std::move(std::as_const(cl)))); - } - - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); - //static_assert(!std::is_invocable_v); // msvc issue - //static_assert(!std::is_invocable_v); // msvc issue - - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(!std::is_invocable_v); - } - - SUBCASE("non_const_method_rref") { - const method_info mi = db.get_method_by_path("clazz::non_const_method_rref"); - REQUIRE(mi); - - const method_info mi2 = db.get_method_by_path("clazz::non_const_method_rref_volatile"); - REQUIRE(mi2); - - { - CHECK(mi.type().arity() == 0); - CHECK(mi.type().class_type() == type_db::get()); - CHECK(mi.type().return_type() == type_db::get()); - CHECK(mi.type().flags() == method_flags::is_rvalue_qualified); - - CHECK(mi2.type().arity() == 0); - CHECK(mi2.type().class_type() == type_db::get()); - CHECK(mi2.type().return_type() == type_db::get()); - CHECK(mi2.type().flags() == (method_flags::is_volatile | method_flags::is_rvalue_qualified)); - } - - { - CHECK_FALSE(mi.is_invocable_with()); - CHECK_FALSE(mi.is_invocable_with()); - CHECK(mi.is_invocable_with()); - CHECK_FALSE(mi.is_invocable_with()); - - CHECK_FALSE(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); - CHECK(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); - } - - { - clazz cl; - - CHECK_THROWS(mi.invoke(cl)); - CHECK_THROWS(mi.invoke(std::as_const(cl))); - CHECK(mi.invoke(std::move(cl)).value() == 9); - CHECK_THROWS(mi.invoke(std::move(std::as_const(cl)))); - - CHECK_THROWS(mi2.invoke(cl)); - CHECK_THROWS(mi2.invoke(std::as_const(cl))); - CHECK(mi2.invoke(std::move(cl)).value() == 9); - CHECK_THROWS(mi2.invoke(std::move(std::as_const(cl)))); - } - - static_assert(!std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(!std::is_invocable_v); - - static_assert(!std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(!std::is_invocable_v); - } - - SUBCASE("non_const_method_noexcept_rref") { - const method_info mi = db.get_method_by_path("clazz::non_const_method_noexcept_rref"); - REQUIRE(mi); - - const method_info mi2 = db.get_method_by_path("clazz::non_const_method_noexcept_rref_volatile"); - REQUIRE(mi2); - - { - CHECK(mi.type().arity() == 0); - CHECK(mi.type().class_type() == type_db::get()); - CHECK(mi.type().return_type() == type_db::get()); - CHECK(mi.type().flags() == (method_flags::is_noexcept | method_flags::is_rvalue_qualified)); - - CHECK(mi2.type().arity() == 0); - CHECK(mi2.type().class_type() == type_db::get()); - CHECK(mi2.type().return_type() == type_db::get()); - CHECK(mi2.type().flags() == (method_flags::is_noexcept | method_flags::is_volatile | method_flags::is_rvalue_qualified)); - } - - { - CHECK_FALSE(mi.is_invocable_with()); - CHECK_FALSE(mi.is_invocable_with()); - CHECK(mi.is_invocable_with()); - CHECK_FALSE(mi.is_invocable_with()); - - CHECK_FALSE(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); - CHECK(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); - } - - { - clazz cl; - - CHECK_THROWS(mi.invoke(cl)); - CHECK_THROWS(mi.invoke(std::as_const(cl))); - CHECK(mi.invoke(std::move(cl)).value() == 10); - CHECK_THROWS(mi.invoke(std::move(std::as_const(cl)))); - - CHECK_THROWS(mi2.invoke(cl)); - CHECK_THROWS(mi2.invoke(std::as_const(cl))); - CHECK(mi2.invoke(std::move(cl)).value() == 10); - CHECK_THROWS(mi2.invoke(std::move(std::as_const(cl)))); - } - - static_assert(!std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(!std::is_invocable_v); - - static_assert(!std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(!std::is_invocable_v); - } - - SUBCASE("const_method_rref") { - const method_info mi = db.get_method_by_path("clazz::const_method_rref"); - REQUIRE(mi); - - const method_info mi2 = db.get_method_by_path("clazz::const_method_rref_volatile"); - REQUIRE(mi2); - - { - CHECK(mi.type().arity() == 0); - CHECK(mi.type().class_type() == type_db::get()); - CHECK(mi.type().return_type() == type_db::get()); - CHECK(mi.type().flags() == (method_flags::is_const | method_flags::is_rvalue_qualified)); - - CHECK(mi2.type().arity() == 0); - CHECK(mi2.type().class_type() == type_db::get()); - CHECK(mi2.type().return_type() == type_db::get()); - CHECK(mi2.type().flags() == (method_flags::is_const | method_flags::is_volatile | method_flags::is_rvalue_qualified)); - } - - { - CHECK_FALSE(mi.is_invocable_with()); - CHECK_FALSE(mi.is_invocable_with()); - CHECK(mi.is_invocable_with()); - CHECK(mi.is_invocable_with()); - - CHECK_FALSE(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); - CHECK(mi2.is_invocable_with()); - CHECK(mi2.is_invocable_with()); - } - - { - clazz cl; - - CHECK_THROWS(mi.invoke(cl)); - CHECK_THROWS(mi.invoke(std::as_const(cl))); - CHECK(mi.invoke(std::move(cl)).value() == 11); - CHECK(mi.invoke(std::move(std::as_const(cl))).value() == 11); - - CHECK_THROWS(mi2.invoke(cl)); - CHECK_THROWS(mi2.invoke(std::as_const(cl))); - CHECK(mi2.invoke(std::move(cl)).value() == 11); - CHECK(mi2.invoke(std::move(std::as_const(cl))).value() == 11); - } - - static_assert(!std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); - - static_assert(!std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); - } - - SUBCASE("const_method_noexcept_rref") { - const method_info mi = db.get_method_by_path("clazz::const_method_noexcept_rref"); - REQUIRE(mi); - - const method_info mi2 = db.get_method_by_path("clazz::const_method_noexcept_rref_volatile"); - REQUIRE(mi2); - - { - CHECK(mi.type().arity() == 0); - CHECK(mi.type().class_type() == type_db::get()); - CHECK(mi.type().return_type() == type_db::get()); - CHECK(mi.type().flags() == (method_flags::is_const | method_flags::is_noexcept | method_flags::is_rvalue_qualified)); - - CHECK(mi2.type().arity() == 0); - CHECK(mi2.type().class_type() == type_db::get()); - CHECK(mi2.type().return_type() == type_db::get()); - CHECK(mi2.type().flags() == (method_flags::is_const | method_flags::is_noexcept | method_flags::is_volatile | method_flags::is_rvalue_qualified)); - } - - { - CHECK_FALSE(mi.is_invocable_with()); - CHECK_FALSE(mi.is_invocable_with()); - CHECK(mi.is_invocable_with()); - CHECK(mi.is_invocable_with()); - - CHECK_FALSE(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); - CHECK(mi2.is_invocable_with()); - CHECK(mi2.is_invocable_with()); - } - - { - clazz cl; - - CHECK_THROWS(mi.invoke(cl)); - CHECK_THROWS(mi.invoke(std::as_const(cl))); - CHECK(mi.invoke(std::move(cl)).value() == 12); - CHECK(mi.invoke(std::move(std::as_const(cl))).value() == 12); - - CHECK_THROWS(mi2.invoke(cl)); - CHECK_THROWS(mi2.invoke(std::as_const(cl))); - CHECK(mi2.invoke(std::move(cl)).value() == 12); - CHECK(mi2.invoke(std::move(std::as_const(cl))).value() == 12); - } - - static_assert(!std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); - - static_assert(!std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); - } -} diff --git a/untests/features/infos/namespace_info_tests.cpp b/untests/features/infos/namespace_info_tests.cpp deleted file mode 100644 index bd029d5..0000000 --- a/untests/features/infos/namespace_info_tests.cpp +++ /dev/null @@ -1,14 +0,0 @@ -/******************************************************************************* - * 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 "_infos_fwd.hpp" - -namespace -{ -} - -TEST_CASE("features/infos/namespace") { -} diff --git a/untests/features/registry/_registry_fwd.hpp b/untests/features/registry/_registry_fwd.hpp deleted file mode 100644 index b826cce..0000000 --- a/untests/features/registry/_registry_fwd.hpp +++ /dev/null @@ -1,9 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "../../meta_tests.hpp" diff --git a/untests/features/registry/registry_tests.cpp b/untests/features/registry/registry_tests.cpp deleted file mode 100644 index c72b2e1..0000000 --- a/untests/features/registry/registry_tests.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/******************************************************************************* - * 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 "_registry_fwd.hpp" - -namespace -{ - using namespace meta_hpp; - using namespace std::string_literals; -} - -namespace -{ - struct ivec2 { - int x{}; - int y{}; - - [[maybe_unused]] ivec2() = default; - [[maybe_unused]] explicit ivec2(int v): x{v}, y{v} {} - [[maybe_unused]] ivec2(int x, int y): x{x}, y{y} {} - }; -} - -TEST_CASE("features/registry/registry") { - auto db = registry{}( - namespace_{"vmath"}(data_{"info", "vmath namespace"}, - class_{"ivec2"}(data_{"info", "ivec2 class"}, - ctor_<>{}, - ctor_{}, - ctor_{}, - member_{"x", &ivec2::x}(data_{"info", "x-coord"}), - member_{"y", &ivec2::y}(data_{"info", "y-coord"}) - ) - ) - ); - - { - const namespace_info vmath_info = db.get_namespace_by_path("vmath"); - REQUIRE(vmath_info); - CHECK(vmath_info.name() == "vmath"); - CHECK(vmath_info.get_data_by_name("info")); - - const class_info ivec2_info = vmath_info.get_class_by_name("ivec2"); - REQUIRE(ivec2_info); - CHECK(ivec2_info.name() == "ivec2"); - CHECK(ivec2_info.get_data_by_name("info")); - - const member_info ivec2_x_info = ivec2_info.get_member_by_name("x"); - REQUIRE(ivec2_x_info); - CHECK(ivec2_x_info.name() == "x"); - CHECK(ivec2_x_info.get_data_by_name("info")); - } - - { - const class_info ivec2_info = db.get_class_by_path("vmath::ivec2"); - REQUIRE(ivec2_info); - CHECK(ivec2_info.name() == "ivec2"); - - const member_info ivec2_x_info = db.get_member_by_path("vmath::ivec2::x"); - REQUIRE(ivec2_x_info); - CHECK(ivec2_x_info.name() == "x"); - - const data_info ivec2_x_data_info = db.get_data_by_path("vmath::ivec2::x::info"); - REQUIRE(ivec2_x_data_info); - CHECK(ivec2_x_data_info.name() == "info"); - } -} diff --git a/untests/features/types/_types_fwd.hpp b/untests/features/types/_types_fwd.hpp deleted file mode 100644 index b826cce..0000000 --- a/untests/features/types/_types_fwd.hpp +++ /dev/null @@ -1,9 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "../../meta_tests.hpp" diff --git a/untests/features/types/arithmetic_type_tests.cpp b/untests/features/types/arithmetic_type_tests.cpp deleted file mode 100644 index c407be1..0000000 --- a/untests/features/types/arithmetic_type_tests.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/******************************************************************************* - * 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 "_types_fwd.hpp" - -namespace -{ - using namespace meta_hpp; - using namespace std::string_literals; -} - -TEST_CASE("features/types/arithmetic") { - SUBCASE("int") { - using type = int; - - REQUIRE(type_db::get()); - REQUIRE(type_db::get().is()); - - const arithmetic_type at = type_db::get().as(); - - CHECK_FALSE(at.raw_type()); - CHECK(at.size() == sizeof(type)); - - CHECK(at.flags() == ( - arithmetic_flags::is_signed | - arithmetic_flags::is_integral)); - - CHECK_FALSE(at.is_const()); - CHECK(at.is_signed()); - CHECK_FALSE(at.is_unsigned()); - CHECK(at.is_integral()); - CHECK_FALSE(at.is_floating_point()); - } - - SUBCASE("const float") { - using type = const float; - - REQUIRE(type_db::get()); - REQUIRE(type_db::get().is()); - - const arithmetic_type at = type_db::get().as(); - - CHECK(at.raw_type() == type_db::get()); - CHECK(at.size() == sizeof(type)); - - CHECK(at.flags() == ( - arithmetic_flags::is_const | - arithmetic_flags::is_signed | - arithmetic_flags::is_floating_point)); - - CHECK(at.is_const()); - CHECK(at.is_signed()); - CHECK_FALSE(at.is_unsigned()); - CHECK_FALSE(at.is_integral()); - CHECK(at.is_floating_point()); - } - - SUBCASE("const unsigned") { - using type = const unsigned; - - REQUIRE(type_db::get()); - REQUIRE(type_db::get().is()); - - const arithmetic_type at = type_db::get().as(); - - CHECK(at.raw_type() == type_db::get()); - CHECK(at.size() == sizeof(type)); - - CHECK(at.flags() == ( - arithmetic_flags::is_const | - arithmetic_flags::is_unsigned | - arithmetic_flags::is_integral)); - - CHECK(at.is_const()); - CHECK_FALSE(at.is_signed()); - CHECK(at.is_unsigned()); - CHECK(at.is_integral()); - CHECK_FALSE(at.is_floating_point()); - } -} diff --git a/untests/features/types/array_type_tests.cpp b/untests/features/types/array_type_tests.cpp deleted file mode 100644 index b2f6169..0000000 --- a/untests/features/types/array_type_tests.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/******************************************************************************* - * 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 "_types_fwd.hpp" - -namespace -{ - using namespace meta_hpp; - using namespace std::string_literals; -} - -TEST_CASE("features/types/array") { - SUBCASE("int[]") { - using type = int[]; - - REQUIRE(type_db::get()); - REQUIRE(type_db::get().is()); - - const array_type at = type_db::get().as(); - - CHECK(at.data_type() == type_db::get()); - CHECK(at.extent() == 0); - - CHECK(at.flags() == (array_flags::is_unbounded)); - - CHECK_FALSE(at.is_bounded()); - CHECK(at.is_unbounded()); - } - - SUBCASE("unsigned[42][]") { - using type = unsigned[][42]; - - REQUIRE(type_db::get()); - REQUIRE(type_db::get().is()); - - const array_type at = type_db::get().as(); - - CHECK(at.data_type() == type_db::get()); - CHECK(at.extent() == 0); - - CHECK(at.flags() == (array_flags::is_unbounded)); - - CHECK_FALSE(at.is_bounded()); - CHECK(at.is_unbounded()); - } - - SUBCASE("const int[42][21]") { - using type = const int[42][21]; - - REQUIRE(type_db::get()); - REQUIRE(type_db::get().is()); - - const array_type at = type_db::get().as(); - - CHECK(at.data_type() == type_db::get()); - CHECK(at.extent() == 42); - - CHECK(at.flags() == (array_flags::is_bounded)); - - CHECK(at.is_bounded()); - CHECK_FALSE(at.is_unbounded()); - } - - SUBCASE("const unsigned[42]") { - using type = const unsigned[42]; - - REQUIRE(type_db::get()); - REQUIRE(type_db::get().is()); - - const array_type at = type_db::get().as(); - - CHECK(at.data_type() == type_db::get()); - CHECK(at.extent() == 42); - - CHECK(at.flags() == (array_flags::is_bounded)); - - CHECK(at.is_bounded()); - CHECK_FALSE(at.is_unbounded()); - } -} diff --git a/untests/features/types/base_type_tests.cpp b/untests/features/types/base_type_tests.cpp deleted file mode 100644 index 0a84731..0000000 --- a/untests/features/types/base_type_tests.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/******************************************************************************* - * 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 "_types_fwd.hpp" - -namespace -{ - using namespace meta_hpp; - using namespace std::string_literals; -} - -namespace -{ - struct base { - virtual ~base() = 0; - }; - - struct derived final : base { - }; -} - -TEST_CASE("features/types/base") { - base_type bt{typename_arg, typename_arg}; - - CHECK(bt.base_class_type() == type_db::get()); - CHECK(bt.derived_class_type() == type_db::get()); -} diff --git a/untests/features/types/class_type_tests.cpp b/untests/features/types/class_type_tests.cpp deleted file mode 100644 index bf4bbbc..0000000 --- a/untests/features/types/class_type_tests.cpp +++ /dev/null @@ -1,143 +0,0 @@ -/******************************************************************************* - * 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 "_types_fwd.hpp" - -namespace -{ - using namespace meta_hpp; - using namespace std::string_literals; -} - -namespace -{ - struct base { - virtual ~base() = 0; - }; - - struct derived final : base { - }; - - struct empty final { - }; - - struct ivec2 final { - int x{}; - int y{}; - }; -} - -TEST_CASE("features/types/class") { - SUBCASE("base") { - using type = base; - - REQUIRE(type_db::get()); - REQUIRE(type_db::get().is()); - - const class_type ct = type_db::get().as(); - - CHECK_FALSE(ct.raw_type()); - CHECK(ct.size() == sizeof(type)); - - CHECK(ct.flags() == ( - class_flags::is_abstract | - class_flags::is_polymorphic)); - - CHECK_FALSE(ct.is_const()); - CHECK_FALSE(ct.is_empty()); - CHECK_FALSE(ct.is_final()); - CHECK(ct.is_abstract()); - CHECK(ct.is_polymorphic()); - } - - SUBCASE("derived") { - using type = derived; - - REQUIRE(type_db::get()); - REQUIRE(type_db::get().is()); - - const class_type ct = type_db::get().as(); - - CHECK_FALSE(ct.raw_type()); - CHECK(ct.size() == sizeof(type)); - - CHECK(ct.flags() == ( - class_flags::is_final | - class_flags::is_polymorphic)); - - CHECK_FALSE(ct.is_const()); - CHECK_FALSE(ct.is_empty()); - CHECK(ct.is_final()); - CHECK_FALSE(ct.is_abstract()); - CHECK(ct.is_polymorphic()); - } - - SUBCASE("empty") { - using type = empty; - - REQUIRE(type_db::get()); - REQUIRE(type_db::get().is()); - - const class_type ct = type_db::get().as(); - - CHECK_FALSE(ct.raw_type()); - CHECK(ct.size() == sizeof(type)); - - CHECK(ct.flags() == ( - class_flags::is_empty | - class_flags::is_final)); - - CHECK_FALSE(ct.is_const()); - CHECK(ct.is_empty()); - CHECK(ct.is_final()); - CHECK_FALSE(ct.is_abstract()); - CHECK_FALSE(ct.is_polymorphic()); - } - - SUBCASE("ivec2") { - using type = ivec2; - - REQUIRE(type_db::get()); - REQUIRE(type_db::get().is()); - - const class_type ct = type_db::get().as(); - - CHECK_FALSE(ct.raw_type()); - CHECK(ct.size() == sizeof(type)); - - CHECK(ct.flags() == ( - class_flags::is_final)); - - CHECK_FALSE(ct.is_const()); - CHECK_FALSE(ct.is_empty()); - CHECK(ct.is_final()); - CHECK_FALSE(ct.is_abstract()); - CHECK_FALSE(ct.is_polymorphic()); - } - - SUBCASE("const ivec2") { - using type = const ivec2; - - REQUIRE(type_db::get()); - REQUIRE(type_db::get().is()); - - const class_type ct = type_db::get().as(); - - REQUIRE(ct.raw_type()); - CHECK(ct.raw_type() == type_db::get()); - CHECK(ct.size() == sizeof(type)); - - CHECK(ct.flags() == ( - class_flags::is_const | - class_flags::is_final)); - - CHECK(ct.is_const()); - CHECK_FALSE(ct.is_empty()); - CHECK(ct.is_final()); - CHECK_FALSE(ct.is_abstract()); - CHECK_FALSE(ct.is_polymorphic()); - } -} diff --git a/untests/features/types/ctor_type_tests.cpp b/untests/features/types/ctor_type_tests.cpp deleted file mode 100644 index 8245684..0000000 --- a/untests/features/types/ctor_type_tests.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/******************************************************************************* - * 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 "_types_fwd.hpp" - -namespace -{ - using namespace meta_hpp; - using namespace std::string_literals; -} - -namespace -{ - struct ivec2 final { - int x{}; - int y{}; - - [[maybe_unused]] ivec2() = default; - [[maybe_unused]] explicit ivec2(int v): x{v}, y{v} {} - [[maybe_unused]] ivec2(int x, int y): x{x}, y{y} {} - }; -} - -TEST_CASE("features/types/ctor") { - SUBCASE("ivec2_void") { - ctor_type ct{typename_arg, typename_arg<>}; - - CHECK(ct.class_type() == type_db::get()); - CHECK(ct.argument_types().size() == 0); - CHECK(ct.arity() == 0); - - CHECK(ct.flags() == (ctor_flags::is_noexcept)); - CHECK(ct.is_noexcept()); - - { - CHECK_FALSE(ct.argument_type(0)); - } - } - - SUBCASE("ivec2_int") { - ctor_type ct{typename_arg, typename_arg}; - - CHECK(ct.arity() == 1); - CHECK(ct.class_type() == type_db::get()); - CHECK(ct.argument_types().size() == 1); - - CHECK(ct.flags() == (ctor_flags{})); - CHECK_FALSE(ct.is_noexcept()); - - { - REQUIRE(ct.argument_type(0)); - const any_type arg0 = ct.argument_type(0); - CHECK(arg0 == type_db::get()); - } - - { - CHECK_FALSE(ct.argument_type(1)); - } - } - - SUBCASE("ivec2_int_int") { - ctor_type ct{typename_arg, typename_arg}; - - CHECK(ct.class_type() == type_db::get()); - CHECK(ct.argument_types().size() == 2); - CHECK(ct.arity() == 2); - - CHECK(ct.flags() == (ctor_flags{})); - CHECK_FALSE(ct.is_noexcept()); - - { - REQUIRE(ct.argument_type(0)); - const any_type arg0 = ct.argument_type(0); - CHECK(arg0 == type_db::get()); - } - - { - REQUIRE(ct.argument_type(1)); - const any_type arg1 = ct.argument_type(1); - CHECK(arg1 == type_db::get()); - } - - { - CHECK_FALSE(ct.argument_type(2)); - } - } -} diff --git a/untests/features/types/enum_type_tests.cpp b/untests/features/types/enum_type_tests.cpp deleted file mode 100644 index 03be3a7..0000000 --- a/untests/features/types/enum_type_tests.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/******************************************************************************* - * 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 "_types_fwd.hpp" - -namespace -{ - using namespace meta_hpp; - using namespace std::string_literals; -} - -namespace -{ - enum class ecolor : unsigned { - red = 0xFF0000, - green = 0x00FF00, - blue = 0x0000FF, - }; -} - -TEST_CASE("features/types/enum") { - SUBCASE("ecolor") { - using type = ecolor; - - REQUIRE(type_db::get()); - REQUIRE(type_db::get().is()); - - const enum_type et = type_db::get().as(); - - CHECK(et.size() == sizeof(type)); - CHECK_FALSE(et.raw_type()); - CHECK(et.underlying_type() == type_db::get()); - - CHECK(et.flags() == (enum_flags{})); - CHECK_FALSE(et.is_const()); - } - - SUBCASE("const ecolor") { - using type = const ecolor; - - REQUIRE(type_db::get()); - REQUIRE(type_db::get().is()); - - const enum_type et = type_db::get().as(); - - CHECK(et.size() == sizeof(type)); - REQUIRE(et.raw_type()); - CHECK(et.raw_type() == type_db::get()); - CHECK(et.underlying_type() == type_db::get()); - - CHECK(et.flags() == (enum_flags::is_const)); - CHECK(et.is_const()); - } -} diff --git a/untests/features/types/function_type_tests.cpp b/untests/features/types/function_type_tests.cpp deleted file mode 100644 index fb3ac00..0000000 --- a/untests/features/types/function_type_tests.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/******************************************************************************* - * 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 "_types_fwd.hpp" - -namespace -{ - using namespace meta_hpp; - using namespace std::string_literals; -} - -namespace -{ - struct ivec2 { - int x{}; - int y{}; - }; - - [[maybe_unused]] void arg_copy(ivec2) {} - [[maybe_unused]] void arg_ref_noexcept(ivec2&) noexcept {} - [[maybe_unused]] void arg_cref_noexcept(const ivec2&) noexcept {} -} - -TEST_CASE("features/types/function") { - SUBCASE("arg_copy") { - using type = decltype(&arg_copy); - - REQUIRE(type_db::get()); - REQUIRE(type_db::get().is()); - - const function_type ft = type_db::get().as(); - CHECK(ft.return_type() == type_db::get()); - CHECK(ft.argument_types().size() == 1); - CHECK(ft.arity() == 1); - - CHECK(ft.flags() == (function_flags{})); - CHECK_FALSE(ft.is_noexcept()); - - { - REQUIRE(ft.argument_type(0)); - const any_type arg0 = ft.argument_type(0); - CHECK(arg0 == type_db::get()); - } - - { - CHECK_FALSE(ft.argument_type(1)); - } - } - - SUBCASE("arg_ref_noexcept") { - using type = decltype(&arg_ref_noexcept); - - REQUIRE(type_db::get()); - REQUIRE(type_db::get().is()); - - const function_type ft = type_db::get().as(); - CHECK(ft.return_type() == type_db::get()); - CHECK(ft.argument_types().size() == 1); - CHECK(ft.arity() == 1); - - CHECK(ft.flags() == (function_flags::is_noexcept)); - CHECK(ft.is_noexcept()); - - { - REQUIRE(ft.argument_type(0)); - const any_type arg0 = ft.argument_type(0); - CHECK(arg0 == type_db::get()); - } - - { - CHECK_FALSE(ft.argument_type(1)); - } - } - - SUBCASE("arg_cref_noexcept") { - using type = decltype(&arg_cref_noexcept); - - REQUIRE(type_db::get()); - REQUIRE(type_db::get().is()); - - const function_type ft = type_db::get().as(); - CHECK(ft.return_type() == type_db::get()); - CHECK(ft.argument_types().size() == 1); - CHECK(ft.arity() == 1); - - CHECK(ft.flags() == (function_flags::is_noexcept)); - CHECK(ft.is_noexcept()); - - { - REQUIRE(ft.argument_type(0)); - const any_type arg0 = ft.argument_type(0); - CHECK(arg0 == type_db::get()); - } - - { - CHECK_FALSE(ft.argument_type(1)); - } - } -} diff --git a/untests/features/types/member_type_tests.cpp b/untests/features/types/member_type_tests.cpp deleted file mode 100644 index e085801..0000000 --- a/untests/features/types/member_type_tests.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/******************************************************************************* - * 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 "_types_fwd.hpp" - -namespace -{ - using namespace meta_hpp; - using namespace std::string_literals; -} - -namespace -{ - struct clazz { - int int_member{}; - const int const_int_member{10}; - }; -} - -TEST_CASE("features/types/member") { - SUBCASE("clazz::int_member") { - using type = decltype(&clazz::int_member); - - REQUIRE(type_db::get()); - REQUIRE(type_db::get().is()); - - const member_type mt = type_db::get().as(); - CHECK(mt.class_type() == type_db::get()); - CHECK(mt.value_type() == type_db::get()); - } - - SUBCASE("clazz::const_int_member") { - using type = decltype(&clazz::const_int_member); - - REQUIRE(type_db::get()); - REQUIRE(type_db::get().is()); - - const member_type mt = type_db::get().as(); - CHECK(mt.class_type() == type_db::get()); - CHECK(mt.value_type() == type_db::get()); - } -} diff --git a/untests/features/types/method_type_tests.cpp b/untests/features/types/method_type_tests.cpp deleted file mode 100644 index 334946d..0000000 --- a/untests/features/types/method_type_tests.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/******************************************************************************* - * 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 "_types_fwd.hpp" - -namespace -{ - using namespace meta_hpp; - using namespace std::string_literals; -} - -namespace -{ - struct ivec2 { - int x{}; - int y{}; - - [[maybe_unused]] int& at(std::size_t i) { - switch ( i ) { - case 0: return x; - case 1: return y; - default: throw std::out_of_range("ivec2::at"); - } - } - - [[maybe_unused]] int length2() const noexcept { - return x * x + y * y; - } - }; -} - -TEST_CASE("features/types/method") { - SUBCASE("ivec2::at") { - using type = decltype(&ivec2::at); - - REQUIRE(type_db::get()); - REQUIRE(type_db::get().is()); - - const method_type mt = type_db::get().as(); - CHECK(mt.class_type() == type_db::get()); - CHECK(mt.return_type() == type_db::get()); - CHECK(mt.argument_types().size() == 1); - CHECK(mt.arity() == 1); - - CHECK(mt.flags() == (method_flags{})); - - CHECK_FALSE(mt.is_const()); - CHECK_FALSE(mt.is_noexcept()); - - { - REQUIRE(mt.argument_type(0)); - const any_type arg0 = mt.argument_type(0); - CHECK(arg0 == type_db::get()); - } - - { - CHECK_FALSE(mt.argument_type(1)); - } - } - - SUBCASE("ivec2::length2") { - using type = decltype(&ivec2::length2); - - REQUIRE(type_db::get()); - REQUIRE(type_db::get().is()); - - const method_type mt = type_db::get().as(); - CHECK(mt.class_type() == type_db::get()); - CHECK(mt.return_type() == type_db::get()); - CHECK(mt.argument_types().size() == 0); - CHECK(mt.arity() == 0); - - CHECK(mt.flags() == ( - method_flags::is_const | - method_flags::is_noexcept)); - - CHECK(mt.is_const()); - CHECK(mt.is_noexcept()); - - { - CHECK_FALSE(mt.argument_type(0)); - } - } -} diff --git a/untests/features/types/pointer_type_tests.cpp b/untests/features/types/pointer_type_tests.cpp deleted file mode 100644 index f267734..0000000 --- a/untests/features/types/pointer_type_tests.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/******************************************************************************* - * 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 "_types_fwd.hpp" - -namespace -{ - using namespace meta_hpp; - using namespace std::string_literals; -} - -namespace -{ - struct ivec2 { - int x{}; - int y{}; - }; -} - -TEST_CASE("features/types/pointer") { - SUBCASE("ivec2*") { - using type = ivec2*; - - REQUIRE(type_db::get()); - REQUIRE(type_db::get().is()); - - const pointer_type pt = type_db::get().as(); - - CHECK(pt.data_type() == type_db::get()); - - CHECK(pt.flags() == (pointer_flags{})); - CHECK_FALSE(pt.is_const()); - } - - SUBCASE("const ivec2*") { - using type = const ivec2*; - - REQUIRE(type_db::get()); - REQUIRE(type_db::get().is()); - - const pointer_type pt = type_db::get().as(); - - CHECK(pt.data_type() == type_db::get()); - - CHECK(pt.flags() == (pointer_flags{})); - CHECK_FALSE(pt.is_const()); - } - - SUBCASE("ivec2* const") { - using type = ivec2* const; - - REQUIRE(type_db::get()); - REQUIRE(type_db::get().is()); - - const pointer_type pt = type_db::get().as(); - - CHECK(pt.data_type() == type_db::get()); - - CHECK(pt.flags() == (pointer_flags::is_const)); - CHECK(pt.is_const()); - } - - SUBCASE("const ivec2* const") { - using type = const ivec2* const; - - REQUIRE(type_db::get()); - REQUIRE(type_db::get().is()); - - const pointer_type pt = type_db::get().as(); - - CHECK(pt.data_type() == type_db::get()); - - CHECK(pt.flags() == (pointer_flags::is_const)); - CHECK(pt.is_const()); - } -} diff --git a/untests/features/types/reference_type_tests.cpp b/untests/features/types/reference_type_tests.cpp deleted file mode 100644 index 0bacb4a..0000000 --- a/untests/features/types/reference_type_tests.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/******************************************************************************* - * 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 "_types_fwd.hpp" - -namespace -{ - using namespace meta_hpp; - using namespace std::string_literals; -} - -namespace -{ - struct ivec2 { - int x{}; - int y{}; - }; -} - -TEST_CASE("features/types/reference") { - SUBCASE("ivec2&") { - REQUIRE(type_db::get()); - REQUIRE(type_db::get().is()); - - const reference_type rt = type_db::get().as(); - - CHECK(rt.data_type() == type_db::get()); - - CHECK(rt.flags() == (reference_flags::is_lvalue)); - - CHECK(rt.is_lvalue()); - CHECK_FALSE(rt.is_rvalue()); - } - - SUBCASE("const ivec2&&") { - REQUIRE(type_db::get()); - REQUIRE(type_db::get().is()); - - const reference_type rt = type_db::get().as(); - - CHECK(rt.data_type() == type_db::get()); - - CHECK(rt.flags() == (reference_flags::is_rvalue)); - - CHECK_FALSE(rt.is_lvalue()); - CHECK(rt.is_rvalue()); - } -} diff --git a/untests/features/types/void_type_tests.cpp b/untests/features/types/void_type_tests.cpp deleted file mode 100644 index e53afb2..0000000 --- a/untests/features/types/void_type_tests.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/******************************************************************************* - * 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 "_types_fwd.hpp" - -namespace -{ - using namespace meta_hpp; - using namespace std::string_literals; -} - -TEST_CASE("features/types/void") { - SUBCASE("void") { - using type = void; - - REQUIRE(type_db::get()); - REQUIRE(type_db::get().is()); - - const void_type vt = type_db::get().as(); - - CHECK_FALSE(vt.raw_type()); - - CHECK(vt.flags() == (void_flags{})); - CHECK_FALSE(vt.is_const()); - } - - SUBCASE("const void") { - using type = const void; - - REQUIRE(type_db::get()); - REQUIRE(type_db::get().is()); - - const void_type vt = type_db::get().as(); - - REQUIRE(vt.raw_type()); - CHECK(vt.raw_type() == type_db::get()); - - CHECK(vt.flags() == (void_flags::is_const)); - CHECK(vt.is_const()); - } -} diff --git a/untests/features/utilities/_utilities_fwd.hpp b/untests/features/utilities/_utilities_fwd.hpp deleted file mode 100644 index b826cce..0000000 --- a/untests/features/utilities/_utilities_fwd.hpp +++ /dev/null @@ -1,9 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "../../meta_tests.hpp" diff --git a/untests/features/utilities/arg_tests.cpp b/untests/features/utilities/arg_tests.cpp deleted file mode 100644 index 053b2ca..0000000 --- a/untests/features/utilities/arg_tests.cpp +++ /dev/null @@ -1,1157 +0,0 @@ -/******************************************************************************* - * 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 "_utilities_fwd.hpp" - -namespace -{ - using namespace meta_hpp; - using namespace std::string_literals; -} - -namespace -{ - struct ivec2 { - int x{}; - int y{}; - - [[maybe_unused]] ivec2() = default; - [[maybe_unused]] explicit ivec2(int v): x{v}, y{v} {} - [[maybe_unused]] ivec2(int x, int y): x{x}, y{y} {} - - [[maybe_unused]] ivec2(ivec2&& other) noexcept { - x = other.x; - y = other.y; - other.x = 0; - other.y = 0; - } - - [[maybe_unused]] ivec2(const ivec2& other) noexcept { - x = other.x; - y = other.y; - } - - ivec2& operator=(ivec2&&) = delete; - ivec2& operator=(const ivec2&) = delete; - }; - - struct ivec3 { - int x{}; - int y{}; - int z{}; - - [[maybe_unused]] ivec3() = default; - [[maybe_unused]] explicit ivec3(int v): x{v}, y{v}, z{v} {} - [[maybe_unused]] ivec3(int x, int y, int z): x{x}, y{y}, z{z} {} - - [[maybe_unused]] ivec3(ivec3&& other) noexcept { - x = other.x; - y = other.y; - z = other.z; - other.x = 0; - other.y = 0; - other.z = 0; - } - - [[maybe_unused]] ivec3(const ivec3& other) noexcept { - x = other.x; - y = other.y; - z = other.z; - } - - ivec3& operator=(ivec3&&) = delete; - ivec3& operator=(const ivec3&) = delete; - }; - - [[maybe_unused]] bool operator==(const ivec2& l, const ivec2& r) noexcept { - return l.x == r.x && l.y == r.y; - } - - [[maybe_unused]] bool operator==(const ivec3& l, const ivec3& r) noexcept { - return l.x == r.x && l.y == r.y && l.z == r.z; - } -} - -TEST_CASE("features/utilities/arg/type") { - SUBCASE("ptr") { - ivec2 v{1,2}; - ivec2* vp = &v; - arg a{vp}; - - CHECK(a.raw_type() == type_db::get()); - CHECK(a.ref_type() == arg::ref_types::ref); - } - - SUBCASE("rptr") { - ivec2 v{1,2}; - ivec2* vp = &v; - arg a{std::move(vp)}; - - CHECK(a.raw_type() == type_db::get()); - CHECK(a.ref_type() == arg::ref_types::rref); - } - - SUBCASE("ptr_c") { - ivec2 v{1,2}; - ivec2* const vp = &v; - arg a{vp}; - - CHECK(a.raw_type() == type_db::get()); - CHECK(a.ref_type() == arg::ref_types::cref); - } - - SUBCASE("rptr_c") { - ivec2 v{1,2}; - ivec2* const vp = &v; - arg a{std::move(vp)}; - - CHECK(a.raw_type() == type_db::get()); - CHECK(a.ref_type() == arg::ref_types::crref); - } - - SUBCASE("cptr") { - const ivec2 v{1,2}; - const ivec2* vp = &v; - arg a{vp}; - - CHECK(a.raw_type() == type_db::get()); - CHECK(a.ref_type() == arg::ref_types::ref); - } - - SUBCASE("crptr") { - const ivec2 v{1,2}; - const ivec2* vp = &v; - arg a{std::move(vp)}; - - CHECK(a.raw_type() == type_db::get()); - CHECK(a.ref_type() == arg::ref_types::rref); - } - - SUBCASE("cptr_c") { - const ivec2 v{1,2}; - const ivec2* const vp = &v; - arg a{vp}; - - CHECK(a.raw_type() == type_db::get()); - CHECK(a.ref_type() == arg::ref_types::cref); - } - - SUBCASE("crptr_c") { - const ivec2 v{1,2}; - const ivec2* const vp = &v; - arg a{std::move(vp)}; - - CHECK(a.raw_type() == type_db::get()); - CHECK(a.ref_type() == arg::ref_types::crref); - } - - SUBCASE("ref") { - ivec2 v{1,2}; - ivec2& vr = v; - arg a{vr}; - - CHECK(a.raw_type() == type_db::get()); - CHECK(a.ref_type() == arg::ref_types::ref); - } - - SUBCASE("cref") { - const ivec2 v{1,2}; - const ivec2& vr = v; - arg a{vr}; - - CHECK(a.raw_type() == type_db::get()); - CHECK(a.ref_type() == arg::ref_types::cref); - } - - SUBCASE("rref") { - ivec2 v{1,2}; - arg a{std::move(v)}; - - CHECK(a.raw_type() == type_db::get()); - CHECK(a.ref_type() == arg::ref_types::rref); - } - - SUBCASE("crref") { - const ivec2 v{1,2}; - arg a{std::move(v)}; - - CHECK(a.raw_type() == type_db::get()); - CHECK(a.ref_type() == arg::ref_types::crref); - } -} - -TEST_CASE("features/utilities/arg/can_cast_to") { - SUBCASE("ptr") { - ivec2 v{1,2}; - ivec2* vp = &v; - arg a{vp}; - - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - - { - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - } - - { - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - - CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - - []([[maybe_unused]] ivec2 *){}(vp); - []([[maybe_unused]] const ivec2 *){}(vp); - []([[maybe_unused]] ivec2 *const){}(vp); - []([[maybe_unused]] const ivec2 *const){}(vp); - - []([[maybe_unused]] ivec2 *&){}(vp); - //[]([[maybe_unused]] const ivec2 *&){}(vp); - []([[maybe_unused]] ivec2 *const &){}(vp); - []([[maybe_unused]] const ivec2 *const &){}(vp); - - //[]([[maybe_unused]] ivec2 *&&){}(vp); - //[]([[maybe_unused]] const ivec2 *&&){}(vp); - //[]([[maybe_unused]] ivec2 *const &&){}(vp); - //[]([[maybe_unused]] const ivec2 *const &&){}(vp); - } - } - - SUBCASE("rptr") { - ivec2 v{1,2}; - ivec2* vp = &v; - arg a{std::move(vp)}; - - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - - { - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - } - - { - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - - CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - - []([[maybe_unused]] ivec2 *){}(std::move(vp)); - []([[maybe_unused]] const ivec2 *){}(std::move(vp)); - []([[maybe_unused]] ivec2 *const){}(std::move(vp)); - []([[maybe_unused]] const ivec2 *const){}(std::move(vp)); - - //[]([[maybe_unused]] ivec2 *&){}(std::move(vp)); - //[]([[maybe_unused]] const ivec2 *&){}(std::move(vp)); - []([[maybe_unused]] ivec2 *const &){}(std::move(vp)); - []([[maybe_unused]] const ivec2 *const &){}(std::move(vp)); - - []([[maybe_unused]] ivec2 *&&){}(std::move(vp)); - //[]([[maybe_unused]] const ivec2 *&&){}(std::move(vp)); - []([[maybe_unused]] ivec2 *const &&){}(std::move(vp)); - []([[maybe_unused]] const ivec2 *const &&){}(std::move(vp)); - } - } - - SUBCASE("ptr_c") { - ivec2 v{1,2}; - ivec2* const vp = &v; - arg a{vp}; - - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - - { - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - } - - { - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - - []([[maybe_unused]] ivec2 *){}(vp); - []([[maybe_unused]] const ivec2 *){}(vp); - []([[maybe_unused]] ivec2 *const &){}(vp); - []([[maybe_unused]] const ivec2 *const &){}(vp); - - // []([[maybe_unused]] ivec2 *&){}(vp); - // []([[maybe_unused]] const ivec2 *&){}(vp); - []([[maybe_unused]] ivec2 *const &){}(vp); - []([[maybe_unused]] const ivec2 *const &){}(vp); - - //[]([[maybe_unused]] ivec2 *&&){}(vp); - //[]([[maybe_unused]] const ivec2 *&&){}(vp); - //[]([[maybe_unused]] ivec2 *const &&){}(vp); - //[]([[maybe_unused]] const ivec2 *const &&){}(vp); - } - } - - SUBCASE("rptr_c") { - ivec2 v{1,2}; - ivec2* const vp = &v; - arg a{std::move(vp)}; - - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - - { - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - } - - { - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - - []([[maybe_unused]] ivec2 *){}(std::move(vp)); - []([[maybe_unused]] const ivec2 *){}(std::move(vp)); - []([[maybe_unused]] ivec2 *const){}(std::move(vp)); - []([[maybe_unused]] const ivec2 *const){}(std::move(vp)); - - //[]([[maybe_unused]] ivec2 *&){}(std::move(vp)); - //[]([[maybe_unused]] const ivec2 *&){}(std::move(vp)); - []([[maybe_unused]] ivec2 *const &){}(std::move(vp)); - []([[maybe_unused]] const ivec2 *const &){}(std::move(vp)); - - //[]([[maybe_unused]] ivec2 *&&){}(std::move(vp)); - //[]([[maybe_unused]] const ivec2 *&&){}(std::move(vp)); - []([[maybe_unused]] ivec2 *const &&){}(std::move(vp)); - []([[maybe_unused]] const ivec2 *const &&){}(std::move(vp)); - } - } - - SUBCASE("cptr") { - const ivec2 v{1,2}; - const ivec2* vp = &v; - arg a{vp}; - - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - - { - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - } - - { - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - - //[]([[maybe_unused]] ivec2 *){}(vp); - []([[maybe_unused]] const ivec2 *){}(vp); - //[]([[maybe_unused]] ivec2 *const){}(vp); - []([[maybe_unused]] const ivec2 *const){}(vp); - - //[]([[maybe_unused]] ivec2 *&){}(vp); - []([[maybe_unused]] const ivec2 *&){}(vp); - //[]([[maybe_unused]] ivec2 *const &){}(vp); - []([[maybe_unused]] const ivec2 *const &){}(vp); - - //[]([[maybe_unused]] ivec2 *&&){}(vp); - //[]([[maybe_unused]] const ivec2 *&&){}(vp); - //[]([[maybe_unused]] ivec2 *const &&){}(vp); - //[]([[maybe_unused]] const ivec2 *const &&){}(vp); - } - } - - SUBCASE("crptr") { - const ivec2 v{1,2}; - const ivec2* vp = &v; - arg a{std::move(vp)}; - - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - - { - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - } - - { - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - - //[]([[maybe_unused]] ivec2 *){}(std::move(vp)); - []([[maybe_unused]] const ivec2 *){}(std::move(vp)); - //[]([[maybe_unused]] ivec2 *const){}(std::move(vp)); - []([[maybe_unused]] const ivec2 *const){}(std::move(vp)); - - //[]([[maybe_unused]] ivec2 *&){}(std::move(vp)); - //[]([[maybe_unused]] const ivec2 *&){}(std::move(vp)); - //[]([[maybe_unused]] ivec2 *const &){}(std::move(vp)); - []([[maybe_unused]] const ivec2 *const &){}(std::move(vp)); - - //[]([[maybe_unused]] ivec2 *&&){}(std::move(vp)); - []([[maybe_unused]] const ivec2 *&&){}(std::move(vp)); - //[]([[maybe_unused]] ivec2 *const &&){}(std::move(vp)); - []([[maybe_unused]] const ivec2 *const &&){}(std::move(vp)); - } - } - - SUBCASE("cptr_c") { - const ivec2 v{1,2}; - const ivec2* const vp = &v; - arg a{vp}; - - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - - { - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - } - - { - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - - //[]([[maybe_unused]] ivec2 *){}(vp); - []([[maybe_unused]] const ivec2 *){}(vp); - //[]([[maybe_unused]] ivec2 *const){}(vp); - []([[maybe_unused]] const ivec2 *const){}(vp); - - //[]([[maybe_unused]] ivec2 *&){}(vp); - //[]([[maybe_unused]] const ivec2 *&){}(vp); - //[]([[maybe_unused]] ivec2 *const &){}(vp); - []([[maybe_unused]] const ivec2 *const &){}(vp); - - //[]([[maybe_unused]] ivec2 *&&){}(vp); - //[]([[maybe_unused]] const ivec2 *&&){}(vp); - //[]([[maybe_unused]] ivec2 *const &&){}(vp); - //[]([[maybe_unused]] const ivec2 *const &&){}(vp); - } - } - - SUBCASE("crptr_c") { - const ivec2 v{1,2}; - const ivec2* const vp = &v; - arg a{std::move(vp)}; - - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - - { - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - } - - { - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - - //[]([[maybe_unused]] ivec2 *){}(std::move(vp)); - []([[maybe_unused]] const ivec2 *){}(std::move(vp)); - //[]([[maybe_unused]] ivec2 *const){}(std::move(vp)); - []([[maybe_unused]] const ivec2 *const){}(std::move(vp)); - - //[]([[maybe_unused]] ivec2 *&){}(std::move(vp)); - //[]([[maybe_unused]] const ivec2 *&){}(std::move(vp)); - //[]([[maybe_unused]] ivec2 *const &){}(std::move(vp)); - []([[maybe_unused]] const ivec2 *const &){}(std::move(vp)); - - //[]([[maybe_unused]] ivec2 *&&){}(std::move(vp)); - //[]([[maybe_unused]] const ivec2 *&&){}(std::move(vp)); - //[]([[maybe_unused]] ivec2 *const &&){}(std::move(vp)); - []([[maybe_unused]] const ivec2 *const &&){}(std::move(vp)); - } - } - - SUBCASE("ref") { - ivec2 v{1,2}; - ivec2& vr = v; - arg a{vr}; - - { - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - - []([[maybe_unused]] ivec2){}(vr); - []([[maybe_unused]] const ivec2){}(vr); - []([[maybe_unused]] ivec2&){}(vr); - []([[maybe_unused]] const ivec2&){}(vr); - //[]([[maybe_unused]] ivec2&&){}(vr); - //[]([[maybe_unused]] const ivec2&&){}(vr); - } - - { - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - } - - { - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - - //[]([[maybe_unused]] ivec2*){}(vr); - //[]([[maybe_unused]] const ivec2*){}(vr); - //[]([[maybe_unused]] ivec2* const){}(vr); - //[]([[maybe_unused]] const ivec2* const){}(vr); - - //[]([[maybe_unused]] ivec2 *&){}(vr); - //[]([[maybe_unused]] const ivec2 *&){}(vr); - //[]([[maybe_unused]] ivec2 *const &){}(vr); - //[]([[maybe_unused]] const ivec2 *const &){}(vr); - - //[]([[maybe_unused]] ivec2 *&&){}(vr); - //[]([[maybe_unused]] const ivec2 *&&){}(vr); - //[]([[maybe_unused]] ivec2 *const &&){}(vr); - //[]([[maybe_unused]] const ivec2 *const &&){}(vr); - } - } - - SUBCASE("cref") { - const ivec2 v{1,2}; - const ivec2& vr = v; - arg a{vr}; - - { - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - - []([[maybe_unused]] ivec2){}(vr); - []([[maybe_unused]] const ivec2){}(vr); - //[]([[maybe_unused]] ivec2&){}(vr); - []([[maybe_unused]] const ivec2&){}(vr); - //[]([[maybe_unused]] ivec2&&){}(vr); - //[]([[maybe_unused]] const ivec2&&){}(vr); - } - - { - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - } - - { - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - - //[]([[maybe_unused]] ivec2*){}(vr); - //[]([[maybe_unused]] const ivec2*){}(vr); - //[]([[maybe_unused]] ivec2* const){}(vr); - //[]([[maybe_unused]] const ivec2* const){}(vr); - - //[]([[maybe_unused]] ivec2 *&){}(vr); - //[]([[maybe_unused]] const ivec2 *&){}(vr); - //[]([[maybe_unused]] ivec2 *const &){}(vr); - //[]([[maybe_unused]] const ivec2 *const &){}(vr); - - //[]([[maybe_unused]] ivec2 *&&){}(vr); - //[]([[maybe_unused]] const ivec2 *&&){}(vr); - //[]([[maybe_unused]] ivec2 *const &&){}(vr); - //[]([[maybe_unused]] const ivec2 *const &&){}(vr); - } - } - - SUBCASE("rref") { - ivec2 v{1,2}; - arg a{std::move(v)}; - - { - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - - []([[maybe_unused]] ivec2){}(std::move(v)); - []([[maybe_unused]] const ivec2){}(std::move(v)); - //[]([[maybe_unused]] ivec2&){}(std::move(v)); - []([[maybe_unused]] const ivec2&){}(std::move(v)); - []([[maybe_unused]] ivec2&&){}(std::move(v)); - []([[maybe_unused]] const ivec2&&){}(std::move(v)); - } - - { - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - } - - { - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - - //[]([[maybe_unused]] ivec2*){}(std::move(v)); - //[]([[maybe_unused]] const ivec2*){}(std::move(v)); - //[]([[maybe_unused]] ivec2* const){}(std::move(v)); - //[]([[maybe_unused]] const ivec2* const){}(std::move(v)); - - //[]([[maybe_unused]] ivec2 *&){}(std::move(v)); - //[]([[maybe_unused]] const ivec2 *&){}(std::move(v)); - //[]([[maybe_unused]] ivec2 *const &){}(std::move(v)); - //[]([[maybe_unused]] const ivec2 *const &){}(std::move(v)); - - //[]([[maybe_unused]] ivec2 *&&){}(std::move(v)); - //[]([[maybe_unused]] const ivec2 *&&){}(std::move(v)); - //[]([[maybe_unused]] ivec2 *const &&){}(std::move(v)); - //[]([[maybe_unused]] const ivec2 *const &&){}(std::move(v)); - } - } - - SUBCASE("crref") { - const ivec2 v{1,2}; - arg a{std::move(v)}; - - { - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - - []([[maybe_unused]] ivec2){}(std::move(v)); - []([[maybe_unused]] const ivec2){}(std::move(v)); - //[]([[maybe_unused]] ivec2&){}(std::move(v)); - []([[maybe_unused]] const ivec2&){}(std::move(v)); - //[]([[maybe_unused]] ivec2&&){}(std::move(v)); - []([[maybe_unused]] const ivec2&&){}(std::move(v)); - } - - { - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - } - - { - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - - //[]([[maybe_unused]] ivec2*){}(std::move(v)); - //[]([[maybe_unused]] const ivec2*){}(std::move(v)); - //[]([[maybe_unused]] ivec2* const){}(std::move(v)); - //[]([[maybe_unused]] const ivec2* const){}(std::move(v)); - - //[]([[maybe_unused]] ivec2 *&){}(std::move(v)); - //[]([[maybe_unused]] const ivec2 *&){}(std::move(v)); - //[]([[maybe_unused]] ivec2 *const &){}(std::move(v)); - //[]([[maybe_unused]] const ivec2 *const &){}(std::move(v)); - - //[]([[maybe_unused]] ivec2 *&&){}(std::move(v)); - //[]([[maybe_unused]] const ivec2 *&&){}(std::move(v)); - //[]([[maybe_unused]] ivec2 *const &&){}(std::move(v)); - //[]([[maybe_unused]] const ivec2 *const &&){}(std::move(v)); - } - } -} - -TEST_CASE("features/utilities/arg/cast") { - SUBCASE("ptr") { - ivec2 v{1,2}; - ivec2* vp = &v; - arg a{vp}; - - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - - { - CHECK(a.cast() == vp); - CHECK(a.cast() == vp); - CHECK(a.cast() == vp); - CHECK(a.cast() == vp); - - CHECK(a.cast() == vp); - CHECK_THROWS(a.cast()); - CHECK(a.cast() == vp); - CHECK(a.cast() == vp); - - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - } - } - - SUBCASE("rptr") { - ivec2 v{1,2}; - ivec2* vp = &v; - - CHECK_THROWS(arg{std::move(vp)}.cast()); - CHECK_THROWS(arg{std::move(vp)}.cast()); - CHECK_THROWS(arg{std::move(vp)}.cast()); - CHECK_THROWS(arg{std::move(vp)}.cast()); - CHECK_THROWS(arg{std::move(vp)}.cast()); - CHECK_THROWS(arg{std::move(vp)}.cast()); - - { - CHECK(arg{std::move(vp)}.cast() == vp); - CHECK(arg{std::move(vp)}.cast() == vp); - CHECK(arg{std::move(vp)}.cast() == vp); - CHECK(arg{std::move(vp)}.cast() == vp); - - CHECK_THROWS(arg{std::move(vp)}.cast()); - CHECK_THROWS(arg{std::move(vp)}.cast()); - CHECK(arg{std::move(vp)}.cast() == vp); - CHECK(arg{std::move(vp)}.cast() == vp); - - CHECK(arg{std::move(vp)}.cast() == vp); - CHECK_THROWS(arg{std::move(vp)}.cast()); - CHECK(arg{std::move(vp)}.cast() == vp); - CHECK(arg{std::move(vp)}.cast() == vp); - } - } - - SUBCASE("ptr_c") { - ivec2 v{1,2}; - ivec2* const vp = &v; - arg a{vp}; - - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - - { - CHECK(a.cast() == vp); - CHECK(a.cast() == vp); - CHECK(a.cast() == vp); - CHECK(a.cast() == vp); - - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK(a.cast() == vp); - CHECK(a.cast() == vp); - - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - } - } - - SUBCASE("rptr_c") { - ivec2 v{1,2}; - ivec2* const vp = &v; - - CHECK_THROWS(arg{std::move(vp)}.cast()); - CHECK_THROWS(arg{std::move(vp)}.cast()); - CHECK_THROWS(arg{std::move(vp)}.cast()); - CHECK_THROWS(arg{std::move(vp)}.cast()); - CHECK_THROWS(arg{std::move(vp)}.cast()); - CHECK_THROWS(arg{std::move(vp)}.cast()); - - { - CHECK(arg{std::move(vp)}.cast() == vp); - CHECK(arg{std::move(vp)}.cast() == vp); - CHECK(arg{std::move(vp)}.cast() == vp); - CHECK(arg{std::move(vp)}.cast() == vp); - - CHECK_THROWS(arg{std::move(vp)}.cast()); - CHECK_THROWS(arg{std::move(vp)}.cast()); - CHECK(arg{std::move(vp)}.cast() == vp); - CHECK(arg{std::move(vp)}.cast() == vp); - - CHECK_THROWS(arg{std::move(vp)}.cast()); - CHECK_THROWS(arg{std::move(vp)}.cast()); - CHECK(arg{std::move(vp)}.cast() == vp); - CHECK(arg{std::move(vp)}.cast() == vp); - } - } - - SUBCASE("cptr") { - const ivec2 v{1,2}; - const ivec2* vp = &v; - arg a{vp}; - - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - - { - CHECK_THROWS(a.cast()); - CHECK(a.cast() == vp); - CHECK_THROWS(a.cast()); - CHECK(a.cast() == vp); - - CHECK_THROWS(a.cast()); - CHECK(a.cast() == vp); - CHECK_THROWS(a.cast()); - CHECK(a.cast() == vp); - - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - } - } - - SUBCASE("crptr") { - const ivec2 v{1,2}; - const ivec2* vp = &v; - - CHECK_THROWS(arg{std::move(vp)}.cast()); - CHECK_THROWS(arg{std::move(vp)}.cast()); - CHECK_THROWS(arg{std::move(vp)}.cast()); - CHECK_THROWS(arg{std::move(vp)}.cast()); - CHECK_THROWS(arg{std::move(vp)}.cast()); - CHECK_THROWS(arg{std::move(vp)}.cast()); - - { - CHECK_THROWS(arg{std::move(vp)}.cast()); - CHECK(arg{std::move(vp)}.cast() == vp); - CHECK_THROWS(arg{std::move(vp)}.cast()); - CHECK(arg{std::move(vp)}.cast() == vp); - - CHECK_THROWS(arg{std::move(vp)}.cast()); - CHECK_THROWS(arg{std::move(vp)}.cast()); - CHECK_THROWS(arg{std::move(vp)}.cast()); - CHECK(arg{std::move(vp)}.cast() == vp); - - CHECK_THROWS(arg{std::move(vp)}.cast()); - CHECK(arg{std::move(vp)}.cast() == vp); - CHECK_THROWS(arg{std::move(vp)}.cast()); - CHECK(arg{std::move(vp)}.cast() == vp); - } - } - - SUBCASE("cptr_c") { - const ivec2 v{1,2}; - const ivec2* const vp = &v; - arg a{vp}; - - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - - { - CHECK_THROWS(a.cast()); - CHECK(a.cast() == vp); - CHECK_THROWS(a.cast()); - CHECK(a.cast() == vp); - - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK(a.cast() == vp); - - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - } - } - - SUBCASE("crptr_c") { - const ivec2 v{1,2}; - const ivec2* const vp = &v; - - CHECK_THROWS(arg{std::move(vp)}.cast()); - CHECK_THROWS(arg{std::move(vp)}.cast()); - CHECK_THROWS(arg{std::move(vp)}.cast()); - CHECK_THROWS(arg{std::move(vp)}.cast()); - CHECK_THROWS(arg{std::move(vp)}.cast()); - CHECK_THROWS(arg{std::move(vp)}.cast()); - - { - CHECK_THROWS(arg{std::move(vp)}.cast()); - CHECK(arg{std::move(vp)}.cast() == vp); - CHECK_THROWS(arg{std::move(vp)}.cast()); - CHECK(arg{std::move(vp)}.cast() == vp); - - CHECK_THROWS(arg{std::move(vp)}.cast()); - CHECK_THROWS(arg{std::move(vp)}.cast()); - CHECK_THROWS(arg{std::move(vp)}.cast()); - CHECK(arg{std::move(vp)}.cast() == vp); - - CHECK_THROWS(arg{std::move(vp)}.cast()); - CHECK_THROWS(arg{std::move(vp)}.cast()); - CHECK_THROWS(arg{std::move(vp)}.cast()); - CHECK(arg{std::move(vp)}.cast() == vp); - } - } - - SUBCASE("ref") { - ivec2 v{1,2}; - ivec2& vr = v; - arg a{vr}; - - CHECK(a.cast() == ivec2{1,2}); - CHECK(a.cast() == ivec2{1,2}); - CHECK(&a.cast() == &v); - CHECK(&a.cast() == &vr); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - } - - SUBCASE("cref") { - const ivec2 v{1,2}; - const ivec2& vr = v; - arg a{vr}; - - CHECK(a.cast() == v); - CHECK(a.cast() == v); - CHECK_THROWS(a.cast()); - CHECK(&a.cast() == &vr); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - } - - SUBCASE("rref") { - CHECK(arg{ivec2{1,2}}.cast() == ivec2{1,2}); - CHECK(arg{ivec2{1,2}}.cast() == ivec2{1,2}); - CHECK_THROWS(arg{ivec2{1,2}}.cast()); - CHECK(arg{ivec2{1,2}}.cast() == ivec2{1,2}); - CHECK(arg{ivec2{1,2}}.cast() == ivec2{1,2}); - CHECK(arg{ivec2{1,2}}.cast() == ivec2{1,2}); - - CHECK_THROWS(arg{ivec2{1,2}}.cast()); - CHECK_THROWS(arg{ivec2{1,2}}.cast()); - CHECK_THROWS(arg{ivec2{1,2}}.cast()); - CHECK_THROWS(arg{ivec2{1,2}}.cast()); - } - - SUBCASE("crref") { - const ivec2 v{1,2}; - arg a{std::move(v)}; - - CHECK(a.cast() == ivec2{1,2}); - CHECK(a.cast() == ivec2{1,2}); - CHECK_THROWS(a.cast()); - CHECK(&a.cast() == &v); - CHECK_THROWS(a.cast()); - CHECK(a.cast() == v); - - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - } -} diff --git a/untests/features/utilities/inst_tests.cpp b/untests/features/utilities/inst_tests.cpp deleted file mode 100644 index a260ac5..0000000 --- a/untests/features/utilities/inst_tests.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/******************************************************************************* - * 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 "_utilities_fwd.hpp" - -namespace -{ - using namespace meta_hpp; - using namespace std::string_literals; -} - -namespace -{ - struct ivec2 { - int x{}; - int y{}; - - [[maybe_unused]] ivec2() = default; - [[maybe_unused]] explicit ivec2(int v): x{v}, y{v} {} - [[maybe_unused]] ivec2(int x, int y): x{x}, y{y} {} - - [[maybe_unused]] ivec2(ivec2&& other) noexcept { - x = other.x; - y = other.y; - other.x = 0; - other.y = 0; - } - - [[maybe_unused]] ivec2(const ivec2& other) noexcept { - x = other.x; - y = other.y; - } - - ivec2& operator=(ivec2&&) = delete; - ivec2& operator=(const ivec2&) = delete; - }; -} - -TEST_CASE("features/utilities/inst/type") { - SUBCASE("ref") { - ivec2 v{1,2}; - ivec2& vr = v; - inst a{vr}; - - CHECK(a.raw_type() == type_db::get()); - CHECK(a.ref_type() == inst::ref_types::ref); - } - - SUBCASE("cref") { - const ivec2 v{1,2}; - const ivec2& vr = v; - inst a{vr}; - - CHECK(a.raw_type() == type_db::get()); - CHECK(a.ref_type() == inst::ref_types::cref); - } - - SUBCASE("rref") { - ivec2 v{1,2}; - inst a{std::move(v)}; - - CHECK(a.raw_type() == type_db::get()); - CHECK(a.ref_type() == inst::ref_types::rref); - } - - SUBCASE("crref") { - const ivec2 v{1,2}; - inst a{std::move(v)}; - - CHECK(a.raw_type() == type_db::get()); - CHECK(a.ref_type() == inst::ref_types::crref); - } -} diff --git a/untests/features/utilities/value_tests.cpp b/untests/features/utilities/value_tests.cpp deleted file mode 100644 index 96b37b4..0000000 --- a/untests/features/utilities/value_tests.cpp +++ /dev/null @@ -1,299 +0,0 @@ -/******************************************************************************* - * 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 "_utilities_fwd.hpp" - -namespace -{ - using namespace meta_hpp; - using namespace std::string_literals; -} - -namespace -{ - struct ivec2 { - int x{}; - int y{}; - - [[maybe_unused]] ivec2() = default; - [[maybe_unused]] explicit ivec2(int v): x{v}, y{v} {} - [[maybe_unused]] ivec2(int x, int y): x{x}, y{y} {} - - ivec2(ivec2&& other) noexcept - : x{other.x} - , y{other.y} { - other.x = 0; - other.y = 0; - ++move_ctor_counter; - } - - ivec2(const ivec2& other) noexcept - : x{other.x} - , y{other.y} { - ++copy_ctor_counter; - } - - ivec2& operator=(ivec2&& other) = delete; - ivec2& operator=(const ivec2& other) = delete; - public: - static int move_ctor_counter; - static int copy_ctor_counter; - }; - - int ivec2::move_ctor_counter{0}; - int ivec2::copy_ctor_counter{0}; - - bool operator==(const ivec2& l, const ivec2& r) noexcept { - return l.x == r.x && l.y == r.y; - } -} - -TEST_CASE("features/utilities/value") { - ivec2::move_ctor_counter = 0; - ivec2::copy_ctor_counter = 0; - - SUBCASE("cast types") { - static_assert(std::is_same_v< - decltype(std::declval().cast()), - ivec2&>); - static_assert(std::is_same_v< - decltype(std::declval().cast()), - ivec2&&>); - static_assert(std::is_same_v< - decltype(std::declval().cast()), - const ivec2&>); - static_assert(std::is_same_v< - decltype(std::declval().cast()), - const ivec2&&>); - } - - SUBCASE("try_cast types") { - static_assert(std::is_same_v< - decltype(std::declval().try_cast()), - ivec2*>); - static_assert(std::is_same_v< - decltype(std::declval().try_cast()), - const ivec2*>); - } - - SUBCASE("ivec2&") { - ivec2 v{1,2}; - ivec2& vr = v; - - value val{vr}; - CHECK(ivec2::move_ctor_counter == 0); - CHECK(ivec2::copy_ctor_counter == 1); - - CHECK(val.type() == type_db::get()); - - CHECK(!std::memcmp(val.data(), &vr, sizeof(ivec2))); - CHECK(!std::memcmp(val.cdata(), &vr, sizeof(ivec2))); - CHECK(!std::memcmp(std::as_const(val).data(), &vr, sizeof(ivec2))); - CHECK(!std::memcmp(std::as_const(val).cdata(), &vr, sizeof(ivec2))); - - CHECK(val == ivec2{1,2}); - CHECK(val == value{ivec2{1,2}}); - - CHECK(val.cast() == ivec2{1,2}); - CHECK(std::as_const(val).cast() == ivec2{1,2}); - - CHECK(*val.try_cast() == ivec2{1,2}); - CHECK(*std::as_const(val).try_cast() == ivec2{1,2}); - } - - SUBCASE("const ivec2&") { - const ivec2 v{1,2}; - const ivec2& vr = v; - - value val{vr}; - CHECK(ivec2::move_ctor_counter == 0); - CHECK(ivec2::copy_ctor_counter == 1); - - CHECK(val.type() == type_db::get()); - - CHECK(!std::memcmp(val.data(), &vr, sizeof(ivec2))); - CHECK(!std::memcmp(val.cdata(), &vr, sizeof(ivec2))); - CHECK(!std::memcmp(std::as_const(val).data(), &vr, sizeof(ivec2))); - CHECK(!std::memcmp(std::as_const(val).cdata(), &vr, sizeof(ivec2))); - - CHECK(val == ivec2{1,2}); - CHECK(val == value{ivec2{1,2}}); - - CHECK(val.cast() == ivec2{1,2}); - CHECK(std::as_const(val).cast() == ivec2{1,2}); - - CHECK(*val.try_cast() == ivec2{1,2}); - CHECK(*std::as_const(val).try_cast() == ivec2{1,2}); - } - - SUBCASE("ivec2&&") { - ivec2 v{1,2}; - - value val{std::move(v)}; - CHECK(ivec2::move_ctor_counter == 1); - CHECK(ivec2::copy_ctor_counter == 0); - - CHECK(val.type() == type_db::get()); - - CHECK(val == ivec2{1,2}); - CHECK(val == value{ivec2{1,2}}); - - CHECK(val.cast() == ivec2{1,2}); - CHECK(std::as_const(val).cast() == ivec2{1,2}); - - CHECK(*val.try_cast() == ivec2{1,2}); - CHECK(*std::as_const(val).try_cast() == ivec2{1,2}); - } - - SUBCASE("const ivec2&&") { - const ivec2 v{1,2}; - - value val{std::move(v)}; - CHECK(ivec2::move_ctor_counter == 0); - CHECK(ivec2::copy_ctor_counter == 1); - - CHECK(val.type() == type_db::get()); - - CHECK(val == ivec2{1,2}); - CHECK(val == value{ivec2{1,2}}); - - CHECK(val.cast() == ivec2{1,2}); - CHECK(std::as_const(val).cast() == ivec2{1,2}); - - CHECK(*val.try_cast() == ivec2{1,2}); - CHECK(*std::as_const(val).try_cast() == ivec2{1,2}); - } - - SUBCASE("value(value&&)") { - ivec2 v{1,2}; - value val_src{std::move(v)}; - CHECK(ivec2::move_ctor_counter == 1); - CHECK(ivec2::copy_ctor_counter == 0); - - value val_dst{std::move(val_src)}; - CHECK(val_dst == ivec2{1,2}); - CHECK(ivec2::move_ctor_counter == 2); - CHECK(ivec2::copy_ctor_counter == 0); - - CHECK(val_src == ivec2{0,0}); - CHECK(val_src.data() != val_dst.data()); - } - - SUBCASE("value(const value&)") { - const ivec2 v{1,2}; - value val_src{v}; - CHECK(ivec2::move_ctor_counter == 0); - CHECK(ivec2::copy_ctor_counter == 1); - - value val_dst{val_src}; - CHECK(val_dst == ivec2{1,2}); - CHECK(ivec2::move_ctor_counter == 0); - CHECK(ivec2::copy_ctor_counter == 2); - - CHECK(val_src == ivec2{1,2}); - CHECK(val_src.data() != val_dst.data()); - } - - SUBCASE("value& operator=(value&&)") { - value val_src1{"world"s}; - value val_src2{ivec2{1,2}}; - CHECK(ivec2::move_ctor_counter == 1); - CHECK(ivec2::copy_ctor_counter == 0); - - value val_dst{"hello"s}; - - val_dst = std::move(val_src1); - CHECK(val_dst == "world"s); - CHECK(ivec2::move_ctor_counter == 1); - CHECK(ivec2::copy_ctor_counter == 0); - - val_dst = std::move(val_src2); - CHECK(val_dst == ivec2{1,2}); - CHECK(ivec2::move_ctor_counter == 2); - CHECK(ivec2::copy_ctor_counter == 0); - - CHECK(val_src2 == ivec2{0,0}); - CHECK(val_src2.data() != val_dst.data()); - } - - SUBCASE("value& operator=(const value&)") { - value val_src1{"world"s}; - value val_src2{ivec2{1,2}}; - CHECK(ivec2::move_ctor_counter == 1); - CHECK(ivec2::copy_ctor_counter == 0); - - value val_dst{"hello"s}; - - val_dst = val_src1; - CHECK(val_dst == "world"s); - CHECK(ivec2::move_ctor_counter == 1); - CHECK(ivec2::copy_ctor_counter == 0); - - val_dst = val_src2; - CHECK(val_dst == ivec2{1,2}); - CHECK(ivec2::move_ctor_counter == 1); - CHECK(ivec2::copy_ctor_counter == 1); - - CHECK(val_src2 == ivec2{1,2}); - CHECK(val_src2.data() != val_dst.data()); - } - - SUBCASE("swap") { - value val1{"world"s}; - value val2{ivec2{1,2}}; - CHECK(ivec2::move_ctor_counter == 1); - CHECK(ivec2::copy_ctor_counter == 0); - - val1.swap(val2); - CHECK(val1 == ivec2{1,2}); - CHECK(val2 == "world"s); - CHECK((ivec2::move_ctor_counter == 2 || ivec2::move_ctor_counter == 3)); - CHECK(ivec2::copy_ctor_counter == 0); - - swap(val1, val2); - CHECK(val1 == "world"s); - CHECK(val2 == ivec2{1,2}); - } - - SUBCASE("ostream") { - std::stringstream str_stream; - CHECK_NOTHROW(str_stream << value{21} << " " << value{42}); - CHECK_THROWS((str_stream << value{ivec2{1,2}})); - REQUIRE(str_stream.str() == "21 42"); - } - - SUBCASE("istream") { - std::stringstream str_stream{"21 42"}; - - value v{ivec2{1,2}}; - CHECK_THROWS(str_stream >> v); - - v = value{0}; - CHECK_NOTHROW(str_stream >> v); - CHECK(v == 21); - CHECK_NOTHROW(str_stream >> v); - CHECK(v == 42); - } - - SUBCASE("operator==") { - CHECK(value{ivec2{1,2}} == ivec2{1,2}); - CHECK_FALSE(value{ivec2{1,2}} == ivec2{1,3}); - - CHECK(ivec2{1,2} == value{ivec2{1,2}}); - CHECK_FALSE(ivec2{1,3} == value{ivec2{1,2}}); - - CHECK(value{ivec2{1,2}} == value{ivec2{1,2}}); - CHECK_FALSE(value{ivec2{1,2}} == value{ivec2{1,3}}); - - { - class empty_class1 {}; - class empty_class2 {}; - - CHECK_FALSE(operator==(value{empty_class1{}}, value{empty_class2{}})); - CHECK_THROWS(operator==(value{empty_class1{}}, value{empty_class1{}})); - } - } -} From 77a0efaaf33360a6526531d753472324883dc796 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Tue, 12 Oct 2021 15:49:22 +0700 Subject: [PATCH 110/233] to C++20 --- CMakeLists.txt | 6 +++--- README.md | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b35fbd9..8a5a2f9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ -# 3.8 version is required for `cxx_std_17` -cmake_minimum_required(VERSION 3.8 FATAL_ERROR) +# 3.12 version is required for `cxx_std_20` +cmake_minimum_required(VERSION 3.12 FATAL_ERROR) if(NOT DEFINED PROJECT_NAME) set(BUILD_AS_STANDALONE ON) @@ -14,7 +14,7 @@ add_subdirectory(vendors/kari.hpp) add_library(${PROJECT_NAME} INTERFACE) target_link_libraries(${PROJECT_NAME} INTERFACE enum.hpp kari.hpp) -target_compile_features(${PROJECT_NAME} INTERFACE cxx_std_17) +target_compile_features(${PROJECT_NAME} INTERFACE cxx_std_20) target_include_directories(${PROJECT_NAME} INTERFACE headers) target_compile_options(${PROJECT_NAME} diff --git a/README.md b/README.md index 28a7de1..fd3fd8a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # meta.hpp -> C++17 tiny reflection library +> C++20 tiny reflection library [![linux][badge.linux]][linux] [![darwin][badge.darwin]][darwin] @@ -13,14 +13,14 @@ [badge.linux]: https://img.shields.io/github/workflow/status/BlackMATov/meta.hpp/linux/main?label=GCC%2FClang&logo=linux [badge.windows]: https://img.shields.io/github/workflow/status/BlackMATov/meta.hpp/windows/main?label=Visual%20Studio&logo=visual-studio [badge.codecov]: https://img.shields.io/codecov/c/github/BlackMATov/meta.hpp/main?logo=codecov -[badge.language]: https://img.shields.io/badge/language-C%2B%2B17-yellow +[badge.language]: https://img.shields.io/badge/language-C%2B%2B20-orange [badge.license]: https://img.shields.io/badge/license-MIT-blue [darwin]: https://github.com/BlackMATov/meta.hpp/actions?query=workflow%3Adarwin [linux]: https://github.com/BlackMATov/meta.hpp/actions?query=workflow%3Alinux [windows]: https://github.com/BlackMATov/meta.hpp/actions?query=workflow%3Awindows [codecov]: https://codecov.io/gh/BlackMATov/meta.hpp -[language]: https://en.wikipedia.org/wiki/C%2B%2B17 +[language]: https://en.wikipedia.org/wiki/C%2B%2B20 [license]: https://en.wikipedia.org/wiki/MIT_License [meta]: https://github.com/BlackMATov/meta.hpp From 0cf2a0b07b1718a2682013289daabe8a2a4570d1 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Mon, 22 Nov 2021 13:49:36 +0700 Subject: [PATCH 111/233] remove kari.hpp submodule --- .gitmodules | 3 --- CMakeLists.txt | 12 ++++++++++-- vendors/kari.hpp | 1 - 3 files changed, 10 insertions(+), 6 deletions(-) delete mode 160000 vendors/kari.hpp diff --git a/.gitmodules b/.gitmodules index a512f37..0e49f1a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,9 +1,6 @@ [submodule "vendors/enum.hpp"] path = vendors/enum.hpp url = https://github.com/BlackMATov/enum.hpp -[submodule "vendors/kari.hpp"] - path = vendors/kari.hpp - url = https://github.com/BlackMATov/kari.hpp [submodule "vendors/doctest"] path = vendors/doctest url = https://github.com/onqtam/doctest diff --git a/CMakeLists.txt b/CMakeLists.txt index 8a5a2f9..59dfac6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,10 +10,9 @@ endif() project(meta.hpp) add_subdirectory(vendors/enum.hpp) -add_subdirectory(vendors/kari.hpp) add_library(${PROJECT_NAME} INTERFACE) -target_link_libraries(${PROJECT_NAME} INTERFACE enum.hpp kari.hpp) +target_link_libraries(${PROJECT_NAME} INTERFACE enum.hpp) target_compile_features(${PROJECT_NAME} INTERFACE cxx_std_20) target_include_directories(${PROJECT_NAME} INTERFACE headers) @@ -26,6 +25,15 @@ target_compile_options(${PROJECT_NAME} > INTERFACE $<$,$>: + -Wno-c++98-compat + -Wno-c++98-compat-pedantic + -Wno-ctad-maybe-unsupported + -Wno-exit-time-destructors + -Wno-float-equal + -Wno-padded + -Wno-shadow-field-in-constructor + -Wno-unknown-warning-option + -Wno-weak-vtables >) if(BUILD_AS_STANDALONE) diff --git a/vendors/kari.hpp b/vendors/kari.hpp deleted file mode 160000 index 3b9dea6..0000000 --- a/vendors/kari.hpp +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 3b9dea6dc7006f36b842e05d3d1766641e428a82 From e729c67b8da438a3fa44668a86eb09b0618cd19a Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Mon, 22 Nov 2021 14:12:08 +0700 Subject: [PATCH 112/233] static type traits and kinds --- headers/meta.hpp/meta_all.hpp | 17 +- headers/meta.hpp/meta_base.hpp | 182 +++++++++++++++ headers/meta.hpp/meta_kinds.hpp | 154 ++++++++++++ headers/meta.hpp/meta_traits.hpp | 116 +++++++++ headers/meta.hpp/meta_traits/array_traits.hpp | 27 +++ headers/meta.hpp/meta_traits/class_traits.hpp | 60 +++++ headers/meta.hpp/meta_traits/ctor_traits.hpp | 31 +++ .../meta.hpp/meta_traits/enum_traits.hpp | 16 +- .../meta.hpp/meta_traits/function_traits.hpp | 39 ++++ .../meta.hpp/meta_traits/member_traits.hpp | 26 +++ .../meta.hpp/meta_traits/method_traits.hpp | 220 ++++++++++++++++++ .../meta.hpp/meta_traits/number_traits.hpp | 27 +++ .../meta.hpp/meta_traits/pointer_traits.hpp | 24 ++ .../meta.hpp/meta_traits/reference_traits.hpp | 26 +++ .../void_traits.hpp} | 11 +- 15 files changed, 970 insertions(+), 6 deletions(-) create mode 100644 headers/meta.hpp/meta_base.hpp create mode 100644 headers/meta.hpp/meta_kinds.hpp create mode 100644 headers/meta.hpp/meta_traits.hpp create mode 100644 headers/meta.hpp/meta_traits/array_traits.hpp create mode 100644 headers/meta.hpp/meta_traits/class_traits.hpp create mode 100644 headers/meta.hpp/meta_traits/ctor_traits.hpp rename untests/meta_tests.cpp => headers/meta.hpp/meta_traits/enum_traits.hpp (54%) create mode 100644 headers/meta.hpp/meta_traits/function_traits.hpp create mode 100644 headers/meta.hpp/meta_traits/member_traits.hpp create mode 100644 headers/meta.hpp/meta_traits/method_traits.hpp create mode 100644 headers/meta.hpp/meta_traits/number_traits.hpp create mode 100644 headers/meta.hpp/meta_traits/pointer_traits.hpp create mode 100644 headers/meta.hpp/meta_traits/reference_traits.hpp rename headers/meta.hpp/{meta_fwd.hpp => meta_traits/void_traits.hpp} (61%) diff --git a/headers/meta.hpp/meta_all.hpp b/headers/meta.hpp/meta_all.hpp index f2adc16..1d7fa5c 100644 --- a/headers/meta.hpp/meta_all.hpp +++ b/headers/meta.hpp/meta_all.hpp @@ -6,4 +6,19 @@ #pragma once -#include "meta_fwd.hpp" +#include "meta_base.hpp" + +#include "meta_kinds.hpp" + +#include "meta_traits.hpp" +#include "meta_traits/array_traits.hpp" +#include "meta_traits/class_traits.hpp" +#include "meta_traits/ctor_traits.hpp" +#include "meta_traits/enum_traits.hpp" +#include "meta_traits/function_traits.hpp" +#include "meta_traits/member_traits.hpp" +#include "meta_traits/method_traits.hpp" +#include "meta_traits/number_traits.hpp" +#include "meta_traits/pointer_traits.hpp" +#include "meta_traits/reference_traits.hpp" +#include "meta_traits/void_traits.hpp" diff --git a/headers/meta.hpp/meta_base.hpp b/headers/meta.hpp/meta_base.hpp new file mode 100644 index 0000000..fbff63e --- /dev/null +++ b/headers/meta.hpp/meta_base.hpp @@ -0,0 +1,182 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace meta_hpp +{ + template < typename Enum > + using bitflags = enum_hpp::bitflags::bitflags; +} + +namespace meta_hpp +{ + template < typename... Types > + struct type_list {}; + + template < std::size_t Index, typename TypeList > + struct type_list_at; + + template < std::size_t Index, typename... Types > + struct type_list_at> { + using type = std::tuple_element_t>; + }; + + template < std::size_t Index, typename TypeList > + using type_list_at_t = typename type_list_at::type; +} + +namespace meta_hpp +{ + template < typename Signature > + constexpr auto select(Signature* func) noexcept -> Signature* { + return func; + } + + template < typename Signature, typename Class > + constexpr auto select(Signature Class::*func) -> decltype(func) { + return func; + } +} + +namespace meta_hpp +{ + class value; + + namespace detail + { + class arg_base; + class arg; + + class inst_base; + class inst; + } +} + +namespace meta_hpp +{ + class ctor; + class evalue; + class function; + class member; + class method; + class scope; + class variable; + + namespace detail + { + struct ctor_state; + struct evalue_state; + struct function_state; + struct member_state; + struct method_state; + struct scope_state; + struct variable_state; + + using ctor_state_ptr = std::shared_ptr; + using evalue_state_ptr = std::shared_ptr; + using function_state_ptr = std::shared_ptr; + using member_state_ptr = std::shared_ptr; + using method_state_ptr = std::shared_ptr; + using scope_state_ptr = std::shared_ptr; + using variable_state_ptr = std::shared_ptr; + } +} + +namespace meta_hpp +{ + class any_type; + class array_type; + class class_type; + class ctor_type; + class enum_type; + class function_type; + class member_type; + class method_type; + class number_type; + class pointer_type; + class reference_type; + class void_type; + + namespace detail + { + struct type_data_base; + struct array_type_data; + struct class_type_data; + struct ctor_type_data; + struct enum_type_data; + struct function_type_data; + struct member_type_data; + struct method_type_data; + struct number_type_data; + struct pointer_type_data; + struct reference_type_data; + struct void_type_data; + + using type_data_base_ptr = std::shared_ptr; + using array_type_data_ptr = std::shared_ptr; + using class_type_data_ptr = std::shared_ptr; + using ctor_type_data_ptr = std::shared_ptr; + using enum_type_data_ptr = std::shared_ptr; + using function_type_data_ptr = std::shared_ptr; + using member_type_data_ptr = std::shared_ptr; + using method_type_data_ptr = std::shared_ptr; + using number_type_data_ptr = std::shared_ptr; + using pointer_type_data_ptr = std::shared_ptr; + using reference_type_data_ptr = std::shared_ptr; + using void_type_data_ptr = std::shared_ptr; + } +} + +namespace meta_hpp +{ + struct ctor_index; + struct evalue_index; + struct function_index; + struct member_index; + struct method_index; + struct variable_index; + + using class_set = std::set>; + using class_map = std::map>; + + using enum_set = std::set>; + using enum_map = std::map>; + + using ctor_map = std::map>; + using evalue_map = std::map>; + using function_map = std::map>; + using member_map = std::map>; + using method_map = std::map>; + using variable_map = std::map>; +} diff --git a/headers/meta.hpp/meta_kinds.hpp b/headers/meta.hpp/meta_kinds.hpp new file mode 100644 index 0000000..3aa55fb --- /dev/null +++ b/headers/meta.hpp/meta_kinds.hpp @@ -0,0 +1,154 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "meta_base.hpp" + +namespace meta_hpp +{ + template < typename T > + concept array_kind = std::is_array_v; + + template < typename T > + concept class_kind = std::is_class_v; + + template < typename T > + concept enum_kind = std::is_enum_v; + + template < typename T > + concept function_kind = std::is_pointer_v && std::is_function_v>; + + template < typename T > + concept member_kind = std::is_member_object_pointer_v; + + template < typename T > + concept method_kind = std::is_member_function_pointer_v; + + template < typename T > + concept number_kind = std::is_arithmetic_v; + + template < typename T > + concept pointer_kind = std::is_pointer_v && !std::is_function_v>; + + template < typename T > + concept reference_kind = std::is_reference_v; + + template < typename T > + concept void_kind = std::is_void_v; +} + +namespace meta_hpp +{ + enum class type_kind : std::uint32_t { + array_, + class_, + ctor_, + enum_, + function_, + member_, + method_, + number_, + pointer_, + reference_, + void_, + }; + + template < typename T > + constexpr type_kind make_type_kind() noexcept { + if constexpr ( array_kind ) { return type_kind::array_; } + if constexpr ( class_kind ) { return type_kind::class_; } + if constexpr ( enum_kind ) { return type_kind::enum_; } + if constexpr ( function_kind ) { return type_kind::function_; } + if constexpr ( member_kind ) { return type_kind::member_; } + if constexpr ( method_kind ) { return type_kind::method_; } + if constexpr ( number_kind ) { return type_kind::number_; } + if constexpr ( pointer_kind ) { return type_kind::pointer_; } + if constexpr ( reference_kind ) { return type_kind::reference_; } + if constexpr ( void_kind ) { return type_kind::void_; } + } +} + +namespace meta_hpp::detail +{ + template < type_kind Kind > + struct type_kind_traits; + + template <> + struct type_kind_traits { + using kind_type = array_type; + using kind_type_data = array_type_data; + }; + + template <> + struct type_kind_traits { + using kind_type = class_type; + using kind_type_data = class_type_data; + }; + + template <> + struct type_kind_traits { + using kind_type = ctor_type; + using kind_type_data = ctor_type_data; + }; + + template <> + struct type_kind_traits { + using kind_type = enum_type; + using kind_type_data = enum_type_data; + }; + + template <> + struct type_kind_traits { + using kind_type = function_type; + using kind_type_data = function_type_data; + }; + + template <> + struct type_kind_traits { + using kind_type = member_type; + using kind_type_data = member_type_data; + }; + + template <> + struct type_kind_traits { + using kind_type = method_type; + using kind_type_data = method_type_data; + }; + + template <> + struct type_kind_traits { + using kind_type = number_type; + using kind_type_data = number_type_data; + }; + + template <> + struct type_kind_traits { + using kind_type = pointer_type; + using kind_type_data = pointer_type_data; + }; + + template <> + struct type_kind_traits { + using kind_type = reference_type; + using kind_type_data = reference_type_data; + }; + + template <> + struct type_kind_traits { + using kind_type = void_type; + using kind_type_data = void_type_data; + }; + + template < typename T > + using kind_type = typename type_kind_traits()>::kind_type; + + template < typename T > + using kind_type_data = typename type_kind_traits()>::kind_type_data; + + template < typename T > + using kind_type_data_ptr = std::shared_ptr>; +} diff --git a/headers/meta.hpp/meta_traits.hpp b/headers/meta.hpp/meta_traits.hpp new file mode 100644 index 0000000..37af24b --- /dev/null +++ b/headers/meta.hpp/meta_traits.hpp @@ -0,0 +1,116 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "meta_base.hpp" +#include "meta_kinds.hpp" + +namespace meta_hpp::detail +{ + template < array_kind Array > + struct array_traits; + + template < class_kind T > + struct class_traits; + + template < class_kind Class, typename... Args > + struct ctor_traits; + + template < enum_kind Enum > + struct enum_traits; + + template < function_kind Function > + struct function_traits; + + template < member_kind Member > + struct member_traits; + + template < method_kind Method > + struct method_traits; + + template < number_kind Number > + struct number_traits; + + template < pointer_kind Pointer > + struct pointer_traits; + + template < reference_kind Reference > + struct reference_traits; + + template < void_kind Void > + struct void_traits; +} + +namespace meta_hpp +{ + enum class array_flags : std::uint32_t { + is_bounded = 1 << 0, + is_unbounded = 1 << 1, + }; + + enum class class_flags : std::uint32_t { + is_empty = 1 << 1, + is_final = 1 << 2, + is_abstract = 1 << 3, + is_polymorphic = 1 << 4, + is_template_instantiation = 1 << 5, + }; + + enum class ctor_flags : std::uint32_t { + is_noexcept = 1 << 0, + }; + + enum class enum_flags : std::uint32_t { + }; + + enum class function_flags : std::uint32_t { + is_noexcept = 1 << 0, + }; + + enum class member_flags : std::uint32_t { + }; + + enum class method_flags : std::uint32_t { + is_const = 1 << 0, + is_noexcept = 1 << 1, + is_volatile = 1 << 2, + is_lvalue_qualified = 1 << 3, + is_rvalue_qualified = 1 << 4, + }; + + enum class number_flags : std::uint32_t { + is_signed = 1 << 1, + is_unsigned = 1 << 2, + is_integral = 1 << 3, + is_floating_point = 1 << 4, + }; + + enum class pointer_flags : std::uint32_t { + is_readonly = 1 << 0, + }; + + enum class reference_flags : std::uint32_t { + is_readonly = 1 << 0, + is_lvalue = 1 << 1, + is_rvalue = 1 << 2, + }; + + enum class void_flags : std::uint32_t { + }; + + ENUM_HPP_OPERATORS_DECL(array_flags) + ENUM_HPP_OPERATORS_DECL(class_flags) + ENUM_HPP_OPERATORS_DECL(ctor_flags) + ENUM_HPP_OPERATORS_DECL(enum_flags) + ENUM_HPP_OPERATORS_DECL(function_flags) + ENUM_HPP_OPERATORS_DECL(member_flags) + ENUM_HPP_OPERATORS_DECL(method_flags) + ENUM_HPP_OPERATORS_DECL(number_flags) + ENUM_HPP_OPERATORS_DECL(pointer_flags) + ENUM_HPP_OPERATORS_DECL(reference_flags) + ENUM_HPP_OPERATORS_DECL(void_flags) +} diff --git a/headers/meta.hpp/meta_traits/array_traits.hpp b/headers/meta.hpp/meta_traits/array_traits.hpp new file mode 100644 index 0000000..e979661 --- /dev/null +++ b/headers/meta.hpp/meta_traits/array_traits.hpp @@ -0,0 +1,27 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_traits.hpp" + +namespace meta_hpp::detail +{ + template < array_kind Array > + struct array_traits { + static constexpr std::size_t extent{std::extent_v}; + + using data_type = std::remove_extent_t; + + static bitflags make_flags() noexcept { + bitflags flags; + if ( std::is_bounded_array_v ) flags.set(array_flags::is_bounded); + if ( std::is_unbounded_array_v ) flags.set(array_flags::is_unbounded); + return flags; + } + }; +} diff --git a/headers/meta.hpp/meta_traits/class_traits.hpp b/headers/meta.hpp/meta_traits/class_traits.hpp new file mode 100644 index 0000000..9b06334 --- /dev/null +++ b/headers/meta.hpp/meta_traits/class_traits.hpp @@ -0,0 +1,60 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_traits.hpp" + +namespace meta_hpp::detail +{ + namespace impl + { + template < class_kind T > + struct class_traits_base { + static constexpr std::size_t arity{0}; + + using argument_types = type_list<>; + + static bitflags make_flags() noexcept { + return {}; + } + + static std::vector make_argument_types() { + return {}; + } + }; + + template < template < typename... > typename T, typename... Args > + struct class_traits_base> { + static constexpr std::size_t arity{sizeof...(Args)}; + + using argument_types = type_list; + + static bitflags make_flags() noexcept { + return class_flags::is_template_instantiation; + } + + static std::vector make_argument_types() { + return { resolve_type()... }; + } + }; + } + + template < class_kind T > + struct class_traits : impl::class_traits_base { + static constexpr std::size_t size{sizeof(T)}; + + static bitflags make_flags() noexcept { + bitflags flags; + if constexpr ( std::is_empty_v ) flags.set(class_flags::is_empty); + if constexpr ( std::is_final_v ) flags.set(class_flags::is_final); + if constexpr ( std::is_abstract_v ) flags.set(class_flags::is_abstract); + if constexpr ( std::is_polymorphic_v ) flags.set(class_flags::is_polymorphic); + return flags | impl::class_traits_base::make_flags(); + } + }; +} diff --git a/headers/meta.hpp/meta_traits/ctor_traits.hpp b/headers/meta.hpp/meta_traits/ctor_traits.hpp new file mode 100644 index 0000000..745f1e0 --- /dev/null +++ b/headers/meta.hpp/meta_traits/ctor_traits.hpp @@ -0,0 +1,31 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_traits.hpp" + +namespace meta_hpp::detail +{ + template < class_kind Class, typename... Args > + struct ctor_traits { + static constexpr std::size_t arity{sizeof...(Args)}; + + using class_type = Class; + using argument_types = type_list; + + static bitflags make_flags() noexcept { + bitflags flags; + if constexpr ( std::is_nothrow_constructible_v ) flags.set(ctor_flags::is_noexcept); + return flags; + } + + static std::vector make_argument_types() { + return { resolve_type()... }; + } + }; +} diff --git a/untests/meta_tests.cpp b/headers/meta.hpp/meta_traits/enum_traits.hpp similarity index 54% rename from untests/meta_tests.cpp rename to headers/meta.hpp/meta_traits/enum_traits.hpp index cbb5826..ba77ce3 100644 --- a/untests/meta_tests.cpp +++ b/headers/meta.hpp/meta_traits/enum_traits.hpp @@ -4,11 +4,19 @@ * Copyright (C) 2021, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ -#include "meta_tests.hpp" +#pragma once -namespace +#include "../meta_base.hpp" +#include "../meta_traits.hpp" + +namespace meta_hpp::detail { -} + template < enum_kind Enum > + struct enum_traits { + using underlying_type = std::underlying_type_t; -TEST_CASE("meta") { + static bitflags make_flags() noexcept { + return {}; + } + }; } diff --git a/headers/meta.hpp/meta_traits/function_traits.hpp b/headers/meta.hpp/meta_traits/function_traits.hpp new file mode 100644 index 0000000..709e6a7 --- /dev/null +++ b/headers/meta.hpp/meta_traits/function_traits.hpp @@ -0,0 +1,39 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_traits.hpp" + +namespace meta_hpp::detail +{ + template < function_kind Function > + struct function_traits; + + template < typename R, typename... Args > + struct function_traits { + static constexpr std::size_t arity{sizeof...(Args)}; + + using return_type = R; + using argument_types = type_list; + + static bitflags make_flags() noexcept { + return {}; + } + + static std::vector make_argument_types() { + return { resolve_type()... }; + } + }; + + template < typename R, typename... Args > + struct function_traits : function_traits { + static bitflags make_flags() noexcept { + return function_flags::is_noexcept; + } + }; +} diff --git a/headers/meta.hpp/meta_traits/member_traits.hpp b/headers/meta.hpp/meta_traits/member_traits.hpp new file mode 100644 index 0000000..0500082 --- /dev/null +++ b/headers/meta.hpp/meta_traits/member_traits.hpp @@ -0,0 +1,26 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_traits.hpp" + +namespace meta_hpp::detail +{ + template < member_kind Member > + struct member_traits; + + template < typename V, typename C > + struct member_traits { + using class_type = C; + using value_type = V; + + static bitflags make_flags() noexcept { + return {}; + } + }; +} diff --git a/headers/meta.hpp/meta_traits/method_traits.hpp b/headers/meta.hpp/meta_traits/method_traits.hpp new file mode 100644 index 0000000..fef9086 --- /dev/null +++ b/headers/meta.hpp/meta_traits/method_traits.hpp @@ -0,0 +1,220 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_traits.hpp" + +namespace meta_hpp::detail +{ + template < method_kind Method > + struct method_traits; + + template < typename R, typename C, typename... Args > + struct method_traits { + static constexpr std::size_t arity{sizeof...(Args)}; + + using class_type = C; + using return_type = R; + using qualified_type = C; + using argument_types = type_list; + + static bitflags make_flags() noexcept { + return {}; + } + + static std::vector make_argument_types() { + return { resolve_type()... }; + } + }; + + template < typename R, typename C, typename... Args > + struct method_traits : method_traits { + using qualified_type = const C; + static bitflags make_flags() noexcept { + return method_flags::is_const; + } + }; + + template < typename R, typename C, typename... Args > + struct method_traits : method_traits { + using qualified_type = C; + static bitflags make_flags() noexcept { + return method_flags::is_noexcept; + } + }; + + template < typename R, typename C, typename... Args > + struct method_traits : method_traits { + using qualified_type = const C; + static bitflags make_flags() noexcept { + return method_flags::is_const | method_flags::is_noexcept; + } + }; + + template < typename R, typename C, typename... Args > + struct method_traits : method_traits { + using qualified_type = C&; + static bitflags make_flags() noexcept { + return method_flags::is_lvalue_qualified; + } + }; + + template < typename R, typename C, typename... Args > + struct method_traits : method_traits { + using qualified_type = C&; + static bitflags make_flags() noexcept { + return method_flags::is_noexcept | method_flags::is_lvalue_qualified; + } + }; + + template < typename R, typename C, typename... Args > + struct method_traits : method_traits { + using qualified_type = const C&; + static bitflags make_flags() noexcept { + return method_flags::is_const | method_flags::is_lvalue_qualified; + } + }; + + template < typename R, typename C, typename... Args > + struct method_traits : method_traits { + using qualified_type = const C&; + static bitflags make_flags() noexcept { + return method_flags::is_const | method_flags::is_noexcept | method_flags::is_lvalue_qualified; + } + }; + + template < typename R, typename C, typename... Args > + struct method_traits : method_traits { + using qualified_type = C&&; + static bitflags make_flags() noexcept { + return method_flags::is_rvalue_qualified; + } + }; + + template < typename R, typename C, typename... Args > + struct method_traits : method_traits { + using qualified_type = C&&; + static bitflags make_flags() noexcept { + return method_flags::is_noexcept | method_flags::is_rvalue_qualified; + } + }; + + template < typename R, typename C, typename... Args > + struct method_traits : method_traits { + using qualified_type = const C&&; + static bitflags make_flags() noexcept { + return method_flags::is_const | method_flags::is_rvalue_qualified; + } + }; + + template < typename R, typename C, typename... Args > + struct method_traits : method_traits { + using qualified_type = const C&&; + static bitflags make_flags() noexcept { + return method_flags::is_const | method_flags::is_noexcept | method_flags::is_rvalue_qualified; + } + }; + + // + + template < typename R, typename C, typename... Args > + struct method_traits : method_traits { + using qualified_type = C; + static bitflags make_flags() noexcept { + return method_flags::is_volatile; + } + }; + + template < typename R, typename C, typename... Args > + struct method_traits : method_traits { + using qualified_type = const C; + static bitflags make_flags() noexcept { + return method_flags::is_volatile | method_flags::is_const; + } + }; + + template < typename R, typename C, typename... Args > + struct method_traits : method_traits { + using qualified_type = C; + static bitflags make_flags() noexcept { + return method_flags::is_volatile | method_flags::is_noexcept; + } + }; + + template < typename R, typename C, typename... Args > + struct method_traits : method_traits { + using qualified_type = const C; + static bitflags make_flags() noexcept { + return method_flags::is_volatile | method_flags::is_const | method_flags::is_noexcept; + } + }; + + template < typename R, typename C, typename... Args > + struct method_traits : method_traits { + using qualified_type = C&; + static bitflags make_flags() noexcept { + return method_flags::is_volatile | method_flags::is_lvalue_qualified; + } + }; + + template < typename R, typename C, typename... Args > + struct method_traits : method_traits { + using qualified_type = C&; + static bitflags make_flags() noexcept { + return method_flags::is_volatile | method_flags::is_noexcept | method_flags::is_lvalue_qualified; + } + }; + + template < typename R, typename C, typename... Args > + struct method_traits : method_traits { + using qualified_type = const C&; + static bitflags make_flags() noexcept { + return method_flags::is_volatile | method_flags::is_const | method_flags::is_lvalue_qualified; + } + }; + + template < typename R, typename C, typename... Args > + struct method_traits : method_traits { + using qualified_type = const C&; + static bitflags make_flags() noexcept { + return method_flags::is_volatile | method_flags::is_const | method_flags::is_noexcept | method_flags::is_lvalue_qualified; + } + }; + + template < typename R, typename C, typename... Args > + struct method_traits : method_traits { + using qualified_type = C&&; + static bitflags make_flags() noexcept { + return method_flags::is_volatile | method_flags::is_rvalue_qualified; + } + }; + + template < typename R, typename C, typename... Args > + struct method_traits : method_traits { + using qualified_type = C&&; + static bitflags make_flags() noexcept { + return method_flags::is_volatile | method_flags::is_noexcept | method_flags::is_rvalue_qualified; + } + }; + + template < typename R, typename C, typename... Args > + struct method_traits : method_traits { + using qualified_type = const C&&; + static bitflags make_flags() noexcept { + return method_flags::is_volatile | method_flags::is_const | method_flags::is_rvalue_qualified; + } + }; + + template < typename R, typename C, typename... Args > + struct method_traits : method_traits { + using qualified_type = const C&&; + static bitflags make_flags() noexcept { + return method_flags::is_volatile | method_flags::is_const | method_flags::is_noexcept | method_flags::is_rvalue_qualified; + } + }; +} diff --git a/headers/meta.hpp/meta_traits/number_traits.hpp b/headers/meta.hpp/meta_traits/number_traits.hpp new file mode 100644 index 0000000..eb69abc --- /dev/null +++ b/headers/meta.hpp/meta_traits/number_traits.hpp @@ -0,0 +1,27 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_traits.hpp" + +namespace meta_hpp::detail +{ + template < number_kind Number > + struct number_traits { + static constexpr std::size_t size{sizeof(Number)}; + + static bitflags make_flags() noexcept { + bitflags flags; + if ( std::is_signed_v ) flags.set(number_flags::is_signed); + if ( std::is_unsigned_v ) flags.set(number_flags::is_unsigned); + if ( std::is_integral_v ) flags.set(number_flags::is_integral); + if ( std::is_floating_point_v ) flags.set(number_flags::is_floating_point); + return flags; + } + }; +} diff --git a/headers/meta.hpp/meta_traits/pointer_traits.hpp b/headers/meta.hpp/meta_traits/pointer_traits.hpp new file mode 100644 index 0000000..5b66ea3 --- /dev/null +++ b/headers/meta.hpp/meta_traits/pointer_traits.hpp @@ -0,0 +1,24 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_traits.hpp" + +namespace meta_hpp::detail +{ + template < pointer_kind Pointer > + struct pointer_traits { + using data_type = std::remove_pointer_t; + + static bitflags make_flags() noexcept { + bitflags flags; + if constexpr ( std::is_const_v ) flags.set(pointer_flags::is_readonly); + return flags; + } + }; +} diff --git a/headers/meta.hpp/meta_traits/reference_traits.hpp b/headers/meta.hpp/meta_traits/reference_traits.hpp new file mode 100644 index 0000000..4eef018 --- /dev/null +++ b/headers/meta.hpp/meta_traits/reference_traits.hpp @@ -0,0 +1,26 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_traits.hpp" + +namespace meta_hpp::detail +{ + template < reference_kind Reference > + struct reference_traits { + using data_type = std::remove_reference_t; + + static bitflags make_flags() noexcept { + bitflags flags; + if constexpr ( std::is_const_v ) flags.set(reference_flags::is_readonly); + if constexpr ( std::is_lvalue_reference_v ) flags.set(reference_flags::is_lvalue); + if constexpr ( std::is_rvalue_reference_v ) flags.set(reference_flags::is_rvalue); + return flags; + } + }; +} diff --git a/headers/meta.hpp/meta_fwd.hpp b/headers/meta.hpp/meta_traits/void_traits.hpp similarity index 61% rename from headers/meta.hpp/meta_fwd.hpp rename to headers/meta.hpp/meta_traits/void_traits.hpp index bae8590..f3ced24 100644 --- a/headers/meta.hpp/meta_fwd.hpp +++ b/headers/meta.hpp/meta_traits/void_traits.hpp @@ -6,6 +6,15 @@ #pragma once -namespace meta_hpp +#include "../meta_base.hpp" +#include "../meta_traits.hpp" + +namespace meta_hpp::detail { + template < void_kind Void > + struct void_traits { + static bitflags make_flags() noexcept { + return {}; + } + }; } From e17c8a4206cec86931984200ed2530204c9ee32b Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Thu, 25 Nov 2021 05:34:00 +0700 Subject: [PATCH 113/233] new basic version --- headers/meta.hpp/meta_all.hpp | 33 + headers/meta.hpp/meta_base.hpp | 2 + headers/meta.hpp/meta_registry.hpp | 94 ++ headers/meta.hpp/meta_registry/class_bind.hpp | 70 + headers/meta.hpp/meta_registry/enum_bind.hpp | 29 + headers/meta.hpp/meta_registry/scope_bind.hpp | 48 + headers/meta.hpp/meta_states.hpp | 329 +++++ headers/meta.hpp/meta_states/ctor.hpp | 146 +++ headers/meta.hpp/meta_states/evalue.hpp | 56 + headers/meta.hpp/meta_states/function.hpp | 160 +++ headers/meta.hpp/meta_states/member.hpp | 124 ++ headers/meta.hpp/meta_states/method.hpp | 176 +++ headers/meta.hpp/meta_states/scope.hpp | 138 ++ headers/meta.hpp/meta_states/variable.hpp | 105 ++ headers/meta.hpp/meta_types.hpp | 722 ++++++++++ headers/meta.hpp/meta_types/any_type.hpp | 169 +++ headers/meta.hpp/meta_types/array_type.hpp | 61 + headers/meta.hpp/meta_types/class_type.hpp | 332 +++++ headers/meta.hpp/meta_types/ctor_type.hpp | 69 + headers/meta.hpp/meta_types/enum_type.hpp | 93 ++ headers/meta.hpp/meta_types/function_type.hpp | 69 + headers/meta.hpp/meta_types/member_type.hpp | 61 + headers/meta.hpp/meta_types/method_type.hpp | 74 ++ headers/meta.hpp/meta_types/number_type.hpp | 56 + headers/meta.hpp/meta_types/pointer_type.hpp | 56 + .../meta.hpp/meta_types/reference_type.hpp | 56 + headers/meta.hpp/meta_types/void_type.hpp | 51 + headers/meta.hpp/meta_utilities.hpp | 238 ++++ headers/meta.hpp/meta_utilities/arg.hpp | 205 +++ headers/meta.hpp/meta_utilities/inst.hpp | 148 +++ headers/meta.hpp/meta_utilities/value.hpp | 306 +++++ untests/examples/class_example.cpp | 38 + untests/examples/complex_example.cpp | 99 ++ untests/examples/enum_example.cpp | 36 + untests/examples/member_example.cpp | 37 + untests/examples/method_example.cpp | 48 + untests/examples/number_example.cpp | 31 + untests/meta_states/evalue_tests.cpp | 58 + untests/meta_states/function_tests.cpp | 107 ++ untests/meta_states/member_tests.cpp | 81 ++ untests/meta_states/method_tests.cpp | 829 ++++++++++++ untests/meta_states/scope_tests.cpp | 114 ++ untests/meta_states/variable_tests.cpp | 100 ++ untests/meta_types/array_type_tests.cpp | 41 + untests/meta_types/class_type_tests.cpp | 465 +++++++ untests/meta_types/enum_type_tests.cpp | 98 ++ untests/meta_types/function_type_tests.cpp | 68 + untests/meta_types/member_type_tests.cpp | 47 + untests/meta_types/method_type_tests.cpp | 68 + untests/meta_types/number_type_tests.cpp | 51 + untests/meta_types/pointer_type_tests.cpp | 53 + untests/meta_types/reference_type_tests.cpp | 61 + untests/meta_types/void_type_tests.cpp | 29 + untests/meta_utilities/arg_tests.cpp | 1157 +++++++++++++++++ untests/meta_utilities/inst_tests.cpp | 72 + untests/meta_utilities/value_tests.cpp | 295 +++++ 56 files changed, 8359 insertions(+) create mode 100644 headers/meta.hpp/meta_registry.hpp create mode 100644 headers/meta.hpp/meta_registry/class_bind.hpp create mode 100644 headers/meta.hpp/meta_registry/enum_bind.hpp create mode 100644 headers/meta.hpp/meta_registry/scope_bind.hpp create mode 100644 headers/meta.hpp/meta_states.hpp create mode 100644 headers/meta.hpp/meta_states/ctor.hpp create mode 100644 headers/meta.hpp/meta_states/evalue.hpp create mode 100644 headers/meta.hpp/meta_states/function.hpp create mode 100644 headers/meta.hpp/meta_states/member.hpp create mode 100644 headers/meta.hpp/meta_states/method.hpp create mode 100644 headers/meta.hpp/meta_states/scope.hpp create mode 100644 headers/meta.hpp/meta_states/variable.hpp create mode 100644 headers/meta.hpp/meta_types.hpp create mode 100644 headers/meta.hpp/meta_types/any_type.hpp create mode 100644 headers/meta.hpp/meta_types/array_type.hpp create mode 100644 headers/meta.hpp/meta_types/class_type.hpp create mode 100644 headers/meta.hpp/meta_types/ctor_type.hpp create mode 100644 headers/meta.hpp/meta_types/enum_type.hpp create mode 100644 headers/meta.hpp/meta_types/function_type.hpp create mode 100644 headers/meta.hpp/meta_types/member_type.hpp create mode 100644 headers/meta.hpp/meta_types/method_type.hpp create mode 100644 headers/meta.hpp/meta_types/number_type.hpp create mode 100644 headers/meta.hpp/meta_types/pointer_type.hpp create mode 100644 headers/meta.hpp/meta_types/reference_type.hpp create mode 100644 headers/meta.hpp/meta_types/void_type.hpp create mode 100644 headers/meta.hpp/meta_utilities.hpp create mode 100644 headers/meta.hpp/meta_utilities/arg.hpp create mode 100644 headers/meta.hpp/meta_utilities/inst.hpp create mode 100644 headers/meta.hpp/meta_utilities/value.hpp create mode 100644 untests/examples/class_example.cpp create mode 100644 untests/examples/complex_example.cpp create mode 100644 untests/examples/enum_example.cpp create mode 100644 untests/examples/member_example.cpp create mode 100644 untests/examples/method_example.cpp create mode 100644 untests/examples/number_example.cpp create mode 100644 untests/meta_states/evalue_tests.cpp create mode 100644 untests/meta_states/function_tests.cpp create mode 100644 untests/meta_states/member_tests.cpp create mode 100644 untests/meta_states/method_tests.cpp create mode 100644 untests/meta_states/scope_tests.cpp create mode 100644 untests/meta_states/variable_tests.cpp create mode 100644 untests/meta_types/array_type_tests.cpp create mode 100644 untests/meta_types/class_type_tests.cpp create mode 100644 untests/meta_types/enum_type_tests.cpp create mode 100644 untests/meta_types/function_type_tests.cpp create mode 100644 untests/meta_types/member_type_tests.cpp create mode 100644 untests/meta_types/method_type_tests.cpp create mode 100644 untests/meta_types/number_type_tests.cpp create mode 100644 untests/meta_types/pointer_type_tests.cpp create mode 100644 untests/meta_types/reference_type_tests.cpp create mode 100644 untests/meta_types/void_type_tests.cpp create mode 100644 untests/meta_utilities/arg_tests.cpp create mode 100644 untests/meta_utilities/inst_tests.cpp create mode 100644 untests/meta_utilities/value_tests.cpp diff --git a/headers/meta.hpp/meta_all.hpp b/headers/meta.hpp/meta_all.hpp index 1d7fa5c..242dcb4 100644 --- a/headers/meta.hpp/meta_all.hpp +++ b/headers/meta.hpp/meta_all.hpp @@ -10,6 +10,20 @@ #include "meta_kinds.hpp" +#include "meta_registry.hpp" +#include "meta_registry/class_bind.hpp" +#include "meta_registry/enum_bind.hpp" +#include "meta_registry/scope_bind.hpp" + +#include "meta_states.hpp" +#include "meta_states/ctor.hpp" +#include "meta_states/evalue.hpp" +#include "meta_states/function.hpp" +#include "meta_states/member.hpp" +#include "meta_states/method.hpp" +#include "meta_states/scope.hpp" +#include "meta_states/variable.hpp" + #include "meta_traits.hpp" #include "meta_traits/array_traits.hpp" #include "meta_traits/class_traits.hpp" @@ -22,3 +36,22 @@ #include "meta_traits/pointer_traits.hpp" #include "meta_traits/reference_traits.hpp" #include "meta_traits/void_traits.hpp" + +#include "meta_types.hpp" +#include "meta_types/any_type.hpp" +#include "meta_types/array_type.hpp" +#include "meta_types/class_type.hpp" +#include "meta_types/ctor_type.hpp" +#include "meta_types/enum_type.hpp" +#include "meta_types/function_type.hpp" +#include "meta_types/member_type.hpp" +#include "meta_types/method_type.hpp" +#include "meta_types/number_type.hpp" +#include "meta_types/pointer_type.hpp" +#include "meta_types/reference_type.hpp" +#include "meta_types/void_type.hpp" + +#include "meta_utilities.hpp" +#include "meta_utilities/arg.hpp" +#include "meta_utilities/inst.hpp" +#include "meta_utilities/value.hpp" diff --git a/headers/meta.hpp/meta_base.hpp b/headers/meta.hpp/meta_base.hpp index fbff63e..099b25f 100644 --- a/headers/meta.hpp/meta_base.hpp +++ b/headers/meta.hpp/meta_base.hpp @@ -165,6 +165,7 @@ namespace meta_hpp struct function_index; struct member_index; struct method_index; + struct scope_index; struct variable_index; using class_set = std::set>; @@ -178,5 +179,6 @@ namespace meta_hpp using function_map = std::map>; using member_map = std::map>; using method_map = std::map>; + using scope_map = std::map>; using variable_map = std::map>; } diff --git a/headers/meta.hpp/meta_registry.hpp b/headers/meta.hpp/meta_registry.hpp new file mode 100644 index 0000000..88f98cf --- /dev/null +++ b/headers/meta.hpp/meta_registry.hpp @@ -0,0 +1,94 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "meta_base.hpp" +#include "meta_states.hpp" + +namespace meta_hpp +{ + template < class_kind Class > + class class_bind final { + public: + explicit class_bind(); + operator class_type() const noexcept; + + template < typename... Args > + class_bind& ctor_(); + + template < class_kind Base > + class_bind& base_(); + + template < function_kind Function > + class_bind& function_(std::string name, Function function); + + template < member_kind Member > + class_bind& member_(std::string name, Member member); + + template < method_kind Method > + class_bind& method_(std::string name, Method method); + + template < pointer_kind Pointer > + class_bind& variable_(std::string name, Pointer pointer); + private: + detail::class_type_data_ptr data_; + }; +} + +namespace meta_hpp +{ + template < enum_kind Enum > + class enum_bind final { + public: + explicit enum_bind(); + operator enum_type() const noexcept; + + enum_bind& evalue_(std::string name, Enum value); + private: + detail::enum_type_data_ptr data_; + }; +} + +namespace meta_hpp +{ + class scope_bind final { + public: + explicit scope_bind(std::string_view name); + operator scope() const noexcept; + + template < class_kind Class > + scope_bind& class_(std::string name); + + template < enum_kind Enum > + scope_bind& enum_(std::string name); + + template < function_kind Function > + scope_bind& function_(std::string name, Function function); + + template < pointer_kind Pointer > + scope_bind& variable_(std::string name, Pointer pointer); + private: + detail::scope_state_ptr state_; + }; +} + +namespace meta_hpp +{ + template < class_kind Class > + class_bind class_() { + return class_bind{}; + } + + template < enum_kind Enum > + enum_bind enum_() { + return enum_bind{}; + } + + inline scope_bind scope_(std::string name) { + return scope_bind{std::move(name)}; + } +} diff --git a/headers/meta.hpp/meta_registry/class_bind.hpp b/headers/meta.hpp/meta_registry/class_bind.hpp new file mode 100644 index 0000000..e4e0b2c --- /dev/null +++ b/headers/meta.hpp/meta_registry/class_bind.hpp @@ -0,0 +1,70 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_registry.hpp" + +namespace meta_hpp +{ + template < class_kind Class > + class_bind::class_bind() + : data_{detail::get_type_data()} {} + + template < class_kind Class > + class_bind::operator class_type() const noexcept { + return class_type{data_}; + } + + template < class_kind Class > + template < typename... Args > + class_bind& class_bind::ctor_() { + auto ctor_state = detail::ctor_state::make(); + data_->ctors.emplace(ctor_state->index, std::move(ctor_state)); + return *this; + } + + template < class_kind Class > + template < class_kind Base > + class_bind& class_bind::base_() { + auto base_data = detail::class_type_data::get(); + data_->bases.emplace(base_data); + return *this; + } + + template < class_kind Class > + template < function_kind Function > + class_bind& class_bind::function_(std::string name, Function function) { + 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 < class_kind Class > + template < member_kind Member > + class_bind& class_bind::member_(std::string name, Member 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 < class_kind Class > + template < method_kind Method > + class_bind& class_bind::method_(std::string name, Method 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 < class_kind Class > + template < pointer_kind Pointer > + class_bind& class_bind::variable_(std::string name, Pointer pointer) { + 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/enum_bind.hpp b/headers/meta.hpp/meta_registry/enum_bind.hpp new file mode 100644 index 0000000..d806c18 --- /dev/null +++ b/headers/meta.hpp/meta_registry/enum_bind.hpp @@ -0,0 +1,29 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_registry.hpp" + +namespace meta_hpp +{ + template < enum_kind Enum > + enum_bind::enum_bind() + : data_{detail::get_type_data()} {} + + template < enum_kind Enum > + enum_bind::operator enum_type() const noexcept { + return enum_type{data_}; + } + + template < enum_kind Enum > + enum_bind& enum_bind::evalue_(std::string name, Enum value) { + auto evalue_state = detail::evalue_state::make(std::move(name), std::move(value)); + data_->evalues.emplace(evalue_state->index, std::move(evalue_state)); + return *this; + } +} diff --git a/headers/meta.hpp/meta_registry/scope_bind.hpp b/headers/meta.hpp/meta_registry/scope_bind.hpp new file mode 100644 index 0000000..f2b2a48 --- /dev/null +++ b/headers/meta.hpp/meta_registry/scope_bind.hpp @@ -0,0 +1,48 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_registry.hpp" + +namespace meta_hpp +{ + inline scope_bind::scope_bind(std::string_view name) + : state_{detail::get_scope_state(name)} {} + + inline scope_bind::operator scope() const noexcept { + return scope{state_}; + } + + template < class_kind Class > + scope_bind& scope_bind::class_(std::string name) { + auto class_data = detail::class_type_data::get(); + state_->classes.emplace(std::move(name), class_data); + return *this; + } + + template < enum_kind Enum > + scope_bind& scope_bind::enum_(std::string name) { + auto enum_data = detail::enum_type_data::get(); + state_->enums.emplace(std::move(name), enum_data); + return *this; + } + + template < 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)); + state_->functions.emplace(function_state->index, std::move(function_state)); + return *this; + } + + template < 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)); + 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 new file mode 100644 index 0000000..0718416 --- /dev/null +++ b/headers/meta.hpp/meta_states.hpp @@ -0,0 +1,329 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "meta_base.hpp" +#include "meta_types.hpp" +#include "meta_utilities.hpp" + +namespace meta_hpp +{ + template < typename T > + concept states_family = + std::same_as || + std::same_as || + std::same_as || + std::same_as || + std::same_as || + std::same_as || + std::same_as; + + template < states_family T, states_family U > + bool operator<(const T& l, const U& r) noexcept { + if ( !static_cast(r) ) { + return false; + } + + if ( !static_cast(l) ) { + return true; + } + + return l.get_index() < r.get_index(); + } + + template < states_family T, states_family U > + bool operator==(const T& l, const U& r) noexcept { + if ( static_cast(l) != static_cast(r) ) { + return false; + } + + if ( !static_cast(l) ) { + return true; + } + + return l.get_index() == r.get_index(); + } + + template < states_family T, states_family U > + bool operator!=(const T& l, const U& r) noexcept { + return !(l == r); + } +} + +namespace meta_hpp +{ + class ctor final { + public: + explicit ctor() = default; + explicit ctor(detail::ctor_state_ptr state); + + bool is_valid() const noexcept; + explicit operator bool() const noexcept; + + const ctor_index& get_index() const noexcept; + const ctor_type& get_type() const noexcept; + + template < typename... Args > + value invoke(Args&&... args) const; + + template < typename... Args > + bool is_invocable_with() const noexcept; + private: + detail::ctor_state_ptr state_; + }; + + class evalue final { + public: + explicit evalue() = default; + explicit evalue(detail::evalue_state_ptr state); + + bool is_valid() const noexcept; + explicit operator bool() const noexcept; + + const evalue_index& get_index() const noexcept; + const enum_type& get_type() const noexcept; + const std::string& get_name() const noexcept; + + const value& get_value() const noexcept; + private: + detail::evalue_state_ptr state_; + }; + + class function final { + public: + explicit function() = default; + explicit function(detail::function_state_ptr state); + + bool is_valid() const noexcept; + explicit operator bool() const noexcept; + + const function_index& get_index() const noexcept; + const function_type& get_type() const noexcept; + const std::string& get_name() const noexcept; + + template < typename... Args > + std::optional invoke(Args&&... args) const; + + template < typename... Args > + bool is_invocable_with() const noexcept; + private: + detail::function_state_ptr state_; + }; + + class member final { + public: + explicit member() = default; + explicit member(detail::member_state_ptr state); + + bool is_valid() const noexcept; + explicit operator bool() const noexcept; + + const member_index& get_index() const noexcept; + const member_type& get_type() const noexcept; + const std::string& get_name() const noexcept; + + template < typename Instance > + value get(Instance&& instance) const; + + template < typename Instance, typename Value > + void set(Instance&& instance, Value&& value) const; + private: + detail::member_state_ptr state_; + }; + + class method final { + public: + explicit method() = default; + explicit method(detail::method_state_ptr state); + + bool is_valid() const noexcept; + explicit operator bool() const noexcept; + + const method_index& get_index() const noexcept; + const method_type& get_type() const noexcept; + const std::string& get_name() const noexcept; + + template < typename Instance, typename... Args > + std::optional invoke(Instance&& instance, Args&&... args) const; + + template < typename Inst, typename... Args > + bool is_invocable_with() const noexcept; + private: + detail::method_state_ptr state_; + }; + + class scope final { + public: + explicit scope() = default; + explicit scope(detail::scope_state_ptr state); + + bool is_valid() const noexcept; + explicit operator bool() const noexcept; + + const scope_index& get_index() const noexcept; + const std::string& get_name() const noexcept; + + const class_map& get_classes() const noexcept; + const enum_map& get_enums() const noexcept; + const function_map& get_functions() const noexcept; + const variable_map& get_variables() const noexcept; + + class_type get_class(std::string_view name) const noexcept; + enum_type get_enum(std::string_view name) const noexcept; + function get_function(std::string_view name) const noexcept; + variable get_variable(std::string_view name) const noexcept; + + template < typename... Args > + function get_function_with(std::string_view name) const noexcept; + function get_function_with(std::string_view name, std::vector args) const noexcept; + function get_function_with(std::string_view name, std::initializer_list args) const noexcept; + private: + detail::scope_state_ptr state_; + }; + + class variable final { + public: + explicit variable() = default; + explicit variable(detail::variable_state_ptr state); + + bool is_valid() const noexcept; + explicit operator bool() const noexcept; + + const variable_index& get_index() const noexcept; + const pointer_type& get_type() const noexcept; + const std::string& get_name() const noexcept; + + value get() const; + + template < typename Value > + void set(Value&& value) const; + private: + detail::variable_state_ptr state_; + }; +} + +namespace meta_hpp::detail +{ + struct ctor_state final { + using invoke_impl = std::function; + using is_invocable_with_impl = std::function; + + ctor_index index; + + invoke_impl invoke; + is_invocable_with_impl is_invocable_with; + + template < class_kind Class, typename... Args > + static ctor_state_ptr make(); + + template < class_kind Class, typename... Args > + explicit ctor_state(ctor_index index, type_list, type_list); + }; + + struct evalue_state final { + evalue_index index; + + class value value; + + template < enum_kind Enum > + static evalue_state_ptr make(std::string name, Enum value); + + template < enum_kind Enum > + explicit evalue_state(evalue_index index, Enum value); + }; + + struct function_state final { + using invoke_impl = std::function(const arg*, std::size_t)>; + using is_invocable_with_impl = std::function; + + function_index index; + + invoke_impl invoke; + is_invocable_with_impl is_invocable_with; + + template < function_kind Function > + static function_state_ptr make(std::string name, Function function); + + template < function_kind Function > + explicit function_state(function_index index, Function function); + }; + + struct member_state final { + using getter_impl = std::function; + using setter_impl = std::function; + + member_index index; + + getter_impl getter; + setter_impl setter; + + template < member_kind Member > + static member_state_ptr make(std::string name, Member member); + + template < member_kind Member > + explicit member_state(member_index index, Member member); + }; + + struct method_state final { + using invoke_impl = std::function(const inst&, const arg*, std::size_t)>; + using is_invocable_with_impl = std::function; + + method_index index; + + invoke_impl invoke; + is_invocable_with_impl is_invocable_with; + + template < method_kind Method > + static method_state_ptr make(std::string name, Method method); + + template < method_kind Method > + explicit method_state(method_index index, Method method); + }; + + struct scope_state final { + scope_index index; + + class_map classes; + enum_map enums; + function_map functions; + variable_map variables; + + static scope_state_ptr get(std::string_view name); + + explicit scope_state(scope_index index); + }; + + struct variable_state final { + using getter_impl = std::function; + using setter_impl = std::function; + + variable_index index; + + getter_impl getter; + setter_impl setter; + + template < pointer_kind Pointer > + static variable_state_ptr make(std::string name, Pointer pointer); + + template < pointer_kind Pointer > + explicit variable_state(variable_index index, Pointer pointer); + }; +} + +namespace meta_hpp +{ + namespace detail + { + inline scope_state_ptr get_scope_state(std::string_view name) { + return scope_state::get(name); + } + } + + inline scope resolve_scope(std::string_view name) { + return scope{detail::get_scope_state(name)}; + } +} diff --git a/headers/meta.hpp/meta_states/ctor.hpp b/headers/meta.hpp/meta_states/ctor.hpp new file mode 100644 index 0000000..c477ed4 --- /dev/null +++ b/headers/meta.hpp/meta_states/ctor.hpp @@ -0,0 +1,146 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_states.hpp" + +#include "../meta_types/ctor_type.hpp" + +namespace meta_hpp::detail +{ + template < class_kind Class, typename... Args, std::size_t... Is > + value raw_ctor_invoke_impl( + const arg* args, + std::index_sequence) + { + using ct = ctor_traits; + using class_type = typename ct::class_type; + using argument_types = typename ct::argument_types; + + if ( !(... && (args + Is)->can_cast_to>()) ) { + throw std::logic_error("an attempt to call a constructor with an incorrect argument types"); + } + + class_type return_value{(args + Is)->cast>()...}; + return value{std::forward(return_value)}; + } + + template < class_kind Class, typename... Args > + value raw_ctor_invoke( + const arg* args, + std::size_t arg_count) + { + using ct = ctor_traits; + + if ( arg_count != ct::arity ) { + throw std::logic_error("an attempt to call a constructor with an incorrect arity"); + } + + return raw_ctor_invoke_impl( + args, + std::make_index_sequence()); + } + + template < class_kind Class, typename... Args > + ctor_state::invoke_impl make_ctor_invoke() { + using namespace std::placeholders; + return std::bind(&raw_ctor_invoke, _1, _2); + } +} + +namespace meta_hpp::detail +{ + template < class_kind Class, typename... Args, std::size_t... Is > + bool raw_ctor_is_invocable_with_impl( + const arg_base* arg_bases, + std::index_sequence) + { + using ct = ctor_traits; + using argument_types = typename ct::argument_types; + return (... && (arg_bases + Is)->can_cast_to>() ); + } + + template < class_kind Class, typename... Args > + bool raw_ctor_is_invocable_with( + const arg_base* arg_bases, + std::size_t arg_count) + { + using ct = ctor_traits; + + if ( arg_count != ct::arity ) { + return false; + } + + return raw_ctor_is_invocable_with_impl( + arg_bases, + std::make_index_sequence()); + } + + template < class_kind Class, typename... Args > + ctor_state::is_invocable_with_impl make_ctor_is_invocable_with() { + using namespace std::placeholders; + return std::bind(&raw_ctor_is_invocable_with, _1, _2); + } +} + +namespace meta_hpp::detail +{ + template < class_kind Class, typename... Args > + ctor_state_ptr ctor_state::make() { + ctor_index index{ctor_type_data::get()}; + return std::make_shared(std::move(index), type_list{}, type_list{}); + } + + template < class_kind Class, typename... Args > + 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()} {} +} + +namespace meta_hpp +{ + inline ctor::ctor(detail::ctor_state_ptr state) + : state_{std::move(state)} {} + + inline bool ctor::is_valid() const noexcept { + return !!state_; + } + + inline ctor::operator bool() const noexcept { + return is_valid(); + } + + inline const ctor_index& ctor::get_index() const noexcept { + return state_->index; + } + + inline const ctor_type& ctor::get_type() const noexcept { + return state_->index.type; + } + + template < typename... Args > + inline value ctor::invoke(Args&&... args) const { + if constexpr ( sizeof...(Args) > 0 ) { + std::array vargs{detail::arg{std::forward(args)}...}; + return state_->invoke(vargs.data(), vargs.size()); + } else { + return state_->invoke(nullptr, 0); + } + } + + template < typename... Args > + inline bool ctor::is_invocable_with() const noexcept { + if constexpr ( sizeof...(Args) > 0 ) { + std::array arg_bases{detail::arg_base{type_list{}}...}; + return state_->is_invocable_with(arg_bases.data(), arg_bases.size()); + } else { + return state_->is_invocable_with(nullptr, 0); + } + } +} diff --git a/headers/meta.hpp/meta_states/evalue.hpp b/headers/meta.hpp/meta_states/evalue.hpp new file mode 100644 index 0000000..0c37330 --- /dev/null +++ b/headers/meta.hpp/meta_states/evalue.hpp @@ -0,0 +1,56 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_states.hpp" + +#include "../meta_types/enum_type.hpp" + +namespace meta_hpp::detail +{ + template < enum_kind Enum > + evalue_state_ptr evalue_state::make(std::string name, Enum value) { + evalue_index index{enum_type_data::get(), std::move(name)}; + return std::make_shared(std::move(index), std::move(value)); + } + + template < enum_kind Enum > + evalue_state::evalue_state(evalue_index index, Enum value) + : index{std::move(index)} + , value{std::move(value)} {} +} + +namespace meta_hpp +{ + inline evalue::evalue(detail::evalue_state_ptr state) + : state_{std::move(state)} {} + + inline bool evalue::is_valid() const noexcept { + return !!state_; + } + + inline evalue::operator bool() const noexcept { + return is_valid(); + } + + inline const evalue_index& evalue::get_index() const noexcept { + return state_->index; + } + + inline const enum_type& evalue::get_type() const noexcept { + return state_->index.type; + } + + inline const std::string& evalue::get_name() const noexcept { + return state_->index.name; + } + + inline const value& evalue::get_value() const noexcept { + return state_->value; + } +} diff --git a/headers/meta.hpp/meta_states/function.hpp b/headers/meta.hpp/meta_states/function.hpp new file mode 100644 index 0000000..faede9b --- /dev/null +++ b/headers/meta.hpp/meta_states/function.hpp @@ -0,0 +1,160 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_states.hpp" + +#include "../meta_types/function_type.hpp" + +namespace meta_hpp::detail +{ + template < function_kind Function, std::size_t... Is > + std::optional raw_function_invoke_impl( + Function function, + const arg* args, + std::index_sequence) + { + using ft = function_traits; + using return_type = typename ft::return_type; + using argument_types = typename ft::argument_types; + + if ( !(... && (args + Is)->can_cast_to>()) ) { + throw std::logic_error("an attempt to call a function with an incorrect argument types"); + } + + if constexpr ( std::is_void_v ) { + std::invoke(function, + (args + Is)->cast>()...); + return std::nullopt; + } else { + return_type return_value{std::invoke(function, + (args + Is)->cast>()...)}; + return value{std::forward(return_value)}; + } + } + + template < function_kind Function > + std::optional raw_function_invoke( + Function function, + const arg* args, + std::size_t arg_count) + { + using ft = function_traits; + + if ( arg_count != ft::arity ) { + throw std::logic_error("an attempt to call a function with an incorrect arity"); + } + + return raw_function_invoke_impl( + function, + args, + std::make_index_sequence()); + } + + template < function_kind Function > + function_state::invoke_impl make_function_invoke(Function function) { + using namespace std::placeholders; + return std::bind(&raw_function_invoke, function, _1, _2); + } +} + +namespace meta_hpp::detail +{ + template < function_kind Function, std::size_t... Is > + bool raw_function_is_invocable_with_impl( + const arg_base* arg_bases, + std::index_sequence) + { + using ft = function_traits; + using argument_types = typename ft::argument_types; + return (... && (arg_bases + Is)->can_cast_to>() ); + } + + template < function_kind Function > + bool raw_function_is_invocable_with( + const arg_base* arg_bases, + std::size_t arg_count) + { + using ft = function_traits; + + if ( arg_count != ft::arity ) { + return false; + } + + return raw_function_is_invocable_with_impl( + arg_bases, + std::make_index_sequence()); + } + + template < function_kind Function > + function_state::is_invocable_with_impl make_function_is_invocable_with() { + using namespace std::placeholders; + return std::bind(&raw_function_is_invocable_with, _1, _2); + } +} + +namespace meta_hpp::detail +{ + template < function_kind Function > + function_state_ptr function_state::make(std::string name, Function function) { + function_index index{function_type_data::get(), std::move(name)}; + return std::make_shared(std::move(index), std::move(function)); + } + + template < function_kind Function > + function_state::function_state(function_index index, Function function) + : index{std::move(index)} + , invoke{make_function_invoke(function)} + , is_invocable_with{make_function_is_invocable_with()} {} +} + +namespace meta_hpp +{ + inline function::function(detail::function_state_ptr state) + : state_{std::move(state)} {} + + inline bool function::is_valid() const noexcept { + return !!state_; + } + + inline function::operator bool() const noexcept { + return is_valid(); + } + + inline const function_index& function::get_index() const noexcept { + return state_->index; + } + + inline const function_type& function::get_type() const noexcept { + return state_->index.type; + } + + inline const std::string& function::get_name() const noexcept { + return state_->index.name; + } + + template < typename... Args > + std::optional function::invoke(Args&&... args) const { + if constexpr ( sizeof...(Args) > 0 ) { + std::array vargs{detail::arg{std::forward(args)}...}; + return state_->invoke(vargs.data(), vargs.size()); + } else { + return state_->invoke(nullptr, 0); + } + } + + template < typename... Args > + bool function::is_invocable_with() const noexcept { + if constexpr ( sizeof...(Args) > 0 ) { + std::array arg_bases{detail::arg_base{type_list{}}...}; + return state_->is_invocable_with(arg_bases.data(), arg_bases.size()); + } else { + return state_->is_invocable_with(nullptr, 0); + } + } +} diff --git a/headers/meta.hpp/meta_states/member.hpp b/headers/meta.hpp/meta_states/member.hpp new file mode 100644 index 0000000..5c18f74 --- /dev/null +++ b/headers/meta.hpp/meta_states/member.hpp @@ -0,0 +1,124 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_states.hpp" + +#include "../meta_types/member_type.hpp" + +namespace meta_hpp::detail +{ + template < 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; + + 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(member, inst.cast())}; + return value{std::forward(return_value)}; + } + + template < member_kind Member > + void raw_member_setter([[maybe_unused]] Member member, const inst& inst, const arg& arg) { + using mt = member_traits; + 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 ) { + if ( inst.is_const() ) { + throw std::logic_error("an attempt to set a member with an const instance type"); + } + + if ( !inst.can_cast_to() ) { + throw std::logic_error("an attempt to set a member with an incorrect instance type"); + } + + if ( !arg.can_cast_to() ) { + throw std::logic_error("an attempt to set a member with an incorrect argument type"); + } + + std::invoke(member, inst.cast()) = arg.cast(); + } else { + throw std::logic_error("an attempt to set a constant member"); + } + } +} + +namespace meta_hpp::detail +{ + template < member_kind Member > + member_state::getter_impl make_member_getter(Member member) { + using namespace std::placeholders; + return std::bind(&raw_member_getter, member, _1); + } + + template < member_kind Member > + member_state::setter_impl make_member_setter(Member member) { + using namespace std::placeholders; + return std::bind(&raw_member_setter, member, _1, _2); + } +} + +namespace meta_hpp::detail +{ + template < member_kind Member > + member_state_ptr member_state::make(std::string name, Member member) { + member_index index{member_type_data::get(), std::move(name)}; + return std::make_shared(std::move(index), std::move(member)); + } + + template < member_kind Member > + member_state::member_state(member_index index, Member member) + : index{std::move(index)} + , getter{make_member_getter(member)} + , setter{make_member_setter(member)} {} +} + +namespace meta_hpp +{ + inline member::member(detail::member_state_ptr state) + : state_{std::move(state)} {} + + inline bool member::is_valid() const noexcept { + return !!state_; + } + + inline member::operator bool() const noexcept { + return is_valid(); + } + + inline const member_index& member::get_index() const noexcept { + return state_->index; + } + + inline const member_type& member::get_type() const noexcept { + return state_->index.type; + } + + inline const std::string& member::get_name() const noexcept { + return state_->index.name; + } + + template < typename Instance > + value member::get(Instance&& instance) const { + return state_->getter(detail::inst{std::forward(instance)}); + } + + template < typename Instance, typename Value > + void member::set(Instance&& instance, Value&& value) const { + state_->setter(detail::inst{std::forward(instance)}, detail::arg{std::forward(value)}); + } +} diff --git a/headers/meta.hpp/meta_states/method.hpp b/headers/meta.hpp/meta_states/method.hpp new file mode 100644 index 0000000..f88bfad --- /dev/null +++ b/headers/meta.hpp/meta_states/method.hpp @@ -0,0 +1,176 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_states.hpp" + +#include "../meta_types/method_type.hpp" + +namespace meta_hpp::detail +{ + template < method_kind Method, std::size_t... Is > + std::optional raw_method_invoke_impl( + Method method, + const inst& inst, + const arg* args, + std::index_sequence) + { + 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; + + if ( !inst.can_cast_to() ) { + throw std::logic_error("an attempt to call a method with an incorrect instance type"); + } + + if ( !(... && (args + Is)->can_cast_to>()) ) { + throw std::logic_error("an attempt to call a method with an incorrect argument types"); + } + + if constexpr ( std::is_void_v ) { + std::invoke(method, + inst.cast(), + (args + Is)->cast>()...); + return std::nullopt; + } else { + return_type return_value{std::invoke(method, + inst.cast(), + (args + Is)->cast>()...)}; + return value{std::forward(return_value)}; + } + } + + template < method_kind Method > + std::optional raw_method_invoke( + Method method, + const inst& inst, + const arg* args, + std::size_t arg_count) + { + using mt = method_traits; + + if ( arg_count != mt::arity ) { + throw std::logic_error("an attempt to call a method with an incorrect arity"); + } + + return raw_method_invoke_impl( + method, + inst, + args, + std::make_index_sequence()); + } + + template < method_kind Method > + method_state::invoke_impl make_method_invoke(Method method) { + using namespace std::placeholders; + return std::bind(&raw_method_invoke, method, _1, _2, _3); + } +} + +namespace meta_hpp::detail +{ + template < method_kind Method, std::size_t... Is > + bool raw_method_is_invocable_with_impl( + const inst_base& inst_base, + const arg_base* arg_bases, + std::index_sequence) + { + using mt = method_traits; + using qualified_type = typename mt::qualified_type; + using argument_types = typename mt::argument_types; + + return inst_base.can_cast_to() + && (... && (arg_bases + Is)->can_cast_to>() ); + } + + template < method_kind Method > + bool raw_method_is_invocable_with( + const inst_base& inst_base, + const arg_base* arg_bases, + std::size_t arg_count) + { + using mt = method_traits; + + if ( arg_count != mt::arity ) { + return false; + } + + return raw_method_is_invocable_with_impl( + inst_base, + arg_bases, + std::make_index_sequence()); + } + + template < method_kind Method > + method_state::is_invocable_with_impl make_method_is_invocable_with() { + using namespace std::placeholders; + return std::bind(&raw_method_is_invocable_with, _1, _2, _3); + } +} + +namespace meta_hpp::detail +{ + template < method_kind Method > + method_state_ptr method_state::make(std::string name, Method method) { + method_index index{method_type_data::get(), std::move(name)}; + return std::make_shared(std::move(index), std::move(method)); + } + + template < method_kind Method > + method_state::method_state(method_index index, Method method) + : index{std::move(index)} + , invoke{make_method_invoke(method)} + , is_invocable_with{make_method_is_invocable_with()} {} +} + +namespace meta_hpp +{ + inline method::method(detail::method_state_ptr state) + : state_{std::move(state)} {} + + inline bool method::is_valid() const noexcept { + return !!state_; + } + + inline method::operator bool() const noexcept { + return is_valid(); + } + + inline const method_index& method::get_index() const noexcept { + return state_->index; + } + + inline const method_type& method::get_type() const noexcept { + return state_->index.type; + } + + inline const std::string& method::get_name() const noexcept { + return state_->index.name; + } + + template < typename Instance, typename... Args > + std::optional method::invoke(Instance&& instance, Args&&... args) const { + if constexpr ( sizeof...(Args) > 0 ) { + std::array vargs{detail::arg{std::forward(args)}...}; + return state_->invoke(detail::inst{std::forward(instance)}, vargs.data(), vargs.size()); + } else { + return state_->invoke(detail::inst{std::forward(instance)}, nullptr, 0); + } + } + + template < typename Inst, typename... Args > + bool method::is_invocable_with() const noexcept { + if constexpr ( sizeof...(Args) > 0 ) { + std::array arg_bases{detail::arg_base{type_list{}}...}; + return state_->is_invocable_with(detail::inst_base{type_list{}}, arg_bases.data(), arg_bases.size()); + } else { + return state_->is_invocable_with(detail::inst_base{type_list{}}, nullptr, 0); + } + } +} diff --git a/headers/meta.hpp/meta_states/scope.hpp b/headers/meta.hpp/meta_states/scope.hpp new file mode 100644 index 0000000..c5fb939 --- /dev/null +++ b/headers/meta.hpp/meta_states/scope.hpp @@ -0,0 +1,138 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_states.hpp" + +namespace meta_hpp::detail +{ + inline scope_state_ptr scope_state::get(std::string_view name) { + static std::map> states; + + if ( auto iter = states.find(name); iter != states.end() ) { + return iter->second; + } + + auto state = std::make_shared(scope_index{std::string{name}}); + return states.emplace(std::string{name}, state).first->second; + } + + inline scope_state::scope_state(scope_index index) + : index{std::move(index)} {} +} + +namespace meta_hpp +{ + inline scope::scope(detail::scope_state_ptr state) + : state_{std::move(state)} {} + + inline bool scope::is_valid() const noexcept { + return !!state_; + } + + inline scope::operator bool() const noexcept { + return is_valid(); + } + + inline const scope_index& scope::get_index() const noexcept { + return state_->index; + } + + inline const std::string& scope::get_name() const noexcept { + return state_->index.name; + } + + inline const class_map& scope::get_classes() const noexcept { + return state_->classes; + } + + inline const enum_map& scope::get_enums() const noexcept { + return state_->enums; + } + + inline const function_map& scope::get_functions() const noexcept { + return state_->functions; + } + + inline const variable_map& scope::get_variables() const noexcept { + return state_->variables; + } + + inline class_type scope::get_class(std::string_view name) const noexcept { + if ( auto iter = state_->classes.find(name); iter != state_->classes.end() ) { + return iter->second; + } + return class_type{}; + } + + inline enum_type scope::get_enum(std::string_view name) const noexcept { + if ( auto iter = state_->enums.find(name); iter != state_->enums.end() ) { + return iter->second; + } + return enum_type{}; + } + + inline function scope::get_function(std::string_view name) const noexcept { + for ( auto&& [index, function] : state_->functions ) { + if ( index.name == name ) { + return function; + } + } + return function{}; + } + + inline variable scope::get_variable(std::string_view name) const noexcept { + for ( auto&& [index, variable] : state_->variables ) { + if ( index.name == name ) { + return variable; + } + } + return variable{}; + } + + template < typename... Args > + function scope::get_function_with(std::string_view name) const noexcept { + return get_function_with(name, {resolve_type()...}); + } + + inline function scope::get_function_with(std::string_view name, std::vector args) const noexcept { + for ( auto&& [index, function] : state_->functions ) { + if ( index.name != name ) { + continue; + } + + if ( function.get_type().get_arity() != args.size() ) { + continue; + } + + const std::vector& function_args = function.get_type().get_argument_types(); + if ( std::equal(args.begin(), args.end(), function_args.begin(), function_args.end()) ) { + return function; + } + } + return function{}; + } + + inline function scope::get_function_with(std::string_view name, std::initializer_list args) const noexcept { + for ( auto&& [index, function] : state_->functions ) { + if ( index.name != name ) { + continue; + } + + if ( function.get_type().get_arity() != args.size() ) { + continue; + } + + const std::vector& function_args = function.get_type().get_argument_types(); + if ( std::equal(args.begin(), args.end(), function_args.begin(), function_args.end()) ) { + return function; + } + } + return function{}; + } +} diff --git a/headers/meta.hpp/meta_states/variable.hpp b/headers/meta.hpp/meta_states/variable.hpp new file mode 100644 index 0000000..ff6353e --- /dev/null +++ b/headers/meta.hpp/meta_states/variable.hpp @@ -0,0 +1,105 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_states.hpp" + +#include "../meta_types/pointer_type.hpp" + +namespace meta_hpp::detail +{ + template < 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)}; + } + + template < pointer_kind Pointer > + void raw_variable_setter([[maybe_unused]] Pointer pointer, const arg& arg) { + using pt = pointer_traits; + using data_type = typename pt::data_type; + + if constexpr ( !std::is_const_v ) { + if ( !arg.can_cast_to() ) { + throw std::logic_error("an attempt to set a variable with an incorrect argument type"); + } + + *pointer = arg.cast(); + } else { + throw std::logic_error("an attempt to set a constant variable"); + } + } +} + +namespace meta_hpp::detail +{ + template < pointer_kind Pointer > + variable_state::getter_impl make_variable_getter(Pointer pointer) { + using namespace std::placeholders; + return std::bind(&raw_variable_getter, pointer); + } + + template < pointer_kind Pointer > + variable_state::setter_impl make_variable_setter(Pointer pointer) { + using namespace std::placeholders; + return std::bind(&raw_variable_setter, pointer, _1); + } +} + +namespace meta_hpp::detail +{ + template < pointer_kind Pointer > + variable_state_ptr variable_state::make(std::string name, Pointer pointer) { + variable_index index{pointer_type_data::get(), std::move(name)}; + return std::make_shared(index, pointer); + } + + 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)} {} +} + +namespace meta_hpp +{ + inline variable::variable(detail::variable_state_ptr state) + : state_{std::move(state)} {} + + inline bool variable::is_valid() const noexcept { + return !!state_; + } + + inline variable::operator bool() const noexcept { + return is_valid(); + } + + inline const variable_index& variable::get_index() const noexcept { + return state_->index; + } + + inline const pointer_type& variable::get_type() const noexcept { + return state_->index.type; + } + + inline const std::string& variable::get_name() const noexcept { + return state_->index.name; + } + + inline value variable::get() const { + return state_->getter(); + } + + template < typename Value > + void variable::set(Value&& value) const { + state_->setter(detail::arg{std::forward(value)}); + } +} diff --git a/headers/meta.hpp/meta_types.hpp b/headers/meta.hpp/meta_types.hpp new file mode 100644 index 0000000..d8dff41 --- /dev/null +++ b/headers/meta.hpp/meta_types.hpp @@ -0,0 +1,722 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "meta_base.hpp" +#include "meta_traits.hpp" + +namespace meta_hpp +{ + class type_id final { + public: + template < typename T > + explicit type_id(type_list) noexcept + : id_{type_to_id()} {} + + type_id(type_id&&) = default; + type_id& operator=(type_id&&) = default; + + type_id(const type_id&) = default; + type_id& operator=(const type_id&) = default; + + std::size_t get_hash() const noexcept { + return std::hash{}(id_); + } + + friend bool operator<(type_id l, type_id r) noexcept { + return l.id_ < r.id_; + } + + friend bool operator==(type_id l, type_id r) noexcept { + return l.id_ == r.id_; + } + + friend bool operator!=(type_id l, type_id r) noexcept { + return l.id_ != r.id_; + } + private: + using underlying_type = std::uint32_t; + underlying_type id_{}; + private: + static underlying_type next() noexcept { + static std::atomic id{}; + return ++id; + } + + template < typename T > + static underlying_type type_to_id() noexcept { + static const underlying_type id{next()}; + return id; + } + }; +} + +namespace meta_hpp +{ + template < typename T > + concept types_family = + std::same_as || + std::same_as || + std::same_as || + std::same_as || + std::same_as || + std::same_as || + std::same_as || + std::same_as || + std::same_as || + std::same_as || + std::same_as || + std::same_as; + + template < types_family T > + bool operator<(type_id l, const T& r) noexcept { + return static_cast(r) && l < r.get_id(); + } + + template < types_family T > + bool operator<(const T& l, type_id r) noexcept { + return !static_cast(l) || l.get_id() < r; + } + + template < types_family T, types_family U > + bool operator<(const T& l, const U& r) noexcept { + if ( !static_cast(r) ) { + return false; + } + + if ( !static_cast(l) ) { + return true; + } + + return l.get_id() < r.get_id(); + } + + template < types_family T > + bool operator==(type_id l, const T& r) noexcept { + return static_cast(r) && l == r.get_id(); + } + + template < types_family T > + bool operator==(const T& l, type_id r) noexcept { + return static_cast(l) && l.get_id() == r; + } + + template < types_family T, types_family U > + bool operator==(const T& l, const U& r) noexcept { + if ( static_cast(l) != static_cast(r) ) { + return false; + } + + if ( !static_cast(l) ) { + return true; + } + + return l.get_id() == r.get_id(); + } + + template < types_family T > + bool operator!=(type_id l, const T& r) noexcept { + return !(l == r); + } + + template < types_family T > + bool operator!=(const T& l, type_id r) noexcept { + return !(l == r); + } + + template < types_family T, types_family U > + bool operator!=(const T& l, const U& r) noexcept { + return !(l == r); + } +} + +namespace meta_hpp +{ + class any_type final { + public: + explicit any_type() = default; + explicit any_type(detail::type_data_base_ptr data); + + bool is_valid() const noexcept; + explicit operator bool() const noexcept; + + type_id get_id() const noexcept; + type_kind get_kind() const noexcept; + + any_type(const array_type& other) noexcept; + any_type(const class_type& other) noexcept; + any_type(const ctor_type& other) noexcept; + any_type(const enum_type& other) noexcept; + any_type(const function_type& other) noexcept; + any_type(const member_type& other) noexcept; + any_type(const method_type& other) noexcept; + any_type(const number_type& other) noexcept; + any_type(const pointer_type& other) noexcept; + any_type(const reference_type& other) noexcept; + any_type(const void_type& other) noexcept; + + bool is_array() const noexcept; + bool is_class() const noexcept; + bool is_ctor() const noexcept; + bool is_enum() const noexcept; + bool is_function() const noexcept; + bool is_member() const noexcept; + bool is_method() const noexcept; + bool is_number() const noexcept; + bool is_pointer() const noexcept; + bool is_reference() const noexcept; + bool is_void() const noexcept; + + array_type as_array() const noexcept; + class_type as_class() const noexcept; + ctor_type as_ctor() const noexcept; + enum_type as_enum() const noexcept; + function_type as_function() const noexcept; + member_type as_member() const noexcept; + method_type as_method() const noexcept; + number_type as_number() const noexcept; + pointer_type as_pointer() const noexcept; + reference_type as_reference() const noexcept; + void_type as_void() const noexcept; + private: + detail::type_data_base_ptr data_; + }; + + class array_type final { + public: + array_type() = default; + array_type(detail::array_type_data_ptr data); + + bool is_valid() const noexcept; + explicit operator bool() const noexcept; + + type_id get_id() const noexcept; + bitflags get_flags() const noexcept; + + std::size_t get_extent() const noexcept; + any_type get_data_type() const noexcept; + private: + friend class any_type; + detail::array_type_data_ptr data_; + }; + + class class_type final { + public: + class_type() = default; + class_type(detail::class_type_data_ptr data); + + bool is_valid() const noexcept; + explicit operator bool() const noexcept; + + type_id get_id() const noexcept; + bitflags get_flags() const noexcept; + + std::size_t get_size() const noexcept; + + std::size_t get_arity() const noexcept; + any_type get_argument_type(std::size_t index) const noexcept; + const std::vector& get_argument_types() const noexcept; + + const ctor_map& get_ctors() const noexcept; + const class_set& get_bases() const noexcept; + const function_map& get_functions() const noexcept; + const member_map& get_members() const noexcept; + const method_map& get_methods() const noexcept; + const variable_map& get_variables() const noexcept; + + template < class_kind Derived > + bool is_base_of() const noexcept; + bool is_base_of(const class_type& derived) const noexcept; + + template < class_kind Base > + bool is_derived_from() const noexcept; + bool is_derived_from(const class_type& base) const noexcept; + + function get_function(std::string_view name) const noexcept; + member get_member(std::string_view name) const noexcept; + method get_method(std::string_view name) const noexcept; + variable get_variable(std::string_view name) const noexcept; + + template < typename... Args > + ctor get_ctor_with() const noexcept; + ctor get_ctor_with(std::vector args) const noexcept; + ctor get_ctor_with(std::initializer_list args) const noexcept; + + template < typename... Args > + function get_function_with(std::string_view name) const noexcept; + function get_function_with(std::string_view name, std::vector args) const noexcept; + function get_function_with(std::string_view name, std::initializer_list args) const noexcept; + + template < typename... Args > + method get_method_with(std::string_view name) const noexcept; + method get_method_with(std::string_view name, std::vector args) const noexcept; + method get_method_with(std::string_view name, std::initializer_list args) const noexcept; + private: + friend class any_type; + detail::class_type_data_ptr data_; + }; + + class ctor_type final { + public: + ctor_type() = default; + ctor_type(detail::ctor_type_data_ptr data); + + bool is_valid() const noexcept; + explicit operator bool() const noexcept; + + type_id get_id() const noexcept; + bitflags get_flags() const noexcept; + + std::size_t get_arity() const noexcept; + any_type get_class_type() const noexcept; + any_type get_argument_type(std::size_t index) const noexcept; + const std::vector& get_argument_types() const noexcept; + private: + friend class any_type; + detail::ctor_type_data_ptr data_; + }; + + class enum_type final { + public: + enum_type() = default; + enum_type(detail::enum_type_data_ptr data); + + bool is_valid() const noexcept; + explicit operator bool() const noexcept; + + type_id get_id() const noexcept; + bitflags get_flags() const noexcept; + + number_type get_underlying_type() const noexcept; + + const evalue_map& get_evalues() const noexcept; + + evalue get_evalue(std::string_view name) const noexcept; + + template < typename Value > + std::optional value_to_name(Value&& value) const noexcept; + std::optional name_to_value(std::string_view name) const noexcept; + private: + friend class any_type; + detail::enum_type_data_ptr data_; + }; + + class function_type final { + public: + function_type() = default; + function_type(detail::function_type_data_ptr data); + + bool is_valid() const noexcept; + explicit operator bool() const noexcept; + + type_id get_id() const noexcept; + bitflags get_flags() const noexcept; + + std::size_t get_arity() const noexcept; + any_type get_return_type() const noexcept; + any_type get_argument_type(std::size_t index) const noexcept; + const std::vector& get_argument_types() const noexcept; + private: + friend class any_type; + detail::function_type_data_ptr data_; + }; + + class member_type final { + public: + member_type() = default; + member_type(detail::member_type_data_ptr data); + + bool is_valid() const noexcept; + explicit operator bool() const noexcept; + + type_id get_id() const noexcept; + bitflags get_flags() const noexcept; + + class_type get_owner_type() const noexcept; + any_type get_value_type() const noexcept; + private: + friend class any_type; + detail::member_type_data_ptr data_; + }; + + class method_type final { + public: + method_type() = default; + method_type(detail::method_type_data_ptr data); + + bool is_valid() const noexcept; + explicit operator bool() const noexcept; + + type_id get_id() const noexcept; + bitflags get_flags() const noexcept; + + std::size_t get_arity() const noexcept; + class_type get_owner_type() const noexcept; + any_type get_return_type() const noexcept; + any_type get_argument_type(std::size_t index) const noexcept; + const std::vector& get_argument_types() const noexcept; + private: + friend class any_type; + detail::method_type_data_ptr data_; + }; + + class number_type final { + public: + number_type() = default; + number_type(detail::number_type_data_ptr data); + + bool is_valid() const noexcept; + explicit operator bool() const noexcept; + + type_id get_id() const noexcept; + bitflags get_flags() const noexcept; + + std::size_t get_size() const noexcept; + private: + friend class any_type; + detail::number_type_data_ptr data_; + }; + + class pointer_type final { + public: + pointer_type() = default; + pointer_type(detail::pointer_type_data_ptr data); + + bool is_valid() const noexcept; + explicit operator bool() const noexcept; + + type_id get_id() const noexcept; + bitflags get_flags() const noexcept; + + any_type get_data_type() const noexcept; + private: + friend class any_type; + detail::pointer_type_data_ptr data_; + }; + + class reference_type final { + public: + reference_type() = default; + reference_type(detail::reference_type_data_ptr data); + + bool is_valid() const noexcept; + explicit operator bool() const noexcept; + + type_id get_id() const noexcept; + bitflags get_flags() const noexcept; + + any_type get_data_type() const noexcept; + private: + friend class any_type; + detail::reference_type_data_ptr data_; + }; + + class void_type final { + public: + void_type() = default; + void_type(detail::void_type_data_ptr data); + + bool is_valid() const noexcept; + explicit operator bool() const noexcept; + + type_id get_id() const noexcept; + bitflags get_flags() const noexcept; + private: + friend class any_type; + detail::void_type_data_ptr data_; + }; +} + +namespace meta_hpp::detail +{ + struct type_data_base { + const type_id id; + const type_kind kind; + + explicit type_data_base(type_id id, type_kind kind) + : id{id} + , kind{kind} {} + }; + + struct array_type_data final : type_data_base { + const bitflags flags; + const std::size_t extent; + const any_type data_type; + + template < array_kind Array > + static array_type_data_ptr get(); + + template < array_kind Array > + explicit array_type_data(type_list); + }; + + struct class_type_data final : type_data_base { + const bitflags flags; + const std::size_t size; + const std::vector argument_types; + + ctor_map ctors; + class_set bases; + function_map functions; + member_map members; + method_map methods; + variable_map variables; + + template < class_kind Class > + static class_type_data_ptr get(); + + template < class_kind Class > + explicit class_type_data(type_list); + }; + + struct ctor_type_data final : type_data_base { + const bitflags flags; + const any_type class_type; + const std::vector argument_types; + + template < class_kind Class, typename... Args > + static ctor_type_data_ptr get(); + + template < class_kind Class, typename... Args > + explicit ctor_type_data(type_list, type_list); + }; + + struct enum_type_data final : type_data_base { + const bitflags flags; + const number_type underlying_type; + + evalue_map evalues; + + template < enum_kind Enum > + static enum_type_data_ptr get(); + + template < enum_kind Enum > + explicit enum_type_data(type_list); + }; + + struct function_type_data final : type_data_base { + const bitflags flags; + const any_type return_type; + const std::vector argument_types; + + template < function_kind Function > + static function_type_data_ptr get(); + + template < function_kind Function > + explicit function_type_data(type_list); + }; + + struct member_type_data final : type_data_base { + const bitflags flags; + const class_type owner_type; + const any_type value_type; + + template < member_kind Member > + static member_type_data_ptr get(); + + template < member_kind Member > + explicit member_type_data(type_list); + }; + + struct method_type_data final : type_data_base { + const bitflags flags; + const class_type owner_type; + const any_type return_type; + const std::vector argument_types; + + template < method_kind Method > + static method_type_data_ptr get(); + + template < method_kind Method > + explicit method_type_data(type_list); + }; + + struct number_type_data final : type_data_base { + const bitflags flags; + const std::size_t size; + + template < number_kind Number > + static number_type_data_ptr get(); + + template < number_kind Number > + explicit number_type_data(type_list); + }; + + struct pointer_type_data final : type_data_base { + const bitflags flags; + const any_type data_type; + + template < pointer_kind Pointer > + static pointer_type_data_ptr get(); + + template < pointer_kind Pointer > + explicit pointer_type_data(type_list); + }; + + struct reference_type_data final : type_data_base { + const bitflags flags; + const any_type data_type; + + template < reference_kind Reference > + static reference_type_data_ptr get(); + + template < reference_kind Reference > + explicit reference_type_data(type_list); + }; + + struct void_type_data final : type_data_base { + const bitflags flags; + + template < void_kind Void > + static void_type_data_ptr get(); + + template < void_kind Void > + explicit void_type_data(type_list); + }; +} + +namespace meta_hpp +{ + struct ctor_index final { + const ctor_type type; + + explicit ctor_index(ctor_type type) + : type{std::move(type)} {} + + friend bool operator<(const ctor_index& l, const ctor_index& r) noexcept { + return l.type < r.type; + } + + friend bool operator==(const ctor_index& l, const ctor_index& r) noexcept { + return l.type == r.type; + } + }; + + struct evalue_index final { + const enum_type type; + const std::string name; + + explicit evalue_index(enum_type type, std::string name) + : type{std::move(type)} + , name{std::move(name)} {} + + friend bool operator<(const evalue_index& l, const evalue_index& r) noexcept { + return std::tie(l.type, l.name) < std::tie(r.type, r.name); + } + + friend bool operator==(const evalue_index& l, const evalue_index& r) noexcept { + return std::tie(l.type, l.name) == std::tie(r.type, r.name); + } + }; + + struct function_index final { + const function_type type; + const std::string name; + + explicit function_index(function_type type, std::string name) + : type{std::move(type)} + , name{std::move(name)} {} + + friend bool operator<(const function_index& l, const function_index& r) noexcept { + return std::tie(l.type, l.name) < std::tie(r.type, r.name); + } + + friend bool operator==(const function_index& l, const function_index& r) noexcept { + return std::tie(l.type, l.name) == std::tie(r.type, r.name); + } + }; + + struct member_index final { + const member_type type; + const std::string name; + + explicit member_index(member_type type, std::string name) + : type{std::move(type)} + , name{std::move(name)} {} + + friend bool operator<(const member_index& l, const member_index& r) noexcept { + return std::tie(l.type, l.name) < std::tie(r.type, r.name); + } + + friend bool operator==(const member_index& l, const member_index& r) noexcept { + return std::tie(l.type, l.name) == std::tie(r.type, r.name); + } + }; + + struct method_index final { + const method_type type; + const std::string name; + + explicit method_index(method_type type, std::string name) + : type{std::move(type)} + , name{std::move(name)} {} + + friend bool operator<(const method_index& l, const method_index& r) noexcept { + return std::tie(l.type, l.name) < std::tie(r.type, r.name); + } + + friend bool operator==(const method_index& l, const method_index& r) noexcept { + return std::tie(l.type, l.name) == std::tie(r.type, r.name); + } + }; + + struct scope_index final { + const std::string name; + + explicit scope_index(std::string name) + : name{std::move(name)} {} + + friend bool operator<(const scope_index& l, const scope_index& r) noexcept { + return l.name < r.name; + } + + friend bool operator==(const scope_index& l, const scope_index& r) noexcept { + return l.name == r.name; + } + }; + + struct variable_index final { + const pointer_type type; + const std::string name; + + explicit variable_index(pointer_type type, std::string name) + : type{std::move(type)} + , name{std::move(name)} {} + + friend bool operator<(const variable_index& l, const variable_index& r) noexcept { + return std::tie(l.type, l.name) < std::tie(r.type, r.name); + } + + friend bool operator==(const variable_index& l, const variable_index& r) noexcept { + return std::tie(l.type, l.name) == std::tie(r.type, r.name); + } + }; +} + +namespace meta_hpp +{ + namespace detail + { + template < typename T > + kind_type_data_ptr get_type_data() { + static_assert(!std::is_const_v && !std::is_volatile_v); + return kind_type_data::template get(); + } + } + + template < typename T > + auto resolve_type() { + using raw_type = std::remove_cv_t; + return detail::kind_type{detail::get_type_data()}; + } + + template < typename T > + auto resolve_type(T&&) { + using raw_type = std::remove_cvref_t; + return detail::kind_type{detail::get_type_data()}; + }; +} diff --git a/headers/meta.hpp/meta_types/any_type.hpp b/headers/meta.hpp/meta_types/any_type.hpp new file mode 100644 index 0000000..e876d21 --- /dev/null +++ b/headers/meta.hpp/meta_types/any_type.hpp @@ -0,0 +1,169 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_types.hpp" + +namespace meta_hpp +{ + inline any_type::any_type(detail::type_data_base_ptr data) + : data_{std::move(data)} {} + + inline bool any_type::is_valid() const noexcept { + return !!data_; + } + + inline any_type::operator bool() const noexcept { + return is_valid(); + } + + inline type_id any_type::get_id() const noexcept { + return data_->id; + } + + inline type_kind any_type::get_kind() const noexcept { + return data_->kind; + } + + inline any_type::any_type(const array_type& other) noexcept + : data_{other.data_} {} + + inline any_type::any_type(const class_type& other) noexcept + : data_{other.data_} {} + + inline any_type::any_type(const ctor_type& other) noexcept + : data_{other.data_} {} + + inline any_type::any_type(const enum_type& other) noexcept + : data_{other.data_} {} + + inline any_type::any_type(const function_type& other) noexcept + : data_{other.data_} {} + + inline any_type::any_type(const member_type& other) noexcept + : data_{other.data_} {} + + inline any_type::any_type(const method_type& other) noexcept + : data_{other.data_} {} + + inline any_type::any_type(const number_type& other) noexcept + : data_{other.data_} {} + + inline any_type::any_type(const pointer_type& other) noexcept + : data_{other.data_} {} + + inline any_type::any_type(const reference_type& other) noexcept + : data_{other.data_} {} + + inline any_type::any_type(const void_type& other) noexcept + : data_{other.data_} {} + + inline bool any_type::is_array() const noexcept { + return data_ && data_->kind == type_kind::array_; + } + + inline bool any_type::is_class() const noexcept { + return data_ && data_->kind == type_kind::class_; + } + + inline bool any_type::is_ctor() const noexcept { + return data_ && data_->kind == type_kind::ctor_; + } + + inline bool any_type::is_enum() const noexcept { + return data_ && data_->kind == type_kind::enum_; + } + + inline bool any_type::is_function() const noexcept { + return data_ && data_->kind == type_kind::function_; + } + + inline bool any_type::is_member() const noexcept { + return data_ && data_->kind == type_kind::member_; + } + + inline bool any_type::is_method() const noexcept { + return data_ && data_->kind == type_kind::method_; + } + + inline bool any_type::is_number() const noexcept { + return data_ && data_->kind == type_kind::number_; + } + + inline bool any_type::is_pointer() const noexcept { + return data_ && data_->kind == type_kind::pointer_; + } + + inline bool any_type::is_reference() const noexcept { + return data_ && data_->kind == type_kind::reference_; + } + + inline bool any_type::is_void() const noexcept { + return data_ && data_->kind == type_kind::void_; + } + + inline array_type any_type::as_array() const noexcept { + return is_array() + ? array_type{std::static_pointer_cast(data_)} + : array_type{}; + } + + inline class_type any_type::as_class() const noexcept { + return is_class() + ? class_type{std::static_pointer_cast(data_)} + : class_type{}; + } + + inline enum_type any_type::as_enum() const noexcept { + return is_enum() + ? enum_type{std::static_pointer_cast(data_)} + : enum_type{}; + } + + inline function_type any_type::as_function() const noexcept { + return is_function() + ? function_type{std::static_pointer_cast(data_)} + : function_type{}; + } + + inline member_type any_type::as_member() const noexcept { + return is_member() + ? member_type{std::static_pointer_cast(data_)} + : member_type{}; + } + + inline method_type any_type::as_method() const noexcept { + return is_method() + ? method_type{std::static_pointer_cast(data_)} + : method_type{}; + } + + inline number_type any_type::as_number() const noexcept { + return is_number() + ? number_type{std::static_pointer_cast(data_)} + : number_type{}; + } + + inline pointer_type any_type::as_pointer() const noexcept { + return is_pointer() + ? pointer_type{std::static_pointer_cast(data_)} + : pointer_type{}; + } + + inline reference_type any_type::as_reference() const noexcept { + return is_reference() + ? reference_type{std::static_pointer_cast(data_)} + : reference_type{}; + } + + inline void_type any_type::as_void() const noexcept { + return is_void() + ? void_type{std::static_pointer_cast(data_)} + : void_type{}; + } +} diff --git a/headers/meta.hpp/meta_types/array_type.hpp b/headers/meta.hpp/meta_types/array_type.hpp new file mode 100644 index 0000000..066a6a0 --- /dev/null +++ b/headers/meta.hpp/meta_types/array_type.hpp @@ -0,0 +1,61 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_types.hpp" + +#include "../meta_traits/array_traits.hpp" + +namespace meta_hpp::detail +{ + template < array_kind Array > + struct array_tag {}; + + template < array_kind Array > + array_type_data_ptr array_type_data::get() { + static array_type_data_ptr data = std::make_shared(type_list{}); + return data; + } + + template < array_kind Array > + array_type_data::array_type_data(type_list) + : type_data_base{type_id{type_list>{}}, type_kind::array_} + , flags{array_traits::make_flags()} + , extent{array_traits::extent} + , data_type{resolve_type::data_type>()} {} +} + +namespace meta_hpp +{ + inline array_type::array_type(detail::array_type_data_ptr data) + : data_{std::move(data)} {} + + inline bool array_type::is_valid() const noexcept { + return !!data_; + } + + inline array_type::operator bool() const noexcept { + return is_valid(); + } + + inline type_id array_type::get_id() const noexcept { + return data_->id; + } + + inline bitflags array_type::get_flags() const noexcept { + return data_->flags; + } + + inline std::size_t array_type::get_extent() const noexcept { + return data_->extent; + } + + inline any_type array_type::get_data_type() const noexcept { + return data_->data_type; + } +} diff --git a/headers/meta.hpp/meta_types/class_type.hpp b/headers/meta.hpp/meta_types/class_type.hpp new file mode 100644 index 0000000..58738e9 --- /dev/null +++ b/headers/meta.hpp/meta_types/class_type.hpp @@ -0,0 +1,332 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_types.hpp" + +#include "../meta_traits/class_traits.hpp" + +namespace meta_hpp::detail +{ + template < class_kind Class > + struct class_tag {}; + + template < class_kind Class > + class_type_data_ptr class_type_data::get() { + static class_type_data_ptr data = std::make_shared(type_list{}); + return data; + } + + template < class_kind Class > + class_type_data::class_type_data(type_list) + : type_data_base{type_id{type_list>{}}, type_kind::class_} + , flags{class_traits::make_flags()} + , size{class_traits::size} + , argument_types{class_traits::make_argument_types()} {} +} + +namespace meta_hpp +{ + inline class_type::class_type(detail::class_type_data_ptr data) + : data_{std::move(data)} {} + + inline bool class_type::is_valid() const noexcept { + return !!data_; + } + + inline class_type::operator bool() const noexcept { + return is_valid(); + } + + inline type_id class_type::get_id() const noexcept { + return data_->id; + } + + inline bitflags class_type::get_flags() const noexcept { + return data_->flags; + } + + inline std::size_t class_type::get_size() const noexcept { + return data_->size; + } + + inline std::size_t class_type::get_arity() const noexcept { + return data_->argument_types.size(); + } + + inline any_type class_type::get_argument_type(std::size_t index) const noexcept { + return index < data_->argument_types.size() ? data_->argument_types[index] : any_type{}; + } + + inline const std::vector& class_type::get_argument_types() const noexcept { + return data_->argument_types; + } + + inline const ctor_map& class_type::get_ctors() const noexcept { + return data_->ctors; + } + + inline const class_set& class_type::get_bases() const noexcept { + return data_->bases; + } + + inline const function_map& class_type::get_functions() const noexcept { + return data_->functions; + } + + inline const member_map& class_type::get_members() const noexcept { + return data_->members; + } + + inline const method_map& class_type::get_methods() const noexcept { + return data_->methods; + } + + inline const variable_map& class_type::get_variables() const noexcept { + return data_->variables; + } + + template < class_kind Derived > + bool class_type::is_base_of() const noexcept { + return is_base_of(resolve_type()); + } + + inline bool class_type::is_base_of(const class_type& derived) const noexcept { + return derived.data_ && derived.data_->bases.contains(*this); + } + + template < class_kind Base > + bool class_type::is_derived_from() const noexcept { + return is_derived_from(resolve_type()); + } + + inline bool class_type::is_derived_from(const class_type& base) const noexcept { + return data_ && data_->bases.contains(base); + } + + inline function class_type::get_function(std::string_view name) const noexcept { + for ( auto&& [index, function] : data_->functions ) { + if ( index.name == name ) { + return function; + } + } + + for ( auto&& base : data_->bases ) { + if ( function function = base.get_function(name); function ) { + return function; + } + } + + return function{}; + } + + inline member class_type::get_member(std::string_view name) const noexcept { + for ( auto&& [index, member] : data_->members ) { + if ( index.name == name ) { + return member; + } + } + + for ( auto&& base : data_->bases ) { + if ( member member = base.get_member(name); member ) { + return member; + } + } + + return member{}; + } + + inline method class_type::get_method(std::string_view name) const noexcept { + for ( auto&& [index, method] : data_->methods ) { + if ( index.name == name ) { + return method; + } + } + + for ( auto&& base : data_->bases ) { + if ( method method = base.get_method(name); method ) { + return method; + } + } + + return method{}; + } + + inline variable class_type::get_variable(std::string_view name) const noexcept { + for ( auto&& [index, variable] : data_->variables ) { + if ( index.name == name ) { + return variable; + } + } + + for ( auto&& base : data_->bases ) { + if ( variable variable = base.get_variable(name); variable ) { + return variable; + } + } + + return variable{}; + } + + // + // get_ctor_with + // + + template < typename... Args > + ctor class_type::get_ctor_with() const noexcept { + return get_ctor_with({resolve_type()...}); + } + + inline ctor class_type::get_ctor_with(std::vector args) const noexcept { + for ( auto&& [index, ctor] : data_->ctors ) { + if ( ctor.get_type().get_arity() != args.size() ) { + continue; + } + + const std::vector& ctor_args = ctor.get_type().get_argument_types(); + if ( std::equal(args.begin(), args.end(), ctor_args.begin(), ctor_args.end()) ) { + return ctor; + } + } + + return ctor{}; + } + + inline ctor class_type::get_ctor_with(std::initializer_list args) const noexcept { + for ( auto&& [index, ctor] : data_->ctors ) { + if ( ctor.get_type().get_arity() != args.size() ) { + continue; + } + + const std::vector& ctor_args = ctor.get_type().get_argument_types(); + if ( std::equal(args.begin(), args.end(), ctor_args.begin(), ctor_args.end()) ) { + return ctor; + } + } + + return ctor{}; + } + + // + // get_function_with + // + + template < typename... Args > + function class_type::get_function_with(std::string_view name) const noexcept { + return get_function_with(name, {resolve_type()...}); + } + + inline function class_type::get_function_with(std::string_view name, std::vector args) const noexcept { + for ( auto&& [index, function] : data_->functions ) { + if ( index.name != name ) { + continue; + } + + if ( function.get_type().get_arity() != args.size() ) { + continue; + } + + const std::vector& function_args = function.get_type().get_argument_types(); + if ( std::equal(args.begin(), args.end(), function_args.begin(), function_args.end()) ) { + return function; + } + } + + for ( auto&& base : data_->bases ) { + if ( function function = base.get_function_with(name, args); function ) { + return function; + } + } + + return function{}; + } + + inline function class_type::get_function_with(std::string_view name, std::initializer_list args) const noexcept { + for ( auto&& [index, function] : data_->functions ) { + if ( index.name != name ) { + continue; + } + + if ( function.get_type().get_arity() != args.size() ) { + continue; + } + + const std::vector& function_args = function.get_type().get_argument_types(); + if ( std::equal(args.begin(), args.end(), function_args.begin(), function_args.end()) ) { + return function; + } + } + + for ( auto&& base : data_->bases ) { + if ( function function = base.get_function_with(name, args); function ) { + return function; + } + } + + return function{}; + } + + // + // get_method_with + // + + template < typename... Args > + method class_type::get_method_with(std::string_view name) const noexcept { + return get_method_with(name, {resolve_type()...}); + } + + inline method class_type::get_method_with(std::string_view name, std::vector args) const noexcept { + for ( auto&& [index, method] : data_->methods ) { + if ( index.name != name ) { + continue; + } + + if ( method.get_type().get_arity() != args.size() ) { + continue; + } + + const std::vector& method_args = method.get_type().get_argument_types(); + if ( std::equal(args.begin(), args.end(), method_args.begin(), method_args.end()) ) { + return method; + } + } + + for ( auto&& base : data_->bases ) { + if ( method method = base.get_method_with(name, args); method ) { + return method; + } + } + + return method{}; + } + + inline method class_type::get_method_with(std::string_view name, std::initializer_list args) const noexcept { + for ( auto&& [index, method] : data_->methods ) { + if ( index.name != name ) { + continue; + } + + if ( method.get_type().get_arity() != args.size() ) { + continue; + } + + const std::vector& method_args = method.get_type().get_argument_types(); + if ( std::equal(args.begin(), args.end(), method_args.begin(), method_args.end()) ) { + return method; + } + } + + for ( auto&& base : data_->bases ) { + if ( method method = base.get_method_with(name, args); method ) { + return method; + } + } + + return method{}; + } +} diff --git a/headers/meta.hpp/meta_types/ctor_type.hpp b/headers/meta.hpp/meta_types/ctor_type.hpp new file mode 100644 index 0000000..1977d3a --- /dev/null +++ b/headers/meta.hpp/meta_types/ctor_type.hpp @@ -0,0 +1,69 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_types.hpp" + +#include "../meta_traits/ctor_traits.hpp" + +namespace meta_hpp::detail +{ + template < class_kind Class, typename... Args > + struct ctor_tag {}; + + template < class_kind Class, typename... Args > + ctor_type_data_ptr ctor_type_data::get() { + static ctor_type_data_ptr data = std::make_shared(type_list{}, type_list{}); + return data; + } + + template < class_kind Class, typename... Args > + ctor_type_data::ctor_type_data(type_list, type_list) + : type_data_base{type_id{type_list>{}}, type_kind::ctor_} + , flags{ctor_traits::make_flags()} + , class_type{resolve_type::class_type>()} + , argument_types{ctor_traits::make_argument_types()} {} +} + +namespace meta_hpp +{ + inline ctor_type::ctor_type(detail::ctor_type_data_ptr data) + : data_{std::move(data)} {} + + inline bool ctor_type::is_valid() const noexcept { + return !!data_; + } + + inline ctor_type::operator bool() const noexcept { + return is_valid(); + } + + inline type_id ctor_type::get_id() const noexcept { + return data_->id; + } + + inline bitflags ctor_type::get_flags() const noexcept { + return data_->flags; + } + + inline std::size_t ctor_type::get_arity() const noexcept { + return data_->argument_types.size(); + } + + inline any_type ctor_type::get_class_type() const noexcept { + return data_->class_type; + } + + inline any_type ctor_type::get_argument_type(std::size_t index) const noexcept { + return index < data_->argument_types.size() ? data_->argument_types[index] : any_type{}; + } + + inline const std::vector& ctor_type::get_argument_types() const noexcept { + return data_->argument_types; + } +} diff --git a/headers/meta.hpp/meta_types/enum_type.hpp b/headers/meta.hpp/meta_types/enum_type.hpp new file mode 100644 index 0000000..8a28611 --- /dev/null +++ b/headers/meta.hpp/meta_types/enum_type.hpp @@ -0,0 +1,93 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_types.hpp" + +#include "../meta_traits/enum_traits.hpp" + +namespace meta_hpp::detail +{ + template < enum_kind Enum > + struct enum_tag {}; + + template < enum_kind Enum > + enum_type_data_ptr enum_type_data::get() { + static enum_type_data_ptr data = std::make_shared(type_list{}); + return data; + } + + template < enum_kind Enum > + enum_type_data::enum_type_data(type_list) + : type_data_base{type_id{type_list>{}}, type_kind::enum_} + , flags{enum_traits::make_flags()} + , underlying_type{resolve_type::underlying_type>()} {} +} + +namespace meta_hpp +{ + inline enum_type::enum_type(detail::enum_type_data_ptr data) + : data_{std::move(data)} {} + + inline bool enum_type::is_valid() const noexcept { + return !!data_; + } + + inline enum_type::operator bool() const noexcept { + return is_valid(); + } + + inline type_id enum_type::get_id() const noexcept { + return data_->id; + } + + inline bitflags enum_type::get_flags() const noexcept { + return data_->flags; + } + + inline number_type enum_type::get_underlying_type() const noexcept { + return data_->underlying_type; + } + + inline const evalue_map& enum_type::get_evalues() const noexcept { + return data_->evalues; + } + + inline evalue enum_type::get_evalue(std::string_view name) const noexcept { + for ( auto&& [index, evalue] : data_->evalues ) { + if ( index.name == name ) { + return evalue; + } + } + return evalue{}; + } + + template < typename Value > + std::optional enum_type::value_to_name(Value&& value) const noexcept { + const detail::arg value_arg{std::forward(value)}; + + if ( value_arg.get_raw_type() != *this ) { + return std::nullopt; + } + + for ( auto&& evalue : data_->evalues ) { + if ( evalue.second.get_value() == value ) { + return evalue.second.get_index().name; + } + } + + return std::nullopt; + } + + inline std::optional enum_type::name_to_value(std::string_view name) const noexcept { + if ( const evalue value = get_evalue(name); value ) { + return value.get_value(); + } + return std::nullopt; + } +} diff --git a/headers/meta.hpp/meta_types/function_type.hpp b/headers/meta.hpp/meta_types/function_type.hpp new file mode 100644 index 0000000..e9cbf88 --- /dev/null +++ b/headers/meta.hpp/meta_types/function_type.hpp @@ -0,0 +1,69 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_types.hpp" + +#include "../meta_traits/function_traits.hpp" + +namespace meta_hpp::detail +{ + template < function_kind Function > + struct function_tag {}; + + template < function_kind Function > + function_type_data_ptr function_type_data::get() { + static function_type_data_ptr data = std::make_shared(type_list{}); + return data; + } + + template < function_kind Function > + function_type_data::function_type_data(type_list) + : type_data_base{type_id{type_list>{}}, type_kind::function_} + , flags{function_traits::make_flags()} + , return_type{resolve_type::return_type>()} + , argument_types{function_traits::make_argument_types()} {} +} + +namespace meta_hpp +{ + inline function_type::function_type(detail::function_type_data_ptr data) + : data_{std::move(data)} {} + + inline bool function_type::is_valid() const noexcept { + return !!data_; + } + + inline function_type::operator bool() const noexcept { + return is_valid(); + } + + inline type_id function_type::get_id() const noexcept { + return data_->id; + } + + inline bitflags function_type::get_flags() const noexcept { + return data_->flags; + } + + inline std::size_t function_type::get_arity() const noexcept { + return data_->argument_types.size(); + } + + inline any_type function_type::get_return_type() const noexcept { + return data_->return_type; + } + + inline any_type function_type::get_argument_type(std::size_t index) const noexcept { + return index < data_->argument_types.size() ? data_->argument_types[index] : any_type{}; + } + + inline const std::vector& function_type::get_argument_types() const noexcept { + return data_->argument_types; + } +} diff --git a/headers/meta.hpp/meta_types/member_type.hpp b/headers/meta.hpp/meta_types/member_type.hpp new file mode 100644 index 0000000..a3e8987 --- /dev/null +++ b/headers/meta.hpp/meta_types/member_type.hpp @@ -0,0 +1,61 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_types.hpp" + +#include "../meta_traits/member_traits.hpp" + +namespace meta_hpp::detail +{ + template < member_kind Member > + struct member_tag {}; + + template < member_kind Member > + member_type_data_ptr member_type_data::get() { + static member_type_data_ptr data = std::make_shared(type_list{}); + return data; + } + + template < member_kind Member > + member_type_data::member_type_data(type_list) + : type_data_base{type_id{type_list>{}}, type_kind::member_} + , flags{member_traits::make_flags()} + , owner_type{resolve_type::class_type>()} + , value_type{resolve_type::value_type>()} {} +} + +namespace meta_hpp +{ + inline member_type::member_type(detail::member_type_data_ptr data) + : data_{std::move(data)} {} + + inline bool member_type::is_valid() const noexcept { + return !!data_; + } + + inline member_type::operator bool() const noexcept { + return is_valid(); + } + + inline type_id member_type::get_id() const noexcept { + return data_->id; + } + + inline bitflags member_type::get_flags() const noexcept { + return data_->flags; + } + + inline class_type member_type::get_owner_type() const noexcept { + return data_->owner_type; + } + + inline any_type member_type::get_value_type() const noexcept { + return data_->value_type; + } +} diff --git a/headers/meta.hpp/meta_types/method_type.hpp b/headers/meta.hpp/meta_types/method_type.hpp new file mode 100644 index 0000000..8c60103 --- /dev/null +++ b/headers/meta.hpp/meta_types/method_type.hpp @@ -0,0 +1,74 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_types.hpp" + +#include "../meta_traits/method_traits.hpp" + +namespace meta_hpp::detail +{ + template < method_kind Method > + struct method_tag {}; + + template < method_kind Method > + method_type_data_ptr method_type_data::get() { + static method_type_data_ptr data = std::make_shared(type_list{}); + return data; + } + + template < method_kind Method > + method_type_data::method_type_data(type_list) + : type_data_base{type_id{type_list>{}}, type_kind::method_} + , flags{method_traits::make_flags()} + , owner_type{resolve_type::class_type>()} + , return_type{resolve_type::return_type>()} + , argument_types{method_traits::make_argument_types()} {} +} + +namespace meta_hpp +{ + inline method_type::method_type(detail::method_type_data_ptr data) + : data_{std::move(data)} {} + + inline bool method_type::is_valid() const noexcept { + return !!data_; + } + + inline method_type::operator bool() const noexcept { + return is_valid(); + } + + inline type_id method_type::get_id() const noexcept { + return data_->id; + } + + inline bitflags method_type::get_flags() const noexcept { + return data_->flags; + } + + inline std::size_t method_type::get_arity() const noexcept { + return data_->argument_types.size(); + } + + inline class_type method_type::get_owner_type() const noexcept { + return data_->owner_type; + } + + inline any_type method_type::get_return_type() const noexcept { + return data_->return_type; + } + + inline any_type method_type::get_argument_type(std::size_t index) const noexcept { + return index < data_->argument_types.size() ? data_->argument_types[index] : any_type{}; + } + + inline const std::vector& method_type::get_argument_types() const noexcept { + return data_->argument_types; + } +} diff --git a/headers/meta.hpp/meta_types/number_type.hpp b/headers/meta.hpp/meta_types/number_type.hpp new file mode 100644 index 0000000..b331bae --- /dev/null +++ b/headers/meta.hpp/meta_types/number_type.hpp @@ -0,0 +1,56 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_types.hpp" + +#include "../meta_traits/number_traits.hpp" + +namespace meta_hpp::detail +{ + template < number_kind Number > + struct number_tag {}; + + template < number_kind Number > + number_type_data_ptr number_type_data::get() { + static number_type_data_ptr data = std::make_shared(type_list{}); + return data; + } + + template < number_kind Number > + number_type_data::number_type_data(type_list) + : type_data_base{type_id{type_list>{}}, type_kind::number_} + , flags{number_traits::make_flags()} + , size{number_traits::size} {} +} + +namespace meta_hpp +{ + inline number_type::number_type(detail::number_type_data_ptr data) + : data_{std::move(data)} {} + + inline bool number_type::is_valid() const noexcept { + return !!data_; + } + + inline number_type::operator bool() const noexcept { + return is_valid(); + } + + inline type_id number_type::get_id() const noexcept { + return data_->id; + } + + inline bitflags number_type::get_flags() const noexcept { + return data_->flags; + } + + inline std::size_t number_type::get_size() const noexcept { + return data_->size; + } +} diff --git a/headers/meta.hpp/meta_types/pointer_type.hpp b/headers/meta.hpp/meta_types/pointer_type.hpp new file mode 100644 index 0000000..6741be1 --- /dev/null +++ b/headers/meta.hpp/meta_types/pointer_type.hpp @@ -0,0 +1,56 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_types.hpp" + +#include "../meta_traits/pointer_traits.hpp" + +namespace meta_hpp::detail +{ + template < pointer_kind Pointer > + struct pointer_tag {}; + + template < pointer_kind Pointer > + pointer_type_data_ptr pointer_type_data::get() { + static pointer_type_data_ptr data = std::make_shared(type_list{}); + return data; + } + + template < pointer_kind Pointer > + pointer_type_data::pointer_type_data(type_list) + : type_data_base{type_id{type_list>{}}, type_kind::pointer_} + , flags{pointer_traits::make_flags()} + , data_type{resolve_type::data_type>()} {} +} + +namespace meta_hpp +{ + inline pointer_type::pointer_type(detail::pointer_type_data_ptr data) + : data_{std::move(data)} {} + + inline bool pointer_type::is_valid() const noexcept { + return !!data_; + } + + inline pointer_type::operator bool() const noexcept { + return is_valid(); + } + + inline type_id pointer_type::get_id() const noexcept { + return data_->id; + } + + inline bitflags pointer_type::get_flags() const noexcept { + return data_->flags; + } + + inline any_type pointer_type::get_data_type() const noexcept { + return data_->data_type; + } +} diff --git a/headers/meta.hpp/meta_types/reference_type.hpp b/headers/meta.hpp/meta_types/reference_type.hpp new file mode 100644 index 0000000..f99bff8 --- /dev/null +++ b/headers/meta.hpp/meta_types/reference_type.hpp @@ -0,0 +1,56 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_types.hpp" + +#include "../meta_traits/reference_traits.hpp" + +namespace meta_hpp::detail +{ + template < reference_kind Reference > + struct reference_tag {}; + + template < reference_kind Reference > + reference_type_data_ptr reference_type_data::get() { + static reference_type_data_ptr data = std::make_shared(type_list{}); + return data; + } + + template < reference_kind Reference > + reference_type_data::reference_type_data(type_list) + : type_data_base{type_id{type_list>{}}, type_kind::reference_} + , flags{reference_traits::make_flags()} + , data_type{resolve_type::data_type>()} {} +} + +namespace meta_hpp +{ + inline reference_type::reference_type(detail::reference_type_data_ptr data) + : data_{std::move(data)} {} + + inline bool reference_type::is_valid() const noexcept { + return !!data_; + } + + inline reference_type::operator bool() const noexcept { + return is_valid(); + } + + inline type_id reference_type::get_id() const noexcept { + return data_->id; + } + + inline bitflags reference_type::get_flags() const noexcept { + return data_->flags; + } + + inline any_type reference_type::get_data_type() const noexcept { + return data_->data_type; + } +} diff --git a/headers/meta.hpp/meta_types/void_type.hpp b/headers/meta.hpp/meta_types/void_type.hpp new file mode 100644 index 0000000..8e04812 --- /dev/null +++ b/headers/meta.hpp/meta_types/void_type.hpp @@ -0,0 +1,51 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_types.hpp" + +#include "../meta_traits/void_traits.hpp" + +namespace meta_hpp::detail +{ + template < void_kind Void > + struct void_tag {}; + + template < void_kind Void > + void_type_data_ptr void_type_data::get() { + static void_type_data_ptr data = std::make_shared(type_list{}); + return data; + } + + template < void_kind Void > + void_type_data::void_type_data(type_list) + : type_data_base{type_id{type_list>{}}, type_kind::void_} + , flags{void_traits::make_flags()} {} +} + +namespace meta_hpp +{ + inline void_type::void_type(detail::void_type_data_ptr data) + : data_{std::move(data)} {} + + inline bool void_type::is_valid() const noexcept { + return !!data_; + } + + inline void_type::operator bool() const noexcept { + return is_valid(); + } + + inline type_id void_type::get_id() const noexcept { + return data_->id; + } + + inline bitflags void_type::get_flags() const noexcept { + return data_->flags; + } +} diff --git a/headers/meta.hpp/meta_utilities.hpp b/headers/meta.hpp/meta_utilities.hpp new file mode 100644 index 0000000..e59abc4 --- /dev/null +++ b/headers/meta.hpp/meta_utilities.hpp @@ -0,0 +1,238 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "meta_base.hpp" + +namespace meta_hpp +{ + class value final { + public: + value() = delete; + + value(value&& other); + value(const value& other); + + value& operator=(value&& other); + value& operator=(const value& other); + + template < typename T, typename Tp = std::decay_t + , std::enable_if_t, int> = 0 + , std::enable_if_t, int> = 0 + , std::enable_if_t, int> = 0 > + explicit value(T&& val); + + template < typename T, typename Tp = std::decay_t + , std::enable_if_t, int> = 0 + , std::enable_if_t, int> = 0 + , std::enable_if_t, int> = 0 > + value& operator=(T&& val); + + void swap(value& other) noexcept; + + const any_type& get_type() const noexcept; + + void* data() noexcept; + const void* data() const noexcept; + const void* cdata() const noexcept; + + template < typename T, typename Tp = std::decay_t > + Tp& cast() &; + + template < typename T, typename Tp = std::decay_t > + Tp&& cast() &&; + + template < typename T, typename Tp = std::decay_t > + const Tp& cast() const &; + + template < typename T, typename Tp = std::decay_t > + const Tp&& cast() const &&; + + template < typename T, typename Tp = std::decay_t > + Tp* try_cast() noexcept; + + template < typename T, typename Tp = std::decay_t > + const Tp* try_cast() const noexcept; + + template < typename T > + friend bool operator==(const value& l, const T& r); + template < typename T > + friend bool operator==(const T& l, const value& r); + friend bool operator==(const value& l, const value& r); + + friend std::istream& operator>>(std::istream& os, value& v); + friend std::ostream& operator<<(std::ostream& os, const value& v); + private: + struct traits; + std::any raw_{}; + const traits* traits_{}; + }; + + inline void swap(value& l, value& r) noexcept { + l.swap(r); + } +} + +namespace meta_hpp::detail +{ + class arg_base { + public: + enum class ref_types { + ref, + rref, + cref, + crref, + }; + public: + arg_base() = delete; + + arg_base(arg_base&&) = delete; + arg_base& operator=(arg_base&&) = delete; + + arg_base(const arg_base&) = delete; + arg_base& operator=(const arg_base&) = delete; + + template < typename T, std::enable_if_t< + std::is_pointer_v || std::is_lvalue_reference_v + , int> = 0 > + explicit arg_base(type_list); + + template < typename T, std::enable_if_t< + std::is_rvalue_reference_v || + (!std::is_pointer_v && !std::is_reference_v) + , int> = 0 > + explicit arg_base(type_list); + + explicit arg_base(value& v); + explicit arg_base(value&& v); + explicit arg_base(const value& v); + explicit arg_base(const value&& v); + + bool is_const() const noexcept; + bool is_lvalue() const noexcept; + bool is_rvalue() const noexcept; + + any_type get_raw_type() const noexcept; + ref_types get_ref_type() const noexcept; + + template < typename To > + bool can_cast_to() const noexcept; + private: + any_type raw_type_{}; + ref_types ref_type_{}; + }; +} + +namespace meta_hpp::detail +{ + class arg final : public arg_base { + public: + arg() = delete; + + arg(arg&&) = delete; + arg& operator=(arg&&) = delete; + + arg(const arg&) = delete; + arg& operator=(const arg&) = delete; + + template < typename T, typename Tp = std::decay_t + , std::enable_if_t, int> = 0 + , std::enable_if_t, int> = 0 + , std::enable_if_t, int> = 0 > + explicit arg(T&& v); + + explicit arg(value& v); + explicit arg(value&& v); + explicit arg(const value& v); + explicit arg(const value&& v); + + template < typename To > + To cast() const; + private: + void* data_{}; + }; +} + +namespace meta_hpp::detail +{ + class inst_base { + public: + enum class ref_types { + ref, + rref, + cref, + crref, + }; + public: + inst_base() = delete; + + inst_base(inst_base&&) = delete; + inst_base& operator=(inst_base&&) = delete; + + inst_base(const inst_base&) = delete; + inst_base& operator=(const inst_base&) = delete; + + template < typename T, std::enable_if_t< + std::is_lvalue_reference_v && std::is_class_v> + , int> = 0> + explicit inst_base(type_list); + + template < typename T, std::enable_if_t< + std::is_class_v || + (std::is_rvalue_reference_v && std::is_class_v>) + , int> = 0> + explicit inst_base(type_list); + + explicit inst_base(value& v); + explicit inst_base(value&& v); + explicit inst_base(const value& v); + explicit inst_base(const value&& v); + + bool is_const() const noexcept; + bool is_lvalue() const noexcept; + bool is_rvalue() const noexcept; + + any_type get_raw_type() const noexcept; + ref_types get_ref_type() const noexcept; + + template < typename To > + bool can_cast_to() const noexcept; + private: + any_type raw_type_{}; + ref_types ref_type_{}; + }; +} + +namespace meta_hpp::detail +{ + class inst final : public inst_base { + public: + inst() = delete; + + inst(inst&&) = delete; + inst& operator=(inst&&) = delete; + + inst(const inst&) = delete; + inst& operator=(const inst&) = delete; + + template < typename T, typename Tp = std::decay_t + , std::enable_if_t, int> = 0 + , std::enable_if_t, int> = 0 + , std::enable_if_t, int> = 0 > + explicit inst(T&& v); + + explicit inst(value& v); + explicit inst(value&& v); + explicit inst(const value& v); + explicit inst(const value&& v); + + template < typename To > + decltype(auto) cast() const; + private: + void* data_{}; + }; +} diff --git a/headers/meta.hpp/meta_utilities/arg.hpp b/headers/meta.hpp/meta_utilities/arg.hpp new file mode 100644 index 0000000..1679ebd --- /dev/null +++ b/headers/meta.hpp/meta_utilities/arg.hpp @@ -0,0 +1,205 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_utilities.hpp" + +namespace meta_hpp::detail +{ + template < typename T, std::enable_if_t< + std::is_pointer_v || std::is_lvalue_reference_v + , int> > + arg_base::arg_base(type_list) + : raw_type_{resolve_type>()} + , ref_type_{std::is_const_v> ? ref_types::cref : ref_types::ref} {} + + template < typename T, std::enable_if_t< + std::is_rvalue_reference_v || + (!std::is_pointer_v && !std::is_reference_v) + , int> > + arg_base::arg_base(type_list) + : raw_type_{resolve_type>()} + , ref_type_{std::is_const_v> ? ref_types::crref : ref_types::rref} {} + + inline arg_base::arg_base(value& v) + : raw_type_{v.get_type()} + , ref_type_{ref_types::ref} {} + + inline arg_base::arg_base(value&& v) + : raw_type_{v.get_type()} + , ref_type_{ref_types::rref} {} + + inline arg_base::arg_base(const value& v) + : raw_type_{v.get_type()} + , ref_type_{ref_types::cref} {} + + inline arg_base::arg_base(const value&& v) + : raw_type_{v.get_type()} + , ref_type_{ref_types::crref} {} + + inline bool arg_base::is_const() const noexcept { + return ref_type_ == ref_types::cref + || ref_type_ == ref_types::crref; + } + + inline bool arg_base::is_lvalue() const noexcept { + return ref_type_ == ref_types::ref + || ref_type_ == ref_types::cref; + } + + inline bool arg_base::is_rvalue() const noexcept { + return ref_type_ == ref_types::rref + || ref_type_ == ref_types::crref; + } + + inline any_type arg_base::get_raw_type() const noexcept { + return raw_type_; + } + + inline arg_base::ref_types arg_base::get_ref_type() const noexcept { + return ref_type_; + } + + template < typename To > + bool arg_base::can_cast_to() const noexcept { + if constexpr ( std::is_pointer_v ) { + using to_raw_type = std::remove_cv_t; + using to_raw_ptr_type = std::remove_cv_t>; + return get_raw_type() == resolve_type() + || get_raw_type() == resolve_type(); + } + + if constexpr ( std::is_reference_v ) { + constexpr bool to_const = std::is_const_v>; + + if constexpr ( !to_const ) { + if ( is_const() ) { + return false; + } + } + + if constexpr ( std::is_lvalue_reference_v ) { + if constexpr ( !to_const ) { + if ( is_rvalue() ) { + return false; + } + } + } + + if constexpr ( std::is_rvalue_reference_v ) { + if ( !is_rvalue() ) { + return false; + } + } + + using to_raw_type = std::remove_cvref_t; + if ( get_raw_type() == resolve_type() ) { + return true; + } + + if constexpr ( to_const && std::is_pointer_v ) { + using to_raw_ptr_type = std::remove_cv_t>; + return get_raw_type() == resolve_type(); + } + + return false; + } + + if constexpr ( !std::is_pointer_v && !std::is_reference_v ) { + using to_raw_type = std::remove_cv_t; + if ( get_raw_type() != resolve_type() ) { + return false; + } + + return (get_ref_type() == ref_types::ref && std::is_constructible_v) + || (get_ref_type() == ref_types::cref && std::is_constructible_v) + || (get_ref_type() == ref_types::rref && std::is_constructible_v) + || (get_ref_type() == ref_types::crref && std::is_constructible_v); + } + } +} + +namespace meta_hpp::detail +{ + template < typename T, typename Tp + , std::enable_if_t, int> + , std::enable_if_t, int> + , std::enable_if_t, int> > + arg::arg(T&& v) + : arg_base{type_list{}} + , data_{const_cast*>(std::addressof(v))} {} + + inline arg::arg(value& v) + : arg_base{v} + , data_{const_cast(v.data())} {} + + inline arg::arg(value&& v) + : arg_base{v} + , data_{const_cast(v.data())} {} + + inline arg::arg(const value& v) + : arg_base{v} + , data_{const_cast(v.data())} {} + + inline arg::arg(const value&& v) + : arg_base{v} + , data_{const_cast(v.data())} {} + + template < typename To > + To arg::cast() const { + if ( !can_cast_to() ) { + throw std::logic_error("bad argument cast"); + } + + if constexpr ( std::is_pointer_v ) { + return *static_cast(data_); + } + + if constexpr ( std::is_reference_v ) { + using raw_type = std::remove_cvref_t; + + if constexpr ( std::is_lvalue_reference_v ) { + return *static_cast(data_); + } + + if constexpr ( std::is_rvalue_reference_v ) { + return std::move(*static_cast(data_)); + } + } + + if constexpr ( !std::is_pointer_v && !std::is_reference_v ) { + using raw_type = std::remove_cv_t; + + if ( get_ref_type() == ref_types::ref ) { + if constexpr ( std::is_constructible_v ) { + return To{*static_cast(data_)}; + } + } + + if ( get_ref_type() == ref_types::cref ) { + if constexpr ( std::is_constructible_v ) { + return To{std::as_const(*static_cast(data_))}; + } + } + + if ( get_ref_type() == ref_types::rref ) { + if constexpr ( std::is_constructible_v ) { + return To{std::move(*static_cast(data_))}; + } + } + + if ( get_ref_type() == ref_types::crref ) { + if constexpr ( std::is_constructible_v ) { + return To{std::move(std::as_const(*static_cast(data_)))}; + } + } + } + + throw std::logic_error("bad argument cast"); + } +} diff --git a/headers/meta.hpp/meta_utilities/inst.hpp b/headers/meta.hpp/meta_utilities/inst.hpp new file mode 100644 index 0000000..fdd374b --- /dev/null +++ b/headers/meta.hpp/meta_utilities/inst.hpp @@ -0,0 +1,148 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_utilities.hpp" + +namespace meta_hpp::detail +{ + template < typename T, std::enable_if_t< + std::is_lvalue_reference_v && std::is_class_v> + , int> > + inst_base::inst_base(type_list) + : raw_type_{resolve_type>()} + , ref_type_{std::is_const_v> ? ref_types::cref : ref_types::ref} {} + + template < typename T, std::enable_if_t< + std::is_class_v || + (std::is_rvalue_reference_v && std::is_class_v>) + , int> > + inst_base::inst_base(type_list) + : raw_type_{resolve_type>()} + , ref_type_{std::is_const_v> ? ref_types::crref : ref_types::rref} {} + + inline inst_base::inst_base(value& v) + : raw_type_{v.get_type()} + , ref_type_{ref_types::ref} {} + + inline inst_base::inst_base(value&& v) + : raw_type_{v.get_type()} + , ref_type_{ref_types::rref} {} + + inline inst_base::inst_base(const value& v) + : raw_type_{v.get_type()} + , ref_type_{ref_types::cref} {} + + inline inst_base::inst_base(const value&& v) + : raw_type_{v.get_type()} + , ref_type_{ref_types::crref} {} + + inline bool inst_base::is_const() const noexcept { + return ref_type_ == ref_types::cref + || ref_type_ == ref_types::crref; + } + + inline bool inst_base::is_lvalue() const noexcept { + return ref_type_ == ref_types::ref + || ref_type_ == ref_types::cref; + } + + inline bool inst_base::is_rvalue() const noexcept { + return ref_type_ == ref_types::rref + || ref_type_ == ref_types::crref; + } + + inline any_type inst_base::get_raw_type() const noexcept { + return raw_type_; + } + + inline inst_base::ref_types inst_base::get_ref_type() const noexcept { + return ref_type_; + } + + template < typename To > + bool inst_base::can_cast_to() const noexcept { + static_assert( + std::is_class_v || + (std::is_reference_v && std::is_class_v>)); + + constexpr bool to_const = std::is_const_v>; + + if constexpr ( !to_const ) { + if ( is_const() ) { + return false; + } + } + + if constexpr ( std::is_lvalue_reference_v ) { + if ( !is_lvalue() ) { + return false; + } + } + + if constexpr ( std::is_rvalue_reference_v ) { + if ( !is_rvalue() ) { + return false; + } + } + + using to_raw_type = std::remove_cvref_t; + return get_raw_type() == resolve_type(); + } +} + +namespace meta_hpp::detail +{ + template < typename T, typename Tp + , std::enable_if_t, int> + , std::enable_if_t, int> + , std::enable_if_t, int> > + inst::inst(T&& v) + : inst_base{type_list{}} + , data_{const_cast*>(std::addressof(v))} {} + + inline inst::inst(value& v) + : inst_base{v} + , data_{const_cast(v.data())} {} + + inline inst::inst(value&& v) + : inst_base{v} + , data_{const_cast(v.data())} {} + + inline inst::inst(const value& v) + : inst_base{v} + , data_{const_cast(v.data())} {} + + inline inst::inst(const value&& v) + : inst_base{v} + , data_{const_cast(v.data())} {} + + template < typename To > + decltype(auto) inst::cast() const { + if ( !can_cast_to() ) { + throw std::logic_error("bad inst cast"); + } + + if constexpr ( std::is_reference_v ) { + using raw_type_with_cv = std::remove_reference_t; + + if constexpr ( std::is_lvalue_reference_v ) { + return *static_cast(data_); + } + + if constexpr ( std::is_rvalue_reference_v ) { + return std::move(*static_cast(data_)); + } + } + + if constexpr ( !std::is_reference_v) { + using raw_type_with_cv = To; + return *static_cast(data_); + } + } +} diff --git a/headers/meta.hpp/meta_utilities/value.hpp b/headers/meta.hpp/meta_utilities/value.hpp new file mode 100644 index 0000000..14304ae --- /dev/null +++ b/headers/meta.hpp/meta_utilities/value.hpp @@ -0,0 +1,306 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_utilities.hpp" + +namespace meta_hpp::detail +{ + template < typename T, typename = void > + struct has_value_type_equality_operator + : std::false_type {}; + + template < typename T > + struct has_value_type_equality_operator() == std::declval() + )>> : std::true_type {}; + + template < typename T > + inline constexpr bool has_value_type_equality_operator_v = has_value_type_equality_operator::value; + + template < typename T, std::enable_if_t< + has_value_type_equality_operator_v + , int> = 0 > + bool value_equals_function(const value& l, const value& r) { + assert(l.get_type() == r.get_type()); + return l.cast() == r.cast(); + } + + template < typename T, std::enable_if_t< + !has_value_type_equality_operator_v + , int> = 0 > + bool value_equals_function([[maybe_unused]] const value& l, [[maybe_unused]] const value& r) { + throw std::logic_error("value type doesn't have equality operator"); + } +} + +namespace meta_hpp::detail +{ + template < typename T, typename = void > + struct has_value_type_istream_operator + : std::false_type {}; + + template < typename T > + struct has_value_type_istream_operator() >> std::declval() + )>> : std::true_type {}; + + template < typename T > + inline constexpr bool has_value_type_istream_operator_v = has_value_type_istream_operator::value; + + template < typename T, std::enable_if_t< + has_value_type_istream_operator_v + , int> = 0 > + void value_istream_function(std::istream& os, value& v) { + os >> v.cast(); + } + + template < typename T, std::enable_if_t< + !has_value_type_istream_operator_v + , int> = 0 > + void value_istream_function([[maybe_unused]] std::istream& os, [[maybe_unused]] value& v) { + throw std::logic_error("value type doesn't have istream operator"); + } +} + +namespace meta_hpp::detail +{ + template < typename T, typename = void > + struct has_value_type_ostream_operator + : std::false_type {}; + + template < typename T > + struct has_value_type_ostream_operator() << std::declval() + )>> : std::true_type {}; + + template < typename T > + inline constexpr bool has_value_type_ostream_operator_v = has_value_type_ostream_operator::value; + + template < typename T, std::enable_if_t< + has_value_type_ostream_operator_v + , int> = 0 > + void value_ostream_function(std::ostream& os, const value& v) { + os << v.cast(); + } + + template < typename T, std::enable_if_t< + !has_value_type_ostream_operator_v + , int> = 0 > + void value_ostream_function([[maybe_unused]] std::ostream& os, [[maybe_unused]] const value& v) { + throw std::logic_error("value type doesn't have ostream operator"); + } +} + +namespace meta_hpp +{ + struct value::traits final { + const any_type type; + + void* (*const data)(value&) noexcept; + const void* (*const cdata)(const value&) noexcept; + + bool (*const equals)(const value&, const value&); + + void (*const move_ctor)(std::any&, value&&); + void (*const copy_ctor)(std::any&, const value&); + + void (*const istream)(std::istream&, value&); + void (*const ostream)(std::ostream&, const value&); + + template < typename T > + static const traits* get() noexcept; + }; + + template < typename T > + const value::traits* value::traits::get() noexcept { + static const traits traits{ + // type + resolve_type(), + + // data + +[](value& v) noexcept -> void* { + return v.try_cast(); + }, + + // cdata + +[](const value& v) noexcept -> const void* { + return v.try_cast(); + }, + + // equals + &detail::value_equals_function, + + // move_ctor + +[](std::any& dst, value&& src) { + if constexpr ( std::is_move_constructible_v ) { + dst.emplace(std::move(src).cast()); + } else { + throw std::logic_error("value type is not move constructible"); + } + }, + + // copy_ctor + +[](std::any& dst, const value& src) { + if constexpr ( std::is_copy_constructible_v ) { + dst.emplace(src.cast()); + } else { + throw std::logic_error("value type is not copy constructible"); + } + }, + + // istream + &detail::value_istream_function, + + // ostream + &detail::value_ostream_function, + }; + return &traits; + } +} + +namespace meta_hpp +{ + inline value::value(value&& other) { + traits_ = other.traits_; + traits_->move_ctor(raw_, std::move(other)); + } + + inline value::value(const value& other) { + traits_ = other.traits_; + traits_->copy_ctor(raw_, other); + } + + inline value& value::operator=(value&& other) { + if ( this != &other ) { + traits_ = other.traits_; + traits_->move_ctor(raw_, std::move(other)); + } + return *this; + } + + inline value& value::operator=(const value& other) { + if ( this != &other ) { + traits_ = other.traits_; + traits_->copy_ctor(raw_, other); + } + return *this; + } + + template < typename T, typename Tp + , std::enable_if_t, int> + , std::enable_if_t, int> + , std::enable_if_t, int> > + value::value(T&& val) + : raw_{std::forward(val)} + , traits_{traits::get()} {} + + template < typename T, typename Tp + , std::enable_if_t, int> + , std::enable_if_t, int> + , std::enable_if_t, int> > + value& value::operator=(T&& val) { + raw_ = std::forward(val); + traits_ = resolve_type(); + return *this; + } + + inline void value::swap(value& other) noexcept { + using std::swap; + swap(raw_, other.raw_); + swap(traits_, other.traits_); + } + + inline const any_type& value::get_type() const noexcept { + return traits_->type; + } + + inline void* value::data() noexcept { + return traits_->data(*this); + } + + inline const void* value::data() const noexcept { + return traits_->cdata(*this); + } + + inline const void* value::cdata() const noexcept { + return traits_->cdata(*this); + } + + template < typename T, typename Tp > + Tp& value::cast() & { + if ( get_type() != resolve_type() ) { + throw std::logic_error("bad value cast"); + } + return std::any_cast(raw_); + } + + template < typename T, typename Tp > + Tp&& value::cast() && { + if ( get_type() != resolve_type() ) { + throw std::logic_error("bad value cast"); + } + return std::move(std::any_cast(raw_)); + } + + template < typename T, typename Tp > + const Tp& value::cast() const & { + if ( get_type() != resolve_type() ) { + throw std::logic_error("bad value cast"); + } + return std::any_cast(raw_); + } + + template < typename T, typename Tp > + const Tp&& value::cast() const && { + if ( get_type() != resolve_type() ) { + throw std::logic_error("bad value cast"); + } + return std::move(std::any_cast(raw_)); + } + + template < typename T, typename Tp > + Tp* value::try_cast() noexcept { + return std::any_cast(&raw_); + } + + template < typename T, typename Tp > + const Tp* value::try_cast() const noexcept { + return std::any_cast(&raw_); + } +} + +namespace meta_hpp +{ + template < typename T > + bool operator==(const value& l, const T& r) { + return l.get_type() == resolve_type() + && std::equal_to<>{}(l.cast(), r); + } + + template < typename T > + bool operator==(const T& l, const value& r) { + return resolve_type() == r.get_type() + && std::equal_to<>{}(l, r.cast()); + } + + inline bool operator==(const value& l, const value& r) { + return l.get_type() == r.get_type() + && l.traits_->equals(l, r); + } + + inline std::istream& operator>>(std::istream& is, value& v) { + v.traits_->istream(is, v); + return is; + } + + inline std::ostream& operator<<(std::ostream& os, const value& v) { + v.traits_->ostream(os, v); + return os; + } +} diff --git a/untests/examples/class_example.cpp b/untests/examples/class_example.cpp new file mode 100644 index 0000000..e2d1eab --- /dev/null +++ b/untests/examples/class_example.cpp @@ -0,0 +1,38 @@ +/******************************************************************************* + * 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_tests.hpp" + +namespace +{ + struct base_clazz { + }; + + struct derived_clazz final : base_clazz { + }; +} + +TEST_CASE("meta/examples/class") { + namespace meta = meta_hpp; + + meta::class_() + .base_(); + + const meta::class_type base_clazz_type = meta::resolve_type(); + REQUIRE(base_clazz_type); + + const meta::class_type derived_clazz_type = meta::resolve_type(); + REQUIRE(derived_clazz_type); + + CHECK(base_clazz_type.is_base_of()); + CHECK(derived_clazz_type.is_derived_from()); + + const meta::class_type int_vector_type = meta::resolve_type>(); + REQUIRE(int_vector_type); + CHECK(int_vector_type.get_arity() == 2); + CHECK(int_vector_type.get_argument_type(0) == meta::resolve_type()); + CHECK(int_vector_type.get_argument_type(1) == meta::resolve_type>()); +} diff --git a/untests/examples/complex_example.cpp b/untests/examples/complex_example.cpp new file mode 100644 index 0000000..47ebd85 --- /dev/null +++ b/untests/examples/complex_example.cpp @@ -0,0 +1,99 @@ +/******************************************************************************* + * 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_tests.hpp" + +namespace +{ + struct ivec2 { + int x{}; + int y{}; + + ivec2() = default; + ivec2(int v) : x{v}, y{v} {} + ivec2(int x, int y) : x{x}, y{y} {} + + int dot(const ivec2& other) const noexcept { + return x * other.x + y * other.y; + } + + int length2() const noexcept { + return dot(*this); + } + + friend bool operator==(const ivec2& l, const ivec2& r) noexcept { + return l.x == r.x && l.y == r.y; + } + }; +} + +TEST_CASE("meta/examples/complex") { + namespace meta = meta_hpp; + + meta::class_() + .ctor_<>() + .ctor_() + .ctor_() + .member_("x", &ivec2::x) + .member_("y", &ivec2::y) + .method_("dot", &ivec2::dot) + .method_("length2", &ivec2::length2); + + const meta::class_type ivec2_type = meta::resolve_type(); + + const meta::member ivec2_x = ivec2_type.get_member("x"); + const meta::member ivec2_y = ivec2_type.get_member("y"); + + const meta::method ivec2_dot = ivec2_type.get_method("dot"); + const meta::method ivec2_length2 = ivec2_type.get_method("length2"); + + { + const ivec2 v = ivec2_type.get_ctor_with<>().invoke().cast(); + CHECK(v == ivec2{}); + + CHECK(ivec2_x.get(v) == 0); + CHECK(ivec2_y.get(v) == 0); + } + + { + const ivec2 v = ivec2_type.get_ctor_with().invoke(3).cast(); + CHECK(v == ivec2{3}); + + CHECK(ivec2_x.get(v) == 3); + CHECK(ivec2_y.get(v) == 3); + } + + { + const meta::value v = ivec2_type.get_ctor_with().invoke(1, 2); + CHECK(v == ivec2{1, 2}); + + CHECK(ivec2_x.get(v) == 1); + CHECK(ivec2_y.get(v) == 2); + } + + { + meta::value v = ivec2_type.get_ctor_with().invoke(1, 2); + + ivec2_x.set(v, 10); + ivec2_y.set(v, 20); + + CHECK(ivec2_x.get(v) == 10); + CHECK(ivec2_y.get(v) == 20); + } + + { + const meta::value v0 = ivec2_type.get_ctor_with().invoke(1, 2); + const meta::value v1 = ivec2_type.get_ctor_with().invoke(3, 4); + + CHECK(ivec2_dot.invoke(v0, v1) == 1 * 3 + 2 * 4); + } + + { + const meta::value v = ivec2_type.get_ctor_with().invoke(3, 4); + + CHECK(ivec2_length2.invoke(v) == 3 * 3 + 4 * 4); + } +} diff --git a/untests/examples/enum_example.cpp b/untests/examples/enum_example.cpp new file mode 100644 index 0000000..7402e25 --- /dev/null +++ b/untests/examples/enum_example.cpp @@ -0,0 +1,36 @@ +/******************************************************************************* + * 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_tests.hpp" + +namespace +{ + enum class color : unsigned { + red = 0xFF0000, + green = 0x00FF00, + blue = 0x0000FF, + white = red | green | blue, + }; +} + +TEST_CASE("meta/examples/enum") { + namespace meta = meta_hpp; + + meta::enum_() + .evalue_("red", color::red) + .evalue_("green", color::green) + .evalue_("blue", color::blue) + .evalue_("white", color::white); + + meta::enum_type color_type = meta::resolve_type(); + REQUIRE(color_type); + + CHECK(color_type.get_underlying_type() == meta::resolve_type()); + + CHECK(color_type.get_evalue("green").get_index().name == "green"); + CHECK(color_type.get_evalue("green").get_value() == color::green); + CHECK_FALSE(color_type.get_evalue("yellow")); +} diff --git a/untests/examples/member_example.cpp b/untests/examples/member_example.cpp new file mode 100644 index 0000000..7f239ee --- /dev/null +++ b/untests/examples/member_example.cpp @@ -0,0 +1,37 @@ +/******************************************************************************* + * 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_tests.hpp" + +namespace +{ + struct ivec2 final { + int x{}; + int y{}; + }; +} + +TEST_CASE("meta/examples/member") { + namespace meta = meta_hpp; + + meta::class_() + .member_("x", &ivec2::x) + .member_("y", &ivec2::y); + + const meta::class_type ivec2_type = meta::resolve_type(); + REQUIRE(ivec2_type); + + CHECK(ivec2_type.get_members().size() == 2); + + const meta::member ivec2_x = ivec2_type.get_member("x"); + REQUIRE(ivec2_x); + + CHECK(ivec2_x.get_index().name == "x"); + CHECK(ivec2_x.get_type() == meta::resolve_type()); + + CHECK(ivec2_x.get_type().get_owner_type() == meta::resolve_type()); + CHECK(ivec2_x.get_type().get_value_type() == meta::resolve_type()); +} diff --git a/untests/examples/method_example.cpp b/untests/examples/method_example.cpp new file mode 100644 index 0000000..308876b --- /dev/null +++ b/untests/examples/method_example.cpp @@ -0,0 +1,48 @@ +/******************************************************************************* + * 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_tests.hpp" + +namespace +{ + struct ivec2 final { + int x{}; + int y{}; + + int dot(const ivec2& other) const noexcept { + return x * other.x + y * other.y; + } + + int length2() const noexcept { + return dot(*this); + } + }; +} + +TEST_CASE("meta/examples/method") { + namespace meta = meta_hpp; + + meta::class_() + .member_("x", &ivec2::x) + .member_("y", &ivec2::y) + .method_("dot", &ivec2::dot) + .method_("length2", &ivec2::length2); + + const meta::class_type ivec2_type = meta::resolve_type(); + REQUIRE(ivec2_type); + + CHECK(ivec2_type.get_methods().size() == 2); + + const meta::method ivec2_dot = ivec2_type.get_method("dot"); + REQUIRE(ivec2_dot); + + CHECK(ivec2_dot.get_index().name == "dot"); + CHECK(ivec2_dot.get_type() == meta::resolve_type()); + + CHECK(ivec2_dot.get_type().get_arity() == 1); + CHECK(ivec2_dot.get_type().get_return_type() == meta::resolve_type()); + CHECK(ivec2_dot.get_type().get_argument_type(0) == meta::resolve_type()); +} diff --git a/untests/examples/number_example.cpp b/untests/examples/number_example.cpp new file mode 100644 index 0000000..877dabc --- /dev/null +++ b/untests/examples/number_example.cpp @@ -0,0 +1,31 @@ +/******************************************************************************* + * 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_tests.hpp" + +namespace +{ +} + +TEST_CASE("meta/examples/number") { + namespace meta = meta_hpp; + + { + const meta::number_type int_type = meta::resolve_type(); + REQUIRE(int_type); + + CHECK(int_type.get_flags().has(meta::number_flags::is_signed)); + CHECK(int_type.get_size() == sizeof(int)); + } + + { + const meta::number_type unsigned_type = meta::resolve_type(); + REQUIRE(unsigned_type); + + CHECK(unsigned_type.get_flags().has(meta::number_flags::is_unsigned)); + CHECK(unsigned_type.get_size() == sizeof(unsigned)); + } +} diff --git a/untests/meta_states/evalue_tests.cpp b/untests/meta_states/evalue_tests.cpp new file mode 100644 index 0000000..ef420a0 --- /dev/null +++ b/untests/meta_states/evalue_tests.cpp @@ -0,0 +1,58 @@ +/******************************************************************************* + * 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_tests.hpp" + +namespace +{ + enum class color : unsigned { + red = 0xFF0000, + green = 0x00FF00, + blue = 0x0000FF, + white = red | green | blue, + }; +} + +TEST_CASE("meta/meta_states/evalue") { + namespace meta = meta_hpp; + + meta::enum_() + .evalue_("red", color::red) + .evalue_("green", color::green) + .evalue_("blue", color::blue) + .evalue_("white", color::white); + + const meta::enum_type color_type = meta::resolve_type(); + REQUIRE(color_type); + + SUBCASE("") { + const meta::evalue evalue; + CHECK_FALSE(evalue); + CHECK_FALSE(evalue.is_valid()); + CHECK(evalue == color_type.get_evalue("non-existent-evalue")); + } + + SUBCASE("operators") { + const meta::evalue blue_e = color_type.get_evalue("blue"); + const meta::evalue white_e = color_type.get_evalue("white"); + CHECK(blue_e == blue_e); + CHECK(blue_e != white_e); + CHECK((blue_e < white_e || white_e < blue_e)); + } + + SUBCASE("green") { + const meta::evalue evalue = color_type.get_evalue("green"); + REQUIRE(evalue); + + CHECK(evalue.get_index().type == evalue.get_type()); + CHECK(evalue.get_index().name == "green"); + + CHECK(evalue.get_type() == meta::resolve_type()); + CHECK(evalue.get_name() == "green"); + + CHECK(evalue.get_value() == color::green); + } +} diff --git a/untests/meta_states/function_tests.cpp b/untests/meta_states/function_tests.cpp new file mode 100644 index 0000000..6069fc9 --- /dev/null +++ b/untests/meta_states/function_tests.cpp @@ -0,0 +1,107 @@ +/******************************************************************************* + * 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_tests.hpp" + +namespace +{ + struct ivec2 { + int x{}; + int y{}; + + static ivec2 iadd(const ivec2& l, const ivec2& r) noexcept { + return {l.x + r.x, l.y + r.y}; + } + + static int ilength2(const ivec2& v) noexcept { + return v.x * v.x + v.y * v.y; + } + }; + + bool operator==(const ivec2& l, const ivec2& r) noexcept { + return l.x == r.x && l.y == r.y; + } +} + +TEST_CASE("meta/meta_states/function") { + namespace meta = meta_hpp; + + meta::class_() + .function_("iadd", &ivec2::iadd) + .function_("ilength2", &ivec2::ilength2); + + const meta::class_type ivec2_type = meta::resolve_type(); + REQUIRE(ivec2_type); + + SUBCASE("") { + const meta::function func; + CHECK_FALSE(func); + CHECK_FALSE(func.is_valid()); + CHECK(func == ivec2_type.get_function("non-existent-function")); + } + + SUBCASE("operators") { + const meta::function iadd_f = ivec2_type.get_function("iadd"); + const meta::function ilength2_f = ivec2_type.get_function("ilength2"); + CHECK(iadd_f == iadd_f); + CHECK(iadd_f != ilength2_f); + CHECK((iadd_f < ilength2_f || ilength2_f < iadd_f)); + } + + SUBCASE("iadd") { + const meta::function func = ivec2_type.get_function("iadd"); + REQUIRE(func); + + CHECK(func.get_index().type == func.get_type()); + CHECK(func.get_index().name == "iadd"); + + CHECK(func.get_type() == meta::resolve_type(&ivec2::iadd)); + CHECK(func.get_name() == "iadd"); + + CHECK_FALSE(func.is_invocable_with<>()); + CHECK_FALSE(func.is_invocable_with()); + CHECK_FALSE(func.is_invocable_with()); + CHECK_FALSE(func.is_invocable_with()); + CHECK_FALSE(func.is_invocable_with()); + + 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(func.invoke(ivec2{1,2}, ivec2{3,4})); + CHECK(func.invoke(ivec2{1,2}, ivec2{3,4}).value() == ivec2{4,6}); + } + + SUBCASE("ilength2") { + const meta::function func = ivec2_type.get_function("ilength2"); + REQUIRE(func); + + CHECK(func.get_index().type == func.get_type()); + CHECK(func.get_index().name == "ilength2"); + + CHECK(func.get_type() == meta::resolve_type(&ivec2::ilength2)); + CHECK(func.get_name() == "ilength2"); + + CHECK_FALSE(func.is_invocable_with<>()); + CHECK_FALSE(func.is_invocable_with()); + CHECK_FALSE(func.is_invocable_with()); + + 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(func.invoke(ivec2{2,3})); + CHECK(func.invoke(ivec2{2,3}).value() == 13); + } +} diff --git a/untests/meta_states/member_tests.cpp b/untests/meta_states/member_tests.cpp new file mode 100644 index 0000000..2d771de --- /dev/null +++ b/untests/meta_states/member_tests.cpp @@ -0,0 +1,81 @@ +/******************************************************************************* + * 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_tests.hpp" + +namespace +{ + struct clazz_1 { + int int_member = 1; + const int const_int_member = 2; + }; +} + +TEST_CASE("meta/meta_states/member") { + namespace meta = meta_hpp; + + meta::class_() + .member_("int_member", &clazz_1::int_member) + .member_("const_int_member", &clazz_1::const_int_member); + + const meta::class_type clazz_1_type = meta::resolve_type(); + REQUIRE(clazz_1_type); + + SUBCASE("") { + const meta::member member; + CHECK_FALSE(member); + CHECK_FALSE(member.is_valid()); + CHECK(member == clazz_1_type.get_member("non-existent-member")); + } + + SUBCASE("operators") { + meta::member int_member_m = clazz_1_type.get_member("int_member"); + meta::member const_int_member_m = clazz_1_type.get_member("const_int_member"); + CHECK(int_member_m == int_member_m); + CHECK(int_member_m != const_int_member_m); + CHECK((int_member_m < const_int_member_m || const_int_member_m < int_member_m)); + } + + SUBCASE("int") { + meta::member vm = clazz_1_type.get_member("int_member"); + REQUIRE(vm); + + CHECK(vm.get_type() == meta::resolve_type(&clazz_1::int_member)); + CHECK(vm.get_name() == "int_member"); + + clazz_1 v; + + CHECK(vm.get(v) == 1); + CHECK(vm.get(std::as_const(v)) == 1); + CHECK(vm.get(std::move(v)) == 1); + CHECK(vm.get(std::move(std::as_const(v))) == 1); + + CHECK_NOTHROW(vm.set(v, 10)); CHECK(vm.get(v) == 10); + CHECK_THROWS(vm.set(std::as_const(v), 11)); CHECK(vm.get(v) == 10); + CHECK_NOTHROW(vm.set(std::move(v), 12)); CHECK(vm.get(v) == 12); + CHECK_THROWS(vm.set(std::move(std::as_const(v)), 13)); CHECK(vm.get(v) == 12); + } + + SUBCASE("const int") { + meta::member vm = clazz_1_type.get_member("const_int_member"); + REQUIRE(vm); + + CHECK(vm.get_type() == meta::resolve_type(&clazz_1::const_int_member)); + CHECK(vm.get_name() == "const_int_member"); + + clazz_1 v; + + CHECK(vm.get(v) == 2); + CHECK(vm.get(std::as_const(v)) == 2); + CHECK(vm.get(std::move(v)) == 2); + CHECK(vm.get(std::move(std::as_const(v))) == 2); + + CHECK_THROWS(vm.set(v, 10)); CHECK(vm.get(v) == 2); + CHECK_THROWS(vm.set(std::as_const(v), 11)); CHECK(vm.get(v) == 2); + CHECK_THROWS(vm.set(std::move(v), 12)); CHECK(vm.get(v) == 2); + CHECK_THROWS(vm.set(std::move(std::as_const(v)), 13)); CHECK(vm.get(v) == 2); + } +} diff --git a/untests/meta_states/method_tests.cpp b/untests/meta_states/method_tests.cpp new file mode 100644 index 0000000..7258f3b --- /dev/null +++ b/untests/meta_states/method_tests.cpp @@ -0,0 +1,829 @@ +/******************************************************************************* + * 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_tests.hpp" + +namespace +{ + struct clazz { + clazz() = default; + + clazz(clazz&&) = delete; + clazz(const clazz&) = delete; + + clazz& operator=(clazz&&) = delete; + clazz& operator=(const clazz&) = delete; + + // + + int non_const_method() { return 1; } + int non_const_method_noexcept() noexcept { return 2; } + + int const_method() const { return 3; } + int const_method_noexcept() const noexcept { return 4; } + + int non_const_method_ref() & { return 5; } + int non_const_method_noexcept_ref() & noexcept { return 6; } + + int const_method_ref() const & { return 7; } + int const_method_noexcept_ref() const & noexcept { return 8; } + + int non_const_method_rref() && { return 9; } + int non_const_method_noexcept_rref() && noexcept { return 10; } + + int const_method_rref() const && { return 11; } + int const_method_noexcept_rref() const && noexcept { return 12; } + + // + + int non_const_method_volatile() volatile { return 1; } + int non_const_method_noexcept_volatile() volatile noexcept { return 2; } + + int const_method_volatile() volatile const { return 3; } + int const_method_noexcept_volatile() volatile const noexcept { return 4; } + + int non_const_method_ref_volatile() volatile & { return 5; } + int non_const_method_noexcept_ref_volatile() volatile & noexcept { return 6; } + + int const_method_ref_volatile() volatile const & { return 7; } + int const_method_noexcept_ref_volatile() volatile const & noexcept { return 8; } + + int non_const_method_rref_volatile() volatile && { return 9; } + int non_const_method_noexcept_rref_volatile() volatile && noexcept { return 10; } + + int const_method_rref_volatile() volatile const && { return 11; } + int const_method_noexcept_rref_volatile() volatile const && noexcept { return 12; } + }; + + struct clazz2 {}; +} + +TEST_CASE("meta/meta_states/method") { + namespace meta = meta_hpp; + + meta::class_() + .method_("non_const_method", &clazz::non_const_method) + .method_("non_const_method_noexcept", &clazz::non_const_method_noexcept) + + .method_("const_method", &clazz::const_method) + .method_("const_method_noexcept", &clazz::const_method_noexcept) + + .method_("non_const_method_ref", &clazz::non_const_method_ref) + .method_("non_const_method_noexcept_ref", &clazz::non_const_method_noexcept_ref) + + .method_("const_method_ref", &clazz::const_method_ref) + .method_("const_method_noexcept_ref", &clazz::const_method_noexcept_ref) + + .method_("non_const_method_rref", &clazz::non_const_method_rref) + .method_("non_const_method_noexcept_rref", &clazz::non_const_method_noexcept_rref) + + .method_("const_method_rref", &clazz::const_method_rref) + .method_("const_method_noexcept_rref", &clazz::const_method_noexcept_rref) + + .method_("non_const_method_volatile", &clazz::non_const_method_volatile) + .method_("non_const_method_noexcept_volatile", &clazz::non_const_method_noexcept_volatile) + + .method_("const_method_volatile", &clazz::const_method_volatile) + .method_("const_method_noexcept_volatile", &clazz::const_method_noexcept_volatile) + + .method_("non_const_method_ref_volatile", &clazz::non_const_method_ref_volatile) + .method_("non_const_method_noexcept_ref_volatile", &clazz::non_const_method_noexcept_ref_volatile) + + .method_("const_method_ref_volatile", &clazz::const_method_ref_volatile) + .method_("const_method_noexcept_ref_volatile", &clazz::const_method_noexcept_ref_volatile) + + .method_("non_const_method_rref_volatile", &clazz::non_const_method_rref_volatile) + .method_("non_const_method_noexcept_rref_volatile", &clazz::non_const_method_noexcept_rref_volatile) + + .method_("const_method_rref_volatile", &clazz::const_method_rref_volatile) + .method_("const_method_noexcept_rref_volatile", &clazz::const_method_noexcept_rref_volatile); + + const meta::class_type ct = meta::resolve_type(); + REQUIRE(ct); + + SUBCASE("") { + const meta::method method; + CHECK_FALSE(method); + CHECK_FALSE(method.is_valid()); + CHECK(method == ct.get_method("non-existent-method")); + } + + SUBCASE("operators") { + const meta::method non_const_method_m = ct.get_method("non_const_method"); + const meta::method non_const_method_volatile_m = ct.get_method("non_const_method_volatile"); + CHECK(non_const_method_m == non_const_method_m); + CHECK(non_const_method_m != non_const_method_volatile_m); + CHECK((non_const_method_m < non_const_method_volatile_m || non_const_method_volatile_m < non_const_method_m)); + } + + SUBCASE("non_const_method") { + const meta::method mi = ct.get_method("non_const_method"); + REQUIRE(mi); + + const meta::method mi2 = ct.get_method("non_const_method_volatile"); + REQUIRE(mi2); + + CHECK(mi.get_name() == "non_const_method"); + CHECK(mi2.get_name() == "non_const_method_volatile"); + + { + CHECK(mi.get_type().get_arity() == 0); + CHECK(mi.get_type().get_owner_type() == meta::resolve_type()); + CHECK(mi.get_type().get_return_type() == meta::resolve_type()); + CHECK(mi.get_type().get_flags() == meta::method_flags{}); + + CHECK(mi2.get_type().get_arity() == 0); + CHECK(mi2.get_type().get_owner_type() == meta::resolve_type()); + CHECK(mi2.get_type().get_return_type() == meta::resolve_type()); + CHECK(mi2.get_type().get_flags() == meta::method_flags::is_volatile); + } + + { + CHECK(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + CHECK(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + + CHECK(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); + CHECK(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); + } + + { + clazz cl; + + CHECK(mi.invoke(cl).value() == 1); + CHECK_THROWS(mi.invoke(std::as_const(cl))); + CHECK(mi.invoke(std::move(cl)).value() == 1); + CHECK_THROWS(mi.invoke(std::move(std::as_const(cl)))); + + CHECK(mi2.invoke(cl).value() == 1); + CHECK_THROWS(mi2.invoke(std::as_const(cl))); + CHECK(mi2.invoke(std::move(cl)).value() == 1); + CHECK_THROWS(mi2.invoke(std::move(std::as_const(cl)))); + } + + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + } + + SUBCASE("non_const_method_noexcept") { + const meta::method mi = ct.get_method("non_const_method_noexcept"); + REQUIRE(mi); + + const meta::method mi2 = ct.get_method("non_const_method_noexcept_volatile"); + REQUIRE(mi2); + + CHECK(mi.get_name() == "non_const_method_noexcept"); + CHECK(mi2.get_name() == "non_const_method_noexcept_volatile"); + + { + CHECK(mi.get_type().get_arity() == 0); + CHECK(mi.get_type().get_owner_type() == meta::resolve_type()); + CHECK(mi.get_type().get_return_type() == meta::resolve_type()); + CHECK(mi.get_type().get_flags() == meta::method_flags::is_noexcept); + + CHECK(mi2.get_type().get_arity() == 0); + CHECK(mi2.get_type().get_owner_type() == meta::resolve_type()); + CHECK(mi2.get_type().get_return_type() == meta::resolve_type()); + CHECK(mi2.get_type().get_flags() == (meta::method_flags::is_noexcept | meta::method_flags::is_volatile)); + } + + { + CHECK(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + CHECK(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + + CHECK(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); + CHECK(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); + } + + { + clazz cl; + + CHECK(mi.invoke(cl).value() == 2); + CHECK_THROWS(mi.invoke(std::as_const(cl))); + CHECK(mi.invoke(std::move(cl)).value() == 2); + CHECK_THROWS(mi.invoke(std::move(std::as_const(cl)))); + + CHECK(mi2.invoke(cl).value() == 2); + CHECK_THROWS(mi2.invoke(std::as_const(cl))); + CHECK(mi2.invoke(std::move(cl)).value() == 2); + CHECK_THROWS(mi2.invoke(std::move(std::as_const(cl)))); + } + + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + } + + SUBCASE("const_method") { + const meta::method mi = ct.get_method("const_method"); + REQUIRE(mi); + + const meta::method mi2 = ct.get_method("const_method_volatile"); + REQUIRE(mi2); + + CHECK(mi.get_name() == "const_method"); + CHECK(mi2.get_name() == "const_method_volatile"); + + { + CHECK(mi.get_type().get_arity() == 0); + CHECK(mi.get_type().get_owner_type() == meta::resolve_type()); + CHECK(mi.get_type().get_return_type() == meta::resolve_type()); + CHECK(mi.get_type().get_flags() == meta::method_flags::is_const); + + CHECK(mi2.get_type().get_arity() == 0); + CHECK(mi2.get_type().get_owner_type() == meta::resolve_type()); + CHECK(mi2.get_type().get_return_type() == meta::resolve_type()); + CHECK(mi2.get_type().get_flags() == (meta::method_flags::is_const | meta::method_flags::is_volatile)); + } + + { + CHECK(mi.is_invocable_with()); + CHECK(mi.is_invocable_with()); + CHECK(mi.is_invocable_with()); + CHECK(mi.is_invocable_with()); + + CHECK(mi2.is_invocable_with()); + CHECK(mi2.is_invocable_with()); + CHECK(mi2.is_invocable_with()); + CHECK(mi2.is_invocable_with()); + } + + { + clazz cl; + + CHECK(mi.invoke(cl).value() == 3); + CHECK(mi.invoke(std::as_const(cl)).value() == 3); + CHECK(mi.invoke(std::move(cl)).value() == 3); + CHECK(mi.invoke(std::move(std::as_const(cl))).value() == 3); + + CHECK(mi2.invoke(cl).value() == 3); + CHECK(mi2.invoke(std::as_const(cl)).value() == 3); + CHECK(mi2.invoke(std::move(cl)).value() == 3); + CHECK(mi2.invoke(std::move(std::as_const(cl))).value() == 3); + } + + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + } + + SUBCASE("const_method_noexcept") { + const meta::method mi = ct.get_method("const_method_noexcept"); + REQUIRE(mi); + + const meta::method mi2 = ct.get_method("const_method_noexcept_volatile"); + REQUIRE(mi2); + + CHECK(mi.get_name() == "const_method_noexcept"); + CHECK(mi2.get_name() == "const_method_noexcept_volatile"); + + { + CHECK(mi.get_type().get_arity() == 0); + CHECK(mi.get_type().get_owner_type() == meta::resolve_type()); + CHECK(mi.get_type().get_return_type() == meta::resolve_type()); + CHECK(mi.get_type().get_flags() == (meta::method_flags::is_const | meta::method_flags::is_noexcept)); + + CHECK(mi2.get_type().get_arity() == 0); + CHECK(mi2.get_type().get_owner_type() == meta::resolve_type()); + CHECK(mi2.get_type().get_return_type() == meta::resolve_type()); + CHECK(mi2.get_type().get_flags() == (meta::method_flags::is_const | meta::method_flags::is_noexcept | meta::method_flags::is_volatile)); + } + + { + CHECK(mi.is_invocable_with()); + CHECK(mi.is_invocable_with()); + CHECK(mi.is_invocable_with()); + CHECK(mi.is_invocable_with()); + + CHECK(mi2.is_invocable_with()); + CHECK(mi2.is_invocable_with()); + CHECK(mi2.is_invocable_with()); + CHECK(mi2.is_invocable_with()); + } + + { + clazz cl; + + CHECK(mi.invoke(cl).value() == 4); + CHECK(mi.invoke(std::as_const(cl)).value() == 4); + CHECK(mi.invoke(std::move(cl)).value() == 4); + CHECK(mi.invoke(std::move(std::as_const(cl))).value() == 4); + + CHECK(mi2.invoke(cl).value() == 4); + CHECK(mi2.invoke(std::as_const(cl)).value() == 4); + CHECK(mi2.invoke(std::move(cl)).value() == 4); + CHECK(mi2.invoke(std::move(std::as_const(cl))).value() == 4); + } + + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + } + + SUBCASE("non_const_method_ref") { + const meta::method mi = ct.get_method("non_const_method_ref"); + REQUIRE(mi); + + const meta::method mi2 = ct.get_method("non_const_method_ref_volatile"); + REQUIRE(mi2); + + CHECK(mi.get_name() == "non_const_method_ref"); + CHECK(mi2.get_name() == "non_const_method_ref_volatile"); + + { + CHECK(mi.get_type().get_arity() == 0); + CHECK(mi.get_type().get_owner_type() == meta::resolve_type()); + CHECK(mi.get_type().get_return_type() == meta::resolve_type()); + CHECK(mi.get_type().get_flags() == meta::method_flags::is_lvalue_qualified); + + CHECK(mi2.get_type().get_arity() == 0); + CHECK(mi2.get_type().get_owner_type() == meta::resolve_type()); + CHECK(mi2.get_type().get_return_type() == meta::resolve_type()); + CHECK(mi2.get_type().get_flags() == (meta::method_flags::is_volatile | meta::method_flags::is_lvalue_qualified)); + } + + { + CHECK(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + + CHECK(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); + } + + { + clazz cl; + + CHECK(mi.invoke(cl).value() == 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(mi2.invoke(cl).value() == 5); + CHECK_THROWS(mi2.invoke(std::as_const(cl))); + CHECK_THROWS(mi2.invoke(std::move(cl))); + CHECK_THROWS(mi2.invoke(std::move(std::as_const(cl)))); + } + + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); + + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); + } + + SUBCASE("non_const_method_noexcept_ref") { + const meta::method mi = ct.get_method("non_const_method_noexcept_ref"); + REQUIRE(mi); + + const meta::method mi2 = ct.get_method("non_const_method_noexcept_ref_volatile"); + REQUIRE(mi2); + + CHECK(mi.get_name() == "non_const_method_noexcept_ref"); + CHECK(mi2.get_name() == "non_const_method_noexcept_ref_volatile"); + + { + CHECK(mi.get_type().get_arity() == 0); + CHECK(mi.get_type().get_owner_type() == meta::resolve_type()); + CHECK(mi.get_type().get_return_type() == meta::resolve_type()); + CHECK(mi.get_type().get_flags() == (meta::method_flags::is_noexcept | meta::method_flags::is_lvalue_qualified)); + + CHECK(mi2.get_type().get_arity() == 0); + CHECK(mi2.get_type().get_owner_type() == meta::resolve_type()); + CHECK(mi2.get_type().get_return_type() == meta::resolve_type()); + CHECK(mi2.get_type().get_flags() == (meta::method_flags::is_noexcept | meta::method_flags::is_volatile | meta::method_flags::is_lvalue_qualified)); + } + + { + CHECK(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + + CHECK(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); + } + + { + clazz cl; + + CHECK(mi.invoke(cl).value() == 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(mi2.invoke(cl).value() == 6); + CHECK_THROWS(mi2.invoke(std::as_const(cl))); + CHECK_THROWS(mi2.invoke(std::move(cl))); + CHECK_THROWS(mi2.invoke(std::move(std::as_const(cl)))); + } + + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); + + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); + } + + SUBCASE("const_method_ref") { + const meta::method mi = ct.get_method("const_method_ref"); + REQUIRE(mi); + + const meta::method mi2 = ct.get_method("const_method_ref_volatile"); + REQUIRE(mi2); + + CHECK(mi.get_name() == "const_method_ref"); + CHECK(mi2.get_name() == "const_method_ref_volatile"); + + { + CHECK(mi.get_type().get_arity() == 0); + CHECK(mi.get_type().get_owner_type() == meta::resolve_type()); + CHECK(mi.get_type().get_return_type() == meta::resolve_type()); + CHECK(mi.get_type().get_flags() == (meta::method_flags::is_const | meta::method_flags::is_lvalue_qualified)); + + CHECK(mi2.get_type().get_arity() == 0); + CHECK(mi2.get_type().get_owner_type() == meta::resolve_type()); + CHECK(mi2.get_type().get_return_type() == meta::resolve_type()); + CHECK(mi2.get_type().get_flags() == (meta::method_flags::is_const | meta::method_flags::is_volatile | meta::method_flags::is_lvalue_qualified)); + } + + { + CHECK(mi.is_invocable_with()); + CHECK(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + + CHECK(mi2.is_invocable_with()); + CHECK(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); + } + + { + clazz cl; + + CHECK(mi.invoke(cl).value() == 7); + CHECK(mi.invoke(std::as_const(cl)).value() == 7); + CHECK_THROWS(mi.invoke(std::move(cl))); + CHECK_THROWS(mi.invoke(std::move(std::as_const(cl)))); + + CHECK(mi2.invoke(cl).value() == 7); + CHECK(mi2.invoke(std::as_const(cl)).value() == 7); + CHECK_THROWS(mi2.invoke(std::move(cl))); + CHECK_THROWS(mi2.invoke(std::move(std::as_const(cl)))); + } + + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + //static_assert(!std::is_invocable_v); // msvc issue + //static_assert(!std::is_invocable_v); // msvc issue + + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); + } + + SUBCASE("const_method_noexcept_ref") { + const meta::method mi = ct.get_method("const_method_noexcept_ref"); + REQUIRE(mi); + + const meta::method mi2 = ct.get_method("const_method_noexcept_ref_volatile"); + REQUIRE(mi2); + + CHECK(mi.get_name() == "const_method_noexcept_ref"); + CHECK(mi2.get_name() == "const_method_noexcept_ref_volatile"); + + { + CHECK(mi.get_type().get_arity() == 0); + CHECK(mi.get_type().get_owner_type() == meta::resolve_type()); + CHECK(mi.get_type().get_return_type() == meta::resolve_type()); + CHECK(mi.get_type().get_flags() == (meta::method_flags::is_const | meta::method_flags::is_noexcept | meta::method_flags::is_lvalue_qualified)); + + CHECK(mi2.get_type().get_arity() == 0); + CHECK(mi2.get_type().get_owner_type() == meta::resolve_type()); + CHECK(mi2.get_type().get_return_type() == meta::resolve_type()); + CHECK(mi2.get_type().get_flags() == (meta::method_flags::is_const | meta::method_flags::is_noexcept | meta::method_flags::is_volatile | meta::method_flags::is_lvalue_qualified)); + } + + { + CHECK(mi.is_invocable_with()); + CHECK(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + + CHECK(mi2.is_invocable_with()); + CHECK(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); + } + + { + clazz cl; + + CHECK(mi.invoke(cl).value() == 8); + CHECK(mi.invoke(std::as_const(cl)).value() == 8); + CHECK_THROWS(mi.invoke(std::move(cl))); + CHECK_THROWS(mi.invoke(std::move(std::as_const(cl)))); + + CHECK(mi2.invoke(cl).value() == 8); + CHECK(mi2.invoke(std::as_const(cl)).value() == 8); + CHECK_THROWS(mi2.invoke(std::move(cl))); + CHECK_THROWS(mi2.invoke(std::move(std::as_const(cl)))); + } + + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + //static_assert(!std::is_invocable_v); // msvc issue + //static_assert(!std::is_invocable_v); // msvc issue + + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); + } + + SUBCASE("non_const_method_rref") { + const meta::method mi = ct.get_method("non_const_method_rref"); + REQUIRE(mi); + + const meta::method mi2 = ct.get_method("non_const_method_rref_volatile"); + REQUIRE(mi2); + + CHECK(mi.get_name() == "non_const_method_rref"); + CHECK(mi2.get_name() == "non_const_method_rref_volatile"); + + { + CHECK(mi.get_type().get_arity() == 0); + CHECK(mi.get_type().get_owner_type() == meta::resolve_type()); + CHECK(mi.get_type().get_return_type() == meta::resolve_type()); + CHECK(mi.get_type().get_flags() == meta::method_flags::is_rvalue_qualified); + + CHECK(mi2.get_type().get_arity() == 0); + CHECK(mi2.get_type().get_owner_type() == meta::resolve_type()); + CHECK(mi2.get_type().get_return_type() == meta::resolve_type()); + CHECK(mi2.get_type().get_flags() == (meta::method_flags::is_volatile | meta::method_flags::is_rvalue_qualified)); + } + + { + CHECK_FALSE(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + CHECK(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + + CHECK_FALSE(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); + CHECK(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); + } + + { + clazz cl; + + CHECK_THROWS(mi.invoke(cl)); + CHECK_THROWS(mi.invoke(std::as_const(cl))); + CHECK(mi.invoke(std::move(cl)).value() == 9); + CHECK_THROWS(mi.invoke(std::move(std::as_const(cl)))); + + CHECK_THROWS(mi2.invoke(cl)); + CHECK_THROWS(mi2.invoke(std::as_const(cl))); + CHECK(mi2.invoke(std::move(cl)).value() == 9); + CHECK_THROWS(mi2.invoke(std::move(std::as_const(cl)))); + } + + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + } + + SUBCASE("non_const_method_noexcept_rref") { + const meta::method mi = ct.get_method("non_const_method_noexcept_rref"); + REQUIRE(mi); + + const meta::method mi2 = ct.get_method("non_const_method_noexcept_rref_volatile"); + REQUIRE(mi2); + + CHECK(mi.get_name() == "non_const_method_noexcept_rref"); + CHECK(mi2.get_name() == "non_const_method_noexcept_rref_volatile"); + + { + CHECK(mi.get_type().get_arity() == 0); + CHECK(mi.get_type().get_owner_type() == meta::resolve_type()); + CHECK(mi.get_type().get_return_type() == meta::resolve_type()); + CHECK(mi.get_type().get_flags() == (meta::method_flags::is_noexcept | meta::method_flags::is_rvalue_qualified)); + + CHECK(mi2.get_type().get_arity() == 0); + CHECK(mi2.get_type().get_owner_type() == meta::resolve_type()); + CHECK(mi2.get_type().get_return_type() == meta::resolve_type()); + CHECK(mi2.get_type().get_flags() == (meta::method_flags::is_noexcept | meta::method_flags::is_volatile | meta::method_flags::is_rvalue_qualified)); + } + + { + CHECK_FALSE(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + CHECK(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + + CHECK_FALSE(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); + CHECK(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); + } + + { + clazz cl; + + CHECK_THROWS(mi.invoke(cl)); + CHECK_THROWS(mi.invoke(std::as_const(cl))); + CHECK(mi.invoke(std::move(cl)).value() == 10); + CHECK_THROWS(mi.invoke(std::move(std::as_const(cl)))); + + CHECK_THROWS(mi2.invoke(cl)); + CHECK_THROWS(mi2.invoke(std::as_const(cl))); + CHECK(mi2.invoke(std::move(cl)).value() == 10); + CHECK_THROWS(mi2.invoke(std::move(std::as_const(cl)))); + } + + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + } + + SUBCASE("const_method_rref") { + const meta::method mi = ct.get_method("const_method_rref"); + REQUIRE(mi); + + const meta::method mi2 = ct.get_method("const_method_rref_volatile"); + REQUIRE(mi2); + + CHECK(mi.get_name() == "const_method_rref"); + CHECK(mi2.get_name() == "const_method_rref_volatile"); + + { + CHECK(mi.get_type().get_arity() == 0); + CHECK(mi.get_type().get_owner_type() == meta::resolve_type()); + CHECK(mi.get_type().get_return_type() == meta::resolve_type()); + CHECK(mi.get_type().get_flags() == (meta::method_flags::is_const | meta::method_flags::is_rvalue_qualified)); + + CHECK(mi2.get_type().get_arity() == 0); + CHECK(mi2.get_type().get_owner_type() == meta::resolve_type()); + CHECK(mi2.get_type().get_return_type() == meta::resolve_type()); + CHECK(mi2.get_type().get_flags() == (meta::method_flags::is_const | meta::method_flags::is_volatile | meta::method_flags::is_rvalue_qualified)); + } + + { + CHECK_FALSE(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + CHECK(mi.is_invocable_with()); + CHECK(mi.is_invocable_with()); + + CHECK_FALSE(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); + CHECK(mi2.is_invocable_with()); + CHECK(mi2.is_invocable_with()); + } + + { + clazz cl; + + CHECK_THROWS(mi.invoke(cl)); + CHECK_THROWS(mi.invoke(std::as_const(cl))); + CHECK(mi.invoke(std::move(cl)).value() == 11); + CHECK(mi.invoke(std::move(std::as_const(cl))).value() == 11); + + CHECK_THROWS(mi2.invoke(cl)); + CHECK_THROWS(mi2.invoke(std::as_const(cl))); + CHECK(mi2.invoke(std::move(cl)).value() == 11); + CHECK(mi2.invoke(std::move(std::as_const(cl))).value() == 11); + } + + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + } + + SUBCASE("const_method_noexcept_rref") { + const meta::method mi = ct.get_method("const_method_noexcept_rref"); + REQUIRE(mi); + + const meta::method mi2 = ct.get_method("const_method_noexcept_rref_volatile"); + REQUIRE(mi2); + + CHECK(mi.get_name() == "const_method_noexcept_rref"); + CHECK(mi2.get_name() == "const_method_noexcept_rref_volatile"); + + { + CHECK(mi.get_type().get_arity() == 0); + CHECK(mi.get_type().get_owner_type() == meta::resolve_type()); + CHECK(mi.get_type().get_return_type() == meta::resolve_type()); + CHECK(mi.get_type().get_flags() == (meta::method_flags::is_const | meta::method_flags::is_noexcept | meta::method_flags::is_rvalue_qualified)); + + CHECK(mi2.get_type().get_arity() == 0); + CHECK(mi2.get_type().get_owner_type() == meta::resolve_type()); + CHECK(mi2.get_type().get_return_type() == meta::resolve_type()); + CHECK(mi2.get_type().get_flags() == (meta::method_flags::is_const | meta::method_flags::is_noexcept | meta::method_flags::is_volatile | meta::method_flags::is_rvalue_qualified)); + } + + { + CHECK_FALSE(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + CHECK(mi.is_invocable_with()); + CHECK(mi.is_invocable_with()); + + CHECK_FALSE(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); + CHECK(mi2.is_invocable_with()); + CHECK(mi2.is_invocable_with()); + } + + { + clazz cl; + + CHECK_THROWS(mi.invoke(cl)); + CHECK_THROWS(mi.invoke(std::as_const(cl))); + CHECK(mi.invoke(std::move(cl)).value() == 12); + CHECK(mi.invoke(std::move(std::as_const(cl))).value() == 12); + + CHECK_THROWS(mi2.invoke(cl)); + CHECK_THROWS(mi2.invoke(std::as_const(cl))); + CHECK(mi2.invoke(std::move(cl)).value() == 12); + CHECK(mi2.invoke(std::move(std::as_const(cl))).value() == 12); + } + + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + } +} diff --git a/untests/meta_states/scope_tests.cpp b/untests/meta_states/scope_tests.cpp new file mode 100644 index 0000000..1041f46 --- /dev/null +++ b/untests/meta_states/scope_tests.cpp @@ -0,0 +1,114 @@ +/******************************************************************************* + * 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_tests.hpp" + +namespace +{ + enum class color { + red, + green, + blue, + }; + + struct ivec2 { + int x{}; + int y{}; + }; + + struct ivec3 { + int x{}; + int y{}; + int z{}; + }; + + ivec2 iadd2(const ivec2& l, const ivec2& r) noexcept { + return {l.x + r.x, l.y + r.y}; + } + + ivec3 iadd3(const ivec3& l, const ivec3& r) noexcept { + return {l.x + r.x, l.y + r.y, l.z + r.z}; + } + + ivec2 global_ivec2 = ivec2{1, 0}; + const ivec3 global_const_ivec3 = ivec3{1, 0}; +} + +TEST_CASE("meta/meta_states/scope") { + namespace meta = meta_hpp; + + meta::scope_("meta/meta_states/scope/math") + .enum_("color") + .class_("ivec2") + .class_("ivec3") + .function_("iadd2", &iadd2) + .function_("iadd3", &iadd3) + .variable_("global_ivec2", &global_ivec2) + .variable_("global_const_ivec3", &global_const_ivec3); + + const meta::scope math_scope = meta::resolve_scope("meta/meta_states/scope/math"); + REQUIRE(math_scope); + REQUIRE(math_scope.is_valid()); + + CHECK(math_scope.get_name() == "meta/meta_states/scope/math"); + CHECK(math_scope.get_classes().size() == 2); + CHECK(math_scope.get_enums().size() == 1); + CHECK(math_scope.get_functions().size() == 2); + CHECK(math_scope.get_variables().size() == 2); + + SUBCASE("") { + const meta::scope scope; + CHECK_FALSE(scope); + CHECK_FALSE(scope.is_valid()); + } + + SUBCASE("operators") { + const meta::scope math1_s = meta::resolve_scope("meta/meta_states/scope/math1"); + const meta::scope math2_s = meta::resolve_scope("meta/meta_states/scope/math2"); + CHECK(math1_s == math1_s); + CHECK(math1_s != math2_s); + CHECK((math1_s < math2_s || math2_s < math1_s)); + } + + SUBCASE("classes") { + CHECK_FALSE(math_scope.get_class("non-existent-class")); + + const meta::class_type ivec2_type = math_scope.get_class("ivec2"); + REQUIRE(ivec2_type); + + const meta::class_type ivec3_type = math_scope.get_class("ivec3"); + REQUIRE(ivec3_type); + } + + SUBCASE("enums") { + CHECK_FALSE(math_scope.get_enum("non-existent-enum")); + + const meta::enum_type color_type = math_scope.get_enum("color"); + REQUIRE(color_type); + } + + SUBCASE("functions") { + CHECK_FALSE(math_scope.get_function("non-existent-function")); + + const meta::function iadd2_func = math_scope.get_function("iadd2"); + REQUIRE(iadd2_func); + + const meta::function iadd3_func = math_scope.get_function("iadd3"); + REQUIRE(iadd3_func); + } + + SUBCASE("variables") { + CHECK_FALSE(math_scope.get_variable("non-existent-variable")); + + const meta::variable global_ivec2_var = math_scope.get_variable("global_ivec2"); + REQUIRE(global_ivec2_var); + CHECK(global_ivec2_var.get_type().get_data_type() == meta::resolve_type()); + + const meta::variable global_const_ivec3_var = math_scope.get_variable("global_const_ivec3"); + REQUIRE(global_const_ivec3_var); + CHECK(global_const_ivec3_var.get_type().get_data_type() == meta::resolve_type()); + } +} diff --git a/untests/meta_states/variable_tests.cpp b/untests/meta_states/variable_tests.cpp new file mode 100644 index 0000000..f15ff90 --- /dev/null +++ b/untests/meta_states/variable_tests.cpp @@ -0,0 +1,100 @@ +/******************************************************************************* + * 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_tests.hpp" + +namespace +{ + struct clazz_1 { + static int int_variable; + static const int const_int_variable; + + static int& ref_int_variable; + static const int& const_ref_int_variable; + }; + + 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; +} + +TEST_CASE("meta/meta_states/variable") { + namespace meta = meta_hpp; + + meta::class_() + .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); + + const meta::class_type clazz_1_type = meta::resolve_type(); + REQUIRE(clazz_1_type); + + SUBCASE("") { + const meta::variable variable; + CHECK_FALSE(variable); + CHECK_FALSE(variable.is_valid()); + CHECK(variable == clazz_1_type.get_variable("non-existent-variable")); + } + + SUBCASE("operators") { + meta::variable int_variable_v = clazz_1_type.get_variable("int_variable"); + meta::variable const_int_variable_v = clazz_1_type.get_variable("const_int_variable"); + CHECK(int_variable_v == int_variable_v); + CHECK(int_variable_v != const_int_variable_v); + CHECK((int_variable_v < const_int_variable_v || const_int_variable_v < int_variable_v)); + } + + SUBCASE("int") { + meta::variable vm = clazz_1_type.get_variable("int_variable"); + REQUIRE(vm); + + CHECK(vm.get_type() == meta::resolve_type(&clazz_1::int_variable)); + CHECK(vm.get_name() == "int_variable"); + + CHECK(vm.get() == 1); + + CHECK_NOTHROW(vm.set(10)); CHECK(vm.get() == 10); + } + + SUBCASE("const int") { + meta::variable vm = clazz_1_type.get_variable("const_int_variable"); + REQUIRE(vm); + + CHECK(vm.get_type() == meta::resolve_type(&clazz_1::const_int_variable)); + CHECK(vm.get_name() == "const_int_variable"); + + CHECK(vm.get() == 2); + + CHECK_THROWS(vm.set(10)); CHECK(vm.get() == 2); + } + + SUBCASE("ref int") { + meta::variable vm = clazz_1_type.get_variable("ref_int_variable"); + REQUIRE(vm); + + CHECK(vm.get_type() == meta::resolve_type(&clazz_1::ref_int_variable)); + CHECK(vm.get_name() == "ref_int_variable"); + + CHECK(vm.get() == 10); + + CHECK_NOTHROW(vm.set(20)); CHECK(vm.get() == 20); + } + + SUBCASE("const ref int") { + meta::variable vm = clazz_1_type.get_variable("const_ref_int_variable"); + REQUIRE(vm); + + CHECK(vm.get_type() == meta::resolve_type(&clazz_1::const_ref_int_variable)); + CHECK(vm.get_name() == "const_ref_int_variable"); + + CHECK(vm.get() == 2); + + CHECK_THROWS(vm.set(10)); CHECK(vm.get() == 2); + } +} diff --git a/untests/meta_types/array_type_tests.cpp b/untests/meta_types/array_type_tests.cpp new file mode 100644 index 0000000..f4fe336 --- /dev/null +++ b/untests/meta_types/array_type_tests.cpp @@ -0,0 +1,41 @@ +/******************************************************************************* + * 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_tests.hpp" + +namespace +{ +} + +TEST_CASE("meta/meta_types/array_type") { + namespace meta = meta_hpp; + + SUBCASE("") { + const meta::array_type type; + CHECK_FALSE(type); + CHECK_FALSE(type.is_valid()); + } + + SUBCASE("int[]") { + const meta::array_type type = meta::resolve_type(); + REQUIRE(type); + + CHECK(type.get_flags() == (meta::array_flags::is_unbounded)); + + CHECK(type.get_extent() == 0); + CHECK(type.get_data_type() == meta::resolve_type()); + } + + SUBCASE("const unsigned[42][21]") { + const meta::array_type type = meta::resolve_type(); + REQUIRE(type); + + CHECK(type.get_flags() == (meta::array_flags::is_bounded)); + + CHECK(type.get_extent() == 42); + CHECK(type.get_data_type() == meta::resolve_type()); + } +} diff --git a/untests/meta_types/class_type_tests.cpp b/untests/meta_types/class_type_tests.cpp new file mode 100644 index 0000000..a17dad8 --- /dev/null +++ b/untests/meta_types/class_type_tests.cpp @@ -0,0 +1,465 @@ +/******************************************************************************* + * 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_tests.hpp" + +namespace +{ + struct base_clazz_1 { + base_clazz_1(int) {} + + int base_member_1 = 1; + int base_method_1() { return 1; } + static int base_function_1() { return 1; } + + int base_method_1_overloaded(int i0) const { return i0; } + int base_method_1_overloaded(float f0) const { return static_cast(f0); } + + static int base_function_1_overloaded(int i0) { return i0; } + static int base_function_1_overloaded(int i0, int i1) { return i0 + i1; } + + static int base_variable_1; + }; + + int base_clazz_1::base_variable_1 = 1; + + struct base_clazz_2 { + base_clazz_2(float) {} + + float base_member_2 = 2.0f; + float base_method_2() { return 2.0f; } + static float base_function_2() { return 2.f; } + + static float base_variable_2; + }; + + float base_clazz_2::base_variable_2 = 2.0f; + + struct derived_clazz final : base_clazz_1, base_clazz_2 { + derived_clazz(int i, float f) + : base_clazz_1{i} + , base_clazz_2{f} {} + + double derived_member = 3.0; + double derived_method() { return 3.0; } + static double derived_function() { return 3.0; } + + static constexpr double derived_variable = 3.0; + }; + + template < typename... Args > + struct variadic_clazz {}; +} + +TEST_CASE("meta/meta_types/class_type") { + namespace meta = meta_hpp; + + meta::class_() + .ctor_() + .member_("base_member_1", &base_clazz_1::base_member_1) + .method_("base_method_1", &base_clazz_1::base_method_1) + .function_("base_function_1", &base_clazz_1::base_function_1) + .method_("base_method_1_overloaded", meta::select(&base_clazz_1::base_method_1_overloaded)) + .method_("base_method_1_overloaded", meta::select(&base_clazz_1::base_method_1_overloaded)) + .function_("base_function_1_overloaded", meta::select(&base_clazz_1::base_function_1_overloaded)) + .function_("base_function_1_overloaded", meta::select(&base_clazz_1::base_function_1_overloaded)) + .variable_("base_variable_1", &base_clazz_1::base_variable_1); + + meta::class_() + .ctor_() + .member_("base_member_2", &base_clazz_2::base_member_2) + .method_("base_method_2", &base_clazz_2::base_method_2) + .function_("base_function_2", &base_clazz_2::base_function_2) + .variable_("base_variable_2", &base_clazz_2::base_variable_2); + + meta::class_() + .ctor_() + .base_() + .base_() + .member_("derived_member", &derived_clazz::derived_member) + .method_("derived_method", &derived_clazz::derived_method) + .function_("derived_function", &derived_clazz::derived_function) + .variable_("derived_variable", &derived_clazz::derived_variable); + + const meta::class_type base_clazz_1_type = meta::resolve_type(); + REQUIRE(base_clazz_1_type); + + const meta::class_type base_clazz_2_type = meta::resolve_type(); + REQUIRE(base_clazz_2_type); + + const meta::class_type derived_clazz_type = meta::resolve_type(); + REQUIRE(derived_clazz_type); + + const meta::class_type variadic_clazz_int_type = meta::resolve_type>(); + REQUIRE(variadic_clazz_int_type); + + const meta::class_type variadic_clazz_int_float_type = meta::resolve_type>(); + REQUIRE(variadic_clazz_int_float_type); + + SUBCASE("get_flags") { + CHECK(base_clazz_1_type.get_flags() == meta::class_flags{}); + CHECK(base_clazz_2_type.get_flags() == meta::class_flags{}); + CHECK(derived_clazz_type.get_flags() == meta::class_flags::is_final); + CHECK(variadic_clazz_int_type.get_flags() == (meta::class_flags::is_empty | meta::class_flags::is_template_instantiation)); + CHECK(variadic_clazz_int_float_type.get_flags() == (meta::class_flags::is_empty | meta::class_flags::is_template_instantiation)); + } + + SUBCASE("get_size") { + CHECK(base_clazz_1_type.get_size() == sizeof(base_clazz_1)); + CHECK(base_clazz_2_type.get_size() == sizeof(base_clazz_2)); + CHECK(derived_clazz_type.get_size() == sizeof(derived_clazz)); + } + + SUBCASE("get_arity") { + { + const meta::class_type type = meta::resolve_type(); + REQUIRE(type); + CHECK(type.get_arity() == 0); + } + { + const meta::class_type type = meta::resolve_type>(); + REQUIRE(type); + CHECK(type.get_arity() == 1); + } + { + const meta::class_type type = meta::resolve_type>(); + REQUIRE(type); + CHECK(type.get_arity() == 2); + } + } + + SUBCASE("get_argument_type") { + { + const meta::class_type type = meta::resolve_type(); + REQUIRE(type); + CHECK_FALSE(type.get_argument_type(0)); + } + { + const meta::class_type type = meta::resolve_type>(); + REQUIRE(type); + CHECK(type.get_argument_type(0) == meta::resolve_type()); + CHECK_FALSE(type.get_argument_type(1)); + } + { + const meta::class_type type = meta::resolve_type>(); + REQUIRE(type); + CHECK(type.get_argument_type(0) == meta::resolve_type()); + CHECK(type.get_argument_type(1) == meta::resolve_type()); + CHECK_FALSE(type.get_argument_type(2)); + } + } + + SUBCASE("get_argument_types") { + { + const meta::class_type type = meta::resolve_type(); + REQUIRE(type); + CHECK(type.get_argument_types() == std::vector{}); + } + { + const meta::class_type type = meta::resolve_type>(); + REQUIRE(type); + CHECK(type.get_argument_types() == std::vector{meta::resolve_type()}); + } + { + const meta::class_type type = meta::resolve_type>(); + REQUIRE(type); + CHECK(type.get_argument_types() == std::vector{meta::resolve_type(), meta::resolve_type()}); + } + } + + SUBCASE("get_ctors") { + CHECK(base_clazz_1_type.get_ctors().size() == 1); + CHECK(base_clazz_2_type.get_ctors().size() == 1); + CHECK(derived_clazz_type.get_ctors().size() == 1); + } + + SUBCASE("get_bases") { + CHECK(base_clazz_1_type.get_bases() == meta::class_set{}); + CHECK(base_clazz_2_type.get_bases() == meta::class_set{}); + CHECK(derived_clazz_type.get_bases() == meta::class_set{base_clazz_1_type, base_clazz_2_type}); + } + + SUBCASE("get_functions") { + CHECK(base_clazz_1_type.get_functions().size() == 3); + CHECK(base_clazz_2_type.get_functions().size() == 1); + CHECK(derived_clazz_type.get_functions().size() == 1); + } + + SUBCASE("get_members") { + CHECK(base_clazz_1_type.get_members().size() == 1); + CHECK(base_clazz_2_type.get_members().size() == 1); + CHECK(derived_clazz_type.get_members().size() == 1); + } + + SUBCASE("get_methods") { + CHECK(base_clazz_1_type.get_methods().size() == 3); + CHECK(base_clazz_2_type.get_methods().size() == 1); + CHECK(derived_clazz_type.get_methods().size() == 1); + } + + SUBCASE("get_variables") { + CHECK(base_clazz_1_type.get_variables().size() == 1); + CHECK(base_clazz_2_type.get_variables().size() == 1); + CHECK(derived_clazz_type.get_variables().size() == 1); + } + + SUBCASE("is_base_of") { + { + CHECK_FALSE(base_clazz_1_type.is_base_of()); + CHECK_FALSE(base_clazz_1_type.is_base_of(base_clazz_1_type)); + + CHECK_FALSE(base_clazz_1_type.is_base_of()); + CHECK_FALSE(base_clazz_1_type.is_base_of(base_clazz_2_type)); + + CHECK(base_clazz_1_type.is_base_of()); + CHECK(base_clazz_1_type.is_base_of(derived_clazz_type)); + } + + { + CHECK_FALSE(base_clazz_2_type.is_base_of()); + CHECK_FALSE(base_clazz_2_type.is_base_of(base_clazz_1_type)); + + CHECK_FALSE(base_clazz_2_type.is_base_of()); + CHECK_FALSE(base_clazz_2_type.is_base_of(base_clazz_2_type)); + + CHECK(base_clazz_2_type.is_base_of()); + CHECK(base_clazz_2_type.is_base_of(derived_clazz_type)); + } + + { + CHECK_FALSE(derived_clazz_type.is_base_of()); + CHECK_FALSE(derived_clazz_type.is_base_of(base_clazz_1_type)); + + CHECK_FALSE(derived_clazz_type.is_base_of()); + CHECK_FALSE(derived_clazz_type.is_base_of(base_clazz_2_type)); + + CHECK_FALSE(derived_clazz_type.is_base_of()); + CHECK_FALSE(derived_clazz_type.is_base_of(derived_clazz_type)); + } + } + + SUBCASE("is_derived_from") { + { + CHECK_FALSE(base_clazz_1_type.is_derived_from()); + CHECK_FALSE(base_clazz_1_type.is_derived_from(base_clazz_1_type)); + + CHECK_FALSE(base_clazz_1_type.is_derived_from()); + CHECK_FALSE(base_clazz_1_type.is_derived_from(base_clazz_2_type)); + + CHECK_FALSE(base_clazz_1_type.is_derived_from()); + CHECK_FALSE(base_clazz_1_type.is_derived_from(derived_clazz_type)); + } + + { + CHECK_FALSE(base_clazz_2_type.is_derived_from()); + CHECK_FALSE(base_clazz_2_type.is_derived_from(base_clazz_1_type)); + + CHECK_FALSE(base_clazz_2_type.is_derived_from()); + CHECK_FALSE(base_clazz_2_type.is_derived_from(base_clazz_2_type)); + + CHECK_FALSE(base_clazz_2_type.is_derived_from()); + CHECK_FALSE(base_clazz_2_type.is_derived_from(derived_clazz_type)); + } + + { + CHECK(derived_clazz_type.is_derived_from()); + CHECK(derived_clazz_type.is_derived_from(base_clazz_1_type)); + + CHECK(derived_clazz_type.is_derived_from()); + CHECK(derived_clazz_type.is_derived_from(base_clazz_2_type)); + + CHECK_FALSE(derived_clazz_type.is_derived_from()); + CHECK_FALSE(derived_clazz_type.is_derived_from(derived_clazz_type)); + } + } + + SUBCASE("get_function") { + CHECK(base_clazz_1_type.get_function("base_function_1")); + CHECK_FALSE(base_clazz_1_type.get_function("base_function_2")); + CHECK_FALSE(base_clazz_1_type.get_function("derived_function")); + + CHECK_FALSE(base_clazz_2_type.get_function("base_function_1")); + CHECK(base_clazz_2_type.get_function("base_function_2")); + CHECK_FALSE(base_clazz_2_type.get_function("derived_function")); + + CHECK(derived_clazz_type.get_function("base_function_1")); + CHECK(derived_clazz_type.get_function("base_function_2")); + CHECK(derived_clazz_type.get_function("derived_function")); + } + + SUBCASE("get_member") { + CHECK(base_clazz_1_type.get_member("base_member_1")); + CHECK_FALSE(base_clazz_1_type.get_member("base_member_2")); + CHECK_FALSE(base_clazz_1_type.get_member("derived_member")); + + CHECK_FALSE(base_clazz_2_type.get_member("base_member_1")); + CHECK(base_clazz_2_type.get_member("base_member_2")); + CHECK_FALSE(base_clazz_2_type.get_member("derived_member")); + + CHECK(derived_clazz_type.get_member("base_member_1")); + CHECK(derived_clazz_type.get_member("base_member_2")); + CHECK(derived_clazz_type.get_member("derived_member")); + } + + SUBCASE("get_method") { + CHECK(base_clazz_1_type.get_method("base_method_1")); + CHECK_FALSE(base_clazz_1_type.get_method("base_method_2")); + CHECK_FALSE(base_clazz_1_type.get_method("derived_method")); + + CHECK_FALSE(base_clazz_2_type.get_method("base_method_1")); + CHECK(base_clazz_2_type.get_method("base_method_2")); + CHECK_FALSE(base_clazz_2_type.get_method("derived_method")); + + CHECK(derived_clazz_type.get_method("base_method_1")); + CHECK(derived_clazz_type.get_method("base_method_2")); + CHECK(derived_clazz_type.get_method("derived_method")); + } + + SUBCASE("get_variable") { + CHECK(base_clazz_1_type.get_variable("base_variable_1")); + CHECK_FALSE(base_clazz_1_type.get_variable("base_variable_2")); + CHECK_FALSE(base_clazz_1_type.get_variable("derived_variable")); + + CHECK_FALSE(base_clazz_2_type.get_variable("base_variable_1")); + CHECK(base_clazz_2_type.get_variable("base_variable_2")); + CHECK_FALSE(base_clazz_2_type.get_variable("derived_variable")); + + CHECK(derived_clazz_type.get_variable("base_variable_1")); + CHECK(derived_clazz_type.get_variable("base_variable_2")); + CHECK(derived_clazz_type.get_variable("derived_variable")); + } + + SUBCASE("get_ctor_with") { + { + CHECK_FALSE(base_clazz_1_type.get_ctor_with<>()); + CHECK(base_clazz_1_type.get_ctor_with()); + CHECK_FALSE(base_clazz_1_type.get_ctor_with()); + } + { + CHECK_FALSE(base_clazz_2_type.get_ctor_with<>()); + CHECK_FALSE(base_clazz_2_type.get_ctor_with()); + CHECK(base_clazz_2_type.get_ctor_with()); + } + { + CHECK_FALSE(derived_clazz_type.get_ctor_with<>()); + CHECK_FALSE(derived_clazz_type.get_ctor_with()); + CHECK_FALSE(derived_clazz_type.get_ctor_with()); + CHECK(derived_clazz_type.get_ctor_with()); + CHECK_FALSE(derived_clazz_type.get_ctor_with()); + } + } + + SUBCASE("get_function_with") { + CHECK(base_clazz_1_type.get_function("base_function_1_overloaded")); + + { + CHECK_FALSE(base_clazz_1_type.get_function_with<>("base_function_1_overloaded")); + CHECK(base_clazz_1_type.get_function_with("base_function_1_overloaded")); + CHECK_FALSE(base_clazz_1_type.get_function_with("base_function_1_overloaded")); + + CHECK_FALSE(base_clazz_1_type.get_function_with<>("base_function_1_overloaded")); + CHECK_FALSE(base_clazz_1_type.get_function_with("base_function_1_overloaded")); + CHECK(base_clazz_1_type.get_function_with("base_function_1_overloaded")); + CHECK_FALSE(base_clazz_1_type.get_function_with("base_function_1_overloaded")); + + CHECK_FALSE(base_clazz_1_type.get_function_with<>("base_function_1_overloaded")); + CHECK_FALSE(base_clazz_1_type.get_function_with("base_function_1_overloaded")); + CHECK_FALSE(base_clazz_1_type.get_function_with("base_function_1_overloaded")); + } + + { + meta::number_type int_type = meta::resolve_type(); + meta::number_type float_type = meta::resolve_type(); + meta::number_type double_type = meta::resolve_type(); + + CHECK_FALSE(base_clazz_1_type.get_function_with<>("base_function_1_overloaded")); + CHECK(base_clazz_1_type.get_function_with("base_function_1_overloaded", {int_type})); + CHECK_FALSE(base_clazz_1_type.get_function_with("base_function_1_overloaded", {int_type, float_type})); + + CHECK_FALSE(base_clazz_1_type.get_function_with("base_function_1_overloaded")); + CHECK_FALSE(base_clazz_1_type.get_function_with("base_function_1_overloaded", {float_type})); + CHECK(base_clazz_1_type.get_function_with("base_function_1_overloaded", {int_type, int_type})); + CHECK_FALSE(base_clazz_1_type.get_function_with("base_function_1_overloaded", {float_type, float_type})); + + CHECK_FALSE(base_clazz_1_type.get_function_with<>("base_function_1_overloaded")); + CHECK_FALSE(base_clazz_1_type.get_function_with("base_function_1_overloaded", {double_type})); + CHECK_FALSE(base_clazz_1_type.get_function_with("base_function_1_overloaded", {double_type, double_type})); + } + + { + meta::number_type int_type = meta::resolve_type(); + meta::number_type float_type = meta::resolve_type(); + meta::number_type double_type = meta::resolve_type(); + + CHECK_FALSE(base_clazz_1_type.get_function_with<>("base_function_1_overloaded")); + CHECK(base_clazz_1_type.get_function_with("base_function_1_overloaded", std::vector{int_type})); + CHECK_FALSE(base_clazz_1_type.get_function_with("base_function_1_overloaded", std::vector{int_type, float_type})); + + CHECK_FALSE(base_clazz_1_type.get_function_with("base_function_1_overloaded")); + CHECK_FALSE(base_clazz_1_type.get_function_with("base_function_1_overloaded", std::vector{float_type})); + CHECK(base_clazz_1_type.get_function_with("base_function_1_overloaded", std::vector{int_type, int_type})); + CHECK_FALSE(base_clazz_1_type.get_function_with("base_function_1_overloaded", std::vector{float_type, float_type})); + + CHECK_FALSE(base_clazz_1_type.get_function_with<>("base_function_1_overloaded")); + CHECK_FALSE(base_clazz_1_type.get_function_with("base_function_1_overloaded", std::vector{double_type})); + CHECK_FALSE(base_clazz_1_type.get_function_with("base_function_1_overloaded", std::vector{double_type, double_type})); + } + } + + SUBCASE("get_method_with") { + CHECK(base_clazz_1_type.get_method("base_method_1_overloaded")); + + { + CHECK_FALSE(base_clazz_1_type.get_method_with<>("base_method_1_overloaded")); + CHECK(base_clazz_1_type.get_method_with("base_method_1_overloaded")); + CHECK_FALSE(base_clazz_1_type.get_method_with("base_method_1_overloaded")); + + CHECK_FALSE(base_clazz_1_type.get_method_with<>("base_method_1_overloaded")); + CHECK(base_clazz_1_type.get_method_with("base_method_1_overloaded")); + CHECK_FALSE(base_clazz_1_type.get_method_with("base_method_1_overloaded")); + + CHECK_FALSE(base_clazz_1_type.get_method_with<>("base_method_1_overloaded")); + CHECK_FALSE(base_clazz_1_type.get_method_with("base_method_1_overloaded")); + CHECK_FALSE(base_clazz_1_type.get_method_with("base_method_1_overloaded")); + } + + { + meta::number_type int_type = meta::resolve_type(); + meta::number_type float_type = meta::resolve_type(); + meta::number_type double_type = meta::resolve_type(); + + CHECK_FALSE(base_clazz_1_type.get_method_with<>("base_method_1_overloaded")); + CHECK(base_clazz_1_type.get_method_with("base_method_1_overloaded", {int_type})); + CHECK_FALSE(base_clazz_1_type.get_method_with("base_method_1_overloaded", {int_type, int_type})); + + CHECK_FALSE(base_clazz_1_type.get_method_with("base_method_1_overloaded")); + CHECK(base_clazz_1_type.get_method_with("base_method_1_overloaded", {float_type})); + CHECK_FALSE(base_clazz_1_type.get_method_with("base_method_1_overloaded", {float_type, float_type})); + + CHECK_FALSE(base_clazz_1_type.get_method_with<>("base_method_1_overloaded")); + CHECK_FALSE(base_clazz_1_type.get_method_with("base_method_1_overloaded", {double_type})); + CHECK_FALSE(base_clazz_1_type.get_method_with("base_method_1_overloaded", {double_type, double_type})); + } + + { + meta::number_type int_type = meta::resolve_type(); + meta::number_type float_type = meta::resolve_type(); + meta::number_type double_type = meta::resolve_type(); + + CHECK_FALSE(base_clazz_1_type.get_method_with<>("base_method_1_overloaded")); + CHECK(base_clazz_1_type.get_method_with("base_method_1_overloaded", std::vector{int_type})); + CHECK_FALSE(base_clazz_1_type.get_method_with("base_method_1_overloaded", std::vector{int_type, int_type})); + + CHECK_FALSE(base_clazz_1_type.get_method_with("base_method_1_overloaded")); + CHECK(base_clazz_1_type.get_method_with("base_method_1_overloaded", std::vector{float_type})); + CHECK_FALSE(base_clazz_1_type.get_method_with("base_method_1_overloaded", std::vector{float_type, float_type})); + + CHECK_FALSE(base_clazz_1_type.get_method_with<>("base_method_1_overloaded")); + CHECK_FALSE(base_clazz_1_type.get_method_with("base_method_1_overloaded", std::vector{double_type})); + CHECK_FALSE(base_clazz_1_type.get_method_with("base_method_1_overloaded", std::vector{double_type, double_type})); + } + } +} diff --git a/untests/meta_types/enum_type_tests.cpp b/untests/meta_types/enum_type_tests.cpp new file mode 100644 index 0000000..76ec642 --- /dev/null +++ b/untests/meta_types/enum_type_tests.cpp @@ -0,0 +1,98 @@ +/******************************************************************************* + * 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_tests.hpp" + +namespace +{ + enum class color : unsigned { + red = 0xFF0000, + green = 0x00FF00, + blue = 0x0000FF, + white = red | green | blue, + }; +} + +TEST_CASE("meta/meta_types/enum_type") { + namespace meta = meta_hpp; + + meta::enum_() + .evalue_("red", color::red) + .evalue_("green", color::green) + .evalue_("blue", color::blue) + .evalue_("white", color::white); + + SUBCASE("color") { + const meta::enum_type color_type = meta::resolve_type(); + REQUIRE(color_type); + + CHECK(color_type.get_id() == meta::resolve_type(color{}).get_id()); + CHECK(color_type.get_underlying_type() == meta::resolve_type()); + + CHECK(color_type.get_evalues().size() == 4); + } + + SUBCASE("const color") { + const meta::enum_type color_type = meta::resolve_type(); + REQUIRE(color_type); + + CHECK(color_type.get_id() == meta::resolve_type(color{}).get_id()); + CHECK(color_type.get_underlying_type() == meta::resolve_type()); + + CHECK(color_type.get_evalues().size() == 4); + } + + SUBCASE("get_evalue") { + const meta::enum_type color_type = meta::resolve_type(); + REQUIRE(color_type); + + { + const meta::evalue green_value = color_type.get_evalue("green"); + REQUIRE(green_value); + CHECK(green_value.get_value() == color::green); + } + + { + const meta::evalue yellow_value = color_type.get_evalue("yellow"); + CHECK_FALSE(yellow_value); + } + } + + SUBCASE("value_to_name") { + const meta::enum_type color_type = meta::resolve_type(); + REQUIRE(color_type); + + { + REQUIRE(color_type.value_to_name(color::red)); + CHECK(color_type.value_to_name(color::red) == "red"); + } + + { + + REQUIRE(color_type.value_to_name(meta::value{color::blue})); + CHECK(color_type.value_to_name(color::blue) == "blue"); + } + + { + REQUIRE_FALSE(color_type.value_to_name(100500)); + REQUIRE_FALSE(color_type.value_to_name(color{100500})); + } + } + + SUBCASE("name_to_value") { + const meta::enum_type color_type = meta::resolve_type(); + REQUIRE(color_type); + + { + REQUIRE(color_type.name_to_value("blue")); + CHECK(color_type.name_to_value("blue") == color::blue); + } + + { + REQUIRE_FALSE(color_type.name_to_value("yellow")); + } + } +} diff --git a/untests/meta_types/function_type_tests.cpp b/untests/meta_types/function_type_tests.cpp new file mode 100644 index 0000000..5bbad1d --- /dev/null +++ b/untests/meta_types/function_type_tests.cpp @@ -0,0 +1,68 @@ +/******************************************************************************* + * 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_tests.hpp" + +namespace +{ + struct ivec2 { + int x{}; + int y{}; + }; + + void arg_copy(ivec2) {} + void arg_ref_noexcept(ivec2&) noexcept {} + void arg_cref_noexcept(const ivec2&) noexcept {} +} + +TEST_CASE("meta/meta_types/function_type") { + namespace meta = meta_hpp; + + SUBCASE("") { + const meta::function_type type; + CHECK_FALSE(type); + CHECK_FALSE(type.is_valid()); + } + + SUBCASE("arg_copy") { + const meta::function_type type = meta::resolve_type(&arg_copy); + REQUIRE(type); + + CHECK(type.get_id() == meta::resolve_type(&arg_copy).get_id()); + CHECK(type.get_flags() == meta::function_flags{}); + + CHECK(type.get_arity() == 1); + CHECK(type.get_return_type() == meta::resolve_type()); + CHECK(type.get_argument_types() == std::vector{meta::resolve_type()}); + + CHECK(type.get_argument_type(0) == meta::resolve_type()); + CHECK_FALSE(type.get_argument_type(1)); + } + + SUBCASE("arg_ref_noexcept") { + const meta::function_type type = meta::resolve_type(&arg_ref_noexcept); + REQUIRE(type); + + CHECK(type.get_id() == meta::resolve_type(&arg_ref_noexcept).get_id()); + CHECK(type.get_flags() == meta::function_flags::is_noexcept); + CHECK(type.get_argument_types() == std::vector{meta::resolve_type()}); + + CHECK(type.get_argument_type(0) == meta::resolve_type()); + CHECK_FALSE(type.get_argument_type(1)); + } + + SUBCASE("arg_cref_noexcept") { + const meta::function_type type = meta::resolve_type(&arg_cref_noexcept); + REQUIRE(type); + + CHECK(type.get_id() == meta::resolve_type(&arg_cref_noexcept).get_id()); + CHECK(type.get_flags() == meta::function_flags::is_noexcept); + CHECK(type.get_argument_types() == std::vector{meta::resolve_type()}); + + CHECK(type.get_argument_type(0) == meta::resolve_type()); + CHECK_FALSE(type.get_argument_type(1)); + } +} diff --git a/untests/meta_types/member_type_tests.cpp b/untests/meta_types/member_type_tests.cpp new file mode 100644 index 0000000..3998ca2 --- /dev/null +++ b/untests/meta_types/member_type_tests.cpp @@ -0,0 +1,47 @@ +/******************************************************************************* + * 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_tests.hpp" + +namespace +{ + struct clazz_1 { + int int_member = 1; + const int const_int_member = 2; + }; +} + +TEST_CASE("meta/meta_types/member_type") { + namespace meta = meta_hpp; + + SUBCASE("") { + const meta::member_type type; + CHECK_FALSE(type); + CHECK_FALSE(type.is_valid()); + } + + SUBCASE("int") { + const meta::member_type type = meta::resolve_type(&clazz_1::int_member); + REQUIRE(type); + + CHECK(type.get_id() == meta::resolve_type(&clazz_1::int_member).get_id()); + CHECK(type.get_flags() == meta::member_flags{}); + + CHECK(type.get_owner_type() == meta::resolve_type()); + CHECK(type.get_value_type() == meta::resolve_type()); + } + + SUBCASE("const int") { + const meta::member_type type = meta::resolve_type(&clazz_1::const_int_member); + REQUIRE(type); + + CHECK(type.get_id() == meta::resolve_type(&clazz_1::const_int_member).get_id()); + CHECK(type.get_flags() == meta::member_flags{}); + + CHECK(type.get_owner_type() == meta::resolve_type()); + CHECK(type.get_value_type() == meta::resolve_type()); + } +} diff --git a/untests/meta_types/method_type_tests.cpp b/untests/meta_types/method_type_tests.cpp new file mode 100644 index 0000000..cbc96a6 --- /dev/null +++ b/untests/meta_types/method_type_tests.cpp @@ -0,0 +1,68 @@ +/******************************************************************************* + * 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_tests.hpp" + +namespace +{ + struct ivec2 { + int x{}; + int y{}; + + int& at(std::size_t i) { + switch ( i ) { + case 0: return x; + case 1: return y; + default: throw std::out_of_range("ivec2::at"); + } + } + + int length2() const noexcept { + return x * x + y * y; + } + }; +} + +TEST_CASE("meta/meta_types/method_type") { + namespace meta = meta_hpp; + + SUBCASE("") { + const meta::method_type type; + CHECK_FALSE(type); + CHECK_FALSE(type.is_valid()); + } + + SUBCASE("ivec2::at") { + const meta::method_type type = meta::resolve_type(&ivec2::at); + REQUIRE(type); + + CHECK(type.get_id() == meta::resolve_type(&ivec2::at).get_id()); + CHECK(type.get_flags() == meta::method_flags{}); + + CHECK(type.get_arity() == 1); + CHECK(type.get_owner_type() == meta::resolve_type()); + CHECK(type.get_return_type() == meta::resolve_type()); + CHECK(type.get_argument_types() == std::vector{meta::resolve_type()}); + + CHECK(type.get_argument_type(0) == meta::resolve_type()); + CHECK_FALSE(type.get_argument_type(1)); + } + + SUBCASE("ivec2::length2") { + const meta::method_type type = meta::resolve_type(&ivec2::length2); + REQUIRE(type); + + CHECK(type.get_id() == meta::resolve_type(&ivec2::length2).get_id()); + CHECK(type.get_flags() == (meta::method_flags::is_const | meta::method_flags::is_noexcept)); + + CHECK(type.get_arity() == 0); + CHECK(type.get_owner_type() == meta::resolve_type()); + CHECK(type.get_return_type() == meta::resolve_type()); + CHECK(type.get_argument_types() == std::vector{}); + + CHECK_FALSE(type.get_argument_type(0)); + } +} diff --git a/untests/meta_types/number_type_tests.cpp b/untests/meta_types/number_type_tests.cpp new file mode 100644 index 0000000..38c6605 --- /dev/null +++ b/untests/meta_types/number_type_tests.cpp @@ -0,0 +1,51 @@ +/******************************************************************************* + * 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_tests.hpp" + +namespace +{ +} + +TEST_CASE("meta/meta_types/number_type") { + namespace meta = meta_hpp; + + SUBCASE("") { + const meta::number_type type; + CHECK_FALSE(type); + CHECK_FALSE(type.is_valid()); + } + + SUBCASE("int") { + const meta::number_type type = meta::resolve_type(); + REQUIRE(type); + + CHECK(type.get_size() == sizeof(int)); + CHECK(type.get_flags() == ( + meta::number_flags::is_signed | + meta::number_flags::is_integral)); + } + + SUBCASE("const float") { + const meta::number_type type = meta::resolve_type(); + REQUIRE(type); + + CHECK(type.get_size() == sizeof(float)); + CHECK(type.get_flags() == ( + meta::number_flags::is_signed | + meta::number_flags::is_floating_point)); + } + + SUBCASE("const unsigned") { + const meta::number_type type = meta::resolve_type(); + REQUIRE(type); + + CHECK(type.get_size() == sizeof(unsigned)); + CHECK(type.get_flags() == ( + meta::number_flags::is_unsigned | + meta::number_flags::is_integral)); + } +} diff --git a/untests/meta_types/pointer_type_tests.cpp b/untests/meta_types/pointer_type_tests.cpp new file mode 100644 index 0000000..7d4c3a2 --- /dev/null +++ b/untests/meta_types/pointer_type_tests.cpp @@ -0,0 +1,53 @@ +/******************************************************************************* + * 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_tests.hpp" + +namespace +{ +} + +TEST_CASE("meta/meta_types/pointer_type") { + namespace meta = meta_hpp; + + SUBCASE("") { + const meta::pointer_type type; + CHECK_FALSE(type); + CHECK_FALSE(type.is_valid()); + } + + SUBCASE("int*") { + const meta::pointer_type type = meta::resolve_type(); + REQUIRE(type); + + CHECK(type.get_id() == meta::resolve_type().get_id()); + CHECK(type.get_data_type() == meta::resolve_type()); + } + + SUBCASE("const int* const") { + const meta::pointer_type type = meta::resolve_type(); + REQUIRE(type); + + CHECK(type.get_id() == meta::resolve_type().get_id()); + CHECK(type.get_data_type() == meta::resolve_type()); + } + + SUBCASE("int**") { + const meta::pointer_type type = meta::resolve_type(); + REQUIRE(type); + + CHECK(type.get_id() == meta::resolve_type().get_id()); + CHECK(type.get_data_type() == meta::resolve_type()); + } + + SUBCASE("const int** const") { + const meta::pointer_type type = meta::resolve_type(); + REQUIRE(type); + + CHECK(type.get_id() == meta::resolve_type().get_id()); + CHECK(type.get_data_type() == meta::resolve_type()); + } +} diff --git a/untests/meta_types/reference_type_tests.cpp b/untests/meta_types/reference_type_tests.cpp new file mode 100644 index 0000000..2f948c9 --- /dev/null +++ b/untests/meta_types/reference_type_tests.cpp @@ -0,0 +1,61 @@ +/******************************************************************************* + * 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_tests.hpp" + +namespace +{ +} + +TEST_CASE("meta/meta_types/reference_type") { + namespace meta = meta_hpp; + + SUBCASE("") { + const meta::reference_type type; + CHECK_FALSE(type); + CHECK_FALSE(type.is_valid()); + } + + SUBCASE("int&") { + const meta::reference_type type = meta::resolve_type(); + REQUIRE(type); + + CHECK(type.get_flags() == (meta::reference_flags::is_lvalue)); + + CHECK(type.get_id() == meta::resolve_type().get_id()); + CHECK(type.get_data_type() == meta::resolve_type()); + } + + SUBCASE("const int&") { + const meta::reference_type type = meta::resolve_type(); + REQUIRE(type); + + CHECK(type.get_flags() == (meta::reference_flags::is_readonly | meta::reference_flags::is_lvalue)); + + CHECK(type.get_id() == meta::resolve_type().get_id()); + CHECK(type.get_data_type() == meta::resolve_type()); + } + + SUBCASE("int&&") { + const meta::reference_type type = meta::resolve_type(); + REQUIRE(type); + + CHECK(type.get_flags() == (meta::reference_flags::is_rvalue)); + + CHECK(type.get_id() == meta::resolve_type().get_id()); + CHECK(type.get_data_type() == meta::resolve_type()); + } + + SUBCASE("const int&&") { + const meta::reference_type type = meta::resolve_type(); + REQUIRE(type); + + CHECK(type.get_flags() == (meta::reference_flags::is_readonly | meta::reference_flags::is_rvalue)); + + CHECK(type.get_id() == meta::resolve_type().get_id()); + CHECK(type.get_data_type() == meta::resolve_type()); + } +} diff --git a/untests/meta_types/void_type_tests.cpp b/untests/meta_types/void_type_tests.cpp new file mode 100644 index 0000000..3593cdf --- /dev/null +++ b/untests/meta_types/void_type_tests.cpp @@ -0,0 +1,29 @@ +/******************************************************************************* + * 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_tests.hpp" + +namespace +{ +} + +TEST_CASE("meta/meta_types/void_type") { + namespace meta = meta_hpp; + + SUBCASE("") { + const meta::void_type type; + CHECK_FALSE(type); + CHECK_FALSE(type.is_valid()); + } + + SUBCASE("void") { + const meta::void_type type = meta::resolve_type(); + REQUIRE(type); + + CHECK(type.get_id() == meta::resolve_type().get_id()); + CHECK(type.get_flags() == meta::void_flags{}); + } +} diff --git a/untests/meta_utilities/arg_tests.cpp b/untests/meta_utilities/arg_tests.cpp new file mode 100644 index 0000000..f895c7c --- /dev/null +++ b/untests/meta_utilities/arg_tests.cpp @@ -0,0 +1,1157 @@ +/******************************************************************************* + * 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_tests.hpp" + +namespace +{ + struct ivec2 { + int x{}; + int y{}; + + [[maybe_unused]] ivec2() = default; + [[maybe_unused]] explicit ivec2(int v): x{v}, y{v} {} + [[maybe_unused]] ivec2(int x, int y): x{x}, y{y} {} + + [[maybe_unused]] ivec2(ivec2&& other) noexcept { + x = other.x; + y = other.y; + other.x = 0; + other.y = 0; + } + + [[maybe_unused]] ivec2(const ivec2& other) noexcept { + x = other.x; + y = other.y; + } + + ivec2& operator=(ivec2&&) = delete; + ivec2& operator=(const ivec2&) = delete; + }; + + struct ivec3 { + int x{}; + int y{}; + int z{}; + + [[maybe_unused]] ivec3() = default; + [[maybe_unused]] explicit ivec3(int v): x{v}, y{v}, z{v} {} + [[maybe_unused]] ivec3(int x, int y, int z): x{x}, y{y}, z{z} {} + + [[maybe_unused]] ivec3(ivec3&& other) noexcept { + x = other.x; + y = other.y; + z = other.z; + other.x = 0; + other.y = 0; + other.z = 0; + } + + [[maybe_unused]] ivec3(const ivec3& other) noexcept { + x = other.x; + y = other.y; + z = other.z; + } + + ivec3& operator=(ivec3&&) = delete; + ivec3& operator=(const ivec3&) = delete; + }; + + [[maybe_unused]] bool operator==(const ivec2& l, const ivec2& r) noexcept { + return l.x == r.x && l.y == r.y; + } + + [[maybe_unused]] bool operator==(const ivec3& l, const ivec3& r) noexcept { + return l.x == r.x && l.y == r.y && l.z == r.z; + } +} + +TEST_CASE("features/meta_utilities/arg/type") { + namespace meta = meta_hpp; + + SUBCASE("ptr") { + ivec2 v{1,2}; + ivec2* vp = &v; + meta::detail::arg a{vp}; + + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::ref); + } + + SUBCASE("rptr") { + ivec2 v{1,2}; + ivec2* vp = &v; + meta::detail::arg a{std::move(vp)}; + + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::rref); + } + + SUBCASE("ptr_c") { + ivec2 v{1,2}; + ivec2* const vp = &v; + meta::detail::arg a{vp}; + + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::cref); + } + + SUBCASE("rptr_c") { + ivec2 v{1,2}; + ivec2* const vp = &v; + meta::detail::arg a{std::move(vp)}; + + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::crref); + } + + SUBCASE("cptr") { + const ivec2 v{1,2}; + const ivec2* vp = &v; + meta::detail::arg a{vp}; + + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::ref); + } + + SUBCASE("crptr") { + const ivec2 v{1,2}; + const ivec2* vp = &v; + meta::detail::arg a{std::move(vp)}; + + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::rref); + } + + SUBCASE("cptr_c") { + const ivec2 v{1,2}; + const ivec2* const vp = &v; + meta::detail::arg a{vp}; + + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::cref); + } + + SUBCASE("crptr_c") { + const ivec2 v{1,2}; + const ivec2* const vp = &v; + meta::detail::arg a{std::move(vp)}; + + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::crref); + } + + SUBCASE("ref") { + ivec2 v{1,2}; + ivec2& vr = v; + meta::detail::arg a{vr}; + + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::ref); + } + + SUBCASE("cref") { + const ivec2 v{1,2}; + const ivec2& vr = v; + meta::detail::arg a{vr}; + + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::cref); + } + + SUBCASE("rref") { + ivec2 v{1,2}; + meta::detail::arg a{std::move(v)}; + + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::rref); + } + + SUBCASE("crref") { + const ivec2 v{1,2}; + meta::detail::arg a{std::move(v)}; + + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::crref); + } +} + +TEST_CASE("features/meta_utilities/arg/can_cast_to") { + namespace meta = meta_hpp; + + SUBCASE("ptr") { + ivec2 v{1,2}; + ivec2* vp = &v; + meta::detail::arg a{vp}; + + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + + { + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + } + + { + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + + CHECK(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + + []([[maybe_unused]] ivec2 *){}(vp); + []([[maybe_unused]] const ivec2 *){}(vp); + []([[maybe_unused]] ivec2 *const){}(vp); + []([[maybe_unused]] const ivec2 *const){}(vp); + + []([[maybe_unused]] ivec2 *&){}(vp); + //[]([[maybe_unused]] const ivec2 *&){}(vp); + []([[maybe_unused]] ivec2 *const &){}(vp); + []([[maybe_unused]] const ivec2 *const &){}(vp); + + //[]([[maybe_unused]] ivec2 *&&){}(vp); + //[]([[maybe_unused]] const ivec2 *&&){}(vp); + //[]([[maybe_unused]] ivec2 *const &&){}(vp); + //[]([[maybe_unused]] const ivec2 *const &&){}(vp); + } + } + + SUBCASE("rptr") { + ivec2 v{1,2}; + ivec2* vp = &v; + meta::detail::arg a{std::move(vp)}; + + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + + { + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + } + + { + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + + CHECK(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + + []([[maybe_unused]] ivec2 *){}(std::move(vp)); + []([[maybe_unused]] const ivec2 *){}(std::move(vp)); + []([[maybe_unused]] ivec2 *const){}(std::move(vp)); + []([[maybe_unused]] const ivec2 *const){}(std::move(vp)); + + //[]([[maybe_unused]] ivec2 *&){}(std::move(vp)); + //[]([[maybe_unused]] const ivec2 *&){}(std::move(vp)); + []([[maybe_unused]] ivec2 *const &){}(std::move(vp)); + []([[maybe_unused]] const ivec2 *const &){}(std::move(vp)); + + []([[maybe_unused]] ivec2 *&&){}(std::move(vp)); + //[]([[maybe_unused]] const ivec2 *&&){}(std::move(vp)); + []([[maybe_unused]] ivec2 *const &&){}(std::move(vp)); + []([[maybe_unused]] const ivec2 *const &&){}(std::move(vp)); + } + } + + SUBCASE("ptr_c") { + ivec2 v{1,2}; + ivec2* const vp = &v; + meta::detail::arg a{vp}; + + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + + { + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + } + + { + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + + []([[maybe_unused]] ivec2 *){}(vp); + []([[maybe_unused]] const ivec2 *){}(vp); + []([[maybe_unused]] ivec2 *const &){}(vp); + []([[maybe_unused]] const ivec2 *const &){}(vp); + + // []([[maybe_unused]] ivec2 *&){}(vp); + // []([[maybe_unused]] const ivec2 *&){}(vp); + []([[maybe_unused]] ivec2 *const &){}(vp); + []([[maybe_unused]] const ivec2 *const &){}(vp); + + //[]([[maybe_unused]] ivec2 *&&){}(vp); + //[]([[maybe_unused]] const ivec2 *&&){}(vp); + //[]([[maybe_unused]] ivec2 *const &&){}(vp); + //[]([[maybe_unused]] const ivec2 *const &&){}(vp); + } + } + + SUBCASE("rptr_c") { + ivec2 v{1,2}; + ivec2* const vp = &v; + meta::detail::arg a{std::move(vp)}; + + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + + { + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + } + + { + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + + []([[maybe_unused]] ivec2 *){}(std::move(vp)); + []([[maybe_unused]] const ivec2 *){}(std::move(vp)); + []([[maybe_unused]] ivec2 *const){}(std::move(vp)); + []([[maybe_unused]] const ivec2 *const){}(std::move(vp)); + + //[]([[maybe_unused]] ivec2 *&){}(std::move(vp)); + //[]([[maybe_unused]] const ivec2 *&){}(std::move(vp)); + []([[maybe_unused]] ivec2 *const &){}(std::move(vp)); + []([[maybe_unused]] const ivec2 *const &){}(std::move(vp)); + + //[]([[maybe_unused]] ivec2 *&&){}(std::move(vp)); + //[]([[maybe_unused]] const ivec2 *&&){}(std::move(vp)); + []([[maybe_unused]] ivec2 *const &&){}(std::move(vp)); + []([[maybe_unused]] const ivec2 *const &&){}(std::move(vp)); + } + } + + SUBCASE("cptr") { + const ivec2 v{1,2}; + const ivec2* vp = &v; + meta::detail::arg a{vp}; + + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + + { + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + } + + { + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); + + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); + + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + + //[]([[maybe_unused]] ivec2 *){}(vp); + []([[maybe_unused]] const ivec2 *){}(vp); + //[]([[maybe_unused]] ivec2 *const){}(vp); + []([[maybe_unused]] const ivec2 *const){}(vp); + + //[]([[maybe_unused]] ivec2 *&){}(vp); + []([[maybe_unused]] const ivec2 *&){}(vp); + //[]([[maybe_unused]] ivec2 *const &){}(vp); + []([[maybe_unused]] const ivec2 *const &){}(vp); + + //[]([[maybe_unused]] ivec2 *&&){}(vp); + //[]([[maybe_unused]] const ivec2 *&&){}(vp); + //[]([[maybe_unused]] ivec2 *const &&){}(vp); + //[]([[maybe_unused]] const ivec2 *const &&){}(vp); + } + } + + SUBCASE("crptr") { + const ivec2 v{1,2}; + const ivec2* vp = &v; + meta::detail::arg a{std::move(vp)}; + + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + + { + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + } + + { + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); + + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); + + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); + + //[]([[maybe_unused]] ivec2 *){}(std::move(vp)); + []([[maybe_unused]] const ivec2 *){}(std::move(vp)); + //[]([[maybe_unused]] ivec2 *const){}(std::move(vp)); + []([[maybe_unused]] const ivec2 *const){}(std::move(vp)); + + //[]([[maybe_unused]] ivec2 *&){}(std::move(vp)); + //[]([[maybe_unused]] const ivec2 *&){}(std::move(vp)); + //[]([[maybe_unused]] ivec2 *const &){}(std::move(vp)); + []([[maybe_unused]] const ivec2 *const &){}(std::move(vp)); + + //[]([[maybe_unused]] ivec2 *&&){}(std::move(vp)); + []([[maybe_unused]] const ivec2 *&&){}(std::move(vp)); + //[]([[maybe_unused]] ivec2 *const &&){}(std::move(vp)); + []([[maybe_unused]] const ivec2 *const &&){}(std::move(vp)); + } + } + + SUBCASE("cptr_c") { + const ivec2 v{1,2}; + const ivec2* const vp = &v; + meta::detail::arg a{vp}; + + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + + { + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + } + + { + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); + + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); + + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + + //[]([[maybe_unused]] ivec2 *){}(vp); + []([[maybe_unused]] const ivec2 *){}(vp); + //[]([[maybe_unused]] ivec2 *const){}(vp); + []([[maybe_unused]] const ivec2 *const){}(vp); + + //[]([[maybe_unused]] ivec2 *&){}(vp); + //[]([[maybe_unused]] const ivec2 *&){}(vp); + //[]([[maybe_unused]] ivec2 *const &){}(vp); + []([[maybe_unused]] const ivec2 *const &){}(vp); + + //[]([[maybe_unused]] ivec2 *&&){}(vp); + //[]([[maybe_unused]] const ivec2 *&&){}(vp); + //[]([[maybe_unused]] ivec2 *const &&){}(vp); + //[]([[maybe_unused]] const ivec2 *const &&){}(vp); + } + } + + SUBCASE("crptr_c") { + const ivec2 v{1,2}; + const ivec2* const vp = &v; + meta::detail::arg a{std::move(vp)}; + + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + + { + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + } + + { + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); + + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); + + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); + + //[]([[maybe_unused]] ivec2 *){}(std::move(vp)); + []([[maybe_unused]] const ivec2 *){}(std::move(vp)); + //[]([[maybe_unused]] ivec2 *const){}(std::move(vp)); + []([[maybe_unused]] const ivec2 *const){}(std::move(vp)); + + //[]([[maybe_unused]] ivec2 *&){}(std::move(vp)); + //[]([[maybe_unused]] const ivec2 *&){}(std::move(vp)); + //[]([[maybe_unused]] ivec2 *const &){}(std::move(vp)); + []([[maybe_unused]] const ivec2 *const &){}(std::move(vp)); + + //[]([[maybe_unused]] ivec2 *&&){}(std::move(vp)); + //[]([[maybe_unused]] const ivec2 *&&){}(std::move(vp)); + //[]([[maybe_unused]] ivec2 *const &&){}(std::move(vp)); + []([[maybe_unused]] const ivec2 *const &&){}(std::move(vp)); + } + } + + SUBCASE("ref") { + ivec2 v{1,2}; + ivec2& vr = v; + meta::detail::arg a{vr}; + + { + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + + []([[maybe_unused]] ivec2){}(vr); + []([[maybe_unused]] const ivec2){}(vr); + []([[maybe_unused]] ivec2&){}(vr); + []([[maybe_unused]] const ivec2&){}(vr); + //[]([[maybe_unused]] ivec2&&){}(vr); + //[]([[maybe_unused]] const ivec2&&){}(vr); + } + + { + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + } + + { + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + + //[]([[maybe_unused]] ivec2*){}(vr); + //[]([[maybe_unused]] const ivec2*){}(vr); + //[]([[maybe_unused]] ivec2* const){}(vr); + //[]([[maybe_unused]] const ivec2* const){}(vr); + + //[]([[maybe_unused]] ivec2 *&){}(vr); + //[]([[maybe_unused]] const ivec2 *&){}(vr); + //[]([[maybe_unused]] ivec2 *const &){}(vr); + //[]([[maybe_unused]] const ivec2 *const &){}(vr); + + //[]([[maybe_unused]] ivec2 *&&){}(vr); + //[]([[maybe_unused]] const ivec2 *&&){}(vr); + //[]([[maybe_unused]] ivec2 *const &&){}(vr); + //[]([[maybe_unused]] const ivec2 *const &&){}(vr); + } + } + + SUBCASE("cref") { + const ivec2 v{1,2}; + const ivec2& vr = v; + meta::detail::arg a{vr}; + + { + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + + []([[maybe_unused]] ivec2){}(vr); + []([[maybe_unused]] const ivec2){}(vr); + //[]([[maybe_unused]] ivec2&){}(vr); + []([[maybe_unused]] const ivec2&){}(vr); + //[]([[maybe_unused]] ivec2&&){}(vr); + //[]([[maybe_unused]] const ivec2&&){}(vr); + } + + { + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + } + + { + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + + //[]([[maybe_unused]] ivec2*){}(vr); + //[]([[maybe_unused]] const ivec2*){}(vr); + //[]([[maybe_unused]] ivec2* const){}(vr); + //[]([[maybe_unused]] const ivec2* const){}(vr); + + //[]([[maybe_unused]] ivec2 *&){}(vr); + //[]([[maybe_unused]] const ivec2 *&){}(vr); + //[]([[maybe_unused]] ivec2 *const &){}(vr); + //[]([[maybe_unused]] const ivec2 *const &){}(vr); + + //[]([[maybe_unused]] ivec2 *&&){}(vr); + //[]([[maybe_unused]] const ivec2 *&&){}(vr); + //[]([[maybe_unused]] ivec2 *const &&){}(vr); + //[]([[maybe_unused]] const ivec2 *const &&){}(vr); + } + } + + SUBCASE("rref") { + ivec2 v{1,2}; + meta::detail::arg a{std::move(v)}; + + { + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + + []([[maybe_unused]] ivec2){}(std::move(v)); + []([[maybe_unused]] const ivec2){}(std::move(v)); + //[]([[maybe_unused]] ivec2&){}(std::move(v)); + []([[maybe_unused]] const ivec2&){}(std::move(v)); + []([[maybe_unused]] ivec2&&){}(std::move(v)); + []([[maybe_unused]] const ivec2&&){}(std::move(v)); + } + + { + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + } + + { + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + + //[]([[maybe_unused]] ivec2*){}(std::move(v)); + //[]([[maybe_unused]] const ivec2*){}(std::move(v)); + //[]([[maybe_unused]] ivec2* const){}(std::move(v)); + //[]([[maybe_unused]] const ivec2* const){}(std::move(v)); + + //[]([[maybe_unused]] ivec2 *&){}(std::move(v)); + //[]([[maybe_unused]] const ivec2 *&){}(std::move(v)); + //[]([[maybe_unused]] ivec2 *const &){}(std::move(v)); + //[]([[maybe_unused]] const ivec2 *const &){}(std::move(v)); + + //[]([[maybe_unused]] ivec2 *&&){}(std::move(v)); + //[]([[maybe_unused]] const ivec2 *&&){}(std::move(v)); + //[]([[maybe_unused]] ivec2 *const &&){}(std::move(v)); + //[]([[maybe_unused]] const ivec2 *const &&){}(std::move(v)); + } + } + + SUBCASE("crref") { + const ivec2 v{1,2}; + meta::detail::arg a{std::move(v)}; + + { + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); + + []([[maybe_unused]] ivec2){}(std::move(v)); + []([[maybe_unused]] const ivec2){}(std::move(v)); + //[]([[maybe_unused]] ivec2&){}(std::move(v)); + []([[maybe_unused]] const ivec2&){}(std::move(v)); + //[]([[maybe_unused]] ivec2&&){}(std::move(v)); + []([[maybe_unused]] const ivec2&&){}(std::move(v)); + } + + { + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + } + + { + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + + //[]([[maybe_unused]] ivec2*){}(std::move(v)); + //[]([[maybe_unused]] const ivec2*){}(std::move(v)); + //[]([[maybe_unused]] ivec2* const){}(std::move(v)); + //[]([[maybe_unused]] const ivec2* const){}(std::move(v)); + + //[]([[maybe_unused]] ivec2 *&){}(std::move(v)); + //[]([[maybe_unused]] const ivec2 *&){}(std::move(v)); + //[]([[maybe_unused]] ivec2 *const &){}(std::move(v)); + //[]([[maybe_unused]] const ivec2 *const &){}(std::move(v)); + + //[]([[maybe_unused]] ivec2 *&&){}(std::move(v)); + //[]([[maybe_unused]] const ivec2 *&&){}(std::move(v)); + //[]([[maybe_unused]] ivec2 *const &&){}(std::move(v)); + //[]([[maybe_unused]] const ivec2 *const &&){}(std::move(v)); + } + } +} + +TEST_CASE("features/meta_utilities/arg/cast") { + namespace meta = meta_hpp; + + SUBCASE("ptr") { + ivec2 v{1,2}; + ivec2* vp = &v; + meta::detail::arg a{vp}; + + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + + { + CHECK(a.cast() == vp); + CHECK(a.cast() == vp); + CHECK(a.cast() == vp); + CHECK(a.cast() == vp); + + CHECK(a.cast() == vp); + CHECK_THROWS(a.cast()); + CHECK(a.cast() == vp); + CHECK(a.cast() == vp); + + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + } + } + + SUBCASE("rptr") { + ivec2 v{1,2}; + ivec2* vp = &v; + + CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); + CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); + CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); + CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); + CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); + CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); + + { + CHECK(meta::detail::arg{std::move(vp)}.cast() == vp); + CHECK(meta::detail::arg{std::move(vp)}.cast() == vp); + CHECK(meta::detail::arg{std::move(vp)}.cast() == vp); + CHECK(meta::detail::arg{std::move(vp)}.cast() == vp); + + CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); + CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); + CHECK(meta::detail::arg{std::move(vp)}.cast() == vp); + CHECK(meta::detail::arg{std::move(vp)}.cast() == vp); + + CHECK(meta::detail::arg{std::move(vp)}.cast() == vp); + CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); + CHECK(meta::detail::arg{std::move(vp)}.cast() == vp); + CHECK(meta::detail::arg{std::move(vp)}.cast() == vp); + } + } + + SUBCASE("ptr_c") { + ivec2 v{1,2}; + ivec2* const vp = &v; + meta::detail::arg a{vp}; + + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + + { + CHECK(a.cast() == vp); + CHECK(a.cast() == vp); + CHECK(a.cast() == vp); + CHECK(a.cast() == vp); + + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK(a.cast() == vp); + CHECK(a.cast() == vp); + + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + } + } + + SUBCASE("rptr_c") { + ivec2 v{1,2}; + ivec2* const vp = &v; + + CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); + CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); + CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); + CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); + CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); + CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); + + { + CHECK(meta::detail::arg{std::move(vp)}.cast() == vp); + CHECK(meta::detail::arg{std::move(vp)}.cast() == vp); + CHECK(meta::detail::arg{std::move(vp)}.cast() == vp); + CHECK(meta::detail::arg{std::move(vp)}.cast() == vp); + + CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); + CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); + CHECK(meta::detail::arg{std::move(vp)}.cast() == vp); + CHECK(meta::detail::arg{std::move(vp)}.cast() == vp); + + CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); + CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); + CHECK(meta::detail::arg{std::move(vp)}.cast() == vp); + CHECK(meta::detail::arg{std::move(vp)}.cast() == vp); + } + } + + SUBCASE("cptr") { + const ivec2 v{1,2}; + const ivec2* vp = &v; + meta::detail::arg a{vp}; + + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + + { + CHECK_THROWS(a.cast()); + CHECK(a.cast() == vp); + CHECK_THROWS(a.cast()); + CHECK(a.cast() == vp); + + CHECK_THROWS(a.cast()); + CHECK(a.cast() == vp); + CHECK_THROWS(a.cast()); + CHECK(a.cast() == vp); + + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + } + } + + SUBCASE("crptr") { + const ivec2 v{1,2}; + const ivec2* vp = &v; + + CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); + CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); + CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); + CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); + CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); + CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); + + { + CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); + CHECK(meta::detail::arg{std::move(vp)}.cast() == vp); + CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); + CHECK(meta::detail::arg{std::move(vp)}.cast() == vp); + + CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); + CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); + CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); + CHECK(meta::detail::arg{std::move(vp)}.cast() == vp); + + CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); + CHECK(meta::detail::arg{std::move(vp)}.cast() == vp); + CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); + CHECK(meta::detail::arg{std::move(vp)}.cast() == vp); + } + } + + SUBCASE("cptr_c") { + const ivec2 v{1,2}; + const ivec2* const vp = &v; + meta::detail::arg a{vp}; + + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + + { + CHECK_THROWS(a.cast()); + CHECK(a.cast() == vp); + CHECK_THROWS(a.cast()); + CHECK(a.cast() == vp); + + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK(a.cast() == vp); + + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + } + } + + SUBCASE("crptr_c") { + const ivec2 v{1,2}; + const ivec2* const vp = &v; + + CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); + CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); + CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); + CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); + CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); + CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); + + { + CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); + CHECK(meta::detail::arg{std::move(vp)}.cast() == vp); + CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); + CHECK(meta::detail::arg{std::move(vp)}.cast() == vp); + + CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); + CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); + CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); + CHECK(meta::detail::arg{std::move(vp)}.cast() == vp); + + CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); + CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); + CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); + CHECK(meta::detail::arg{std::move(vp)}.cast() == vp); + } + } + + SUBCASE("ref") { + ivec2 v{1,2}; + ivec2& vr = v; + meta::detail::arg a{vr}; + + CHECK(a.cast() == ivec2{1,2}); + CHECK(a.cast() == ivec2{1,2}); + CHECK(&a.cast() == &v); + CHECK(&a.cast() == &vr); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + } + + SUBCASE("cref") { + const ivec2 v{1,2}; + const ivec2& vr = v; + meta::detail::arg a{vr}; + + CHECK(a.cast() == v); + CHECK(a.cast() == v); + CHECK_THROWS(a.cast()); + CHECK(&a.cast() == &vr); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + } + + SUBCASE("rref") { + CHECK(meta::detail::arg{ivec2{1,2}}.cast() == ivec2{1,2}); + CHECK(meta::detail::arg{ivec2{1,2}}.cast() == ivec2{1,2}); + CHECK_THROWS(meta::detail::arg{ivec2{1,2}}.cast()); + CHECK(meta::detail::arg{ivec2{1,2}}.cast() == ivec2{1,2}); + CHECK(meta::detail::arg{ivec2{1,2}}.cast() == ivec2{1,2}); + CHECK(meta::detail::arg{ivec2{1,2}}.cast() == ivec2{1,2}); + + CHECK_THROWS(meta::detail::arg{ivec2{1,2}}.cast()); + CHECK_THROWS(meta::detail::arg{ivec2{1,2}}.cast()); + CHECK_THROWS(meta::detail::arg{ivec2{1,2}}.cast()); + CHECK_THROWS(meta::detail::arg{ivec2{1,2}}.cast()); + } + + SUBCASE("crref") { + const ivec2 v{1,2}; + meta::detail::arg a{std::move(v)}; + + CHECK(a.cast() == ivec2{1,2}); + CHECK(a.cast() == ivec2{1,2}); + CHECK_THROWS(a.cast()); + CHECK(&a.cast() == &v); + CHECK_THROWS(a.cast()); + CHECK(a.cast() == v); + + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + CHECK_THROWS(a.cast()); + } +} diff --git a/untests/meta_utilities/inst_tests.cpp b/untests/meta_utilities/inst_tests.cpp new file mode 100644 index 0000000..5f29099 --- /dev/null +++ b/untests/meta_utilities/inst_tests.cpp @@ -0,0 +1,72 @@ +/******************************************************************************* + * 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_tests.hpp" + +namespace +{ + struct ivec2 { + int x{}; + int y{}; + + [[maybe_unused]] ivec2() = default; + [[maybe_unused]] explicit ivec2(int v): x{v}, y{v} {} + [[maybe_unused]] ivec2(int x, int y): x{x}, y{y} {} + + [[maybe_unused]] ivec2(ivec2&& other) noexcept { + x = other.x; + y = other.y; + other.x = 0; + other.y = 0; + } + + [[maybe_unused]] ivec2(const ivec2& other) noexcept { + x = other.x; + y = other.y; + } + + ivec2& operator=(ivec2&&) = delete; + ivec2& operator=(const ivec2&) = delete; + }; +} + +TEST_CASE("features/meta_utilities/inst") { + namespace meta = meta_hpp; + + SUBCASE("ref") { + ivec2 v{1,2}; + ivec2& vr = v; + meta::detail::inst a{vr}; + + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::inst::ref_types::ref); + } + + SUBCASE("cref") { + const ivec2 v{1,2}; + const ivec2& vr = v; + meta::detail::inst a{vr}; + + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::inst::ref_types::cref); + } + + SUBCASE("rref") { + ivec2 v{1,2}; + meta::detail::inst a{std::move(v)}; + + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::inst::ref_types::rref); + } + + SUBCASE("crref") { + const ivec2 v{1,2}; + meta::detail::inst a{std::move(v)}; + + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::inst::ref_types::crref); + } +} diff --git a/untests/meta_utilities/value_tests.cpp b/untests/meta_utilities/value_tests.cpp new file mode 100644 index 0000000..5f26f36 --- /dev/null +++ b/untests/meta_utilities/value_tests.cpp @@ -0,0 +1,295 @@ +/******************************************************************************* + * 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_tests.hpp" + +namespace +{ + struct ivec2 { + int x{}; + int y{}; + + [[maybe_unused]] ivec2() = default; + [[maybe_unused]] explicit ivec2(int v): x{v}, y{v} {} + [[maybe_unused]] ivec2(int x, int y): x{x}, y{y} {} + + ivec2(ivec2&& other) noexcept + : x{other.x} + , y{other.y} { + other.x = 0; + other.y = 0; + ++move_ctor_counter; + } + + ivec2(const ivec2& other) noexcept + : x{other.x} + , y{other.y} { + ++copy_ctor_counter; + } + + ivec2& operator=(ivec2&& other) = delete; + ivec2& operator=(const ivec2& other) = delete; + public: + static int move_ctor_counter; + static int copy_ctor_counter; + }; + + int ivec2::move_ctor_counter{0}; + int ivec2::copy_ctor_counter{0}; + + bool operator==(const ivec2& l, const ivec2& r) noexcept { + return l.x == r.x && l.y == r.y; + } +} + +TEST_CASE("meta/meta_utilities/value") { + namespace meta = meta_hpp; + + ivec2::move_ctor_counter = 0; + ivec2::copy_ctor_counter = 0; + + SUBCASE("cast types") { + static_assert(std::is_same_v< + decltype(std::declval().cast()), + ivec2&>); + static_assert(std::is_same_v< + decltype(std::declval().cast()), + ivec2&&>); + static_assert(std::is_same_v< + decltype(std::declval().cast()), + const ivec2&>); + static_assert(std::is_same_v< + decltype(std::declval().cast()), + const ivec2&&>); + } + + SUBCASE("try_cast types") { + static_assert(std::is_same_v< + decltype(std::declval().try_cast()), + ivec2*>); + static_assert(std::is_same_v< + decltype(std::declval().try_cast()), + const ivec2*>); + } + + SUBCASE("ivec2&") { + ivec2 v{1,2}; + ivec2& vr = v; + + meta::value val{vr}; + CHECK(ivec2::move_ctor_counter == 0); + CHECK(ivec2::copy_ctor_counter == 1); + + CHECK(val.get_type() == meta::resolve_type()); + + CHECK(!std::memcmp(val.data(), &vr, sizeof(ivec2))); + CHECK(!std::memcmp(val.cdata(), &vr, sizeof(ivec2))); + CHECK(!std::memcmp(std::as_const(val).data(), &vr, sizeof(ivec2))); + CHECK(!std::memcmp(std::as_const(val).cdata(), &vr, sizeof(ivec2))); + + CHECK(val == ivec2{1,2}); + CHECK(val == meta::value{ivec2{1,2}}); + + CHECK(val.cast() == ivec2{1,2}); + CHECK(std::as_const(val).cast() == ivec2{1,2}); + + CHECK(*val.try_cast() == ivec2{1,2}); + CHECK(*std::as_const(val).try_cast() == ivec2{1,2}); + } + + SUBCASE("const ivec2&") { + const ivec2 v{1,2}; + const ivec2& vr = v; + + meta::value val{vr}; + CHECK(ivec2::move_ctor_counter == 0); + CHECK(ivec2::copy_ctor_counter == 1); + + CHECK(val.get_type() == meta::resolve_type()); + + CHECK(!std::memcmp(val.data(), &vr, sizeof(ivec2))); + CHECK(!std::memcmp(val.cdata(), &vr, sizeof(ivec2))); + CHECK(!std::memcmp(std::as_const(val).data(), &vr, sizeof(ivec2))); + CHECK(!std::memcmp(std::as_const(val).cdata(), &vr, sizeof(ivec2))); + + CHECK(val == ivec2{1,2}); + CHECK(val == meta::value{ivec2{1,2}}); + + CHECK(val.cast() == ivec2{1,2}); + CHECK(std::as_const(val).cast() == ivec2{1,2}); + + CHECK(*val.try_cast() == ivec2{1,2}); + CHECK(*std::as_const(val).try_cast() == ivec2{1,2}); + } + + SUBCASE("ivec2&&") { + ivec2 v{1,2}; + + meta::value val{std::move(v)}; + CHECK(ivec2::move_ctor_counter == 1); + CHECK(ivec2::copy_ctor_counter == 0); + + CHECK(val.get_type() == meta::resolve_type()); + + CHECK(val == ivec2{1,2}); + CHECK(val == meta::value{ivec2{1,2}}); + + CHECK(val.cast() == ivec2{1,2}); + CHECK(std::as_const(val).cast() == ivec2{1,2}); + + CHECK(*val.try_cast() == ivec2{1,2}); + CHECK(*std::as_const(val).try_cast() == ivec2{1,2}); + } + + SUBCASE("const ivec2&&") { + const ivec2 v{1,2}; + + meta::value val{std::move(v)}; + CHECK(ivec2::move_ctor_counter == 0); + CHECK(ivec2::copy_ctor_counter == 1); + + CHECK(val.get_type() == meta::resolve_type()); + + CHECK(val == ivec2{1,2}); + CHECK(val == meta::value{ivec2{1,2}}); + + CHECK(val.cast() == ivec2{1,2}); + CHECK(std::as_const(val).cast() == ivec2{1,2}); + + CHECK(*val.try_cast() == ivec2{1,2}); + CHECK(*std::as_const(val).try_cast() == ivec2{1,2}); + } + + SUBCASE("value(value&&)") { + ivec2 v{1,2}; + meta::value val_src{std::move(v)}; + CHECK(ivec2::move_ctor_counter == 1); + CHECK(ivec2::copy_ctor_counter == 0); + + meta::value val_dst{std::move(val_src)}; + CHECK(val_dst == ivec2{1,2}); + CHECK(ivec2::move_ctor_counter == 2); + CHECK(ivec2::copy_ctor_counter == 0); + + CHECK(val_src == ivec2{0,0}); + CHECK(val_src.data() != val_dst.data()); + } + + SUBCASE("value(const meta::value&)") { + const ivec2 v{1,2}; + meta::value val_src{v}; + CHECK(ivec2::move_ctor_counter == 0); + CHECK(ivec2::copy_ctor_counter == 1); + + meta::value val_dst{val_src}; + CHECK(val_dst == ivec2{1,2}); + CHECK(ivec2::move_ctor_counter == 0); + CHECK(ivec2::copy_ctor_counter == 2); + + CHECK(val_src == ivec2{1,2}); + CHECK(val_src.data() != val_dst.data()); + } + + SUBCASE("value& operator=(value&&)") { + meta::value val_src1{std::string("world")}; + meta::value val_src2{ivec2{1,2}}; + CHECK(ivec2::move_ctor_counter == 1); + CHECK(ivec2::copy_ctor_counter == 0); + + meta::value val_dst{std::string("hello")}; + + val_dst = std::move(val_src1); + CHECK(val_dst == std::string("world")); + CHECK(ivec2::move_ctor_counter == 1); + CHECK(ivec2::copy_ctor_counter == 0); + + val_dst = std::move(val_src2); + CHECK(val_dst == ivec2{1,2}); + CHECK(ivec2::move_ctor_counter == 2); + CHECK(ivec2::copy_ctor_counter == 0); + + CHECK(val_src2 == ivec2{0,0}); + CHECK(val_src2.data() != val_dst.data()); + } + + SUBCASE("value& operator=(const meta::value&)") { + meta::value val_src1{std::string("world")}; + meta::value val_src2{ivec2{1,2}}; + CHECK(ivec2::move_ctor_counter == 1); + CHECK(ivec2::copy_ctor_counter == 0); + + meta::value val_dst{std::string("hello")}; + + val_dst = val_src1; + CHECK(val_dst == std::string("world")); + CHECK(ivec2::move_ctor_counter == 1); + CHECK(ivec2::copy_ctor_counter == 0); + + val_dst = val_src2; + CHECK(val_dst == ivec2{1,2}); + CHECK(ivec2::move_ctor_counter == 1); + CHECK(ivec2::copy_ctor_counter == 1); + + CHECK(val_src2 == ivec2{1,2}); + CHECK(val_src2.data() != val_dst.data()); + } + + SUBCASE("swap") { + meta::value val1{std::string("world")}; + meta::value val2{ivec2{1,2}}; + CHECK(ivec2::move_ctor_counter == 1); + CHECK(ivec2::copy_ctor_counter == 0); + + val1.swap(val2); + CHECK(val1 == ivec2{1,2}); + CHECK(val2 == std::string("world")); + CHECK((ivec2::move_ctor_counter == 2 || ivec2::move_ctor_counter == 3)); + CHECK(ivec2::copy_ctor_counter == 0); + + swap(val1, val2); + CHECK(val1 == std::string("world")); + CHECK(val2 == ivec2{1,2}); + } + + SUBCASE("ostream") { + std::stringstream str_stream; + CHECK_NOTHROW(str_stream << meta::value{21} << " " << meta::value{42}); + CHECK_THROWS((str_stream << meta::value{ivec2{1,2}})); + REQUIRE(str_stream.str() == "21 42"); + } + + SUBCASE("istream") { + std::stringstream str_stream{"21 42"}; + + meta::value v{ivec2{1,2}}; + CHECK_THROWS(str_stream >> v); + + v = meta::value{0}; + CHECK_NOTHROW(str_stream >> v); + CHECK(v == 21); + CHECK_NOTHROW(str_stream >> v); + CHECK(v == 42); + } + + SUBCASE("operator==") { + CHECK(meta::value{ivec2{1,2}} == ivec2{1,2}); + CHECK_FALSE(meta::value{ivec2{1,2}} == ivec2{1,3}); + + CHECK(ivec2{1,2} == meta::value{ivec2{1,2}}); + CHECK_FALSE(ivec2{1,3} == meta::value{ivec2{1,2}}); + + CHECK(meta::value{ivec2{1,2}} == meta::value{ivec2{1,2}}); + CHECK_FALSE(meta::value{ivec2{1,2}} == meta::value{ivec2{1,3}}); + + { + class empty_class1 {}; + class empty_class2 {}; + + CHECK_FALSE(operator==(meta::value{empty_class1{}}, meta::value{empty_class2{}})); + CHECK_THROWS(operator==(meta::value{empty_class1{}}, meta::value{empty_class1{}})); + } + } +} From 78e45607dd6e4462095b896e5cc264cd74b9328a Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Thu, 25 Nov 2021 18:57:53 +0700 Subject: [PATCH 114/233] fix deep is_base_of and is_derived_from --- headers/meta.hpp/meta_registry/class_bind.hpp | 4 ++ headers/meta.hpp/meta_types/class_type.hpp | 32 ++++++++++++++- untests/meta_types/class_type_tests.cpp | 40 ++++++++++++++++++- 3 files changed, 72 insertions(+), 4 deletions(-) diff --git a/headers/meta.hpp/meta_registry/class_bind.hpp b/headers/meta.hpp/meta_registry/class_bind.hpp index e4e0b2c..dc074bd 100644 --- a/headers/meta.hpp/meta_registry/class_bind.hpp +++ b/headers/meta.hpp/meta_registry/class_bind.hpp @@ -23,6 +23,7 @@ namespace meta_hpp template < class_kind Class > template < typename... Args > class_bind& class_bind::ctor_() { + static_assert(std::is_constructible_v); auto ctor_state = detail::ctor_state::make(); data_->ctors.emplace(ctor_state->index, std::move(ctor_state)); return *this; @@ -31,6 +32,7 @@ namespace meta_hpp template < class_kind Class > template < class_kind Base > class_bind& class_bind::base_() { + static_assert(std::is_base_of_v); auto base_data = detail::class_type_data::get(); data_->bases.emplace(base_data); return *this; @@ -47,6 +49,7 @@ namespace meta_hpp template < class_kind Class > template < member_kind Member > class_bind& class_bind::member_(std::string name, Member member) { + static_assert(std::same_as::class_type>); 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; @@ -55,6 +58,7 @@ namespace meta_hpp template < class_kind Class > template < method_kind Method > class_bind& class_bind::method_(std::string name, Method method) { + static_assert(std::same_as::class_type>); 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; diff --git a/headers/meta.hpp/meta_types/class_type.hpp b/headers/meta.hpp/meta_types/class_type.hpp index 58738e9..2a33cc3 100644 --- a/headers/meta.hpp/meta_types/class_type.hpp +++ b/headers/meta.hpp/meta_types/class_type.hpp @@ -97,7 +97,21 @@ namespace meta_hpp } inline bool class_type::is_base_of(const class_type& derived) const noexcept { - return derived.data_ && derived.data_->bases.contains(*this); + if ( !is_valid() || !derived.is_valid() ) { + return false; + } + + if ( derived.data_->bases.contains(*this) ) { + return true; + } + + for ( auto&& derived_base : derived.data_->bases ) { + if ( is_base_of(derived_base) ) { + return true; + } + } + + return false; } template < class_kind Base > @@ -106,7 +120,21 @@ namespace meta_hpp } inline bool class_type::is_derived_from(const class_type& base) const noexcept { - return data_ && data_->bases.contains(base); + if ( !is_valid() || !base.is_valid() ) { + return false; + } + + if ( data_->bases.contains(base) ) { + return true; + } + + for ( auto&& self_base : data_->bases ) { + if ( self_base.is_derived_from(base) ) { + return true; + } + } + + return false; } inline function class_type::get_function(std::string_view name) const noexcept { diff --git a/untests/meta_types/class_type_tests.cpp b/untests/meta_types/class_type_tests.cpp index a17dad8..cfbcbd6 100644 --- a/untests/meta_types/class_type_tests.cpp +++ b/untests/meta_types/class_type_tests.cpp @@ -38,7 +38,7 @@ namespace float base_clazz_2::base_variable_2 = 2.0f; - struct derived_clazz final : base_clazz_1, base_clazz_2 { + struct derived_clazz : base_clazz_1, base_clazz_2 { derived_clazz(int i, float f) : base_clazz_1{i} , base_clazz_2{f} {} @@ -50,6 +50,10 @@ namespace static constexpr double derived_variable = 3.0; }; + struct final_derived_clazz final : derived_clazz { + using derived_clazz::derived_clazz; + }; + template < typename... Args > struct variadic_clazz {}; } @@ -84,6 +88,10 @@ TEST_CASE("meta/meta_types/class_type") { .function_("derived_function", &derived_clazz::derived_function) .variable_("derived_variable", &derived_clazz::derived_variable); + meta::class_() + .ctor_() + .base_(); + const meta::class_type base_clazz_1_type = meta::resolve_type(); REQUIRE(base_clazz_1_type); @@ -93,6 +101,9 @@ TEST_CASE("meta/meta_types/class_type") { const meta::class_type derived_clazz_type = meta::resolve_type(); REQUIRE(derived_clazz_type); + const meta::class_type final_derived_clazz_type = meta::resolve_type(); + REQUIRE(final_derived_clazz_type); + const meta::class_type variadic_clazz_int_type = meta::resolve_type>(); REQUIRE(variadic_clazz_int_type); @@ -102,7 +113,8 @@ TEST_CASE("meta/meta_types/class_type") { SUBCASE("get_flags") { CHECK(base_clazz_1_type.get_flags() == meta::class_flags{}); CHECK(base_clazz_2_type.get_flags() == meta::class_flags{}); - CHECK(derived_clazz_type.get_flags() == meta::class_flags::is_final); + CHECK(derived_clazz_type.get_flags() == meta::class_flags{}); + CHECK(final_derived_clazz_type.get_flags() == meta::class_flags::is_final); CHECK(variadic_clazz_int_type.get_flags() == (meta::class_flags::is_empty | meta::class_flags::is_template_instantiation)); CHECK(variadic_clazz_int_float_type.get_flags() == (meta::class_flags::is_empty | meta::class_flags::is_template_instantiation)); } @@ -111,6 +123,7 @@ TEST_CASE("meta/meta_types/class_type") { CHECK(base_clazz_1_type.get_size() == sizeof(base_clazz_1)); CHECK(base_clazz_2_type.get_size() == sizeof(base_clazz_2)); CHECK(derived_clazz_type.get_size() == sizeof(derived_clazz)); + CHECK(final_derived_clazz_type.get_size() == sizeof(final_derived_clazz)); } SUBCASE("get_arity") { @@ -174,36 +187,42 @@ TEST_CASE("meta/meta_types/class_type") { CHECK(base_clazz_1_type.get_ctors().size() == 1); CHECK(base_clazz_2_type.get_ctors().size() == 1); CHECK(derived_clazz_type.get_ctors().size() == 1); + CHECK(final_derived_clazz_type.get_ctors().size() == 1); } SUBCASE("get_bases") { CHECK(base_clazz_1_type.get_bases() == meta::class_set{}); CHECK(base_clazz_2_type.get_bases() == meta::class_set{}); CHECK(derived_clazz_type.get_bases() == meta::class_set{base_clazz_1_type, base_clazz_2_type}); + CHECK(final_derived_clazz_type.get_bases() == meta::class_set{derived_clazz_type}); } SUBCASE("get_functions") { CHECK(base_clazz_1_type.get_functions().size() == 3); CHECK(base_clazz_2_type.get_functions().size() == 1); CHECK(derived_clazz_type.get_functions().size() == 1); + CHECK(final_derived_clazz_type.get_functions().size() == 0); } SUBCASE("get_members") { CHECK(base_clazz_1_type.get_members().size() == 1); CHECK(base_clazz_2_type.get_members().size() == 1); CHECK(derived_clazz_type.get_members().size() == 1); + CHECK(final_derived_clazz_type.get_members().size() == 0); } SUBCASE("get_methods") { CHECK(base_clazz_1_type.get_methods().size() == 3); CHECK(base_clazz_2_type.get_methods().size() == 1); CHECK(derived_clazz_type.get_methods().size() == 1); + CHECK(final_derived_clazz_type.get_methods().size() == 0); } SUBCASE("get_variables") { CHECK(base_clazz_1_type.get_variables().size() == 1); CHECK(base_clazz_2_type.get_variables().size() == 1); CHECK(derived_clazz_type.get_variables().size() == 1); + CHECK(final_derived_clazz_type.get_variables().size() == 0); } SUBCASE("is_base_of") { @@ -216,6 +235,9 @@ TEST_CASE("meta/meta_types/class_type") { CHECK(base_clazz_1_type.is_base_of()); CHECK(base_clazz_1_type.is_base_of(derived_clazz_type)); + + CHECK(base_clazz_1_type.is_base_of()); + CHECK(base_clazz_1_type.is_base_of(final_derived_clazz_type)); } { @@ -227,6 +249,9 @@ TEST_CASE("meta/meta_types/class_type") { CHECK(base_clazz_2_type.is_base_of()); CHECK(base_clazz_2_type.is_base_of(derived_clazz_type)); + + CHECK(base_clazz_2_type.is_base_of()); + CHECK(base_clazz_2_type.is_base_of(final_derived_clazz_type)); } { @@ -274,6 +299,17 @@ TEST_CASE("meta/meta_types/class_type") { CHECK_FALSE(derived_clazz_type.is_derived_from()); CHECK_FALSE(derived_clazz_type.is_derived_from(derived_clazz_type)); } + + { + CHECK(final_derived_clazz_type.is_derived_from()); + CHECK(final_derived_clazz_type.is_derived_from(base_clazz_1_type)); + + CHECK(final_derived_clazz_type.is_derived_from()); + CHECK(final_derived_clazz_type.is_derived_from(base_clazz_2_type)); + + CHECK(final_derived_clazz_type.is_derived_from()); + CHECK(final_derived_clazz_type.is_derived_from(derived_clazz_type)); + } } SUBCASE("get_function") { From 19a588bf75a74b3fa17cd3f4b569c8523ee15953 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Thu, 25 Nov 2021 22:18:27 +0700 Subject: [PATCH 115/233] hide kind concepts --- headers/meta.hpp/meta_base.hpp | 34 ++++++------ headers/meta.hpp/meta_kinds.hpp | 34 ++++++------ headers/meta.hpp/meta_registry.hpp | 26 ++++----- headers/meta.hpp/meta_registry/class_bind.hpp | 26 ++++----- headers/meta.hpp/meta_registry/enum_bind.hpp | 6 +- headers/meta.hpp/meta_registry/scope_bind.hpp | 8 +-- headers/meta.hpp/meta_states.hpp | 27 +++++---- headers/meta.hpp/meta_states/ctor.hpp | 2 +- headers/meta.hpp/meta_states/function.hpp | 2 +- headers/meta.hpp/meta_states/method.hpp | 6 +- headers/meta.hpp/meta_types.hpp | 55 ++++++++++--------- headers/meta.hpp/meta_types/class_type.hpp | 4 +- 12 files changed, 118 insertions(+), 112 deletions(-) diff --git a/headers/meta.hpp/meta_base.hpp b/headers/meta.hpp/meta_base.hpp index 099b25f..e69e458 100644 --- a/headers/meta.hpp/meta_base.hpp +++ b/headers/meta.hpp/meta_base.hpp @@ -39,23 +39,6 @@ namespace meta_hpp using bitflags = enum_hpp::bitflags::bitflags; } -namespace meta_hpp -{ - template < typename... Types > - struct type_list {}; - - template < std::size_t Index, typename TypeList > - struct type_list_at; - - template < std::size_t Index, typename... Types > - struct type_list_at> { - using type = std::tuple_element_t>; - }; - - template < std::size_t Index, typename TypeList > - using type_list_at_t = typename type_list_at::type; -} - namespace meta_hpp { template < typename Signature > @@ -67,6 +50,23 @@ namespace meta_hpp constexpr auto select(Signature Class::*func) -> decltype(func) { return func; } + + namespace detail + { + template < typename... Types > + struct type_list {}; + + template < std::size_t Index, typename TypeList > + struct type_list_at; + + template < std::size_t Index, typename... Types > + struct type_list_at> { + using type = std::tuple_element_t>; + }; + + template < std::size_t Index, typename TypeList > + using type_list_at_t = typename type_list_at::type; + } } namespace meta_hpp diff --git a/headers/meta.hpp/meta_kinds.hpp b/headers/meta.hpp/meta_kinds.hpp index 3aa55fb..c524c13 100644 --- a/headers/meta.hpp/meta_kinds.hpp +++ b/headers/meta.hpp/meta_kinds.hpp @@ -9,6 +9,23 @@ #include "meta_base.hpp" namespace meta_hpp +{ + enum class type_kind : std::uint32_t { + array_, + class_, + ctor_, + enum_, + function_, + member_, + method_, + number_, + pointer_, + reference_, + void_, + }; +} + +namespace meta_hpp::detail { template < typename T > concept array_kind = std::is_array_v; @@ -39,23 +56,6 @@ namespace meta_hpp template < typename T > concept void_kind = std::is_void_v; -} - -namespace meta_hpp -{ - enum class type_kind : std::uint32_t { - array_, - class_, - ctor_, - enum_, - function_, - member_, - method_, - number_, - pointer_, - reference_, - void_, - }; template < typename T > constexpr type_kind make_type_kind() noexcept { diff --git a/headers/meta.hpp/meta_registry.hpp b/headers/meta.hpp/meta_registry.hpp index 88f98cf..ec2f827 100644 --- a/headers/meta.hpp/meta_registry.hpp +++ b/headers/meta.hpp/meta_registry.hpp @@ -11,7 +11,7 @@ namespace meta_hpp { - template < class_kind Class > + template < detail::class_kind Class > class class_bind final { public: explicit class_bind(); @@ -20,19 +20,19 @@ namespace meta_hpp template < typename... Args > class_bind& ctor_(); - template < class_kind Base > + template < detail::class_kind Base > class_bind& base_(); - template < function_kind Function > + template < detail::function_kind Function > class_bind& function_(std::string name, Function function); - template < member_kind Member > + template < detail::member_kind Member > class_bind& member_(std::string name, Member member); - template < method_kind Method > + template < detail::method_kind Method > class_bind& method_(std::string name, Method method); - template < pointer_kind Pointer > + template < detail::pointer_kind Pointer > class_bind& variable_(std::string name, Pointer pointer); private: detail::class_type_data_ptr data_; @@ -41,7 +41,7 @@ namespace meta_hpp namespace meta_hpp { - template < enum_kind Enum > + template < detail::enum_kind Enum > class enum_bind final { public: explicit enum_bind(); @@ -60,16 +60,16 @@ namespace meta_hpp explicit scope_bind(std::string_view name); operator scope() const noexcept; - template < class_kind Class > + template < detail::class_kind Class > scope_bind& class_(std::string name); - template < enum_kind Enum > + template < detail::enum_kind Enum > scope_bind& enum_(std::string name); - template < function_kind Function > + template < detail::function_kind Function > scope_bind& function_(std::string name, Function function); - template < pointer_kind Pointer > + template < detail::pointer_kind Pointer > scope_bind& variable_(std::string name, Pointer pointer); private: detail::scope_state_ptr state_; @@ -78,12 +78,12 @@ namespace meta_hpp namespace meta_hpp { - template < class_kind Class > + template < detail::class_kind Class > class_bind class_() { return class_bind{}; } - template < enum_kind Enum > + template < detail::enum_kind Enum > enum_bind enum_() { return enum_bind{}; } diff --git a/headers/meta.hpp/meta_registry/class_bind.hpp b/headers/meta.hpp/meta_registry/class_bind.hpp index dc074bd..65c432d 100644 --- a/headers/meta.hpp/meta_registry/class_bind.hpp +++ b/headers/meta.hpp/meta_registry/class_bind.hpp @@ -11,16 +11,16 @@ namespace meta_hpp { - template < class_kind Class > + template < detail::class_kind Class > class_bind::class_bind() : data_{detail::get_type_data()} {} - template < class_kind Class > + template < detail::class_kind Class > class_bind::operator class_type() const noexcept { return class_type{data_}; } - template < class_kind Class > + template < detail::class_kind Class > template < typename... Args > class_bind& class_bind::ctor_() { static_assert(std::is_constructible_v); @@ -29,8 +29,8 @@ namespace meta_hpp return *this; } - template < class_kind Class > - template < class_kind Base > + template < detail::class_kind Class > + template < detail::class_kind Base > class_bind& class_bind::base_() { static_assert(std::is_base_of_v); auto base_data = detail::class_type_data::get(); @@ -38,16 +38,16 @@ namespace meta_hpp return *this; } - template < class_kind Class > - template < function_kind Function > + template < detail::class_kind Class > + template < detail::function_kind Function > class_bind& class_bind::function_(std::string name, Function function) { 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 < class_kind Class > - template < member_kind Member > + template < detail::class_kind Class > + template < detail::member_kind Member > class_bind& class_bind::member_(std::string name, Member member) { static_assert(std::same_as::class_type>); auto member_state = detail::member_state::make(std::move(name), std::move(member)); @@ -55,8 +55,8 @@ namespace meta_hpp return *this; } - template < class_kind Class > - template < method_kind Method > + template < detail::class_kind Class > + template < detail::method_kind Method > class_bind& class_bind::method_(std::string name, Method method) { static_assert(std::same_as::class_type>); auto method_state = detail::method_state::make(std::move(name), std::move(method)); @@ -64,8 +64,8 @@ namespace meta_hpp return *this; } - template < class_kind Class > - template < pointer_kind Pointer > + template < detail::class_kind Class > + template < detail::pointer_kind Pointer > class_bind& class_bind::variable_(std::string name, Pointer pointer) { auto variable_state = detail::variable_state::make(std::move(name), std::move(pointer)); data_->variables.emplace(variable_state->index, std::move(variable_state)); diff --git a/headers/meta.hpp/meta_registry/enum_bind.hpp b/headers/meta.hpp/meta_registry/enum_bind.hpp index d806c18..0ada250 100644 --- a/headers/meta.hpp/meta_registry/enum_bind.hpp +++ b/headers/meta.hpp/meta_registry/enum_bind.hpp @@ -11,16 +11,16 @@ namespace meta_hpp { - template < enum_kind Enum > + template < detail::enum_kind Enum > enum_bind::enum_bind() : data_{detail::get_type_data()} {} - template < enum_kind Enum > + template < detail::enum_kind Enum > enum_bind::operator enum_type() const noexcept { return enum_type{data_}; } - template < enum_kind Enum > + template < detail::enum_kind Enum > enum_bind& enum_bind::evalue_(std::string name, Enum value) { auto evalue_state = detail::evalue_state::make(std::move(name), std::move(value)); data_->evalues.emplace(evalue_state->index, std::move(evalue_state)); diff --git a/headers/meta.hpp/meta_registry/scope_bind.hpp b/headers/meta.hpp/meta_registry/scope_bind.hpp index f2b2a48..2d7a495 100644 --- a/headers/meta.hpp/meta_registry/scope_bind.hpp +++ b/headers/meta.hpp/meta_registry/scope_bind.hpp @@ -18,28 +18,28 @@ namespace meta_hpp return scope{state_}; } - template < class_kind Class > + template < detail::class_kind Class > scope_bind& scope_bind::class_(std::string name) { auto class_data = detail::class_type_data::get(); state_->classes.emplace(std::move(name), class_data); return *this; } - template < enum_kind Enum > + template < detail::enum_kind Enum > scope_bind& scope_bind::enum_(std::string name) { auto enum_data = detail::enum_type_data::get(); state_->enums.emplace(std::move(name), enum_data); return *this; } - template < function_kind Function > + 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)); state_->functions.emplace(function_state->index, std::move(function_state)); return *this; } - template < pointer_kind Pointer > + 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)); state_->variables.emplace(variable_state->index, std::move(variable_state)); diff --git a/headers/meta.hpp/meta_states.hpp b/headers/meta.hpp/meta_states.hpp index 0718416..c6a19c0 100644 --- a/headers/meta.hpp/meta_states.hpp +++ b/headers/meta.hpp/meta_states.hpp @@ -12,17 +12,20 @@ namespace meta_hpp { - template < typename T > - concept states_family = - std::same_as || - std::same_as || - std::same_as || - std::same_as || - std::same_as || - std::same_as || - std::same_as; + namespace detail + { + template < typename T > + concept state_family = + std::same_as || + std::same_as || + std::same_as || + std::same_as || + std::same_as || + std::same_as || + std::same_as; + } - template < states_family T, states_family U > + template < detail::state_family T, detail::state_family U > bool operator<(const T& l, const U& r) noexcept { if ( !static_cast(r) ) { return false; @@ -35,7 +38,7 @@ namespace meta_hpp return l.get_index() < r.get_index(); } - template < states_family T, states_family U > + template < detail::state_family T, detail::state_family U > bool operator==(const T& l, const U& r) noexcept { if ( static_cast(l) != static_cast(r) ) { return false; @@ -48,7 +51,7 @@ namespace meta_hpp return l.get_index() == r.get_index(); } - template < states_family T, states_family U > + template < detail::state_family T, detail::state_family U > bool operator!=(const T& l, const U& r) noexcept { return !(l == r); } diff --git a/headers/meta.hpp/meta_states/ctor.hpp b/headers/meta.hpp/meta_states/ctor.hpp index c477ed4..6328a80 100644 --- a/headers/meta.hpp/meta_states/ctor.hpp +++ b/headers/meta.hpp/meta_states/ctor.hpp @@ -137,7 +137,7 @@ namespace meta_hpp template < typename... Args > inline bool ctor::is_invocable_with() const noexcept { if constexpr ( sizeof...(Args) > 0 ) { - std::array arg_bases{detail::arg_base{type_list{}}...}; + std::array arg_bases{detail::arg_base{detail::type_list{}}...}; return state_->is_invocable_with(arg_bases.data(), arg_bases.size()); } else { return state_->is_invocable_with(nullptr, 0); diff --git a/headers/meta.hpp/meta_states/function.hpp b/headers/meta.hpp/meta_states/function.hpp index faede9b..f1d913c 100644 --- a/headers/meta.hpp/meta_states/function.hpp +++ b/headers/meta.hpp/meta_states/function.hpp @@ -151,7 +151,7 @@ namespace meta_hpp template < typename... Args > bool function::is_invocable_with() const noexcept { if constexpr ( sizeof...(Args) > 0 ) { - std::array arg_bases{detail::arg_base{type_list{}}...}; + std::array arg_bases{detail::arg_base{detail::type_list{}}...}; return state_->is_invocable_with(arg_bases.data(), arg_bases.size()); } else { return state_->is_invocable_with(nullptr, 0); diff --git a/headers/meta.hpp/meta_states/method.hpp b/headers/meta.hpp/meta_states/method.hpp index f88bfad..c20c96e 100644 --- a/headers/meta.hpp/meta_states/method.hpp +++ b/headers/meta.hpp/meta_states/method.hpp @@ -167,10 +167,10 @@ namespace meta_hpp template < typename Inst, typename... Args > bool method::is_invocable_with() const noexcept { if constexpr ( sizeof...(Args) > 0 ) { - std::array arg_bases{detail::arg_base{type_list{}}...}; - return state_->is_invocable_with(detail::inst_base{type_list{}}, arg_bases.data(), arg_bases.size()); + std::array arg_bases{detail::arg_base{detail::type_list{}}...}; + return state_->is_invocable_with(detail::inst_base{detail::type_list{}}, arg_bases.data(), arg_bases.size()); } else { - return state_->is_invocable_with(detail::inst_base{type_list{}}, nullptr, 0); + return state_->is_invocable_with(detail::inst_base{detail::type_list{}}, nullptr, 0); } } } diff --git a/headers/meta.hpp/meta_types.hpp b/headers/meta.hpp/meta_types.hpp index d8dff41..50c8d49 100644 --- a/headers/meta.hpp/meta_types.hpp +++ b/headers/meta.hpp/meta_types.hpp @@ -14,7 +14,7 @@ namespace meta_hpp class type_id final { public: template < typename T > - explicit type_id(type_list) noexcept + explicit type_id(detail::type_list) noexcept : id_{type_to_id()} {} type_id(type_id&&) = default; @@ -57,32 +57,35 @@ namespace meta_hpp namespace meta_hpp { - template < typename T > - concept types_family = - std::same_as || - std::same_as || - std::same_as || - std::same_as || - std::same_as || - std::same_as || - std::same_as || - std::same_as || - std::same_as || - std::same_as || - std::same_as || - std::same_as; + namespace detail + { + template < typename T > + concept type_family = + std::same_as || + std::same_as || + std::same_as || + std::same_as || + std::same_as || + std::same_as || + std::same_as || + std::same_as || + std::same_as || + std::same_as || + std::same_as || + std::same_as; + } - template < types_family T > + template < detail::type_family T > bool operator<(type_id l, const T& r) noexcept { return static_cast(r) && l < r.get_id(); } - template < types_family T > + template < detail::type_family T > bool operator<(const T& l, type_id r) noexcept { return !static_cast(l) || l.get_id() < r; } - template < types_family T, types_family U > + template < detail::type_family T, detail::type_family U > bool operator<(const T& l, const U& r) noexcept { if ( !static_cast(r) ) { return false; @@ -95,17 +98,17 @@ namespace meta_hpp return l.get_id() < r.get_id(); } - template < types_family T > + template < detail::type_family T > bool operator==(type_id l, const T& r) noexcept { return static_cast(r) && l == r.get_id(); } - template < types_family T > + template < detail::type_family T > bool operator==(const T& l, type_id r) noexcept { return static_cast(l) && l.get_id() == r; } - template < types_family T, types_family U > + template < detail::type_family T, detail::type_family U > bool operator==(const T& l, const U& r) noexcept { if ( static_cast(l) != static_cast(r) ) { return false; @@ -118,17 +121,17 @@ namespace meta_hpp return l.get_id() == r.get_id(); } - template < types_family T > + template < detail::type_family T > bool operator!=(type_id l, const T& r) noexcept { return !(l == r); } - template < types_family T > + template < detail::type_family T > bool operator!=(const T& l, type_id r) noexcept { return !(l == r); } - template < types_family T, types_family U > + template < detail::type_family T, detail::type_family U > bool operator!=(const T& l, const U& r) noexcept { return !(l == r); } @@ -228,11 +231,11 @@ namespace meta_hpp const method_map& get_methods() const noexcept; const variable_map& get_variables() const noexcept; - template < class_kind Derived > + template < detail::class_kind Derived > bool is_base_of() const noexcept; bool is_base_of(const class_type& derived) const noexcept; - template < class_kind Base > + template < detail::class_kind Base > bool is_derived_from() const noexcept; bool is_derived_from(const class_type& base) const noexcept; diff --git a/headers/meta.hpp/meta_types/class_type.hpp b/headers/meta.hpp/meta_types/class_type.hpp index 2a33cc3..ad9a43f 100644 --- a/headers/meta.hpp/meta_types/class_type.hpp +++ b/headers/meta.hpp/meta_types/class_type.hpp @@ -91,7 +91,7 @@ namespace meta_hpp return data_->variables; } - template < class_kind Derived > + template < detail::class_kind Derived > bool class_type::is_base_of() const noexcept { return is_base_of(resolve_type()); } @@ -114,7 +114,7 @@ namespace meta_hpp return false; } - template < class_kind Base > + template < detail::class_kind Base > bool class_type::is_derived_from() const noexcept { return is_derived_from(resolve_type()); } From 7b512e182cbdaca00c0486826d32562451cde403 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Thu, 25 Nov 2021 23:10:40 +0700 Subject: [PATCH 116/233] remove unnecessary type operators --- headers/meta.hpp/meta_types.hpp | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/headers/meta.hpp/meta_types.hpp b/headers/meta.hpp/meta_types.hpp index 50c8d49..3285c43 100644 --- a/headers/meta.hpp/meta_types.hpp +++ b/headers/meta.hpp/meta_types.hpp @@ -75,16 +75,6 @@ namespace meta_hpp std::same_as; } - template < detail::type_family T > - bool operator<(type_id l, const T& r) noexcept { - return static_cast(r) && l < r.get_id(); - } - - template < detail::type_family T > - bool operator<(const T& l, type_id r) noexcept { - return !static_cast(l) || l.get_id() < r; - } - template < detail::type_family T, detail::type_family U > bool operator<(const T& l, const U& r) noexcept { if ( !static_cast(r) ) { @@ -98,16 +88,6 @@ namespace meta_hpp return l.get_id() < r.get_id(); } - template < detail::type_family T > - bool operator==(type_id l, const T& r) noexcept { - return static_cast(r) && l == r.get_id(); - } - - template < detail::type_family T > - bool operator==(const T& l, type_id r) noexcept { - return static_cast(l) && l.get_id() == r; - } - template < detail::type_family T, detail::type_family U > bool operator==(const T& l, const U& r) noexcept { if ( static_cast(l) != static_cast(r) ) { @@ -121,16 +101,6 @@ namespace meta_hpp return l.get_id() == r.get_id(); } - template < detail::type_family T > - bool operator!=(type_id l, const T& r) noexcept { - return !(l == r); - } - - template < detail::type_family T > - bool operator!=(const T& l, type_id r) noexcept { - return !(l == r); - } - template < detail::type_family T, detail::type_family U > bool operator!=(const T& l, const U& r) noexcept { return !(l == r); From 89b51d3bdccb04ed3f5ff89b77c48e411069e0ad Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 26 Nov 2021 06:06:32 +0700 Subject: [PATCH 117/233] static and local scopes --- headers/meta.hpp/meta_registry.hpp | 14 +++++-- headers/meta.hpp/meta_registry/class_bind.hpp | 5 +-- headers/meta.hpp/meta_registry/enum_bind.hpp | 2 +- headers/meta.hpp/meta_registry/scope_bind.hpp | 13 +++--- headers/meta.hpp/meta_states.hpp | 12 ++---- headers/meta.hpp/meta_states/ctor.hpp | 2 +- headers/meta.hpp/meta_states/evalue.hpp | 2 +- headers/meta.hpp/meta_states/function.hpp | 2 +- headers/meta.hpp/meta_states/member.hpp | 2 +- headers/meta.hpp/meta_states/method.hpp | 2 +- headers/meta.hpp/meta_states/scope.hpp | 10 +++-- headers/meta.hpp/meta_states/variable.hpp | 2 +- headers/meta.hpp/meta_types.hpp | 40 ++++++++----------- headers/meta.hpp/meta_types/array_type.hpp | 2 +- headers/meta.hpp/meta_types/class_type.hpp | 2 +- headers/meta.hpp/meta_types/ctor_type.hpp | 2 +- headers/meta.hpp/meta_types/enum_type.hpp | 2 +- headers/meta.hpp/meta_types/function_type.hpp | 2 +- headers/meta.hpp/meta_types/member_type.hpp | 2 +- headers/meta.hpp/meta_types/method_type.hpp | 2 +- headers/meta.hpp/meta_types/number_type.hpp | 2 +- headers/meta.hpp/meta_types/pointer_type.hpp | 2 +- .../meta.hpp/meta_types/reference_type.hpp | 2 +- headers/meta.hpp/meta_types/void_type.hpp | 2 +- untests/meta_states/scope_tests.cpp | 22 +++++----- 25 files changed, 76 insertions(+), 76 deletions(-) diff --git a/headers/meta.hpp/meta_registry.hpp b/headers/meta.hpp/meta_registry.hpp index ec2f827..d09fcf2 100644 --- a/headers/meta.hpp/meta_registry.hpp +++ b/headers/meta.hpp/meta_registry.hpp @@ -57,7 +57,11 @@ namespace meta_hpp { class scope_bind final { public: - explicit scope_bind(std::string_view name); + struct local_tag {}; + struct static_tag {}; + + explicit scope_bind(std::string_view name, local_tag); + explicit scope_bind(std::string_view name, static_tag); operator scope() const noexcept; template < detail::class_kind Class > @@ -88,7 +92,11 @@ namespace meta_hpp return enum_bind{}; } - inline scope_bind scope_(std::string name) { - return scope_bind{std::move(name)}; + inline scope_bind local_scope_(std::string name) { + return scope_bind{std::move(name), scope_bind::local_tag()}; + } + + inline scope_bind static_scope_(std::string name) { + return scope_bind{std::move(name), scope_bind::static_tag()}; } } diff --git a/headers/meta.hpp/meta_registry/class_bind.hpp b/headers/meta.hpp/meta_registry/class_bind.hpp index 65c432d..952562f 100644 --- a/headers/meta.hpp/meta_registry/class_bind.hpp +++ b/headers/meta.hpp/meta_registry/class_bind.hpp @@ -13,7 +13,7 @@ namespace meta_hpp { template < detail::class_kind Class > class_bind::class_bind() - : data_{detail::get_type_data()} {} + : data_{detail::class_type_data::get_static()} {} template < detail::class_kind Class > class_bind::operator class_type() const noexcept { @@ -33,8 +33,7 @@ namespace meta_hpp template < detail::class_kind Base > class_bind& class_bind::base_() { static_assert(std::is_base_of_v); - auto base_data = detail::class_type_data::get(); - data_->bases.emplace(base_data); + data_->bases.emplace(resolve_type()); return *this; } diff --git a/headers/meta.hpp/meta_registry/enum_bind.hpp b/headers/meta.hpp/meta_registry/enum_bind.hpp index 0ada250..b6ab51e 100644 --- a/headers/meta.hpp/meta_registry/enum_bind.hpp +++ b/headers/meta.hpp/meta_registry/enum_bind.hpp @@ -13,7 +13,7 @@ namespace meta_hpp { template < detail::enum_kind Enum > enum_bind::enum_bind() - : data_{detail::get_type_data()} {} + : data_{detail::enum_type_data::get_static()} {} template < detail::enum_kind Enum > enum_bind::operator enum_type() const noexcept { diff --git a/headers/meta.hpp/meta_registry/scope_bind.hpp b/headers/meta.hpp/meta_registry/scope_bind.hpp index 2d7a495..32cfe84 100644 --- a/headers/meta.hpp/meta_registry/scope_bind.hpp +++ b/headers/meta.hpp/meta_registry/scope_bind.hpp @@ -11,8 +11,11 @@ namespace meta_hpp { - inline scope_bind::scope_bind(std::string_view name) - : state_{detail::get_scope_state(name)} {} + inline scope_bind::scope_bind(std::string_view name, local_tag) + : state_{detail::scope_state::make(std::string{name})} {} + + inline scope_bind::scope_bind(std::string_view name, static_tag) + : state_{detail::scope_state::get_static(name)} {} inline scope_bind::operator scope() const noexcept { return scope{state_}; @@ -20,15 +23,13 @@ namespace meta_hpp template < detail::class_kind Class > scope_bind& scope_bind::class_(std::string name) { - auto class_data = detail::class_type_data::get(); - state_->classes.emplace(std::move(name), class_data); + state_->classes.emplace(std::move(name), resolve_type()); return *this; } template < detail::enum_kind Enum > scope_bind& scope_bind::enum_(std::string name) { - auto enum_data = detail::enum_type_data::get(); - state_->enums.emplace(std::move(name), enum_data); + state_->enums.emplace(std::move(name), resolve_type()); return *this; } diff --git a/headers/meta.hpp/meta_states.hpp b/headers/meta.hpp/meta_states.hpp index c6a19c0..ee1772a 100644 --- a/headers/meta.hpp/meta_states.hpp +++ b/headers/meta.hpp/meta_states.hpp @@ -295,7 +295,8 @@ namespace meta_hpp::detail function_map functions; variable_map variables; - static scope_state_ptr get(std::string_view name); + static scope_state_ptr make(std::string name); + static scope_state_ptr get_static(std::string_view name); explicit scope_state(scope_index index); }; @@ -319,14 +320,7 @@ namespace meta_hpp::detail namespace meta_hpp { - namespace detail - { - inline scope_state_ptr get_scope_state(std::string_view name) { - return scope_state::get(name); - } - } - inline scope resolve_scope(std::string_view name) { - return scope{detail::get_scope_state(name)}; + return scope{detail::scope_state::get_static(name)}; } } diff --git a/headers/meta.hpp/meta_states/ctor.hpp b/headers/meta.hpp/meta_states/ctor.hpp index 6328a80..eb952b6 100644 --- a/headers/meta.hpp/meta_states/ctor.hpp +++ b/headers/meta.hpp/meta_states/ctor.hpp @@ -92,7 +92,7 @@ namespace meta_hpp::detail { template < class_kind Class, typename... Args > ctor_state_ptr ctor_state::make() { - ctor_index index{ctor_type_data::get()}; + ctor_index index{ctor_type_data::get_static()}; return std::make_shared(std::move(index), type_list{}, type_list{}); } diff --git a/headers/meta.hpp/meta_states/evalue.hpp b/headers/meta.hpp/meta_states/evalue.hpp index 0c37330..3db728f 100644 --- a/headers/meta.hpp/meta_states/evalue.hpp +++ b/headers/meta.hpp/meta_states/evalue.hpp @@ -15,7 +15,7 @@ namespace meta_hpp::detail { template < enum_kind Enum > evalue_state_ptr evalue_state::make(std::string name, Enum value) { - evalue_index index{enum_type_data::get(), std::move(name)}; + evalue_index index{enum_type_data::get_static(), std::move(name)}; return std::make_shared(std::move(index), std::move(value)); } diff --git a/headers/meta.hpp/meta_states/function.hpp b/headers/meta.hpp/meta_states/function.hpp index f1d913c..4e96e9e 100644 --- a/headers/meta.hpp/meta_states/function.hpp +++ b/headers/meta.hpp/meta_states/function.hpp @@ -102,7 +102,7 @@ namespace meta_hpp::detail { template < function_kind Function > function_state_ptr function_state::make(std::string name, Function function) { - function_index index{function_type_data::get(), std::move(name)}; + function_index index{function_type_data::get_static(), std::move(name)}; return std::make_shared(std::move(index), std::move(function)); } diff --git a/headers/meta.hpp/meta_states/member.hpp b/headers/meta.hpp/meta_states/member.hpp index 5c18f74..7b2c22b 100644 --- a/headers/meta.hpp/meta_states/member.hpp +++ b/headers/meta.hpp/meta_states/member.hpp @@ -76,7 +76,7 @@ namespace meta_hpp::detail { template < member_kind Member > member_state_ptr member_state::make(std::string name, Member member) { - member_index index{member_type_data::get(), std::move(name)}; + member_index index{member_type_data::get_static(), std::move(name)}; return std::make_shared(std::move(index), std::move(member)); } diff --git a/headers/meta.hpp/meta_states/method.hpp b/headers/meta.hpp/meta_states/method.hpp index c20c96e..c3e8bac 100644 --- a/headers/meta.hpp/meta_states/method.hpp +++ b/headers/meta.hpp/meta_states/method.hpp @@ -118,7 +118,7 @@ namespace meta_hpp::detail { template < method_kind Method > method_state_ptr method_state::make(std::string name, Method method) { - method_index index{method_type_data::get(), std::move(name)}; + method_index index{method_type_data::get_static(), std::move(name)}; return std::make_shared(std::move(index), std::move(method)); } diff --git a/headers/meta.hpp/meta_states/scope.hpp b/headers/meta.hpp/meta_states/scope.hpp index c5fb939..7f889ed 100644 --- a/headers/meta.hpp/meta_states/scope.hpp +++ b/headers/meta.hpp/meta_states/scope.hpp @@ -11,15 +11,19 @@ namespace meta_hpp::detail { - inline scope_state_ptr scope_state::get(std::string_view name) { + inline scope_state_ptr scope_state::make(std::string name) { + scope_index index{std::move(name)}; + return std::make_shared(std::move(index)); + } + + inline scope_state_ptr scope_state::get_static(std::string_view name) { static std::map> states; if ( auto iter = states.find(name); iter != states.end() ) { return iter->second; } - auto state = std::make_shared(scope_index{std::string{name}}); - return states.emplace(std::string{name}, state).first->second; + return states.emplace(std::string{name}, make(std::string{name})).first->second; } inline scope_state::scope_state(scope_index index) diff --git a/headers/meta.hpp/meta_states/variable.hpp b/headers/meta.hpp/meta_states/variable.hpp index ff6353e..38ae51f 100644 --- a/headers/meta.hpp/meta_states/variable.hpp +++ b/headers/meta.hpp/meta_states/variable.hpp @@ -58,7 +58,7 @@ namespace meta_hpp::detail { template < pointer_kind Pointer > variable_state_ptr variable_state::make(std::string name, Pointer pointer) { - variable_index index{pointer_type_data::get(), std::move(name)}; + variable_index index{pointer_type_data::get_static(), std::move(name)}; return std::make_shared(index, pointer); } diff --git a/headers/meta.hpp/meta_types.hpp b/headers/meta.hpp/meta_types.hpp index 3285c43..45546aa 100644 --- a/headers/meta.hpp/meta_types.hpp +++ b/headers/meta.hpp/meta_types.hpp @@ -421,7 +421,7 @@ namespace meta_hpp::detail const any_type data_type; template < array_kind Array > - static array_type_data_ptr get(); + static array_type_data_ptr get_static(); template < array_kind Array > explicit array_type_data(type_list); @@ -440,7 +440,7 @@ namespace meta_hpp::detail variable_map variables; template < class_kind Class > - static class_type_data_ptr get(); + static class_type_data_ptr get_static(); template < class_kind Class > explicit class_type_data(type_list); @@ -452,7 +452,7 @@ namespace meta_hpp::detail const std::vector argument_types; template < class_kind Class, typename... Args > - static ctor_type_data_ptr get(); + static ctor_type_data_ptr get_static(); template < class_kind Class, typename... Args > explicit ctor_type_data(type_list, type_list); @@ -465,7 +465,7 @@ namespace meta_hpp::detail evalue_map evalues; template < enum_kind Enum > - static enum_type_data_ptr get(); + static enum_type_data_ptr get_static(); template < enum_kind Enum > explicit enum_type_data(type_list); @@ -477,7 +477,7 @@ namespace meta_hpp::detail const std::vector argument_types; template < function_kind Function > - static function_type_data_ptr get(); + static function_type_data_ptr get_static(); template < function_kind Function > explicit function_type_data(type_list); @@ -489,7 +489,7 @@ namespace meta_hpp::detail const any_type value_type; template < member_kind Member > - static member_type_data_ptr get(); + static member_type_data_ptr get_static(); template < member_kind Member > explicit member_type_data(type_list); @@ -502,7 +502,7 @@ namespace meta_hpp::detail const std::vector argument_types; template < method_kind Method > - static method_type_data_ptr get(); + static method_type_data_ptr get_static(); template < method_kind Method > explicit method_type_data(type_list); @@ -513,7 +513,7 @@ namespace meta_hpp::detail const std::size_t size; template < number_kind Number > - static number_type_data_ptr get(); + static number_type_data_ptr get_static(); template < number_kind Number > explicit number_type_data(type_list); @@ -524,7 +524,7 @@ namespace meta_hpp::detail const any_type data_type; template < pointer_kind Pointer > - static pointer_type_data_ptr get(); + static pointer_type_data_ptr get_static(); template < pointer_kind Pointer > explicit pointer_type_data(type_list); @@ -535,7 +535,7 @@ namespace meta_hpp::detail const any_type data_type; template < reference_kind Reference > - static reference_type_data_ptr get(); + static reference_type_data_ptr get_static(); template < reference_kind Reference > explicit reference_type_data(type_list); @@ -545,7 +545,7 @@ namespace meta_hpp::detail const bitflags flags; template < void_kind Void > - static void_type_data_ptr get(); + static void_type_data_ptr get_static(); template < void_kind Void > explicit void_type_data(type_list); @@ -672,24 +672,18 @@ namespace meta_hpp namespace meta_hpp { - namespace detail - { - template < typename T > - kind_type_data_ptr get_type_data() { - static_assert(!std::is_const_v && !std::is_volatile_v); - return kind_type_data::template get(); - } - } - template < typename T > auto resolve_type() { using raw_type = std::remove_cv_t; - return detail::kind_type{detail::get_type_data()}; + + using kind_type = detail::kind_type; + using kind_type_data = detail::kind_type_data; + + return kind_type{kind_type_data::template get_static()}; } template < typename T > auto resolve_type(T&&) { - using raw_type = std::remove_cvref_t; - return detail::kind_type{detail::get_type_data()}; + return resolve_type>(); }; } diff --git a/headers/meta.hpp/meta_types/array_type.hpp b/headers/meta.hpp/meta_types/array_type.hpp index 066a6a0..4dedd7e 100644 --- a/headers/meta.hpp/meta_types/array_type.hpp +++ b/headers/meta.hpp/meta_types/array_type.hpp @@ -17,7 +17,7 @@ namespace meta_hpp::detail struct array_tag {}; template < array_kind Array > - array_type_data_ptr array_type_data::get() { + array_type_data_ptr array_type_data::get_static() { static array_type_data_ptr data = std::make_shared(type_list{}); return data; } diff --git a/headers/meta.hpp/meta_types/class_type.hpp b/headers/meta.hpp/meta_types/class_type.hpp index ad9a43f..62118b8 100644 --- a/headers/meta.hpp/meta_types/class_type.hpp +++ b/headers/meta.hpp/meta_types/class_type.hpp @@ -17,7 +17,7 @@ namespace meta_hpp::detail struct class_tag {}; template < class_kind Class > - class_type_data_ptr class_type_data::get() { + class_type_data_ptr class_type_data::get_static() { static class_type_data_ptr data = std::make_shared(type_list{}); return data; } diff --git a/headers/meta.hpp/meta_types/ctor_type.hpp b/headers/meta.hpp/meta_types/ctor_type.hpp index 1977d3a..d05458d 100644 --- a/headers/meta.hpp/meta_types/ctor_type.hpp +++ b/headers/meta.hpp/meta_types/ctor_type.hpp @@ -17,7 +17,7 @@ namespace meta_hpp::detail struct ctor_tag {}; template < class_kind Class, typename... Args > - ctor_type_data_ptr ctor_type_data::get() { + ctor_type_data_ptr ctor_type_data::get_static() { static ctor_type_data_ptr data = std::make_shared(type_list{}, type_list{}); return data; } diff --git a/headers/meta.hpp/meta_types/enum_type.hpp b/headers/meta.hpp/meta_types/enum_type.hpp index 8a28611..506567e 100644 --- a/headers/meta.hpp/meta_types/enum_type.hpp +++ b/headers/meta.hpp/meta_types/enum_type.hpp @@ -17,7 +17,7 @@ namespace meta_hpp::detail struct enum_tag {}; template < enum_kind Enum > - enum_type_data_ptr enum_type_data::get() { + enum_type_data_ptr enum_type_data::get_static() { static enum_type_data_ptr data = std::make_shared(type_list{}); return data; } diff --git a/headers/meta.hpp/meta_types/function_type.hpp b/headers/meta.hpp/meta_types/function_type.hpp index e9cbf88..433d0cb 100644 --- a/headers/meta.hpp/meta_types/function_type.hpp +++ b/headers/meta.hpp/meta_types/function_type.hpp @@ -17,7 +17,7 @@ namespace meta_hpp::detail struct function_tag {}; template < function_kind Function > - function_type_data_ptr function_type_data::get() { + function_type_data_ptr function_type_data::get_static() { static function_type_data_ptr data = std::make_shared(type_list{}); return data; } diff --git a/headers/meta.hpp/meta_types/member_type.hpp b/headers/meta.hpp/meta_types/member_type.hpp index a3e8987..432d155 100644 --- a/headers/meta.hpp/meta_types/member_type.hpp +++ b/headers/meta.hpp/meta_types/member_type.hpp @@ -17,7 +17,7 @@ namespace meta_hpp::detail struct member_tag {}; template < member_kind Member > - member_type_data_ptr member_type_data::get() { + member_type_data_ptr member_type_data::get_static() { static member_type_data_ptr data = std::make_shared(type_list{}); return data; } diff --git a/headers/meta.hpp/meta_types/method_type.hpp b/headers/meta.hpp/meta_types/method_type.hpp index 8c60103..9bfd4fe 100644 --- a/headers/meta.hpp/meta_types/method_type.hpp +++ b/headers/meta.hpp/meta_types/method_type.hpp @@ -17,7 +17,7 @@ namespace meta_hpp::detail struct method_tag {}; template < method_kind Method > - method_type_data_ptr method_type_data::get() { + method_type_data_ptr method_type_data::get_static() { static method_type_data_ptr data = std::make_shared(type_list{}); return data; } diff --git a/headers/meta.hpp/meta_types/number_type.hpp b/headers/meta.hpp/meta_types/number_type.hpp index b331bae..9eef28b 100644 --- a/headers/meta.hpp/meta_types/number_type.hpp +++ b/headers/meta.hpp/meta_types/number_type.hpp @@ -17,7 +17,7 @@ namespace meta_hpp::detail struct number_tag {}; template < number_kind Number > - number_type_data_ptr number_type_data::get() { + number_type_data_ptr number_type_data::get_static() { static number_type_data_ptr data = std::make_shared(type_list{}); return data; } diff --git a/headers/meta.hpp/meta_types/pointer_type.hpp b/headers/meta.hpp/meta_types/pointer_type.hpp index 6741be1..e7e16ec 100644 --- a/headers/meta.hpp/meta_types/pointer_type.hpp +++ b/headers/meta.hpp/meta_types/pointer_type.hpp @@ -17,7 +17,7 @@ namespace meta_hpp::detail struct pointer_tag {}; template < pointer_kind Pointer > - pointer_type_data_ptr pointer_type_data::get() { + pointer_type_data_ptr pointer_type_data::get_static() { static pointer_type_data_ptr data = std::make_shared(type_list{}); return data; } diff --git a/headers/meta.hpp/meta_types/reference_type.hpp b/headers/meta.hpp/meta_types/reference_type.hpp index f99bff8..e0dda8d 100644 --- a/headers/meta.hpp/meta_types/reference_type.hpp +++ b/headers/meta.hpp/meta_types/reference_type.hpp @@ -17,7 +17,7 @@ namespace meta_hpp::detail struct reference_tag {}; template < reference_kind Reference > - reference_type_data_ptr reference_type_data::get() { + reference_type_data_ptr reference_type_data::get_static() { static reference_type_data_ptr data = std::make_shared(type_list{}); return data; } diff --git a/headers/meta.hpp/meta_types/void_type.hpp b/headers/meta.hpp/meta_types/void_type.hpp index 8e04812..c6e204a 100644 --- a/headers/meta.hpp/meta_types/void_type.hpp +++ b/headers/meta.hpp/meta_types/void_type.hpp @@ -17,7 +17,7 @@ namespace meta_hpp::detail struct void_tag {}; template < void_kind Void > - void_type_data_ptr void_type_data::get() { + void_type_data_ptr void_type_data::get_static() { static void_type_data_ptr data = std::make_shared(type_list{}); return data; } diff --git a/untests/meta_states/scope_tests.cpp b/untests/meta_states/scope_tests.cpp index 1041f46..32b3cdf 100644 --- a/untests/meta_states/scope_tests.cpp +++ b/untests/meta_states/scope_tests.cpp @@ -33,21 +33,21 @@ namespace return {l.x + r.x, l.y + r.y, l.z + r.z}; } - ivec2 global_ivec2 = ivec2{1, 0}; - const ivec3 global_const_ivec3 = ivec3{1, 0}; + ivec2 static_ivec2 = ivec2{1, 0}; + const ivec3 static_const_ivec3 = ivec3{1, 0}; } TEST_CASE("meta/meta_states/scope") { namespace meta = meta_hpp; - meta::scope_("meta/meta_states/scope/math") + meta::static_scope_("meta/meta_states/scope/math") .enum_("color") .class_("ivec2") .class_("ivec3") .function_("iadd2", &iadd2) .function_("iadd3", &iadd3) - .variable_("global_ivec2", &global_ivec2) - .variable_("global_const_ivec3", &global_const_ivec3); + .variable_("static_ivec2", &static_ivec2) + .variable_("static_const_ivec3", &static_const_ivec3); const meta::scope math_scope = meta::resolve_scope("meta/meta_states/scope/math"); REQUIRE(math_scope); @@ -103,12 +103,12 @@ TEST_CASE("meta/meta_states/scope") { SUBCASE("variables") { CHECK_FALSE(math_scope.get_variable("non-existent-variable")); - const meta::variable global_ivec2_var = math_scope.get_variable("global_ivec2"); - REQUIRE(global_ivec2_var); - CHECK(global_ivec2_var.get_type().get_data_type() == meta::resolve_type()); + const meta::variable static_ivec2_var = math_scope.get_variable("static_ivec2"); + REQUIRE(static_ivec2_var); + CHECK(static_ivec2_var.get_type().get_data_type() == meta::resolve_type()); - const meta::variable global_const_ivec3_var = math_scope.get_variable("global_const_ivec3"); - REQUIRE(global_const_ivec3_var); - CHECK(global_const_ivec3_var.get_type().get_data_type() == meta::resolve_type()); + const meta::variable static_const_ivec3_var = math_scope.get_variable("static_const_ivec3"); + REQUIRE(static_const_ivec3_var); + CHECK(static_const_ivec3_var.get_type().get_data_type() == meta::resolve_type()); } } From 06ee5631336d3ea92a2cdf509ae22501eb06ae7e Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 26 Nov 2021 08:13:47 +0700 Subject: [PATCH 118/233] invoke operator aliases --- headers/meta.hpp/meta_states.hpp | 9 +++++++++ headers/meta.hpp/meta_states/ctor.hpp | 5 +++++ headers/meta.hpp/meta_states/function.hpp | 5 +++++ headers/meta.hpp/meta_states/method.hpp | 5 +++++ 4 files changed, 24 insertions(+) diff --git a/headers/meta.hpp/meta_states.hpp b/headers/meta.hpp/meta_states.hpp index ee1772a..42a9a13 100644 --- a/headers/meta.hpp/meta_states.hpp +++ b/headers/meta.hpp/meta_states.hpp @@ -73,6 +73,9 @@ namespace meta_hpp template < typename... Args > value invoke(Args&&... args) const; + template < typename... Args > + value operator()(Args&&... args) const; + template < typename... Args > bool is_invocable_with() const noexcept; private: @@ -111,6 +114,9 @@ namespace meta_hpp template < typename... Args > std::optional invoke(Args&&... args) const; + template < typename... Args > + std::optional operator()(Args&&... args) const; + template < typename... Args > bool is_invocable_with() const noexcept; private: @@ -153,6 +159,9 @@ namespace meta_hpp template < typename Instance, typename... Args > std::optional invoke(Instance&& instance, Args&&... args) const; + template < typename Instance, typename... Args > + std::optional operator()(Instance&& instance, Args&&... args) const; + template < typename Inst, typename... Args > bool is_invocable_with() const noexcept; private: diff --git a/headers/meta.hpp/meta_states/ctor.hpp b/headers/meta.hpp/meta_states/ctor.hpp index eb952b6..4769617 100644 --- a/headers/meta.hpp/meta_states/ctor.hpp +++ b/headers/meta.hpp/meta_states/ctor.hpp @@ -134,6 +134,11 @@ namespace meta_hpp } } + template < typename... Args > + value ctor::operator()(Args&&... args) const { + return invoke(std::forward(args)...); + } + template < typename... Args > inline bool ctor::is_invocable_with() const noexcept { if constexpr ( sizeof...(Args) > 0 ) { diff --git a/headers/meta.hpp/meta_states/function.hpp b/headers/meta.hpp/meta_states/function.hpp index 4e96e9e..0746da7 100644 --- a/headers/meta.hpp/meta_states/function.hpp +++ b/headers/meta.hpp/meta_states/function.hpp @@ -148,6 +148,11 @@ namespace meta_hpp } } + template < typename... Args > + std::optional function::operator()(Args&&... args) const { + return invoke(std::forward(args)...); + } + template < typename... Args > bool function::is_invocable_with() const noexcept { if constexpr ( sizeof...(Args) > 0 ) { diff --git a/headers/meta.hpp/meta_states/method.hpp b/headers/meta.hpp/meta_states/method.hpp index c3e8bac..0680524 100644 --- a/headers/meta.hpp/meta_states/method.hpp +++ b/headers/meta.hpp/meta_states/method.hpp @@ -164,6 +164,11 @@ namespace meta_hpp } } + template < typename Instance, typename... Args > + std::optional method::operator()(Instance&& instance, Args&&... args) const { + return invoke(std::forward(instance), std::forward(args)...); + } + template < typename Inst, typename... Args > bool method::is_invocable_with() const noexcept { if constexpr ( sizeof...(Args) > 0 ) { From 8eb15af7be3ced92425ea2bac613bd7491dac88c Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 26 Nov 2021 08:18:18 +0700 Subject: [PATCH 119/233] class_type create function --- headers/meta.hpp/meta_types.hpp | 6 ++++++ headers/meta.hpp/meta_types/class_type.hpp | 15 +++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/headers/meta.hpp/meta_types.hpp b/headers/meta.hpp/meta_types.hpp index 45546aa..d4ba9ac 100644 --- a/headers/meta.hpp/meta_types.hpp +++ b/headers/meta.hpp/meta_types.hpp @@ -201,6 +201,12 @@ namespace meta_hpp const method_map& get_methods() const noexcept; const variable_map& get_variables() const noexcept; + template < typename... Args > + std::optional create(Args&&... args) const; + + template < typename... Args > + std::optional operator()(Args&&... args) const; + template < detail::class_kind Derived > bool is_base_of() const noexcept; bool is_base_of(const class_type& derived) const noexcept; diff --git a/headers/meta.hpp/meta_types/class_type.hpp b/headers/meta.hpp/meta_types/class_type.hpp index 62118b8..5d88614 100644 --- a/headers/meta.hpp/meta_types/class_type.hpp +++ b/headers/meta.hpp/meta_types/class_type.hpp @@ -91,6 +91,21 @@ namespace meta_hpp return data_->variables; } + template < typename... Args > + std::optional class_type::create(Args&&... args) const { + for ( auto&& ctor : data_->ctors ) { + if ( ctor.second.is_invocable_with() ) { + return ctor.second.invoke(std::forward(args)...); + } + } + return std::nullopt; + } + + template < typename... Args > + std::optional class_type::operator()(Args&&... args) const { + return create(std::forward(args)...); + } + template < detail::class_kind Derived > bool class_type::is_base_of() const noexcept { return is_base_of(resolve_type()); From 0fe5278a03b94a5962f7550d0a24f41ea5a25d45 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sat, 27 Nov 2021 01:01:54 +0700 Subject: [PATCH 120/233] inst cast to base --- CMakeLists.txt | 1 + headers/meta.hpp/meta_utilities.hpp | 40 ++-- headers/meta.hpp/meta_utilities/arg.hpp | 26 +-- headers/meta.hpp/meta_utilities/inst.hpp | 94 +++++---- untests/meta_states/method_tests.cpp | 247 +++++++++++++++++++++++ untests/meta_utilities/arg_tests.cpp | 122 +++++++++++ untests/meta_utilities/inst_tests.cpp | 104 ++++++++-- 7 files changed, 538 insertions(+), 96 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 59dfac6..d4d87f3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,6 +31,7 @@ target_compile_options(${PROJECT_NAME} -Wno-exit-time-destructors -Wno-float-equal -Wno-padded + -Wno-shadow-field -Wno-shadow-field-in-constructor -Wno-unknown-warning-option -Wno-weak-vtables diff --git a/headers/meta.hpp/meta_utilities.hpp b/headers/meta.hpp/meta_utilities.hpp index e59abc4..ac698ef 100644 --- a/headers/meta.hpp/meta_utilities.hpp +++ b/headers/meta.hpp/meta_utilities.hpp @@ -97,12 +97,12 @@ namespace meta_hpp::detail arg_base& operator=(const arg_base&) = delete; template < typename T, std::enable_if_t< - std::is_pointer_v || std::is_lvalue_reference_v + (std::is_pointer_v || std::is_lvalue_reference_v) , int> = 0 > explicit arg_base(type_list); template < typename T, std::enable_if_t< - std::is_rvalue_reference_v || + (std::is_rvalue_reference_v) || (!std::is_pointer_v && !std::is_reference_v) , int> = 0 > explicit arg_base(type_list); @@ -139,17 +139,16 @@ namespace meta_hpp::detail arg(const arg&) = delete; arg& operator=(const arg&) = delete; + template < typename T, typename Tp = std::decay_t + , std::enable_if_t, int> = 0 > + explicit arg(T&& v); + template < typename T, typename Tp = std::decay_t , std::enable_if_t, int> = 0 , std::enable_if_t, int> = 0 , std::enable_if_t, int> = 0 > explicit arg(T&& v); - explicit arg(value& v); - explicit arg(value&& v); - explicit arg(const value& v); - explicit arg(const value&& v); - template < typename To > To cast() const; private: @@ -177,12 +176,12 @@ namespace meta_hpp::detail inst_base& operator=(const inst_base&) = delete; template < typename T, std::enable_if_t< - std::is_lvalue_reference_v && std::is_class_v> + (std::is_lvalue_reference_v && std::is_class_v>) , int> = 0> explicit inst_base(type_list); template < typename T, std::enable_if_t< - std::is_class_v || + (std::is_class_v) || (std::is_rvalue_reference_v && std::is_class_v>) , int> = 0> explicit inst_base(type_list); @@ -196,14 +195,17 @@ namespace meta_hpp::detail bool is_lvalue() const noexcept; bool is_rvalue() const noexcept; - any_type get_raw_type() const noexcept; ref_types get_ref_type() const noexcept; + const class_type& get_raw_type() const noexcept; - template < typename To > + template < typename To, std::enable_if_t< + (std::is_class_v) || + (std::is_reference_v && std::is_class_v>) + , int> = 0> bool can_cast_to() const noexcept; private: - any_type raw_type_{}; ref_types ref_type_{}; + class_type raw_type_{}; }; } @@ -220,17 +222,19 @@ namespace meta_hpp::detail inst& operator=(const inst&) = delete; template < typename T, typename Tp = std::decay_t + , std::enable_if_t, int> = 0 > + explicit inst(T&& v); + + template < typename T, class_kind Tp = std::decay_t , std::enable_if_t, int> = 0 , std::enable_if_t, int> = 0 , std::enable_if_t, int> = 0 > explicit inst(T&& v); - explicit inst(value& v); - explicit inst(value&& v); - explicit inst(const value& v); - explicit inst(const value&& v); - - template < typename To > + template < typename To, std::enable_if_t< + (std::is_class_v) || + (std::is_reference_v && std::is_class_v>) + , int> = 0> decltype(auto) cast() const; private: void* data_{}; diff --git a/headers/meta.hpp/meta_utilities/arg.hpp b/headers/meta.hpp/meta_utilities/arg.hpp index 1679ebd..0ef3082 100644 --- a/headers/meta.hpp/meta_utilities/arg.hpp +++ b/headers/meta.hpp/meta_utilities/arg.hpp @@ -12,14 +12,14 @@ namespace meta_hpp::detail { template < typename T, std::enable_if_t< - std::is_pointer_v || std::is_lvalue_reference_v + (std::is_pointer_v || std::is_lvalue_reference_v) , int> > arg_base::arg_base(type_list) : raw_type_{resolve_type>()} , ref_type_{std::is_const_v> ? ref_types::cref : ref_types::ref} {} template < typename T, std::enable_if_t< - std::is_rvalue_reference_v || + (std::is_rvalue_reference_v) || (!std::is_pointer_v && !std::is_reference_v) , int> > arg_base::arg_base(type_list) @@ -126,6 +126,12 @@ namespace meta_hpp::detail namespace meta_hpp::detail { + template < typename T, typename Tp + , std::enable_if_t, int> > + arg::arg(T&& v) + : arg_base{std::forward(v)} + , data_{const_cast(v.data())} {} + template < typename T, typename Tp , std::enable_if_t, int> , std::enable_if_t, int> @@ -134,22 +140,6 @@ namespace meta_hpp::detail : arg_base{type_list{}} , data_{const_cast*>(std::addressof(v))} {} - inline arg::arg(value& v) - : arg_base{v} - , data_{const_cast(v.data())} {} - - inline arg::arg(value&& v) - : arg_base{v} - , data_{const_cast(v.data())} {} - - inline arg::arg(const value& v) - : arg_base{v} - , data_{const_cast(v.data())} {} - - inline arg::arg(const value&& v) - : arg_base{v} - , data_{const_cast(v.data())} {} - template < typename To > To arg::cast() const { if ( !can_cast_to() ) { diff --git a/headers/meta.hpp/meta_utilities/inst.hpp b/headers/meta.hpp/meta_utilities/inst.hpp index fdd374b..b4b7397 100644 --- a/headers/meta.hpp/meta_utilities/inst.hpp +++ b/headers/meta.hpp/meta_utilities/inst.hpp @@ -12,35 +12,51 @@ namespace meta_hpp::detail { template < typename T, std::enable_if_t< - std::is_lvalue_reference_v && std::is_class_v> + (std::is_lvalue_reference_v && std::is_class_v>) , int> > inst_base::inst_base(type_list) - : raw_type_{resolve_type>()} - , ref_type_{std::is_const_v> ? ref_types::cref : ref_types::ref} {} + : ref_type_{std::is_const_v> ? ref_types::cref : ref_types::ref} + , raw_type_{resolve_type>()} {} template < typename T, std::enable_if_t< - std::is_class_v || + (std::is_class_v) || (std::is_rvalue_reference_v && std::is_class_v>) , int> > inst_base::inst_base(type_list) - : raw_type_{resolve_type>()} - , ref_type_{std::is_const_v> ? ref_types::crref : ref_types::rref} {} + : ref_type_{std::is_const_v> ? ref_types::crref : ref_types::rref} + , raw_type_{resolve_type>()} {} inline inst_base::inst_base(value& v) - : raw_type_{v.get_type()} - , ref_type_{ref_types::ref} {} + : ref_type_{ref_types::ref} + , raw_type_{v.get_type().as_class()} { + if ( !v.get_type().is_class() ) { + throw std::logic_error("an attempt to create an instance with a non-class value type"); + } + } inline inst_base::inst_base(value&& v) - : raw_type_{v.get_type()} - , ref_type_{ref_types::rref} {} + : ref_type_{ref_types::rref} + , raw_type_{v.get_type().as_class()} { + if ( !v.get_type().is_class() ) { + throw std::logic_error("an attempt to create an instance with a non-class value type"); + } + } inline inst_base::inst_base(const value& v) - : raw_type_{v.get_type()} - , ref_type_{ref_types::cref} {} + : ref_type_{ref_types::cref} + , raw_type_{v.get_type().as_class()} { + if ( !v.get_type().is_class() ) { + throw std::logic_error("an attempt to create an instance with a non-class value type"); + } + } inline inst_base::inst_base(const value&& v) - : raw_type_{v.get_type()} - , ref_type_{ref_types::crref} {} + : ref_type_{ref_types::crref} + , raw_type_{v.get_type().as_class()} { + if ( !v.get_type().is_class() ) { + throw std::logic_error("an attempt to create an instance with a non-class value type"); + } + } inline bool inst_base::is_const() const noexcept { return ref_type_ == ref_types::cref @@ -57,20 +73,19 @@ namespace meta_hpp::detail || ref_type_ == ref_types::crref; } - inline any_type inst_base::get_raw_type() const noexcept { - return raw_type_; - } - inline inst_base::ref_types inst_base::get_ref_type() const noexcept { return ref_type_; } - template < typename To > - bool inst_base::can_cast_to() const noexcept { - static_assert( - std::is_class_v || - (std::is_reference_v && std::is_class_v>)); + inline const class_type& inst_base::get_raw_type() const noexcept { + return raw_type_; + } + template < typename To, std::enable_if_t< + (std::is_class_v) || + (std::is_reference_v && std::is_class_v>) + , int> > + bool inst_base::can_cast_to() const noexcept { constexpr bool to_const = std::is_const_v>; if constexpr ( !to_const ) { @@ -92,13 +107,21 @@ namespace meta_hpp::detail } using to_raw_type = std::remove_cvref_t; - return get_raw_type() == resolve_type(); + + return get_raw_type() == resolve_type() + || get_raw_type().is_derived_from(resolve_type()); } } namespace meta_hpp::detail { template < typename T, typename Tp + , std::enable_if_t, int> > + inst::inst(T&& v) + : inst_base{std::forward(v)} + , data_{const_cast(v.data())} {} + + template < typename T, class_kind Tp , std::enable_if_t, int> , std::enable_if_t, int> , std::enable_if_t, int> > @@ -106,26 +129,13 @@ namespace meta_hpp::detail : inst_base{type_list{}} , data_{const_cast*>(std::addressof(v))} {} - inline inst::inst(value& v) - : inst_base{v} - , data_{const_cast(v.data())} {} - - inline inst::inst(value&& v) - : inst_base{v} - , data_{const_cast(v.data())} {} - - inline inst::inst(const value& v) - : inst_base{v} - , data_{const_cast(v.data())} {} - - inline inst::inst(const value&& v) - : inst_base{v} - , data_{const_cast(v.data())} {} - - template < typename To > + template < typename To, std::enable_if_t< + (std::is_class_v) || + (std::is_reference_v && std::is_class_v>) + , int> > decltype(auto) inst::cast() const { if ( !can_cast_to() ) { - throw std::logic_error("bad inst cast"); + throw std::logic_error("bad an instance cast"); } if constexpr ( std::is_reference_v ) { diff --git a/untests/meta_states/method_tests.cpp b/untests/meta_states/method_tests.cpp index 7258f3b..c8c6635 100644 --- a/untests/meta_states/method_tests.cpp +++ b/untests/meta_states/method_tests.cpp @@ -58,12 +58,19 @@ namespace int const_method_noexcept_rref_volatile() volatile const && noexcept { return 12; } }; + struct derived_clazz : clazz { + [[maybe_unused]] derived_clazz() = default; + }; + struct clazz2 {}; } TEST_CASE("meta/meta_states/method") { namespace meta = meta_hpp; + meta::class_() + .base_(); + meta::class_() .method_("non_const_method", &clazz::non_const_method) .method_("non_const_method_noexcept", &clazz::non_const_method_noexcept) @@ -151,6 +158,16 @@ TEST_CASE("meta/meta_states/method") { CHECK_FALSE(mi2.is_invocable_with()); CHECK(mi2.is_invocable_with()); CHECK_FALSE(mi2.is_invocable_with()); + + CHECK(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + CHECK(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + + CHECK(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); + CHECK(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); } { @@ -176,6 +193,16 @@ TEST_CASE("meta/meta_states/method") { static_assert(!std::is_invocable_v); static_assert(std::is_invocable_v); static_assert(!std::is_invocable_v); + + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); } SUBCASE("non_const_method_noexcept") { @@ -210,6 +237,16 @@ TEST_CASE("meta/meta_states/method") { CHECK_FALSE(mi2.is_invocable_with()); CHECK(mi2.is_invocable_with()); CHECK_FALSE(mi2.is_invocable_with()); + + CHECK(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + CHECK(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + + CHECK(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); + CHECK(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); } { @@ -235,6 +272,16 @@ TEST_CASE("meta/meta_states/method") { static_assert(!std::is_invocable_v); static_assert(std::is_invocable_v); static_assert(!std::is_invocable_v); + + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); } SUBCASE("const_method") { @@ -269,6 +316,16 @@ TEST_CASE("meta/meta_states/method") { CHECK(mi2.is_invocable_with()); CHECK(mi2.is_invocable_with()); CHECK(mi2.is_invocable_with()); + + CHECK(mi.is_invocable_with()); + CHECK(mi.is_invocable_with()); + CHECK(mi.is_invocable_with()); + CHECK(mi.is_invocable_with()); + + CHECK(mi2.is_invocable_with()); + CHECK(mi2.is_invocable_with()); + CHECK(mi2.is_invocable_with()); + CHECK(mi2.is_invocable_with()); } { @@ -294,6 +351,16 @@ TEST_CASE("meta/meta_states/method") { static_assert(std::is_invocable_v); static_assert(std::is_invocable_v); static_assert(std::is_invocable_v); + + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); } SUBCASE("const_method_noexcept") { @@ -328,6 +395,16 @@ TEST_CASE("meta/meta_states/method") { CHECK(mi2.is_invocable_with()); CHECK(mi2.is_invocable_with()); CHECK(mi2.is_invocable_with()); + + CHECK(mi.is_invocable_with()); + CHECK(mi.is_invocable_with()); + CHECK(mi.is_invocable_with()); + CHECK(mi.is_invocable_with()); + + CHECK(mi2.is_invocable_with()); + CHECK(mi2.is_invocable_with()); + CHECK(mi2.is_invocable_with()); + CHECK(mi2.is_invocable_with()); } { @@ -353,6 +430,16 @@ TEST_CASE("meta/meta_states/method") { static_assert(std::is_invocable_v); static_assert(std::is_invocable_v); static_assert(std::is_invocable_v); + + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); } SUBCASE("non_const_method_ref") { @@ -387,6 +474,16 @@ TEST_CASE("meta/meta_states/method") { CHECK_FALSE(mi2.is_invocable_with()); CHECK_FALSE(mi2.is_invocable_with()); CHECK_FALSE(mi2.is_invocable_with()); + + CHECK(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + + CHECK(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); } { @@ -412,6 +509,16 @@ TEST_CASE("meta/meta_states/method") { static_assert(!std::is_invocable_v); static_assert(!std::is_invocable_v); static_assert(!std::is_invocable_v); + + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); + + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); } SUBCASE("non_const_method_noexcept_ref") { @@ -446,6 +553,16 @@ TEST_CASE("meta/meta_states/method") { CHECK_FALSE(mi2.is_invocable_with()); CHECK_FALSE(mi2.is_invocable_with()); CHECK_FALSE(mi2.is_invocable_with()); + + CHECK(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + + CHECK(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); } { @@ -471,6 +588,16 @@ TEST_CASE("meta/meta_states/method") { static_assert(!std::is_invocable_v); static_assert(!std::is_invocable_v); static_assert(!std::is_invocable_v); + + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); + + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); } SUBCASE("const_method_ref") { @@ -505,6 +632,16 @@ TEST_CASE("meta/meta_states/method") { CHECK(mi2.is_invocable_with()); CHECK_FALSE(mi2.is_invocable_with()); CHECK_FALSE(mi2.is_invocable_with()); + + CHECK(mi.is_invocable_with()); + CHECK(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + + CHECK(mi2.is_invocable_with()); + CHECK(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); } { @@ -530,6 +667,16 @@ TEST_CASE("meta/meta_states/method") { static_assert(std::is_invocable_v); static_assert(!std::is_invocable_v); static_assert(!std::is_invocable_v); + + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + //static_assert(!std::is_invocable_v); // msvc issue + //static_assert(!std::is_invocable_v); // msvc issue + + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); } SUBCASE("const_method_noexcept_ref") { @@ -564,6 +711,16 @@ TEST_CASE("meta/meta_states/method") { CHECK(mi2.is_invocable_with()); CHECK_FALSE(mi2.is_invocable_with()); CHECK_FALSE(mi2.is_invocable_with()); + + CHECK(mi.is_invocable_with()); + CHECK(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + + CHECK(mi2.is_invocable_with()); + CHECK(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); } { @@ -589,6 +746,16 @@ TEST_CASE("meta/meta_states/method") { static_assert(std::is_invocable_v); static_assert(!std::is_invocable_v); static_assert(!std::is_invocable_v); + + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + //static_assert(!std::is_invocable_v); // msvc issue + //static_assert(!std::is_invocable_v); // msvc issue + + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); } SUBCASE("non_const_method_rref") { @@ -623,6 +790,16 @@ TEST_CASE("meta/meta_states/method") { CHECK_FALSE(mi2.is_invocable_with()); CHECK(mi2.is_invocable_with()); CHECK_FALSE(mi2.is_invocable_with()); + + CHECK_FALSE(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + CHECK(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + + CHECK_FALSE(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); + CHECK(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); } { @@ -648,6 +825,16 @@ TEST_CASE("meta/meta_states/method") { static_assert(!std::is_invocable_v); static_assert(std::is_invocable_v); static_assert(!std::is_invocable_v); + + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); } SUBCASE("non_const_method_noexcept_rref") { @@ -682,6 +869,16 @@ TEST_CASE("meta/meta_states/method") { CHECK_FALSE(mi2.is_invocable_with()); CHECK(mi2.is_invocable_with()); CHECK_FALSE(mi2.is_invocable_with()); + + CHECK_FALSE(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + CHECK(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + + CHECK_FALSE(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); + CHECK(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); } { @@ -707,6 +904,16 @@ TEST_CASE("meta/meta_states/method") { static_assert(!std::is_invocable_v); static_assert(std::is_invocable_v); static_assert(!std::is_invocable_v); + + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); } SUBCASE("const_method_rref") { @@ -741,6 +948,16 @@ TEST_CASE("meta/meta_states/method") { CHECK_FALSE(mi2.is_invocable_with()); CHECK(mi2.is_invocable_with()); CHECK(mi2.is_invocable_with()); + + CHECK_FALSE(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + CHECK(mi.is_invocable_with()); + CHECK(mi.is_invocable_with()); + + CHECK_FALSE(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); + CHECK(mi2.is_invocable_with()); + CHECK(mi2.is_invocable_with()); } { @@ -766,6 +983,16 @@ TEST_CASE("meta/meta_states/method") { static_assert(!std::is_invocable_v); static_assert(std::is_invocable_v); static_assert(std::is_invocable_v); + + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); } SUBCASE("const_method_noexcept_rref") { @@ -800,6 +1027,16 @@ TEST_CASE("meta/meta_states/method") { CHECK_FALSE(mi2.is_invocable_with()); CHECK(mi2.is_invocable_with()); CHECK(mi2.is_invocable_with()); + + CHECK_FALSE(mi.is_invocable_with()); + CHECK_FALSE(mi.is_invocable_with()); + CHECK(mi.is_invocable_with()); + CHECK(mi.is_invocable_with()); + + CHECK_FALSE(mi2.is_invocable_with()); + CHECK_FALSE(mi2.is_invocable_with()); + CHECK(mi2.is_invocable_with()); + CHECK(mi2.is_invocable_with()); } { @@ -825,5 +1062,15 @@ TEST_CASE("meta/meta_states/method") { static_assert(!std::is_invocable_v); static_assert(std::is_invocable_v); static_assert(std::is_invocable_v); + + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); } } diff --git a/untests/meta_utilities/arg_tests.cpp b/untests/meta_utilities/arg_tests.cpp index f895c7c..af794ee 100644 --- a/untests/meta_utilities/arg_tests.cpp +++ b/untests/meta_utilities/arg_tests.cpp @@ -69,6 +69,128 @@ namespace } } +TEST_CASE("features/meta_utilities/arg/from_value") { + namespace meta = meta_hpp; + + SUBCASE("ptr") { + ivec2 v{1,2}; + ivec2* vp = &v; + meta::value vvp{vp}; + meta::detail::arg a{vvp}; + + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::ref); + } + + SUBCASE("rptr") { + ivec2 v{1,2}; + ivec2* vp = &v; + meta::value vvp{vp}; + meta::detail::arg a{std::move(vvp)}; + + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::rref); + } + + SUBCASE("ptr_c") { + ivec2 v{1,2}; + ivec2* const vp = &v; + const meta::value vvp{vp}; + meta::detail::arg a{vvp}; + + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::cref); + } + + SUBCASE("rptr_c") { + ivec2 v{1,2}; + ivec2* const vp = &v; + const meta::value vvp{vp}; + meta::detail::arg a{std::move(vvp)}; + + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::crref); + } + + SUBCASE("cptr") { + const ivec2 v{1,2}; + const ivec2* vp = &v; + meta::value vvp{vp}; + meta::detail::arg a{vvp}; + + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::ref); + } + + SUBCASE("crptr") { + const ivec2 v{1,2}; + const ivec2* vp = &v; + meta::value vvp{vp}; + meta::detail::arg a{std::move(vvp)}; + + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::rref); + } + + SUBCASE("cptr_c") { + const ivec2 v{1,2}; + const ivec2* const vp = &v; + const meta::value vvp{vp}; + meta::detail::arg a{vvp}; + + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::cref); + } + + SUBCASE("crptr_c") { + const ivec2 v{1,2}; + const ivec2* const vp = &v; + const meta::value vvp{vp}; + meta::detail::arg a{std::move(vvp)}; + + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::crref); + } + + SUBCASE("ref") { + ivec2 v{1,2}; + ivec2& vr = v; + meta::value vvr{vr}; + meta::detail::arg a{vvr}; + + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::ref); + } + + SUBCASE("cref") { + const ivec2 v{1,2}; + const ivec2& vr = v; + const meta::value vvr{vr}; + meta::detail::arg a{vvr}; + + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::cref); + } + + SUBCASE("rref") { + ivec2 v{1,2}; + meta::value vv{v}; + meta::detail::arg a{std::move(vv)}; + + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::rref); + } + + SUBCASE("crref") { + const ivec2 v{1,2}; + const meta::value vv{v}; + meta::detail::arg a{std::move(vv)}; + + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::crref); + } +} + TEST_CASE("features/meta_utilities/arg/type") { namespace meta = meta_hpp; diff --git a/untests/meta_utilities/inst_tests.cpp b/untests/meta_utilities/inst_tests.cpp index 5f29099..9048994 100644 --- a/untests/meta_utilities/inst_tests.cpp +++ b/untests/meta_utilities/inst_tests.cpp @@ -31,42 +31,110 @@ namespace ivec2& operator=(ivec2&&) = delete; ivec2& operator=(const ivec2&) = delete; }; + + struct derived_ivec2 : ivec2 { + [[maybe_unused]] derived_ivec2() = default; + [[maybe_unused]] explicit derived_ivec2(int v): ivec2{v, v} {} + [[maybe_unused]] derived_ivec2(int x, int y): ivec2{x, y} {} + }; } TEST_CASE("features/meta_utilities/inst") { namespace meta = meta_hpp; SUBCASE("ref") { - ivec2 v{1,2}; - ivec2& vr = v; - meta::detail::inst a{vr}; + { + derived_ivec2 v{1,2}; + derived_ivec2& vr = v; + meta::detail::inst a{vr}; - CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::inst::ref_types::ref); + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::inst::ref_types::ref); + } + { + meta::value v{derived_ivec2{1,2}}; + meta::value& vr = v; + meta::detail::inst a{vr}; + + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::inst::ref_types::ref); + + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + } } SUBCASE("cref") { - const ivec2 v{1,2}; - const ivec2& vr = v; - meta::detail::inst a{vr}; + { + const derived_ivec2 v{1,2}; + const derived_ivec2& vr = v; + meta::detail::inst a{vr}; - CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::inst::ref_types::cref); + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::inst::ref_types::cref); + } + { + const meta::value v{derived_ivec2{1,2}}; + const meta::value& vr = v; + meta::detail::inst a{vr}; + + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::inst::ref_types::cref); + + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + } } SUBCASE("rref") { - ivec2 v{1,2}; - meta::detail::inst a{std::move(v)}; + { + derived_ivec2 v{1,2}; + meta::detail::inst a{std::move(v)}; - CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::inst::ref_types::rref); + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::inst::ref_types::rref); + } + { + meta::value v{derived_ivec2{1,2}}; + meta::detail::inst a{std::move(v)}; + + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::inst::ref_types::rref); + + CHECK(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); + CHECK(a.can_cast_to()); + } } SUBCASE("crref") { - const ivec2 v{1,2}; - meta::detail::inst a{std::move(v)}; + { + const derived_ivec2 v{1,2}; + meta::detail::inst a{std::move(v)}; - CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::inst::ref_types::crref); + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::inst::ref_types::crref); + } + { + const meta::value v{derived_ivec2{1,2}}; + meta::detail::inst a{std::move(v)}; + + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::inst::ref_types::crref); + + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK_FALSE(a.can_cast_to()); + CHECK(a.can_cast_to()); + } } } From 15c4d1c3c681f30a81759dd69e3caa5342ab7a21 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sat, 27 Nov 2021 19:26:06 +0700 Subject: [PATCH 121/233] new class example --- untests/examples/class_example.cpp | 95 +++++++++++++++++++++++++----- 1 file changed, 80 insertions(+), 15 deletions(-) diff --git a/untests/examples/class_example.cpp b/untests/examples/class_example.cpp index e2d1eab..7e7a0fb 100644 --- a/untests/examples/class_example.cpp +++ b/untests/examples/class_example.cpp @@ -8,31 +8,96 @@ namespace { - struct base_clazz { + class shape { + public: + shape() = default; + shape(const shape&) = default; + shape& operator=(const shape&) = default; + + virtual ~shape() {} + virtual double area() const = 0; }; - struct derived_clazz final : base_clazz { + class circle : public shape { + double radius_; + public: + circle(const circle&) = default; + circle& operator=(const circle&) = default; + + explicit circle(double radius) : radius_{radius} {} + double area() const override { return 3.1415926536 * radius_ * radius_; } + + double radius() const { return radius_; } + }; + + class rectangle : public shape { + double width_; + double height_; + public: + rectangle(const rectangle&) = default; + rectangle& operator=(const rectangle&) = default; + + explicit rectangle(double width, double height) : width_{width}, height_{height} {} + double area() const override { return width_ * height_; } + + double width() const { return width_; } + double height() const { return height_; } }; } TEST_CASE("meta/examples/class") { namespace meta = meta_hpp; - meta::class_() - .base_(); + meta::class_() + .method_("area", &shape::area); - const meta::class_type base_clazz_type = meta::resolve_type(); - REQUIRE(base_clazz_type); + meta::class_() + .base_() + .ctor_() + .method_("radius", &circle::radius); - const meta::class_type derived_clazz_type = meta::resolve_type(); - REQUIRE(derived_clazz_type); + meta::class_() + .base_() + .ctor_() + .method_("width", &rectangle::width) + .method_("height", &rectangle::height); - CHECK(base_clazz_type.is_base_of()); - CHECK(derived_clazz_type.is_derived_from()); + const meta::scope geometry = meta::local_scope_("geometry") + .class_("shape") + .class_("circle") + .class_("rectangle"); - const meta::class_type int_vector_type = meta::resolve_type>(); - REQUIRE(int_vector_type); - CHECK(int_vector_type.get_arity() == 2); - CHECK(int_vector_type.get_argument_type(0) == meta::resolve_type()); - CHECK(int_vector_type.get_argument_type(1) == meta::resolve_type>()); + const meta::class_type shape_type = geometry.get_class("shape"); + const meta::method area_method = shape_type.get_method("area"); + + { + const meta::class_type circle_type = geometry.get_class("circle"); + + const meta::method radius_method = circle_type.get_method("radius"); + + const meta::value circle_v = circle_type.create(5.0).value(); + + const meta::value circle_area_v = area_method(circle_v).value(); + const meta::value circle_radius_v = radius_method(circle_v).value(); + + CHECK(circle_area_v.cast() == doctest::Approx(78.5).epsilon(0.1)); + CHECK(circle_radius_v == 5.0); + } + + { + const meta::class_type rectangle_type = geometry.get_class("rectangle"); + + const meta::method width_method = rectangle_type.get_method("width"); + const meta::method height_method = rectangle_type.get_method("height"); + + const meta::value rectangle_v = rectangle_type(10.0, 20.0).value(); + + const meta::value rectangle_area_v = area_method(rectangle_v).value(); + const meta::value rectangle_width_v = width_method(rectangle_v).value(); + const meta::value rectangle_height_v = height_method(rectangle_v).value(); + + CHECK(rectangle_area_v.cast() == doctest::Approx(200.0).epsilon(0.1)); + CHECK(rectangle_width_v == 10.0); + CHECK(rectangle_height_v == 20.0); + } } From 1c48e85dbeb96c3e3cc624553c78caf253ff154c Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Mon, 29 Nov 2021 19:07:15 +0700 Subject: [PATCH 122/233] remove volatile support --- headers/meta.hpp/meta_traits.hpp | 1 - .../meta.hpp/meta_traits/method_traits.hpp | 98 ---- untests/meta_states/method_tests.cpp | 494 +----------------- 3 files changed, 24 insertions(+), 569 deletions(-) diff --git a/headers/meta.hpp/meta_traits.hpp b/headers/meta.hpp/meta_traits.hpp index 37af24b..86bb82e 100644 --- a/headers/meta.hpp/meta_traits.hpp +++ b/headers/meta.hpp/meta_traits.hpp @@ -77,7 +77,6 @@ namespace meta_hpp enum class method_flags : std::uint32_t { is_const = 1 << 0, is_noexcept = 1 << 1, - is_volatile = 1 << 2, is_lvalue_qualified = 1 << 3, is_rvalue_qualified = 1 << 4, }; diff --git a/headers/meta.hpp/meta_traits/method_traits.hpp b/headers/meta.hpp/meta_traits/method_traits.hpp index fef9086..e75ddf4 100644 --- a/headers/meta.hpp/meta_traits/method_traits.hpp +++ b/headers/meta.hpp/meta_traits/method_traits.hpp @@ -119,102 +119,4 @@ namespace meta_hpp::detail return method_flags::is_const | method_flags::is_noexcept | method_flags::is_rvalue_qualified; } }; - - // - - template < typename R, typename C, typename... Args > - struct method_traits : method_traits { - using qualified_type = C; - static bitflags make_flags() noexcept { - return method_flags::is_volatile; - } - }; - - template < typename R, typename C, typename... Args > - struct method_traits : method_traits { - using qualified_type = const C; - static bitflags make_flags() noexcept { - return method_flags::is_volatile | method_flags::is_const; - } - }; - - template < typename R, typename C, typename... Args > - struct method_traits : method_traits { - using qualified_type = C; - static bitflags make_flags() noexcept { - return method_flags::is_volatile | method_flags::is_noexcept; - } - }; - - template < typename R, typename C, typename... Args > - struct method_traits : method_traits { - using qualified_type = const C; - static bitflags make_flags() noexcept { - return method_flags::is_volatile | method_flags::is_const | method_flags::is_noexcept; - } - }; - - template < typename R, typename C, typename... Args > - struct method_traits : method_traits { - using qualified_type = C&; - static bitflags make_flags() noexcept { - return method_flags::is_volatile | method_flags::is_lvalue_qualified; - } - }; - - template < typename R, typename C, typename... Args > - struct method_traits : method_traits { - using qualified_type = C&; - static bitflags make_flags() noexcept { - return method_flags::is_volatile | method_flags::is_noexcept | method_flags::is_lvalue_qualified; - } - }; - - template < typename R, typename C, typename... Args > - struct method_traits : method_traits { - using qualified_type = const C&; - static bitflags make_flags() noexcept { - return method_flags::is_volatile | method_flags::is_const | method_flags::is_lvalue_qualified; - } - }; - - template < typename R, typename C, typename... Args > - struct method_traits : method_traits { - using qualified_type = const C&; - static bitflags make_flags() noexcept { - return method_flags::is_volatile | method_flags::is_const | method_flags::is_noexcept | method_flags::is_lvalue_qualified; - } - }; - - template < typename R, typename C, typename... Args > - struct method_traits : method_traits { - using qualified_type = C&&; - static bitflags make_flags() noexcept { - return method_flags::is_volatile | method_flags::is_rvalue_qualified; - } - }; - - template < typename R, typename C, typename... Args > - struct method_traits : method_traits { - using qualified_type = C&&; - static bitflags make_flags() noexcept { - return method_flags::is_volatile | method_flags::is_noexcept | method_flags::is_rvalue_qualified; - } - }; - - template < typename R, typename C, typename... Args > - struct method_traits : method_traits { - using qualified_type = const C&&; - static bitflags make_flags() noexcept { - return method_flags::is_volatile | method_flags::is_const | method_flags::is_rvalue_qualified; - } - }; - - template < typename R, typename C, typename... Args > - struct method_traits : method_traits { - using qualified_type = const C&&; - static bitflags make_flags() noexcept { - return method_flags::is_volatile | method_flags::is_const | method_flags::is_noexcept | method_flags::is_rvalue_qualified; - } - }; } diff --git a/untests/meta_states/method_tests.cpp b/untests/meta_states/method_tests.cpp index c8c6635..ac67c8d 100644 --- a/untests/meta_states/method_tests.cpp +++ b/untests/meta_states/method_tests.cpp @@ -36,26 +36,6 @@ namespace int const_method_rref() const && { return 11; } int const_method_noexcept_rref() const && noexcept { return 12; } - - // - - int non_const_method_volatile() volatile { return 1; } - int non_const_method_noexcept_volatile() volatile noexcept { return 2; } - - int const_method_volatile() volatile const { return 3; } - int const_method_noexcept_volatile() volatile const noexcept { return 4; } - - int non_const_method_ref_volatile() volatile & { return 5; } - int non_const_method_noexcept_ref_volatile() volatile & noexcept { return 6; } - - int const_method_ref_volatile() volatile const & { return 7; } - int const_method_noexcept_ref_volatile() volatile const & noexcept { return 8; } - - int non_const_method_rref_volatile() volatile && { return 9; } - int non_const_method_noexcept_rref_volatile() volatile && noexcept { return 10; } - - int const_method_rref_volatile() volatile const && { return 11; } - int const_method_noexcept_rref_volatile() volatile const && noexcept { return 12; } }; struct derived_clazz : clazz { @@ -88,25 +68,7 @@ TEST_CASE("meta/meta_states/method") { .method_("non_const_method_noexcept_rref", &clazz::non_const_method_noexcept_rref) .method_("const_method_rref", &clazz::const_method_rref) - .method_("const_method_noexcept_rref", &clazz::const_method_noexcept_rref) - - .method_("non_const_method_volatile", &clazz::non_const_method_volatile) - .method_("non_const_method_noexcept_volatile", &clazz::non_const_method_noexcept_volatile) - - .method_("const_method_volatile", &clazz::const_method_volatile) - .method_("const_method_noexcept_volatile", &clazz::const_method_noexcept_volatile) - - .method_("non_const_method_ref_volatile", &clazz::non_const_method_ref_volatile) - .method_("non_const_method_noexcept_ref_volatile", &clazz::non_const_method_noexcept_ref_volatile) - - .method_("const_method_ref_volatile", &clazz::const_method_ref_volatile) - .method_("const_method_noexcept_ref_volatile", &clazz::const_method_noexcept_ref_volatile) - - .method_("non_const_method_rref_volatile", &clazz::non_const_method_rref_volatile) - .method_("non_const_method_noexcept_rref_volatile", &clazz::non_const_method_noexcept_rref_volatile) - - .method_("const_method_rref_volatile", &clazz::const_method_rref_volatile) - .method_("const_method_noexcept_rref_volatile", &clazz::const_method_noexcept_rref_volatile); + .method_("const_method_noexcept_rref", &clazz::const_method_noexcept_rref); const meta::class_type ct = meta::resolve_type(); REQUIRE(ct); @@ -120,32 +82,23 @@ TEST_CASE("meta/meta_states/method") { SUBCASE("operators") { const meta::method non_const_method_m = ct.get_method("non_const_method"); - const meta::method non_const_method_volatile_m = ct.get_method("non_const_method_volatile"); + const meta::method non_const_method_rref_m = ct.get_method("non_const_method_rref"); CHECK(non_const_method_m == non_const_method_m); - CHECK(non_const_method_m != non_const_method_volatile_m); - CHECK((non_const_method_m < non_const_method_volatile_m || non_const_method_volatile_m < non_const_method_m)); + CHECK(non_const_method_m != non_const_method_rref_m); + CHECK((non_const_method_m < non_const_method_rref_m || non_const_method_rref_m < non_const_method_m)); } SUBCASE("non_const_method") { const meta::method mi = ct.get_method("non_const_method"); REQUIRE(mi); - const meta::method mi2 = ct.get_method("non_const_method_volatile"); - REQUIRE(mi2); - CHECK(mi.get_name() == "non_const_method"); - CHECK(mi2.get_name() == "non_const_method_volatile"); { CHECK(mi.get_type().get_arity() == 0); CHECK(mi.get_type().get_owner_type() == meta::resolve_type()); CHECK(mi.get_type().get_return_type() == meta::resolve_type()); CHECK(mi.get_type().get_flags() == meta::method_flags{}); - - CHECK(mi2.get_type().get_arity() == 0); - CHECK(mi2.get_type().get_owner_type() == meta::resolve_type()); - CHECK(mi2.get_type().get_return_type() == meta::resolve_type()); - CHECK(mi2.get_type().get_flags() == meta::method_flags::is_volatile); } { @@ -154,20 +107,10 @@ TEST_CASE("meta/meta_states/method") { CHECK(mi.is_invocable_with()); CHECK_FALSE(mi.is_invocable_with()); - CHECK(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); - CHECK(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); - CHECK(mi.is_invocable_with()); CHECK_FALSE(mi.is_invocable_with()); CHECK(mi.is_invocable_with()); CHECK_FALSE(mi.is_invocable_with()); - - CHECK(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); - CHECK(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); } { @@ -177,11 +120,6 @@ TEST_CASE("meta/meta_states/method") { CHECK_THROWS(mi.invoke(std::as_const(cl))); CHECK(mi.invoke(std::move(cl)).value() == 1); CHECK_THROWS(mi.invoke(std::move(std::as_const(cl)))); - - CHECK(mi2.invoke(cl).value() == 1); - CHECK_THROWS(mi2.invoke(std::as_const(cl))); - CHECK(mi2.invoke(std::move(cl)).value() == 1); - CHECK_THROWS(mi2.invoke(std::move(std::as_const(cl)))); } static_assert(std::is_invocable_v); @@ -189,42 +127,23 @@ TEST_CASE("meta/meta_states/method") { static_assert(std::is_invocable_v); static_assert(!std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(std::is_invocable_v); static_assert(!std::is_invocable_v); static_assert(std::is_invocable_v); static_assert(!std::is_invocable_v); - - static_assert(std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(!std::is_invocable_v); } SUBCASE("non_const_method_noexcept") { const meta::method mi = ct.get_method("non_const_method_noexcept"); REQUIRE(mi); - const meta::method mi2 = ct.get_method("non_const_method_noexcept_volatile"); - REQUIRE(mi2); - CHECK(mi.get_name() == "non_const_method_noexcept"); - CHECK(mi2.get_name() == "non_const_method_noexcept_volatile"); { CHECK(mi.get_type().get_arity() == 0); CHECK(mi.get_type().get_owner_type() == meta::resolve_type()); CHECK(mi.get_type().get_return_type() == meta::resolve_type()); CHECK(mi.get_type().get_flags() == meta::method_flags::is_noexcept); - - CHECK(mi2.get_type().get_arity() == 0); - CHECK(mi2.get_type().get_owner_type() == meta::resolve_type()); - CHECK(mi2.get_type().get_return_type() == meta::resolve_type()); - CHECK(mi2.get_type().get_flags() == (meta::method_flags::is_noexcept | meta::method_flags::is_volatile)); } { @@ -233,20 +152,10 @@ TEST_CASE("meta/meta_states/method") { CHECK(mi.is_invocable_with()); CHECK_FALSE(mi.is_invocable_with()); - CHECK(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); - CHECK(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); - CHECK(mi.is_invocable_with()); CHECK_FALSE(mi.is_invocable_with()); CHECK(mi.is_invocable_with()); CHECK_FALSE(mi.is_invocable_with()); - - CHECK(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); - CHECK(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); } { @@ -256,11 +165,6 @@ TEST_CASE("meta/meta_states/method") { CHECK_THROWS(mi.invoke(std::as_const(cl))); CHECK(mi.invoke(std::move(cl)).value() == 2); CHECK_THROWS(mi.invoke(std::move(std::as_const(cl)))); - - CHECK(mi2.invoke(cl).value() == 2); - CHECK_THROWS(mi2.invoke(std::as_const(cl))); - CHECK(mi2.invoke(std::move(cl)).value() == 2); - CHECK_THROWS(mi2.invoke(std::move(std::as_const(cl)))); } static_assert(std::is_invocable_v); @@ -268,42 +172,23 @@ TEST_CASE("meta/meta_states/method") { static_assert(std::is_invocable_v); static_assert(!std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(std::is_invocable_v); static_assert(!std::is_invocable_v); static_assert(std::is_invocable_v); static_assert(!std::is_invocable_v); - - static_assert(std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(!std::is_invocable_v); } SUBCASE("const_method") { const meta::method mi = ct.get_method("const_method"); REQUIRE(mi); - const meta::method mi2 = ct.get_method("const_method_volatile"); - REQUIRE(mi2); - CHECK(mi.get_name() == "const_method"); - CHECK(mi2.get_name() == "const_method_volatile"); { CHECK(mi.get_type().get_arity() == 0); CHECK(mi.get_type().get_owner_type() == meta::resolve_type()); CHECK(mi.get_type().get_return_type() == meta::resolve_type()); CHECK(mi.get_type().get_flags() == meta::method_flags::is_const); - - CHECK(mi2.get_type().get_arity() == 0); - CHECK(mi2.get_type().get_owner_type() == meta::resolve_type()); - CHECK(mi2.get_type().get_return_type() == meta::resolve_type()); - CHECK(mi2.get_type().get_flags() == (meta::method_flags::is_const | meta::method_flags::is_volatile)); } { @@ -312,20 +197,10 @@ TEST_CASE("meta/meta_states/method") { CHECK(mi.is_invocable_with()); CHECK(mi.is_invocable_with()); - CHECK(mi2.is_invocable_with()); - CHECK(mi2.is_invocable_with()); - CHECK(mi2.is_invocable_with()); - CHECK(mi2.is_invocable_with()); - CHECK(mi.is_invocable_with()); CHECK(mi.is_invocable_with()); CHECK(mi.is_invocable_with()); CHECK(mi.is_invocable_with()); - - CHECK(mi2.is_invocable_with()); - CHECK(mi2.is_invocable_with()); - CHECK(mi2.is_invocable_with()); - CHECK(mi2.is_invocable_with()); } { @@ -335,11 +210,6 @@ TEST_CASE("meta/meta_states/method") { CHECK(mi.invoke(std::as_const(cl)).value() == 3); CHECK(mi.invoke(std::move(cl)).value() == 3); CHECK(mi.invoke(std::move(std::as_const(cl))).value() == 3); - - CHECK(mi2.invoke(cl).value() == 3); - CHECK(mi2.invoke(std::as_const(cl)).value() == 3); - CHECK(mi2.invoke(std::move(cl)).value() == 3); - CHECK(mi2.invoke(std::move(std::as_const(cl))).value() == 3); } static_assert(std::is_invocable_v); @@ -347,42 +217,23 @@ TEST_CASE("meta/meta_states/method") { static_assert(std::is_invocable_v); static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); static_assert(std::is_invocable_v); static_assert(std::is_invocable_v); static_assert(std::is_invocable_v); - - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); } SUBCASE("const_method_noexcept") { const meta::method mi = ct.get_method("const_method_noexcept"); REQUIRE(mi); - const meta::method mi2 = ct.get_method("const_method_noexcept_volatile"); - REQUIRE(mi2); - CHECK(mi.get_name() == "const_method_noexcept"); - CHECK(mi2.get_name() == "const_method_noexcept_volatile"); { CHECK(mi.get_type().get_arity() == 0); CHECK(mi.get_type().get_owner_type() == meta::resolve_type()); CHECK(mi.get_type().get_return_type() == meta::resolve_type()); CHECK(mi.get_type().get_flags() == (meta::method_flags::is_const | meta::method_flags::is_noexcept)); - - CHECK(mi2.get_type().get_arity() == 0); - CHECK(mi2.get_type().get_owner_type() == meta::resolve_type()); - CHECK(mi2.get_type().get_return_type() == meta::resolve_type()); - CHECK(mi2.get_type().get_flags() == (meta::method_flags::is_const | meta::method_flags::is_noexcept | meta::method_flags::is_volatile)); } { @@ -391,20 +242,10 @@ TEST_CASE("meta/meta_states/method") { CHECK(mi.is_invocable_with()); CHECK(mi.is_invocable_with()); - CHECK(mi2.is_invocable_with()); - CHECK(mi2.is_invocable_with()); - CHECK(mi2.is_invocable_with()); - CHECK(mi2.is_invocable_with()); - CHECK(mi.is_invocable_with()); CHECK(mi.is_invocable_with()); CHECK(mi.is_invocable_with()); CHECK(mi.is_invocable_with()); - - CHECK(mi2.is_invocable_with()); - CHECK(mi2.is_invocable_with()); - CHECK(mi2.is_invocable_with()); - CHECK(mi2.is_invocable_with()); } { @@ -414,11 +255,6 @@ TEST_CASE("meta/meta_states/method") { CHECK(mi.invoke(std::as_const(cl)).value() == 4); CHECK(mi.invoke(std::move(cl)).value() == 4); CHECK(mi.invoke(std::move(std::as_const(cl))).value() == 4); - - CHECK(mi2.invoke(cl).value() == 4); - CHECK(mi2.invoke(std::as_const(cl)).value() == 4); - CHECK(mi2.invoke(std::move(cl)).value() == 4); - CHECK(mi2.invoke(std::move(std::as_const(cl))).value() == 4); } static_assert(std::is_invocable_v); @@ -426,42 +262,23 @@ TEST_CASE("meta/meta_states/method") { static_assert(std::is_invocable_v); static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); static_assert(std::is_invocable_v); static_assert(std::is_invocable_v); static_assert(std::is_invocable_v); - - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); } SUBCASE("non_const_method_ref") { const meta::method mi = ct.get_method("non_const_method_ref"); REQUIRE(mi); - const meta::method mi2 = ct.get_method("non_const_method_ref_volatile"); - REQUIRE(mi2); - CHECK(mi.get_name() == "non_const_method_ref"); - CHECK(mi2.get_name() == "non_const_method_ref_volatile"); { CHECK(mi.get_type().get_arity() == 0); CHECK(mi.get_type().get_owner_type() == meta::resolve_type()); CHECK(mi.get_type().get_return_type() == meta::resolve_type()); CHECK(mi.get_type().get_flags() == meta::method_flags::is_lvalue_qualified); - - CHECK(mi2.get_type().get_arity() == 0); - CHECK(mi2.get_type().get_owner_type() == meta::resolve_type()); - CHECK(mi2.get_type().get_return_type() == meta::resolve_type()); - CHECK(mi2.get_type().get_flags() == (meta::method_flags::is_volatile | meta::method_flags::is_lvalue_qualified)); } { @@ -470,20 +287,10 @@ TEST_CASE("meta/meta_states/method") { CHECK_FALSE(mi.is_invocable_with()); CHECK_FALSE(mi.is_invocable_with()); - CHECK(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); - CHECK(mi.is_invocable_with()); CHECK_FALSE(mi.is_invocable_with()); CHECK_FALSE(mi.is_invocable_with()); CHECK_FALSE(mi.is_invocable_with()); - - CHECK(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); } { @@ -493,11 +300,6 @@ TEST_CASE("meta/meta_states/method") { 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(mi2.invoke(cl).value() == 5); - CHECK_THROWS(mi2.invoke(std::as_const(cl))); - CHECK_THROWS(mi2.invoke(std::move(cl))); - CHECK_THROWS(mi2.invoke(std::move(std::as_const(cl)))); } static_assert(std::is_invocable_v); @@ -505,42 +307,23 @@ TEST_CASE("meta/meta_states/method") { static_assert(!std::is_invocable_v); static_assert(!std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(std::is_invocable_v); static_assert(!std::is_invocable_v); static_assert(!std::is_invocable_v); static_assert(!std::is_invocable_v); - - static_assert(std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(!std::is_invocable_v); } SUBCASE("non_const_method_noexcept_ref") { const meta::method mi = ct.get_method("non_const_method_noexcept_ref"); REQUIRE(mi); - const meta::method mi2 = ct.get_method("non_const_method_noexcept_ref_volatile"); - REQUIRE(mi2); - CHECK(mi.get_name() == "non_const_method_noexcept_ref"); - CHECK(mi2.get_name() == "non_const_method_noexcept_ref_volatile"); { CHECK(mi.get_type().get_arity() == 0); CHECK(mi.get_type().get_owner_type() == meta::resolve_type()); CHECK(mi.get_type().get_return_type() == meta::resolve_type()); CHECK(mi.get_type().get_flags() == (meta::method_flags::is_noexcept | meta::method_flags::is_lvalue_qualified)); - - CHECK(mi2.get_type().get_arity() == 0); - CHECK(mi2.get_type().get_owner_type() == meta::resolve_type()); - CHECK(mi2.get_type().get_return_type() == meta::resolve_type()); - CHECK(mi2.get_type().get_flags() == (meta::method_flags::is_noexcept | meta::method_flags::is_volatile | meta::method_flags::is_lvalue_qualified)); } { @@ -549,20 +332,10 @@ TEST_CASE("meta/meta_states/method") { CHECK_FALSE(mi.is_invocable_with()); CHECK_FALSE(mi.is_invocable_with()); - CHECK(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); - CHECK(mi.is_invocable_with()); CHECK_FALSE(mi.is_invocable_with()); CHECK_FALSE(mi.is_invocable_with()); CHECK_FALSE(mi.is_invocable_with()); - - CHECK(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); } { @@ -572,11 +345,6 @@ TEST_CASE("meta/meta_states/method") { 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(mi2.invoke(cl).value() == 6); - CHECK_THROWS(mi2.invoke(std::as_const(cl))); - CHECK_THROWS(mi2.invoke(std::move(cl))); - CHECK_THROWS(mi2.invoke(std::move(std::as_const(cl)))); } static_assert(std::is_invocable_v); @@ -584,64 +352,35 @@ TEST_CASE("meta/meta_states/method") { static_assert(!std::is_invocable_v); static_assert(!std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(std::is_invocable_v); static_assert(!std::is_invocable_v); static_assert(!std::is_invocable_v); static_assert(!std::is_invocable_v); - - static_assert(std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(!std::is_invocable_v); } SUBCASE("const_method_ref") { const meta::method mi = ct.get_method("const_method_ref"); REQUIRE(mi); - const meta::method mi2 = ct.get_method("const_method_ref_volatile"); - REQUIRE(mi2); - CHECK(mi.get_name() == "const_method_ref"); - CHECK(mi2.get_name() == "const_method_ref_volatile"); { CHECK(mi.get_type().get_arity() == 0); CHECK(mi.get_type().get_owner_type() == meta::resolve_type()); CHECK(mi.get_type().get_return_type() == meta::resolve_type()); CHECK(mi.get_type().get_flags() == (meta::method_flags::is_const | meta::method_flags::is_lvalue_qualified)); - - CHECK(mi2.get_type().get_arity() == 0); - CHECK(mi2.get_type().get_owner_type() == meta::resolve_type()); - CHECK(mi2.get_type().get_return_type() == meta::resolve_type()); - CHECK(mi2.get_type().get_flags() == (meta::method_flags::is_const | meta::method_flags::is_volatile | meta::method_flags::is_lvalue_qualified)); } { CHECK(mi.is_invocable_with()); CHECK(mi.is_invocable_with()); - CHECK_FALSE(mi.is_invocable_with()); - CHECK_FALSE(mi.is_invocable_with()); - - CHECK(mi2.is_invocable_with()); - CHECK(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); + CHECK(mi.is_invocable_with()); + CHECK(mi.is_invocable_with()); CHECK(mi.is_invocable_with()); CHECK(mi.is_invocable_with()); - CHECK_FALSE(mi.is_invocable_with()); - CHECK_FALSE(mi.is_invocable_with()); - - CHECK(mi2.is_invocable_with()); - CHECK(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); + CHECK(mi.is_invocable_with()); + CHECK(mi.is_invocable_with()); } { @@ -649,78 +388,44 @@ TEST_CASE("meta/meta_states/method") { CHECK(mi.invoke(cl).value() == 7); CHECK(mi.invoke(std::as_const(cl)).value() == 7); - CHECK_THROWS(mi.invoke(std::move(cl))); - CHECK_THROWS(mi.invoke(std::move(std::as_const(cl)))); - - CHECK(mi2.invoke(cl).value() == 7); - CHECK(mi2.invoke(std::as_const(cl)).value() == 7); - CHECK_THROWS(mi2.invoke(std::move(cl))); - CHECK_THROWS(mi2.invoke(std::move(std::as_const(cl)))); + CHECK(mi.invoke(std::move(cl)) == 7); + CHECK(mi.invoke(std::move(std::as_const(cl))) == 7); } static_assert(std::is_invocable_v); static_assert(std::is_invocable_v); - //static_assert(!std::is_invocable_v); // msvc issue - //static_assert(!std::is_invocable_v); // msvc issue - - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); static_assert(std::is_invocable_v); static_assert(std::is_invocable_v); - //static_assert(!std::is_invocable_v); // msvc issue - //static_assert(!std::is_invocable_v); // msvc issue - - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); } SUBCASE("const_method_noexcept_ref") { const meta::method mi = ct.get_method("const_method_noexcept_ref"); REQUIRE(mi); - const meta::method mi2 = ct.get_method("const_method_noexcept_ref_volatile"); - REQUIRE(mi2); - CHECK(mi.get_name() == "const_method_noexcept_ref"); - CHECK(mi2.get_name() == "const_method_noexcept_ref_volatile"); { CHECK(mi.get_type().get_arity() == 0); CHECK(mi.get_type().get_owner_type() == meta::resolve_type()); CHECK(mi.get_type().get_return_type() == meta::resolve_type()); CHECK(mi.get_type().get_flags() == (meta::method_flags::is_const | meta::method_flags::is_noexcept | meta::method_flags::is_lvalue_qualified)); - - CHECK(mi2.get_type().get_arity() == 0); - CHECK(mi2.get_type().get_owner_type() == meta::resolve_type()); - CHECK(mi2.get_type().get_return_type() == meta::resolve_type()); - CHECK(mi2.get_type().get_flags() == (meta::method_flags::is_const | meta::method_flags::is_noexcept | meta::method_flags::is_volatile | meta::method_flags::is_lvalue_qualified)); } { CHECK(mi.is_invocable_with()); CHECK(mi.is_invocable_with()); - CHECK_FALSE(mi.is_invocable_with()); - CHECK_FALSE(mi.is_invocable_with()); - - CHECK(mi2.is_invocable_with()); - CHECK(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); + CHECK(mi.is_invocable_with()); + CHECK(mi.is_invocable_with()); CHECK(mi.is_invocable_with()); CHECK(mi.is_invocable_with()); - CHECK_FALSE(mi.is_invocable_with()); - CHECK_FALSE(mi.is_invocable_with()); - - CHECK(mi2.is_invocable_with()); - CHECK(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); + CHECK(mi.is_invocable_with()); + CHECK(mi.is_invocable_with()); } { @@ -728,56 +433,32 @@ TEST_CASE("meta/meta_states/method") { CHECK(mi.invoke(cl).value() == 8); CHECK(mi.invoke(std::as_const(cl)).value() == 8); - CHECK_THROWS(mi.invoke(std::move(cl))); - CHECK_THROWS(mi.invoke(std::move(std::as_const(cl)))); - - CHECK(mi2.invoke(cl).value() == 8); - CHECK(mi2.invoke(std::as_const(cl)).value() == 8); - CHECK_THROWS(mi2.invoke(std::move(cl))); - CHECK_THROWS(mi2.invoke(std::move(std::as_const(cl)))); + CHECK(mi.invoke(std::move(cl)) == 8); + CHECK(mi.invoke(std::move(std::as_const(cl))) == 8); } static_assert(std::is_invocable_v); static_assert(std::is_invocable_v); - //static_assert(!std::is_invocable_v); // msvc issue - //static_assert(!std::is_invocable_v); // msvc issue - - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); static_assert(std::is_invocable_v); static_assert(std::is_invocable_v); - //static_assert(!std::is_invocable_v); // msvc issue - //static_assert(!std::is_invocable_v); // msvc issue - - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); } SUBCASE("non_const_method_rref") { const meta::method mi = ct.get_method("non_const_method_rref"); REQUIRE(mi); - const meta::method mi2 = ct.get_method("non_const_method_rref_volatile"); - REQUIRE(mi2); - CHECK(mi.get_name() == "non_const_method_rref"); - CHECK(mi2.get_name() == "non_const_method_rref_volatile"); { CHECK(mi.get_type().get_arity() == 0); CHECK(mi.get_type().get_owner_type() == meta::resolve_type()); CHECK(mi.get_type().get_return_type() == meta::resolve_type()); CHECK(mi.get_type().get_flags() == meta::method_flags::is_rvalue_qualified); - - CHECK(mi2.get_type().get_arity() == 0); - CHECK(mi2.get_type().get_owner_type() == meta::resolve_type()); - CHECK(mi2.get_type().get_return_type() == meta::resolve_type()); - CHECK(mi2.get_type().get_flags() == (meta::method_flags::is_volatile | meta::method_flags::is_rvalue_qualified)); } { @@ -786,20 +467,10 @@ TEST_CASE("meta/meta_states/method") { CHECK(mi.is_invocable_with()); CHECK_FALSE(mi.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); - CHECK(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); - CHECK_FALSE(mi.is_invocable_with()); CHECK_FALSE(mi.is_invocable_with()); CHECK(mi.is_invocable_with()); CHECK_FALSE(mi.is_invocable_with()); - - CHECK_FALSE(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); - CHECK(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); } { @@ -809,11 +480,6 @@ TEST_CASE("meta/meta_states/method") { CHECK_THROWS(mi.invoke(std::as_const(cl))); CHECK(mi.invoke(std::move(cl)).value() == 9); CHECK_THROWS(mi.invoke(std::move(std::as_const(cl)))); - - CHECK_THROWS(mi2.invoke(cl)); - CHECK_THROWS(mi2.invoke(std::as_const(cl))); - CHECK(mi2.invoke(std::move(cl)).value() == 9); - CHECK_THROWS(mi2.invoke(std::move(std::as_const(cl)))); } static_assert(!std::is_invocable_v); @@ -821,42 +487,23 @@ TEST_CASE("meta/meta_states/method") { static_assert(std::is_invocable_v); static_assert(!std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(!std::is_invocable_v); static_assert(!std::is_invocable_v); static_assert(std::is_invocable_v); static_assert(!std::is_invocable_v); - - static_assert(!std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(!std::is_invocable_v); } SUBCASE("non_const_method_noexcept_rref") { const meta::method mi = ct.get_method("non_const_method_noexcept_rref"); REQUIRE(mi); - const meta::method mi2 = ct.get_method("non_const_method_noexcept_rref_volatile"); - REQUIRE(mi2); - CHECK(mi.get_name() == "non_const_method_noexcept_rref"); - CHECK(mi2.get_name() == "non_const_method_noexcept_rref_volatile"); { CHECK(mi.get_type().get_arity() == 0); CHECK(mi.get_type().get_owner_type() == meta::resolve_type()); CHECK(mi.get_type().get_return_type() == meta::resolve_type()); CHECK(mi.get_type().get_flags() == (meta::method_flags::is_noexcept | meta::method_flags::is_rvalue_qualified)); - - CHECK(mi2.get_type().get_arity() == 0); - CHECK(mi2.get_type().get_owner_type() == meta::resolve_type()); - CHECK(mi2.get_type().get_return_type() == meta::resolve_type()); - CHECK(mi2.get_type().get_flags() == (meta::method_flags::is_noexcept | meta::method_flags::is_volatile | meta::method_flags::is_rvalue_qualified)); } { @@ -865,20 +512,10 @@ TEST_CASE("meta/meta_states/method") { CHECK(mi.is_invocable_with()); CHECK_FALSE(mi.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); - CHECK(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); - CHECK_FALSE(mi.is_invocable_with()); CHECK_FALSE(mi.is_invocable_with()); CHECK(mi.is_invocable_with()); CHECK_FALSE(mi.is_invocable_with()); - - CHECK_FALSE(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); - CHECK(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); } { @@ -888,11 +525,6 @@ TEST_CASE("meta/meta_states/method") { CHECK_THROWS(mi.invoke(std::as_const(cl))); CHECK(mi.invoke(std::move(cl)).value() == 10); CHECK_THROWS(mi.invoke(std::move(std::as_const(cl)))); - - CHECK_THROWS(mi2.invoke(cl)); - CHECK_THROWS(mi2.invoke(std::as_const(cl))); - CHECK(mi2.invoke(std::move(cl)).value() == 10); - CHECK_THROWS(mi2.invoke(std::move(std::as_const(cl)))); } static_assert(!std::is_invocable_v); @@ -900,42 +532,23 @@ TEST_CASE("meta/meta_states/method") { static_assert(std::is_invocable_v); static_assert(!std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(!std::is_invocable_v); static_assert(!std::is_invocable_v); static_assert(std::is_invocable_v); static_assert(!std::is_invocable_v); - - static_assert(!std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(!std::is_invocable_v); } SUBCASE("const_method_rref") { const meta::method mi = ct.get_method("const_method_rref"); REQUIRE(mi); - const meta::method mi2 = ct.get_method("const_method_rref_volatile"); - REQUIRE(mi2); - CHECK(mi.get_name() == "const_method_rref"); - CHECK(mi2.get_name() == "const_method_rref_volatile"); { CHECK(mi.get_type().get_arity() == 0); CHECK(mi.get_type().get_owner_type() == meta::resolve_type()); CHECK(mi.get_type().get_return_type() == meta::resolve_type()); CHECK(mi.get_type().get_flags() == (meta::method_flags::is_const | meta::method_flags::is_rvalue_qualified)); - - CHECK(mi2.get_type().get_arity() == 0); - CHECK(mi2.get_type().get_owner_type() == meta::resolve_type()); - CHECK(mi2.get_type().get_return_type() == meta::resolve_type()); - CHECK(mi2.get_type().get_flags() == (meta::method_flags::is_const | meta::method_flags::is_volatile | meta::method_flags::is_rvalue_qualified)); } { @@ -944,20 +557,10 @@ TEST_CASE("meta/meta_states/method") { CHECK(mi.is_invocable_with()); CHECK(mi.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); - CHECK(mi2.is_invocable_with()); - CHECK(mi2.is_invocable_with()); - CHECK_FALSE(mi.is_invocable_with()); CHECK_FALSE(mi.is_invocable_with()); CHECK(mi.is_invocable_with()); CHECK(mi.is_invocable_with()); - - CHECK_FALSE(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); - CHECK(mi2.is_invocable_with()); - CHECK(mi2.is_invocable_with()); } { @@ -967,11 +570,6 @@ TEST_CASE("meta/meta_states/method") { CHECK_THROWS(mi.invoke(std::as_const(cl))); CHECK(mi.invoke(std::move(cl)).value() == 11); CHECK(mi.invoke(std::move(std::as_const(cl))).value() == 11); - - CHECK_THROWS(mi2.invoke(cl)); - CHECK_THROWS(mi2.invoke(std::as_const(cl))); - CHECK(mi2.invoke(std::move(cl)).value() == 11); - CHECK(mi2.invoke(std::move(std::as_const(cl))).value() == 11); } static_assert(!std::is_invocable_v); @@ -979,42 +577,23 @@ TEST_CASE("meta/meta_states/method") { static_assert(std::is_invocable_v); static_assert(std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(!std::is_invocable_v); static_assert(!std::is_invocable_v); static_assert(std::is_invocable_v); static_assert(std::is_invocable_v); - - static_assert(!std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); } SUBCASE("const_method_noexcept_rref") { const meta::method mi = ct.get_method("const_method_noexcept_rref"); REQUIRE(mi); - const meta::method mi2 = ct.get_method("const_method_noexcept_rref_volatile"); - REQUIRE(mi2); - CHECK(mi.get_name() == "const_method_noexcept_rref"); - CHECK(mi2.get_name() == "const_method_noexcept_rref_volatile"); { CHECK(mi.get_type().get_arity() == 0); CHECK(mi.get_type().get_owner_type() == meta::resolve_type()); CHECK(mi.get_type().get_return_type() == meta::resolve_type()); CHECK(mi.get_type().get_flags() == (meta::method_flags::is_const | meta::method_flags::is_noexcept | meta::method_flags::is_rvalue_qualified)); - - CHECK(mi2.get_type().get_arity() == 0); - CHECK(mi2.get_type().get_owner_type() == meta::resolve_type()); - CHECK(mi2.get_type().get_return_type() == meta::resolve_type()); - CHECK(mi2.get_type().get_flags() == (meta::method_flags::is_const | meta::method_flags::is_noexcept | meta::method_flags::is_volatile | meta::method_flags::is_rvalue_qualified)); } { @@ -1023,20 +602,10 @@ TEST_CASE("meta/meta_states/method") { CHECK(mi.is_invocable_with()); CHECK(mi.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); - CHECK(mi2.is_invocable_with()); - CHECK(mi2.is_invocable_with()); - CHECK_FALSE(mi.is_invocable_with()); CHECK_FALSE(mi.is_invocable_with()); CHECK(mi.is_invocable_with()); CHECK(mi.is_invocable_with()); - - CHECK_FALSE(mi2.is_invocable_with()); - CHECK_FALSE(mi2.is_invocable_with()); - CHECK(mi2.is_invocable_with()); - CHECK(mi2.is_invocable_with()); } { @@ -1046,11 +615,6 @@ TEST_CASE("meta/meta_states/method") { CHECK_THROWS(mi.invoke(std::as_const(cl))); CHECK(mi.invoke(std::move(cl)).value() == 12); CHECK(mi.invoke(std::move(std::as_const(cl))).value() == 12); - - CHECK_THROWS(mi2.invoke(cl)); - CHECK_THROWS(mi2.invoke(std::as_const(cl))); - CHECK(mi2.invoke(std::move(cl)).value() == 12); - CHECK(mi2.invoke(std::move(std::as_const(cl))).value() == 12); } static_assert(!std::is_invocable_v); @@ -1058,19 +622,9 @@ TEST_CASE("meta/meta_states/method") { static_assert(std::is_invocable_v); static_assert(std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(!std::is_invocable_v); static_assert(!std::is_invocable_v); static_assert(std::is_invocable_v); static_assert(std::is_invocable_v); - - static_assert(!std::is_invocable_v); - static_assert(!std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); } } From b77a38afdb59523d93d2b899e3a8c28181691872 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Mon, 29 Nov 2021 20:26:00 +0700 Subject: [PATCH 123/233] add value less operator --- headers/meta.hpp/meta_utilities/value.hpp | 118 +++++++++++++++------- untests/meta_utilities/value_tests.cpp | 25 ++++- 2 files changed, 106 insertions(+), 37 deletions(-) diff --git a/headers/meta.hpp/meta_utilities/value.hpp b/headers/meta.hpp/meta_utilities/value.hpp index 14304ae..4b4fedf 100644 --- a/headers/meta.hpp/meta_utilities/value.hpp +++ b/headers/meta.hpp/meta_utilities/value.hpp @@ -12,28 +12,54 @@ namespace meta_hpp::detail { template < typename T, typename = void > - struct has_value_type_equality_operator - : std::false_type {}; + struct has_value_type_less_op : std::false_type {}; template < typename T > - struct has_value_type_equality_operator() < std::declval() + )>> : std::true_type {}; + + template < typename T > + concept has_value_type_less_op_kind = has_value_type_less_op::value; + + template < typename T > + concept has_not_value_type_less_op_kind = !has_value_type_less_op::value; + + template < has_value_type_less_op_kind T > + bool value_less_function(const value& l, const value& r) { + assert(l.get_type() == r.get_type()); + return l.cast() < r.cast(); + } + + template < has_not_value_type_less_op_kind T > + bool value_less_function([[maybe_unused]] const value& l, [[maybe_unused]] const value& r) { + throw std::logic_error("value type doesn't have less operator"); + } +} + +namespace meta_hpp::detail +{ + template < typename T, typename = void > + struct has_value_type_equals_op : std::false_type {}; + + template < typename T > + struct has_value_type_equals_op() == std::declval() )>> : std::true_type {}; template < typename T > - inline constexpr bool has_value_type_equality_operator_v = has_value_type_equality_operator::value; + concept has_value_type_equals_op_kind = has_value_type_equals_op::value; - template < typename T, std::enable_if_t< - has_value_type_equality_operator_v - , int> = 0 > + template < typename T > + concept has_not_value_type_equals_op_kind = !has_value_type_equals_op::value; + + template < has_value_type_equals_op_kind T > bool value_equals_function(const value& l, const value& r) { assert(l.get_type() == r.get_type()); return l.cast() == r.cast(); } - template < typename T, std::enable_if_t< - !has_value_type_equality_operator_v - , int> = 0 > + template < has_not_value_type_equals_op_kind T > bool value_equals_function([[maybe_unused]] const value& l, [[maybe_unused]] const value& r) { throw std::logic_error("value type doesn't have equality operator"); } @@ -42,27 +68,25 @@ namespace meta_hpp::detail namespace meta_hpp::detail { template < typename T, typename = void > - struct has_value_type_istream_operator - : std::false_type {}; + struct has_value_type_istream_op : std::false_type {}; template < typename T > - struct has_value_type_istream_operator() >> std::declval() )>> : std::true_type {}; template < typename T > - inline constexpr bool has_value_type_istream_operator_v = has_value_type_istream_operator::value; + concept has_value_type_istream_op_kind = has_value_type_istream_op::value; - template < typename T, std::enable_if_t< - has_value_type_istream_operator_v - , int> = 0 > + template < typename T > + concept has_not_value_type_istream_op_kind = !has_value_type_istream_op::value; + + template < has_value_type_istream_op_kind T > void value_istream_function(std::istream& os, value& v) { os >> v.cast(); } - template < typename T, std::enable_if_t< - !has_value_type_istream_operator_v - , int> = 0 > + template < has_not_value_type_istream_op_kind T > void value_istream_function([[maybe_unused]] std::istream& os, [[maybe_unused]] value& v) { throw std::logic_error("value type doesn't have istream operator"); } @@ -71,27 +95,25 @@ namespace meta_hpp::detail namespace meta_hpp::detail { template < typename T, typename = void > - struct has_value_type_ostream_operator - : std::false_type {}; + struct has_value_type_ostream_op : std::false_type {}; template < typename T > - struct has_value_type_ostream_operator() << std::declval() )>> : std::true_type {}; template < typename T > - inline constexpr bool has_value_type_ostream_operator_v = has_value_type_ostream_operator::value; + concept has_value_type_ostream_op_kind = has_value_type_ostream_op::value; - template < typename T, std::enable_if_t< - has_value_type_ostream_operator_v - , int> = 0 > + template < typename T > + concept has_not_value_type_ostream_op_kind = !has_value_type_ostream_op::value; + + template < has_value_type_ostream_op_kind T > void value_ostream_function(std::ostream& os, const value& v) { os << v.cast(); } - template < typename T, std::enable_if_t< - !has_value_type_ostream_operator_v - , int> = 0 > + template < has_not_value_type_ostream_op_kind T > void value_ostream_function([[maybe_unused]] std::ostream& os, [[maybe_unused]] const value& v) { throw std::logic_error("value type doesn't have ostream operator"); } @@ -105,6 +127,7 @@ namespace meta_hpp void* (*const data)(value&) noexcept; const void* (*const cdata)(const value&) noexcept; + bool (*const less)(const value&, const value&); bool (*const equals)(const value&, const value&); void (*const move_ctor)(std::any&, value&&); @@ -133,6 +156,9 @@ namespace meta_hpp return v.try_cast(); }, + // less + &detail::value_less_function, + // equals &detail::value_equals_function, @@ -275,25 +301,45 @@ namespace meta_hpp } } +namespace meta_hpp +{ + template < typename T > + bool operator<(const value& l, const T& r) { + return (l.get_type() < resolve_type()) + || (l.get_type() == resolve_type() && std::less<>{}(l.cast(), r)); + } + + template < typename T > + bool operator<(const T& l, const value& r) { + return (resolve_type() < r.get_type()) + || (resolve_type() == r.get_type() && std::less<>{}(l, r.cast())); + } + + inline bool operator<(const value& l, const value& r) { + return (l.get_type() < r.get_type()) + || (l.get_type() == r.get_type() && l.traits_->less(l, r)); + } +} + namespace meta_hpp { template < typename T > bool operator==(const value& l, const T& r) { - return l.get_type() == resolve_type() - && std::equal_to<>{}(l.cast(), r); + return l.get_type() == resolve_type() && std::equal_to<>{}(l.cast(), r); } template < typename T > bool operator==(const T& l, const value& r) { - return resolve_type() == r.get_type() - && std::equal_to<>{}(l, r.cast()); + return resolve_type() == r.get_type() && std::equal_to<>{}(l, r.cast()); } inline bool operator==(const value& l, const value& r) { - return l.get_type() == r.get_type() - && l.traits_->equals(l, r); + return l.get_type() == r.get_type() && l.traits_->equals(l, r); } +} +namespace meta_hpp +{ inline std::istream& operator>>(std::istream& is, value& v) { v.traits_->istream(is, v); return is; diff --git a/untests/meta_utilities/value_tests.cpp b/untests/meta_utilities/value_tests.cpp index 5f26f36..1444ba3 100644 --- a/untests/meta_utilities/value_tests.cpp +++ b/untests/meta_utilities/value_tests.cpp @@ -40,8 +40,12 @@ namespace int ivec2::move_ctor_counter{0}; int ivec2::copy_ctor_counter{0}; + bool operator<(const ivec2& l, const ivec2& r) noexcept { + return std::tie(l.x, l.y) < std::tie(r.x, r.y); + } + bool operator==(const ivec2& l, const ivec2& r) noexcept { - return l.x == r.x && l.y == r.y; + return std::tie(l.x, l.y) == std::tie(r.x, r.y); } } @@ -274,6 +278,25 @@ TEST_CASE("meta/meta_utilities/value") { CHECK(v == 42); } + SUBCASE("operator<") { + CHECK(meta::value{ivec2{1,2}} < ivec2{1,3}); + CHECK_FALSE(meta::value{ivec2{1,3}} < ivec2{1,2}); + + CHECK(ivec2{1,2} < meta::value{ivec2{1,3}}); + CHECK_FALSE(ivec2{1,3} < meta::value{ivec2{1,2}}); + + CHECK(meta::value{ivec2{1,2}} < meta::value{ivec2{1,3}}); + CHECK_FALSE(meta::value{ivec2{1,3}} < meta::value{ivec2{1,2}}); + + { + class empty_class1 {}; + class empty_class2 {}; + + CHECK(operator<(meta::value{empty_class1{}}, meta::value{empty_class2{}})); + CHECK_THROWS(operator<(meta::value{empty_class1{}}, meta::value{empty_class1{}})); + } + } + SUBCASE("operator==") { CHECK(meta::value{ivec2{1,2}} == ivec2{1,2}); CHECK_FALSE(meta::value{ivec2{1,2}} == ivec2{1,3}); From a901d6f3861318da24a8c5591169ddbdee67fd8a Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Mon, 29 Nov 2021 23:20:05 +0700 Subject: [PATCH 124/233] is_invocable_with with variables --- headers/meta.hpp/meta_states.hpp | 11 ++++++++++- headers/meta.hpp/meta_states/ctor.hpp | 14 ++++++++++++-- headers/meta.hpp/meta_states/function.hpp | 10 ++++++++++ headers/meta.hpp/meta_states/method.hpp | 16 +++++++++++++--- 4 files changed, 45 insertions(+), 6 deletions(-) diff --git a/headers/meta.hpp/meta_states.hpp b/headers/meta.hpp/meta_states.hpp index 42a9a13..b614952 100644 --- a/headers/meta.hpp/meta_states.hpp +++ b/headers/meta.hpp/meta_states.hpp @@ -78,6 +78,9 @@ namespace meta_hpp template < typename... Args > bool is_invocable_with() const noexcept; + + template < typename... Args > + bool is_invocable_with(Args&&... args) const noexcept; private: detail::ctor_state_ptr state_; }; @@ -119,6 +122,9 @@ namespace meta_hpp template < typename... Args > bool is_invocable_with() const noexcept; + + template < typename... Args > + bool is_invocable_with(Args&&... args) const noexcept; private: detail::function_state_ptr state_; }; @@ -162,8 +168,11 @@ namespace meta_hpp template < typename Instance, typename... Args > std::optional operator()(Instance&& instance, Args&&... args) const; - template < typename Inst, typename... Args > + template < typename Instance, typename... Args > bool is_invocable_with() const noexcept; + + template < typename Instance, typename... Args > + bool is_invocable_with(Instance&& instance, Args&&... args) const noexcept; private: detail::method_state_ptr state_; }; diff --git a/headers/meta.hpp/meta_states/ctor.hpp b/headers/meta.hpp/meta_states/ctor.hpp index 4769617..56b4345 100644 --- a/headers/meta.hpp/meta_states/ctor.hpp +++ b/headers/meta.hpp/meta_states/ctor.hpp @@ -125,7 +125,7 @@ namespace meta_hpp } template < typename... Args > - inline value ctor::invoke(Args&&... args) const { + value ctor::invoke(Args&&... args) const { if constexpr ( sizeof...(Args) > 0 ) { std::array vargs{detail::arg{std::forward(args)}...}; return state_->invoke(vargs.data(), vargs.size()); @@ -140,7 +140,7 @@ namespace meta_hpp } template < typename... Args > - inline bool ctor::is_invocable_with() const noexcept { + bool ctor::is_invocable_with() const noexcept { if constexpr ( sizeof...(Args) > 0 ) { std::array arg_bases{detail::arg_base{detail::type_list{}}...}; return state_->is_invocable_with(arg_bases.data(), arg_bases.size()); @@ -148,4 +148,14 @@ namespace meta_hpp return state_->is_invocable_with(nullptr, 0); } } + + template < typename... Args > + bool ctor::is_invocable_with(Args&&... args) const noexcept { + if constexpr ( sizeof...(Args) > 0 ) { + std::array vargs{detail::arg{std::forward(args)}...}; + return state_->is_invocable_with(vargs.data(), vargs.size()); + } else { + return state_->is_invocable_with(nullptr, 0); + } + } } diff --git a/headers/meta.hpp/meta_states/function.hpp b/headers/meta.hpp/meta_states/function.hpp index 0746da7..61e6082 100644 --- a/headers/meta.hpp/meta_states/function.hpp +++ b/headers/meta.hpp/meta_states/function.hpp @@ -162,4 +162,14 @@ namespace meta_hpp return state_->is_invocable_with(nullptr, 0); } } + + template < typename... Args > + bool function::is_invocable_with(Args&&... args) const noexcept { + if constexpr ( sizeof...(Args) > 0 ) { + std::array vargs{detail::arg{std::forward(args)}...}; + return state_->is_invocable_with(vargs.data(), vargs.size()); + } else { + return state_->is_invocable_with(nullptr, 0); + } + } } diff --git a/headers/meta.hpp/meta_states/method.hpp b/headers/meta.hpp/meta_states/method.hpp index 0680524..c6a1c1d 100644 --- a/headers/meta.hpp/meta_states/method.hpp +++ b/headers/meta.hpp/meta_states/method.hpp @@ -169,13 +169,23 @@ namespace meta_hpp return invoke(std::forward(instance), std::forward(args)...); } - template < typename Inst, typename... Args > + template < typename Instance, typename... Args > bool method::is_invocable_with() const noexcept { if constexpr ( sizeof...(Args) > 0 ) { std::array arg_bases{detail::arg_base{detail::type_list{}}...}; - return state_->is_invocable_with(detail::inst_base{detail::type_list{}}, arg_bases.data(), arg_bases.size()); + return state_->is_invocable_with(detail::inst_base{detail::type_list{}}, arg_bases.data(), arg_bases.size()); } else { - return state_->is_invocable_with(detail::inst_base{detail::type_list{}}, nullptr, 0); + return state_->is_invocable_with(detail::inst_base{detail::type_list{}}, nullptr, 0); + } + } + + template < typename Instance, typename... Args > + bool method::is_invocable_with(Instance&& instance, Args&&... args) const noexcept { + if constexpr ( sizeof...(Args) > 0 ) { + std::array vargs{detail::arg{std::forward(args)}...}; + return state_->is_invocable_with(detail::inst{std::forward(instance)}, vargs.data(), vargs.size()); + } else { + return state_->is_invocable_with(detail::inst{std::forward(instance)}, nullptr, 0); } } } From f199ec508f328e239c725b616b5f3b113af1c78b Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Mon, 29 Nov 2021 23:39:45 +0700 Subject: [PATCH 125/233] style fixes --- headers/meta.hpp/meta_states/ctor.hpp | 19 +++++++----- headers/meta.hpp/meta_states/function.hpp | 19 +++++++----- headers/meta.hpp/meta_states/member.hpp | 6 ++-- headers/meta.hpp/meta_states/method.hpp | 37 ++++++++++++----------- 4 files changed, 46 insertions(+), 35 deletions(-) diff --git a/headers/meta.hpp/meta_states/ctor.hpp b/headers/meta.hpp/meta_states/ctor.hpp index 56b4345..c6f3b51 100644 --- a/headers/meta.hpp/meta_states/ctor.hpp +++ b/headers/meta.hpp/meta_states/ctor.hpp @@ -57,17 +57,17 @@ namespace meta_hpp::detail { template < class_kind Class, typename... Args, std::size_t... Is > bool raw_ctor_is_invocable_with_impl( - const arg_base* arg_bases, + const arg_base* args, std::index_sequence) { using ct = ctor_traits; using argument_types = typename ct::argument_types; - return (... && (arg_bases + Is)->can_cast_to>() ); + return (... && (args + Is)->can_cast_to>() ); } template < class_kind Class, typename... Args > bool raw_ctor_is_invocable_with( - const arg_base* arg_bases, + const arg_base* args, std::size_t arg_count) { using ct = ctor_traits; @@ -77,7 +77,7 @@ namespace meta_hpp::detail } return raw_ctor_is_invocable_with_impl( - arg_bases, + args, std::make_index_sequence()); } @@ -126,8 +126,9 @@ namespace meta_hpp template < typename... Args > value ctor::invoke(Args&&... args) const { + using namespace detail; if constexpr ( sizeof...(Args) > 0 ) { - std::array vargs{detail::arg{std::forward(args)}...}; + std::array vargs{arg{std::forward(args)}...}; return state_->invoke(vargs.data(), vargs.size()); } else { return state_->invoke(nullptr, 0); @@ -141,9 +142,10 @@ namespace meta_hpp template < typename... Args > bool ctor::is_invocable_with() const noexcept { + using namespace detail; if constexpr ( sizeof...(Args) > 0 ) { - std::array arg_bases{detail::arg_base{detail::type_list{}}...}; - return state_->is_invocable_with(arg_bases.data(), arg_bases.size()); + std::array vargs{arg_base{type_list{}}...}; + return state_->is_invocable_with(vargs.data(), vargs.size()); } else { return state_->is_invocable_with(nullptr, 0); } @@ -151,8 +153,9 @@ namespace meta_hpp template < typename... Args > bool ctor::is_invocable_with(Args&&... args) const noexcept { + using namespace detail; if constexpr ( sizeof...(Args) > 0 ) { - std::array vargs{detail::arg{std::forward(args)}...}; + std::array vargs{arg{std::forward(args)}...}; return state_->is_invocable_with(vargs.data(), vargs.size()); } else { return state_->is_invocable_with(nullptr, 0); diff --git a/headers/meta.hpp/meta_states/function.hpp b/headers/meta.hpp/meta_states/function.hpp index 61e6082..71ae5b6 100644 --- a/headers/meta.hpp/meta_states/function.hpp +++ b/headers/meta.hpp/meta_states/function.hpp @@ -67,17 +67,17 @@ namespace meta_hpp::detail { template < function_kind Function, std::size_t... Is > bool raw_function_is_invocable_with_impl( - const arg_base* arg_bases, + const arg_base* args, std::index_sequence) { using ft = function_traits; using argument_types = typename ft::argument_types; - return (... && (arg_bases + Is)->can_cast_to>() ); + return (... && (args + Is)->can_cast_to>() ); } template < function_kind Function > bool raw_function_is_invocable_with( - const arg_base* arg_bases, + const arg_base* args, std::size_t arg_count) { using ft = function_traits; @@ -87,7 +87,7 @@ namespace meta_hpp::detail } return raw_function_is_invocable_with_impl( - arg_bases, + args, std::make_index_sequence()); } @@ -140,8 +140,9 @@ namespace meta_hpp template < typename... Args > std::optional function::invoke(Args&&... args) const { + using namespace detail; if constexpr ( sizeof...(Args) > 0 ) { - std::array vargs{detail::arg{std::forward(args)}...}; + std::array vargs{arg{std::forward(args)}...}; return state_->invoke(vargs.data(), vargs.size()); } else { return state_->invoke(nullptr, 0); @@ -155,9 +156,10 @@ namespace meta_hpp template < typename... Args > bool function::is_invocable_with() const noexcept { + using namespace detail; if constexpr ( sizeof...(Args) > 0 ) { - std::array arg_bases{detail::arg_base{detail::type_list{}}...}; - return state_->is_invocable_with(arg_bases.data(), arg_bases.size()); + std::array vargs{arg_base{type_list{}}...}; + return state_->is_invocable_with(vargs.data(), vargs.size()); } else { return state_->is_invocable_with(nullptr, 0); } @@ -165,8 +167,9 @@ namespace meta_hpp template < typename... Args > bool function::is_invocable_with(Args&&... args) const noexcept { + using namespace detail; if constexpr ( sizeof...(Args) > 0 ) { - std::array vargs{detail::arg{std::forward(args)}...}; + std::array vargs{arg{std::forward(args)}...}; return state_->is_invocable_with(vargs.data(), vargs.size()); } else { return state_->is_invocable_with(nullptr, 0); diff --git a/headers/meta.hpp/meta_states/member.hpp b/headers/meta.hpp/meta_states/member.hpp index 7b2c22b..de1f4f6 100644 --- a/headers/meta.hpp/meta_states/member.hpp +++ b/headers/meta.hpp/meta_states/member.hpp @@ -114,11 +114,13 @@ namespace meta_hpp template < typename Instance > value member::get(Instance&& instance) const { - return state_->getter(detail::inst{std::forward(instance)}); + using namespace detail; + return state_->getter(inst{std::forward(instance)}); } template < typename Instance, typename Value > void member::set(Instance&& instance, Value&& value) const { - state_->setter(detail::inst{std::forward(instance)}, detail::arg{std::forward(value)}); + using namespace detail; + state_->setter(inst{std::forward(instance)}, arg{std::forward(value)}); } } diff --git a/headers/meta.hpp/meta_states/method.hpp b/headers/meta.hpp/meta_states/method.hpp index c6a1c1d..85a9756 100644 --- a/headers/meta.hpp/meta_states/method.hpp +++ b/headers/meta.hpp/meta_states/method.hpp @@ -77,22 +77,22 @@ namespace meta_hpp::detail { template < method_kind Method, std::size_t... Is > bool raw_method_is_invocable_with_impl( - const inst_base& inst_base, - const arg_base* arg_bases, + const inst_base& inst, + const arg_base* args, std::index_sequence) { using mt = method_traits; using qualified_type = typename mt::qualified_type; using argument_types = typename mt::argument_types; - return inst_base.can_cast_to() - && (... && (arg_bases + Is)->can_cast_to>() ); + return inst.can_cast_to() + && (... && (args + Is)->can_cast_to>() ); } template < method_kind Method > bool raw_method_is_invocable_with( - const inst_base& inst_base, - const arg_base* arg_bases, + const inst_base& inst, + const arg_base* args, std::size_t arg_count) { using mt = method_traits; @@ -102,8 +102,8 @@ namespace meta_hpp::detail } return raw_method_is_invocable_with_impl( - inst_base, - arg_bases, + inst, + args, std::make_index_sequence()); } @@ -156,11 +156,12 @@ namespace meta_hpp template < typename Instance, typename... Args > std::optional method::invoke(Instance&& instance, Args&&... args) const { + using namespace detail; if constexpr ( sizeof...(Args) > 0 ) { - std::array vargs{detail::arg{std::forward(args)}...}; - return state_->invoke(detail::inst{std::forward(instance)}, vargs.data(), vargs.size()); + std::array vargs{arg{std::forward(args)}...}; + return state_->invoke(inst{std::forward(instance)}, vargs.data(), vargs.size()); } else { - return state_->invoke(detail::inst{std::forward(instance)}, nullptr, 0); + return state_->invoke(inst{std::forward(instance)}, nullptr, 0); } } @@ -171,21 +172,23 @@ namespace meta_hpp template < typename Instance, typename... Args > bool method::is_invocable_with() const noexcept { + using namespace detail; if constexpr ( sizeof...(Args) > 0 ) { - std::array arg_bases{detail::arg_base{detail::type_list{}}...}; - return state_->is_invocable_with(detail::inst_base{detail::type_list{}}, arg_bases.data(), arg_bases.size()); + std::array vargs{arg_base{type_list{}}...}; + return state_->is_invocable_with(inst_base{type_list{}}, vargs.data(), vargs.size()); } else { - return state_->is_invocable_with(detail::inst_base{detail::type_list{}}, nullptr, 0); + return state_->is_invocable_with(inst_base{type_list{}}, nullptr, 0); } } template < typename Instance, typename... Args > bool method::is_invocable_with(Instance&& instance, Args&&... args) const noexcept { + using namespace detail; if constexpr ( sizeof...(Args) > 0 ) { - std::array vargs{detail::arg{std::forward(args)}...}; - return state_->is_invocable_with(detail::inst{std::forward(instance)}, vargs.data(), vargs.size()); + std::array vargs{arg{std::forward(args)}...}; + return state_->is_invocable_with(inst{std::forward(instance)}, vargs.data(), vargs.size()); } else { - return state_->is_invocable_with(detail::inst{std::forward(instance)}, nullptr, 0); + return state_->is_invocable_with(inst{std::forward(instance)}, nullptr, 0); } } } From 6f0cce9340630b867f47a53c2aa05b7ca5ef90f0 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Tue, 30 Nov 2021 15:21:00 +0700 Subject: [PATCH 126/233] new inst tests and fixes --- CMakeLists.txt | 1 + headers/meta.hpp/meta_utilities.hpp | 17 +- headers/meta.hpp/meta_utilities/inst.hpp | 66 +++--- untests/meta_utilities/inst_tests.cpp | 269 ++++++++++++++--------- 4 files changed, 216 insertions(+), 137 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d4d87f3..36bbe89 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,6 +30,7 @@ target_compile_options(${PROJECT_NAME} -Wno-ctad-maybe-unsupported -Wno-exit-time-destructors -Wno-float-equal + -Wno-ignored-qualifiers -Wno-padded -Wno-shadow-field -Wno-shadow-field-in-constructor diff --git a/headers/meta.hpp/meta_utilities.hpp b/headers/meta.hpp/meta_utilities.hpp index ac698ef..52e745f 100644 --- a/headers/meta.hpp/meta_utilities.hpp +++ b/headers/meta.hpp/meta_utilities.hpp @@ -58,6 +58,12 @@ namespace meta_hpp template < typename T, typename Tp = std::decay_t > const Tp* try_cast() const noexcept; + template < typename T > + friend bool operator<(const value& l, const T& r); + template < typename T > + friend bool operator<(const T& l, const value& r); + friend bool operator<(const value& l, const value& r); + template < typename T > friend bool operator==(const value& l, const T& r); template < typename T > @@ -161,10 +167,10 @@ namespace meta_hpp::detail class inst_base { public: enum class ref_types { - ref, - rref, - cref, - crref, + lvalue, + const_lvalue, + rvalue, + const_rvalue, }; public: inst_base() = delete; @@ -187,8 +193,9 @@ namespace meta_hpp::detail explicit inst_base(type_list); explicit inst_base(value& v); - explicit inst_base(value&& v); explicit inst_base(const value& v); + + explicit inst_base(value&& v); explicit inst_base(const value&& v); bool is_const() const noexcept; diff --git a/headers/meta.hpp/meta_utilities/inst.hpp b/headers/meta.hpp/meta_utilities/inst.hpp index b4b7397..754140e 100644 --- a/headers/meta.hpp/meta_utilities/inst.hpp +++ b/headers/meta.hpp/meta_utilities/inst.hpp @@ -15,7 +15,7 @@ namespace meta_hpp::detail (std::is_lvalue_reference_v && std::is_class_v>) , int> > inst_base::inst_base(type_list) - : ref_type_{std::is_const_v> ? ref_types::cref : ref_types::ref} + : ref_type_{std::is_const_v> ? ref_types::const_lvalue : ref_types::lvalue} , raw_type_{resolve_type>()} {} template < typename T, std::enable_if_t< @@ -23,19 +23,11 @@ namespace meta_hpp::detail (std::is_rvalue_reference_v && std::is_class_v>) , int> > inst_base::inst_base(type_list) - : ref_type_{std::is_const_v> ? ref_types::crref : ref_types::rref} + : ref_type_{std::is_const_v> ? ref_types::const_rvalue : ref_types::rvalue} , raw_type_{resolve_type>()} {} inline inst_base::inst_base(value& v) - : ref_type_{ref_types::ref} - , raw_type_{v.get_type().as_class()} { - if ( !v.get_type().is_class() ) { - throw std::logic_error("an attempt to create an instance with a non-class value type"); - } - } - - inline inst_base::inst_base(value&& v) - : ref_type_{ref_types::rref} + : ref_type_{ref_types::lvalue} , raw_type_{v.get_type().as_class()} { if ( !v.get_type().is_class() ) { throw std::logic_error("an attempt to create an instance with a non-class value type"); @@ -43,7 +35,15 @@ namespace meta_hpp::detail } inline inst_base::inst_base(const value& v) - : ref_type_{ref_types::cref} + : ref_type_{ref_types::const_lvalue} + , raw_type_{v.get_type().as_class()} { + if ( !v.get_type().is_class() ) { + throw std::logic_error("an attempt to create an instance with a non-class value type"); + } + } + + inline inst_base::inst_base(value&& v) + : ref_type_{ref_types::rvalue} , raw_type_{v.get_type().as_class()} { if ( !v.get_type().is_class() ) { throw std::logic_error("an attempt to create an instance with a non-class value type"); @@ -51,7 +51,7 @@ namespace meta_hpp::detail } inline inst_base::inst_base(const value&& v) - : ref_type_{ref_types::crref} + : ref_type_{ref_types::const_rvalue} , raw_type_{v.get_type().as_class()} { if ( !v.get_type().is_class() ) { throw std::logic_error("an attempt to create an instance with a non-class value type"); @@ -59,18 +59,18 @@ namespace meta_hpp::detail } inline bool inst_base::is_const() const noexcept { - return ref_type_ == ref_types::cref - || ref_type_ == ref_types::crref; + return ref_type_ == ref_types::const_lvalue + || ref_type_ == ref_types::const_rvalue; } inline bool inst_base::is_lvalue() const noexcept { - return ref_type_ == ref_types::ref - || ref_type_ == ref_types::cref; + return ref_type_ == ref_types::lvalue + || ref_type_ == ref_types::const_lvalue; } inline bool inst_base::is_rvalue() const noexcept { - return ref_type_ == ref_types::rref - || ref_type_ == ref_types::crref; + return ref_type_ == ref_types::rvalue + || ref_type_ == ref_types::const_rvalue; } inline inst_base::ref_types inst_base::get_ref_type() const noexcept { @@ -86,28 +86,30 @@ namespace meta_hpp::detail (std::is_reference_v && std::is_class_v>) , int> > bool inst_base::can_cast_to() const noexcept { - constexpr bool to_const = std::is_const_v>; + using to_raw_type = std::remove_cvref_t; + using to_raw_type_cv = std::remove_reference_t; - if constexpr ( !to_const ) { + if constexpr ( !std::is_const_v ) { if ( is_const() ) { return false; } } - if constexpr ( std::is_lvalue_reference_v ) { - if ( !is_lvalue() ) { + if constexpr ( std::is_reference_v ) { + const auto check_qualifiers = [](ref_types self_ref_type){ + switch ( self_ref_type ) { + case ref_types::lvalue: return std::is_convertible_v; + case ref_types::const_lvalue: return std::is_convertible_v; + case ref_types::rvalue: return std::is_convertible_v; + case ref_types::const_rvalue: return std::is_convertible_v; + } + }; + + if ( !check_qualifiers(get_ref_type()) ) { return false; } } - if constexpr ( std::is_rvalue_reference_v ) { - if ( !is_rvalue() ) { - return false; - } - } - - using to_raw_type = std::remove_cvref_t; - return get_raw_type() == resolve_type() || get_raw_type().is_derived_from(resolve_type()); } @@ -135,7 +137,7 @@ namespace meta_hpp::detail , int> > decltype(auto) inst::cast() const { if ( !can_cast_to() ) { - throw std::logic_error("bad an instance cast"); + throw std::logic_error("bad instance cast"); } if constexpr ( std::is_reference_v ) { diff --git a/untests/meta_utilities/inst_tests.cpp b/untests/meta_utilities/inst_tests.cpp index 9048994..dd20b2c 100644 --- a/untests/meta_utilities/inst_tests.cpp +++ b/untests/meta_utilities/inst_tests.cpp @@ -8,133 +8,202 @@ namespace { - struct ivec2 { - int x{}; - int y{}; - - [[maybe_unused]] ivec2() = default; - [[maybe_unused]] explicit ivec2(int v): x{v}, y{v} {} - [[maybe_unused]] ivec2(int x, int y): x{x}, y{y} {} - - [[maybe_unused]] ivec2(ivec2&& other) noexcept { - x = other.x; - y = other.y; - other.x = 0; - other.y = 0; - } - - [[maybe_unused]] ivec2(const ivec2& other) noexcept { - x = other.x; - y = other.y; - } - - ivec2& operator=(ivec2&&) = delete; - ivec2& operator=(const ivec2&) = delete; + struct clazz { + int m1() { return 1; } + int m2() & { return 1; } + int m3() && { return 1; } + int m4() const { return 1; } + int m5() const & { return 1; } + int m6() const && { return 1; } }; - struct derived_ivec2 : ivec2 { - [[maybe_unused]] derived_ivec2() = default; - [[maybe_unused]] explicit derived_ivec2(int v): ivec2{v, v} {} - [[maybe_unused]] derived_ivec2(int x, int y): ivec2{x, y} {} - }; + struct dclazz : clazz {}; } -TEST_CASE("features/meta_utilities/inst") { +#define META_HPP_CHECK_INVOCABLE(Inst, FName, Qualifiers)\ + {\ + using namespace meta::detail;\ + auto method_ptr = meta::select(&clazz::FName);\ + meta::method m_state{method_state::make("", method_ptr)};\ + \ + if ( std::is_invocable_v ) {\ + CHECK(inst{Inst}.can_cast_to());\ + CHECK(inst_base{type_list{}}.can_cast_to());\ + \ + CHECK(m_state.is_invocable_with());\ + CHECK(m_state.invoke(Inst) == 1);\ + } else {\ + CHECK_FALSE(inst{Inst}.can_cast_to());\ + CHECK_FALSE(inst_base{type_list{}}.can_cast_to());\ + \ + CHECK_FALSE(m_state.is_invocable_with());\ + CHECK_THROWS(m_state.invoke(Inst));\ + }\ + } + +TEST_CASE("features/meta_utilities/inst2") { namespace meta = meta_hpp; - SUBCASE("ref") { + meta::class_() + .base_(); +} + +TEST_CASE("features/meta_utilities/inst2") { + namespace meta = meta_hpp; + + { + // lvalue + auto LV = []() -> clazz& { static clazz v; return v; }; + auto LV2 = []() -> dclazz& { static dclazz v; return v; }; + { - derived_ivec2 v{1,2}; - derived_ivec2& vr = v; - meta::detail::inst a{vr}; - - CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::inst::ref_types::ref); + meta::detail::inst i{LV()}; + CHECK(i.get_raw_type() == meta::resolve_type()); + CHECK(i.get_ref_type() == meta::detail::inst::ref_types::lvalue); } - { - meta::value v{derived_ivec2{1,2}}; - meta::value& vr = v; - meta::detail::inst a{vr}; - CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::inst::ref_types::ref); + META_HPP_CHECK_INVOCABLE(LV(), m1, ); + META_HPP_CHECK_INVOCABLE(LV(), m2, &); + META_HPP_CHECK_INVOCABLE(LV(), m3, &&); + META_HPP_CHECK_INVOCABLE(LV(), m4, const); + META_HPP_CHECK_INVOCABLE(LV(), m5, const &); + META_HPP_CHECK_INVOCABLE(LV(), m6, const &&); - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - } + META_HPP_CHECK_INVOCABLE(LV2(), m1, ); + META_HPP_CHECK_INVOCABLE(LV2(), m2, &); + META_HPP_CHECK_INVOCABLE(LV2(), m3, &&); + META_HPP_CHECK_INVOCABLE(LV2(), m4, const); + META_HPP_CHECK_INVOCABLE(LV2(), m5, const &); + META_HPP_CHECK_INVOCABLE(LV2(), m6, const &&); } - SUBCASE("cref") { + { + // const lvalue + auto CLV = []() -> const clazz& { static clazz v; return v; }; + auto CLV2 = []() -> const dclazz& { static dclazz v; return v; }; + { - const derived_ivec2 v{1,2}; - const derived_ivec2& vr = v; - meta::detail::inst a{vr}; - - CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::inst::ref_types::cref); + meta::detail::inst i{CLV()}; + CHECK(i.get_raw_type() == meta::resolve_type()); + CHECK(i.get_ref_type() == meta::detail::inst::ref_types::const_lvalue); } - { - const meta::value v{derived_ivec2{1,2}}; - const meta::value& vr = v; - meta::detail::inst a{vr}; - CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::inst::ref_types::cref); + META_HPP_CHECK_INVOCABLE(CLV(), m1, ); + META_HPP_CHECK_INVOCABLE(CLV(), m2, &); + META_HPP_CHECK_INVOCABLE(CLV(), m3, &&); + META_HPP_CHECK_INVOCABLE(CLV(), m4, const); + META_HPP_CHECK_INVOCABLE(CLV(), m5, const &); + META_HPP_CHECK_INVOCABLE(CLV(), m6, const &&); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - } + META_HPP_CHECK_INVOCABLE(CLV2(), m1, ); + META_HPP_CHECK_INVOCABLE(CLV2(), m2, &); + META_HPP_CHECK_INVOCABLE(CLV2(), m3, &&); + META_HPP_CHECK_INVOCABLE(CLV2(), m4, const); + META_HPP_CHECK_INVOCABLE(CLV2(), m5, const &); + META_HPP_CHECK_INVOCABLE(CLV2(), m6, const &&); } - SUBCASE("rref") { + { + // xvalue + auto XV = []() -> clazz&& { static clazz v; return std::move(v); }; + auto XV2 = []() -> dclazz&& { static dclazz v; return std::move(v); }; + { - derived_ivec2 v{1,2}; - meta::detail::inst a{std::move(v)}; - - CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::inst::ref_types::rref); + meta::detail::inst i{XV()}; + CHECK(i.get_raw_type() == meta::resolve_type()); + CHECK(i.get_ref_type() == meta::detail::inst::ref_types::rvalue); } - { - meta::value v{derived_ivec2{1,2}}; - meta::detail::inst a{std::move(v)}; - CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::inst::ref_types::rref); + META_HPP_CHECK_INVOCABLE(XV(), m1, ); + META_HPP_CHECK_INVOCABLE(XV(), m2, &); + META_HPP_CHECK_INVOCABLE(XV(), m3, &&); + META_HPP_CHECK_INVOCABLE(XV(), m4, const); + META_HPP_CHECK_INVOCABLE(XV(), m5, const &); + META_HPP_CHECK_INVOCABLE(XV(), m6, const &&); - CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - } + META_HPP_CHECK_INVOCABLE(XV2(), m1, ); + META_HPP_CHECK_INVOCABLE(XV2(), m2, &); + META_HPP_CHECK_INVOCABLE(XV2(), m3, &&); + META_HPP_CHECK_INVOCABLE(XV2(), m4, const); + META_HPP_CHECK_INVOCABLE(XV2(), m5, const &); + META_HPP_CHECK_INVOCABLE(XV2(), m6, const &&); } - SUBCASE("crref") { + { + // const xvalue + auto CXV = []() -> const clazz&& { static clazz v; return std::move(v); }; + auto CXV2 = []() -> const dclazz&& { static dclazz v; return std::move(v); }; + { - const derived_ivec2 v{1,2}; - meta::detail::inst a{std::move(v)}; - - CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::inst::ref_types::crref); + meta::detail::inst i{CXV()}; + CHECK(i.get_raw_type() == meta::resolve_type()); + CHECK(i.get_ref_type() == meta::detail::inst::ref_types::const_rvalue); } + + META_HPP_CHECK_INVOCABLE(CXV(), m1, ); + META_HPP_CHECK_INVOCABLE(CXV(), m2, &); + META_HPP_CHECK_INVOCABLE(CXV(), m3, &&); + META_HPP_CHECK_INVOCABLE(CXV(), m4, const); + META_HPP_CHECK_INVOCABLE(CXV(), m5, const &); + META_HPP_CHECK_INVOCABLE(CXV(), m6, const &&); + + META_HPP_CHECK_INVOCABLE(CXV2(), m1, ); + META_HPP_CHECK_INVOCABLE(CXV2(), m2, &); + META_HPP_CHECK_INVOCABLE(CXV2(), m3, &&); + META_HPP_CHECK_INVOCABLE(CXV2(), m4, const); + META_HPP_CHECK_INVOCABLE(CXV2(), m5, const &); + META_HPP_CHECK_INVOCABLE(CXV2(), m6, const &&); + } + + { + // prvalue + auto PRV = []() -> clazz { return clazz{}; }; + auto PRV2 = []() -> dclazz { return dclazz{}; }; + { - const meta::value v{derived_ivec2{1,2}}; - meta::detail::inst a{std::move(v)}; - - CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::inst::ref_types::crref); - - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); + meta::detail::inst i{PRV()}; + CHECK(i.get_raw_type() == meta::resolve_type()); + CHECK(i.get_ref_type() == meta::detail::inst::ref_types::rvalue); } + + META_HPP_CHECK_INVOCABLE(PRV(), m1, ); + META_HPP_CHECK_INVOCABLE(PRV(), m2, &); + META_HPP_CHECK_INVOCABLE(PRV(), m3, &&); + META_HPP_CHECK_INVOCABLE(PRV(), m4, const); + META_HPP_CHECK_INVOCABLE(PRV(), m5, const &); + META_HPP_CHECK_INVOCABLE(PRV(), m6, const &&); + + META_HPP_CHECK_INVOCABLE(PRV2(), m1, ); + META_HPP_CHECK_INVOCABLE(PRV2(), m2, &); + META_HPP_CHECK_INVOCABLE(PRV2(), m3, &&); + META_HPP_CHECK_INVOCABLE(PRV2(), m4, const); + META_HPP_CHECK_INVOCABLE(PRV2(), m5, const &); + META_HPP_CHECK_INVOCABLE(PRV2(), m6, const &&); + } + + { + // const prvalue + auto CPRV = []() -> const clazz { return clazz{}; }; + auto CPRV2 = []() -> const dclazz { return dclazz{}; }; + + { + meta::detail::inst i{CPRV()}; + CHECK(i.get_raw_type() == meta::resolve_type()); + CHECK(i.get_ref_type() == meta::detail::inst::ref_types::const_rvalue); + } + + META_HPP_CHECK_INVOCABLE(CPRV(), m1, ); + META_HPP_CHECK_INVOCABLE(CPRV(), m2, &); + META_HPP_CHECK_INVOCABLE(CPRV(), m3, &&); + META_HPP_CHECK_INVOCABLE(CPRV(), m4, const); + META_HPP_CHECK_INVOCABLE(CPRV(), m5, const &); + META_HPP_CHECK_INVOCABLE(CPRV(), m6, const &&); + + META_HPP_CHECK_INVOCABLE(CPRV2(), m1, ); + META_HPP_CHECK_INVOCABLE(CPRV2(), m2, &); + META_HPP_CHECK_INVOCABLE(CPRV2(), m3, &&); + META_HPP_CHECK_INVOCABLE(CPRV2(), m4, const); + META_HPP_CHECK_INVOCABLE(CPRV2(), m5, const &); + META_HPP_CHECK_INVOCABLE(CPRV2(), m6, const &&); } } From f926dbba24e513261ea01ed63d98f4cd2aea0504 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 3 Dec 2021 06:56:31 +0700 Subject: [PATCH 127/233] more inst tests --- CMakeLists.txt | 1 - headers/meta.hpp/meta_utilities/value.hpp | 144 ++++++------------ untests/meta_utilities/inst_tests.cpp | 169 +++++++++++++++++++++- 3 files changed, 214 insertions(+), 100 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 36bbe89..d4d87f3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,7 +30,6 @@ target_compile_options(${PROJECT_NAME} -Wno-ctad-maybe-unsupported -Wno-exit-time-destructors -Wno-float-equal - -Wno-ignored-qualifiers -Wno-padded -Wno-shadow-field -Wno-shadow-field-in-constructor diff --git a/headers/meta.hpp/meta_utilities/value.hpp b/headers/meta.hpp/meta_utilities/value.hpp index 4b4fedf..2f6cd54 100644 --- a/headers/meta.hpp/meta_utilities/value.hpp +++ b/headers/meta.hpp/meta_utilities/value.hpp @@ -18,23 +18,6 @@ namespace meta_hpp::detail struct has_value_type_less_op() < std::declval() )>> : std::true_type {}; - - template < typename T > - concept has_value_type_less_op_kind = has_value_type_less_op::value; - - template < typename T > - concept has_not_value_type_less_op_kind = !has_value_type_less_op::value; - - template < has_value_type_less_op_kind T > - bool value_less_function(const value& l, const value& r) { - assert(l.get_type() == r.get_type()); - return l.cast() < r.cast(); - } - - template < has_not_value_type_less_op_kind T > - bool value_less_function([[maybe_unused]] const value& l, [[maybe_unused]] const value& r) { - throw std::logic_error("value type doesn't have less operator"); - } } namespace meta_hpp::detail @@ -46,23 +29,6 @@ namespace meta_hpp::detail struct has_value_type_equals_op() == std::declval() )>> : std::true_type {}; - - template < typename T > - concept has_value_type_equals_op_kind = has_value_type_equals_op::value; - - template < typename T > - concept has_not_value_type_equals_op_kind = !has_value_type_equals_op::value; - - template < has_value_type_equals_op_kind T > - bool value_equals_function(const value& l, const value& r) { - assert(l.get_type() == r.get_type()); - return l.cast() == r.cast(); - } - - template < has_not_value_type_equals_op_kind T > - bool value_equals_function([[maybe_unused]] const value& l, [[maybe_unused]] const value& r) { - throw std::logic_error("value type doesn't have equality operator"); - } } namespace meta_hpp::detail @@ -74,22 +40,6 @@ namespace meta_hpp::detail struct has_value_type_istream_op() >> std::declval() )>> : std::true_type {}; - - template < typename T > - concept has_value_type_istream_op_kind = has_value_type_istream_op::value; - - template < typename T > - concept has_not_value_type_istream_op_kind = !has_value_type_istream_op::value; - - template < has_value_type_istream_op_kind T > - void value_istream_function(std::istream& os, value& v) { - os >> v.cast(); - } - - template < has_not_value_type_istream_op_kind T > - void value_istream_function([[maybe_unused]] std::istream& os, [[maybe_unused]] value& v) { - throw std::logic_error("value type doesn't have istream operator"); - } } namespace meta_hpp::detail @@ -101,22 +51,6 @@ namespace meta_hpp::detail struct has_value_type_ostream_op() << std::declval() )>> : std::true_type {}; - - template < typename T > - concept has_value_type_ostream_op_kind = has_value_type_ostream_op::value; - - template < typename T > - concept has_not_value_type_ostream_op_kind = !has_value_type_ostream_op::value; - - template < has_value_type_ostream_op_kind T > - void value_ostream_function(std::ostream& os, const value& v) { - os << v.cast(); - } - - template < has_not_value_type_ostream_op_kind T > - void value_ostream_function([[maybe_unused]] std::ostream& os, [[maybe_unused]] const value& v) { - throw std::logic_error("value type doesn't have ostream operator"); - } } namespace meta_hpp @@ -133,8 +67,8 @@ namespace meta_hpp void (*const move_ctor)(std::any&, value&&); void (*const copy_ctor)(std::any&, const value&); - void (*const istream)(std::istream&, value&); - void (*const ostream)(std::ostream&, const value&); + std::istream& (*const istream)(std::istream&, value&); + std::ostream& (*const ostream)(std::ostream&, const value&); template < typename T > static const traits* get() noexcept; @@ -143,27 +77,33 @@ namespace meta_hpp template < typename T > const value::traits* value::traits::get() noexcept { static const traits traits{ - // type - resolve_type(), + .type = resolve_type(), - // data - +[](value& v) noexcept -> void* { + .data = +[](value& v) noexcept -> void* { return v.try_cast(); }, - // cdata - +[](const value& v) noexcept -> const void* { + .cdata = +[](const value& v) noexcept -> const void* { return v.try_cast(); }, - // less - &detail::value_less_function, + .less = +[](const value& l, const value& r) -> bool { + if constexpr ( detail::has_value_type_less_op::value ) { + return l.cast() < r.cast(); + } else { + throw std::logic_error("value type doesn't have less operator"); + } + }, - // equals - &detail::value_equals_function, + .equals = +[](const value& l, const value& r) -> bool { + if constexpr ( detail::has_value_type_equals_op::value ) { + return l.cast() == r.cast(); + } else { + throw std::logic_error("value type doesn't have equality operator"); + } + }, - // move_ctor - +[](std::any& dst, value&& src) { + .move_ctor = +[](std::any& dst, value&& src) { if constexpr ( std::is_move_constructible_v ) { dst.emplace(std::move(src).cast()); } else { @@ -171,8 +111,7 @@ namespace meta_hpp } }, - // copy_ctor - +[](std::any& dst, const value& src) { + .copy_ctor = +[](std::any& dst, const value& src) { if constexpr ( std::is_copy_constructible_v ) { dst.emplace(src.cast()); } else { @@ -180,11 +119,21 @@ namespace meta_hpp } }, - // istream - &detail::value_istream_function, + .istream = +[](std::istream& os, value& v) -> std::istream& { + if constexpr ( detail::has_value_type_istream_op::value ) { + return os >> v.cast(); + } else { + throw std::logic_error("value type doesn't have istream operator"); + } + }, - // ostream - &detail::value_ostream_function, + .ostream = +[](std::ostream& os, const value& v) -> std::ostream& { + if constexpr ( detail::has_value_type_ostream_op::value ) { + return os << v.cast(); + } else { + throw std::logic_error("value type doesn't have ostream operator"); + } + }, }; return &traits; } @@ -305,19 +254,18 @@ namespace meta_hpp { template < typename T > bool operator<(const value& l, const T& r) { - return (l.get_type() < resolve_type()) - || (l.get_type() == resolve_type() && std::less<>{}(l.cast(), r)); + const any_type& r_type = resolve_type(); + return (l.get_type() < r_type) || (l.get_type() == r_type && std::less<>{}(l.cast(), r)); } template < typename T > bool operator<(const T& l, const value& r) { - return (resolve_type() < r.get_type()) - || (resolve_type() == r.get_type() && std::less<>{}(l, r.cast())); + const any_type& l_type = resolve_type(); + return (l_type < r.get_type()) || (l_type == r.get_type() && std::less<>{}(l, r.cast())); } inline bool operator<(const value& l, const value& r) { - return (l.get_type() < r.get_type()) - || (l.get_type() == r.get_type() && l.traits_->less(l, r)); + return (l.get_type() < r.get_type()) || (l.get_type() == r.get_type() && l.traits_->less(l, r)); } } @@ -325,12 +273,14 @@ namespace meta_hpp { template < typename T > bool operator==(const value& l, const T& r) { - return l.get_type() == resolve_type() && std::equal_to<>{}(l.cast(), r); + const any_type& r_type = resolve_type(); + return l.get_type() == r_type && std::equal_to<>{}(l.cast(), r); } template < typename T > bool operator==(const T& l, const value& r) { - return resolve_type() == r.get_type() && std::equal_to<>{}(l, r.cast()); + const any_type& l_type = resolve_type(); + return l_type == r.get_type() && std::equal_to<>{}(l, r.cast()); } inline bool operator==(const value& l, const value& r) { @@ -341,12 +291,10 @@ namespace meta_hpp namespace meta_hpp { inline std::istream& operator>>(std::istream& is, value& v) { - v.traits_->istream(is, v); - return is; + return v.traits_->istream(is, v); } inline std::ostream& operator<<(std::ostream& os, const value& v) { - v.traits_->ostream(os, v); - return os; + return v.traits_->ostream(os, v); } } diff --git a/untests/meta_utilities/inst_tests.cpp b/untests/meta_utilities/inst_tests.cpp index dd20b2c..0549475 100644 --- a/untests/meta_utilities/inst_tests.cpp +++ b/untests/meta_utilities/inst_tests.cpp @@ -29,18 +29,37 @@ namespace if ( std::is_invocable_v ) {\ CHECK(inst{Inst}.can_cast_to());\ CHECK(inst_base{type_list{}}.can_cast_to());\ + CHECK_NOTHROW(inst{Inst}.cast());\ \ CHECK(m_state.is_invocable_with());\ CHECK(m_state.invoke(Inst) == 1);\ } else {\ CHECK_FALSE(inst{Inst}.can_cast_to());\ CHECK_FALSE(inst_base{type_list{}}.can_cast_to());\ + CHECK_THROWS(inst{Inst}.cast());\ \ CHECK_FALSE(m_state.is_invocable_with());\ CHECK_THROWS(m_state.invoke(Inst));\ }\ } +#define META_HPP_CHECK_INVOCABLE_2(FromValue, FName, FromType, ToQualifiers)\ + {\ + using namespace meta::detail;\ + auto method_ptr = meta::select(&clazz::FName);\ + meta::method m_state{method_state::make("", method_ptr)};\ + \ + if ( std::is_invocable_v ) {\ + CHECK(m_state.is_invocable_with());\ + CHECK(m_state.is_invocable_with(FromValue));\ + CHECK(m_state.invoke(FromValue) == 1);\ + } else {\ + CHECK_FALSE(m_state.is_invocable_with());\ + CHECK_FALSE(m_state.is_invocable_with(FromValue));\ + CHECK_THROWS(m_state.invoke(FromValue));\ + }\ + } + TEST_CASE("features/meta_utilities/inst2") { namespace meta = meta_hpp; @@ -48,7 +67,7 @@ TEST_CASE("features/meta_utilities/inst2") { .base_(); } -TEST_CASE("features/meta_utilities/inst2") { +TEST_CASE("features/meta_utilities/inst2/refs") { namespace meta = meta_hpp; { @@ -207,3 +226,151 @@ TEST_CASE("features/meta_utilities/inst2") { META_HPP_CHECK_INVOCABLE(CPRV2(), m6, const &&); } } + +TEST_CASE("features/meta_utilities/inst2/values") { + namespace meta = meta_hpp; + + { + // lvalue + auto LV = []() -> meta::value& { static meta::value v{clazz{}}; return v; }; + auto LV2 = []() -> meta::value& { static meta::value v{dclazz{}}; return v; }; + + meta::detail::arg a{LV()}; + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::lvalue); + + META_HPP_CHECK_INVOCABLE_2(LV(), m1, clazz&, ); + META_HPP_CHECK_INVOCABLE_2(LV(), m2, clazz&, &); + META_HPP_CHECK_INVOCABLE_2(LV(), m3, clazz&, &&); + META_HPP_CHECK_INVOCABLE_2(LV(), m4, clazz&, const); + META_HPP_CHECK_INVOCABLE_2(LV(), m5, clazz&, const &); + META_HPP_CHECK_INVOCABLE_2(LV(), m6, clazz&, const &&); + + META_HPP_CHECK_INVOCABLE_2(LV2(), m1, dclazz&, ); + META_HPP_CHECK_INVOCABLE_2(LV2(), m2, dclazz&, &); + META_HPP_CHECK_INVOCABLE_2(LV2(), m3, dclazz&, &&); + META_HPP_CHECK_INVOCABLE_2(LV2(), m4, dclazz&, const); + META_HPP_CHECK_INVOCABLE_2(LV2(), m5, dclazz&, const &); + META_HPP_CHECK_INVOCABLE_2(LV2(), m6, dclazz&, const &&); + } + + { + // const lvalue + auto CLV = []() -> const meta::value& { static meta::value v{clazz{}}; return v; }; + auto CLV2 = []() -> const meta::value& { static meta::value v{dclazz{}}; return v; }; + + meta::detail::arg a{CLV()}; + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::const_lvalue); + + META_HPP_CHECK_INVOCABLE_2(CLV(), m1, const clazz&, ); + META_HPP_CHECK_INVOCABLE_2(CLV(), m2, const clazz&, &); + META_HPP_CHECK_INVOCABLE_2(CLV(), m3, const clazz&, &&); + META_HPP_CHECK_INVOCABLE_2(CLV(), m4, const clazz&, const); + META_HPP_CHECK_INVOCABLE_2(CLV(), m5, const clazz&, const &); + META_HPP_CHECK_INVOCABLE_2(CLV(), m6, const clazz&, const &&); + + META_HPP_CHECK_INVOCABLE_2(CLV2(), m1, const dclazz&, ); + META_HPP_CHECK_INVOCABLE_2(CLV2(), m2, const dclazz&, &); + META_HPP_CHECK_INVOCABLE_2(CLV2(), m3, const dclazz&, &&); + META_HPP_CHECK_INVOCABLE_2(CLV2(), m4, const dclazz&, const); + META_HPP_CHECK_INVOCABLE_2(CLV2(), m5, const dclazz&, const &); + META_HPP_CHECK_INVOCABLE_2(CLV2(), m6, const dclazz&, const &&); + } + + { + // xvalue + auto XV = []() -> meta::value&& { static meta::value v{clazz{}}; return std::move(v); }; + auto XV2 = []() -> meta::value&& { static meta::value v{dclazz{}}; return std::move(v); }; + + meta::detail::arg a{XV()}; + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::rvalue); + + META_HPP_CHECK_INVOCABLE_2(XV(), m1, clazz&&, ); + META_HPP_CHECK_INVOCABLE_2(XV(), m2, clazz&&, &); + META_HPP_CHECK_INVOCABLE_2(XV(), m3, clazz&&, &&); + META_HPP_CHECK_INVOCABLE_2(XV(), m4, clazz&&, const); + META_HPP_CHECK_INVOCABLE_2(XV(), m5, clazz&&, const &); + META_HPP_CHECK_INVOCABLE_2(XV(), m6, clazz&&, const &&); + + META_HPP_CHECK_INVOCABLE_2(XV2(), m1, dclazz&&, ); + META_HPP_CHECK_INVOCABLE_2(XV2(), m2, dclazz&&, &); + META_HPP_CHECK_INVOCABLE_2(XV2(), m3, dclazz&&, &&); + META_HPP_CHECK_INVOCABLE_2(XV2(), m4, dclazz&&, const); + META_HPP_CHECK_INVOCABLE_2(XV2(), m5, dclazz&&, const &); + META_HPP_CHECK_INVOCABLE_2(XV2(), m6, dclazz&&, const &&); + } + + { + // const xvalue + auto CXV = []() -> const meta::value&& { static meta::value v{clazz{}}; return std::move(v); }; + auto CXV2 = []() -> const meta::value&& { static meta::value v{dclazz{}}; return std::move(v); }; + + meta::detail::arg a{CXV()}; + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::const_rvalue); + + META_HPP_CHECK_INVOCABLE_2(CXV(), m1, const clazz&&, ); + META_HPP_CHECK_INVOCABLE_2(CXV(), m2, const clazz&&, &); + META_HPP_CHECK_INVOCABLE_2(CXV(), m3, const clazz&&, &&); + META_HPP_CHECK_INVOCABLE_2(CXV(), m4, const clazz&&, const); + META_HPP_CHECK_INVOCABLE_2(CXV(), m5, const clazz&&, const &); + META_HPP_CHECK_INVOCABLE_2(CXV(), m6, const clazz&&, const &&); + + META_HPP_CHECK_INVOCABLE_2(CXV2(), m1, const dclazz&&, ); + META_HPP_CHECK_INVOCABLE_2(CXV2(), m2, const dclazz&&, &); + META_HPP_CHECK_INVOCABLE_2(CXV2(), m3, const dclazz&&, &&); + META_HPP_CHECK_INVOCABLE_2(CXV2(), m4, const dclazz&&, const); + META_HPP_CHECK_INVOCABLE_2(CXV2(), m5, const dclazz&&, const &); + META_HPP_CHECK_INVOCABLE_2(CXV2(), m6, const dclazz&&, const &&); + } + + { + // prvalue + auto PRV = []() -> meta::value { return meta::value{clazz{}}; }; + auto PRV2 = []() -> meta::value { return meta::value{dclazz{}}; }; + + meta::detail::arg a{PRV()}; + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::rvalue); + + META_HPP_CHECK_INVOCABLE_2(PRV(), m1, clazz, ); + META_HPP_CHECK_INVOCABLE_2(PRV(), m2, clazz, &); + META_HPP_CHECK_INVOCABLE_2(PRV(), m3, clazz, &&); + META_HPP_CHECK_INVOCABLE_2(PRV(), m4, clazz, const); + META_HPP_CHECK_INVOCABLE_2(PRV(), m5, clazz, const &); + META_HPP_CHECK_INVOCABLE_2(PRV(), m6, clazz, const &&); + + META_HPP_CHECK_INVOCABLE_2(PRV2(), m1, dclazz, ); + META_HPP_CHECK_INVOCABLE_2(PRV2(), m2, dclazz, &); + META_HPP_CHECK_INVOCABLE_2(PRV2(), m3, dclazz, &&); + META_HPP_CHECK_INVOCABLE_2(PRV2(), m4, dclazz, const); + META_HPP_CHECK_INVOCABLE_2(PRV2(), m5, dclazz, const &); + META_HPP_CHECK_INVOCABLE_2(PRV2(), m6, dclazz, const &&); + } + + { + // const prvalue + auto CPRV = []() -> const meta::value { return meta::value{clazz{}}; }; + auto CPRV2 = []() -> const meta::value { return meta::value{dclazz{}}; }; + + meta::detail::arg a{CPRV()}; + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::const_rvalue); + + META_HPP_CHECK_INVOCABLE_2(CPRV(), m1, const clazz, ); + META_HPP_CHECK_INVOCABLE_2(CPRV(), m2, const clazz, &); + META_HPP_CHECK_INVOCABLE_2(CPRV(), m3, const clazz, &&); + META_HPP_CHECK_INVOCABLE_2(CPRV(), m4, const clazz, const); + META_HPP_CHECK_INVOCABLE_2(CPRV(), m5, const clazz, const &); + META_HPP_CHECK_INVOCABLE_2(CPRV(), m6, const clazz, const &&); + + META_HPP_CHECK_INVOCABLE_2(CPRV2(), m1, const dclazz, ); + META_HPP_CHECK_INVOCABLE_2(CPRV2(), m2, const dclazz, &); + META_HPP_CHECK_INVOCABLE_2(CPRV2(), m3, const dclazz, &&); + META_HPP_CHECK_INVOCABLE_2(CPRV2(), m4, const dclazz, const); + META_HPP_CHECK_INVOCABLE_2(CPRV2(), m5, const dclazz, const &); + META_HPP_CHECK_INVOCABLE_2(CPRV2(), m6, const dclazz, const &&); + } +} From 2c00f330f5d852dd1ca69fda214de4483f6088e6 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sat, 4 Dec 2021 03:40:28 +0700 Subject: [PATCH 128/233] more arg supported casts --- headers/meta.hpp/meta_utilities.hpp | 20 +- headers/meta.hpp/meta_utilities/arg.hpp | 139 +- untests/meta_utilities/arg_tests.cpp | 2237 +++++++++++------------ 3 files changed, 1163 insertions(+), 1233 deletions(-) diff --git a/headers/meta.hpp/meta_utilities.hpp b/headers/meta.hpp/meta_utilities.hpp index 52e745f..845ac86 100644 --- a/headers/meta.hpp/meta_utilities.hpp +++ b/headers/meta.hpp/meta_utilities.hpp @@ -88,10 +88,10 @@ namespace meta_hpp::detail class arg_base { public: enum class ref_types { - ref, - rref, - cref, - crref, + lvalue, + const_lvalue, + rvalue, + const_rvalue, }; public: arg_base() = delete; @@ -103,33 +103,33 @@ namespace meta_hpp::detail arg_base& operator=(const arg_base&) = delete; template < typename T, std::enable_if_t< - (std::is_pointer_v || std::is_lvalue_reference_v) + (std::is_lvalue_reference_v) , int> = 0 > explicit arg_base(type_list); template < typename T, std::enable_if_t< - (std::is_rvalue_reference_v) || - (!std::is_pointer_v && !std::is_reference_v) + (std::is_rvalue_reference_v || !std::is_reference_v) , int> = 0 > explicit arg_base(type_list); explicit arg_base(value& v); - explicit arg_base(value&& v); explicit arg_base(const value& v); + + explicit arg_base(value&& v); explicit arg_base(const value&& v); bool is_const() const noexcept; bool is_lvalue() const noexcept; bool is_rvalue() const noexcept; - any_type get_raw_type() const noexcept; ref_types get_ref_type() const noexcept; + const any_type& get_raw_type() const noexcept; template < typename To > bool can_cast_to() const noexcept; private: - any_type raw_type_{}; ref_types ref_type_{}; + any_type raw_type_{}; }; } diff --git a/headers/meta.hpp/meta_utilities/arg.hpp b/headers/meta.hpp/meta_utilities/arg.hpp index 0ef3082..19450fa 100644 --- a/headers/meta.hpp/meta_utilities/arg.hpp +++ b/headers/meta.hpp/meta_utilities/arg.hpp @@ -12,115 +12,108 @@ namespace meta_hpp::detail { template < typename T, std::enable_if_t< - (std::is_pointer_v || std::is_lvalue_reference_v) + (std::is_lvalue_reference_v) , int> > arg_base::arg_base(type_list) - : raw_type_{resolve_type>()} - , ref_type_{std::is_const_v> ? ref_types::cref : ref_types::ref} {} + : ref_type_{std::is_const_v> ? ref_types::const_lvalue : ref_types::lvalue} + , raw_type_{resolve_type>()} {} template < typename T, std::enable_if_t< - (std::is_rvalue_reference_v) || - (!std::is_pointer_v && !std::is_reference_v) + (std::is_rvalue_reference_v || !std::is_reference_v) , int> > arg_base::arg_base(type_list) - : raw_type_{resolve_type>()} - , ref_type_{std::is_const_v> ? ref_types::crref : ref_types::rref} {} + : ref_type_{std::is_const_v> ? ref_types::const_rvalue : ref_types::rvalue} + , raw_type_{resolve_type>()} {} inline arg_base::arg_base(value& v) - : raw_type_{v.get_type()} - , ref_type_{ref_types::ref} {} - - inline arg_base::arg_base(value&& v) - : raw_type_{v.get_type()} - , ref_type_{ref_types::rref} {} + : ref_type_{ref_types::lvalue} + , raw_type_{v.get_type()} {} inline arg_base::arg_base(const value& v) - : raw_type_{v.get_type()} - , ref_type_{ref_types::cref} {} + : ref_type_{ref_types::const_lvalue} + , raw_type_{v.get_type()} {} + + inline arg_base::arg_base(value&& v) + : ref_type_{ref_types::rvalue} + , raw_type_{v.get_type()} {} inline arg_base::arg_base(const value&& v) - : raw_type_{v.get_type()} - , ref_type_{ref_types::crref} {} + : ref_type_{ref_types::const_rvalue} + , raw_type_{v.get_type()} {} inline bool arg_base::is_const() const noexcept { - return ref_type_ == ref_types::cref - || ref_type_ == ref_types::crref; + return ref_type_ == ref_types::const_lvalue + || ref_type_ == ref_types::const_rvalue; } inline bool arg_base::is_lvalue() const noexcept { - return ref_type_ == ref_types::ref - || ref_type_ == ref_types::cref; + return ref_type_ == ref_types::lvalue + || ref_type_ == ref_types::const_lvalue; } inline bool arg_base::is_rvalue() const noexcept { - return ref_type_ == ref_types::rref - || ref_type_ == ref_types::crref; - } - - inline any_type arg_base::get_raw_type() const noexcept { - return raw_type_; + return ref_type_ == ref_types::rvalue + || ref_type_ == ref_types::const_rvalue; } inline arg_base::ref_types arg_base::get_ref_type() const noexcept { return ref_type_; } + inline const any_type& arg_base::get_raw_type() const noexcept { + return raw_type_; + } + template < typename To > bool arg_base::can_cast_to() const noexcept { - if constexpr ( std::is_pointer_v ) { - using to_raw_type = std::remove_cv_t; - using to_raw_ptr_type = std::remove_cv_t>; - return get_raw_type() == resolve_type() - || get_raw_type() == resolve_type(); - } + using to_raw_type_cv = std::remove_reference_t; + using to_raw_type = std::remove_cv_t; - if constexpr ( std::is_reference_v ) { - constexpr bool to_const = std::is_const_v>; + static_assert( + !(std::is_reference_v && std::is_pointer_v), + "references to pointers are not supported yet"); - if constexpr ( !to_const ) { - if ( is_const() ) { - return false; - } + const auto check_qualifiers = [this](){ + switch ( get_ref_type() ) { + case ref_types::lvalue: return std::is_convertible_v; + case ref_types::const_lvalue: return std::is_convertible_v; + case ref_types::rvalue: return std::is_convertible_v; + case ref_types::const_rvalue: return std::is_convertible_v; } + }; - if constexpr ( std::is_lvalue_reference_v ) { - if constexpr ( !to_const ) { - if ( is_rvalue() ) { - return false; - } - } - } + const auto check_convertible = [this](){ + const auto is_a = [](const any_type& base, const any_type& derived){ + return (base == derived) + || (base.is_class() && derived.is_class() && base.as_class().is_base_of(derived.as_class())); + }; - if constexpr ( std::is_rvalue_reference_v ) { - if ( !is_rvalue() ) { - return false; - } - } + const any_type& from_type = get_raw_type(); + const any_type& to_type = resolve_type(); - using to_raw_type = std::remove_cvref_t; - if ( get_raw_type() == resolve_type() ) { + if ( is_a(to_type, from_type) ) { return true; } - if constexpr ( to_const && std::is_pointer_v ) { - using to_raw_ptr_type = std::remove_cv_t>; - return get_raw_type() == resolve_type(); - } - - return false; - } - - if constexpr ( !std::is_pointer_v && !std::is_reference_v ) { - using to_raw_type = std::remove_cv_t; - if ( get_raw_type() != resolve_type() ) { + if ( std::is_lvalue_reference_v && !std::is_const_v ) { return false; } - return (get_ref_type() == ref_types::ref && std::is_constructible_v) - || (get_ref_type() == ref_types::cref && std::is_constructible_v) - || (get_ref_type() == ref_types::rref && std::is_constructible_v) - || (get_ref_type() == ref_types::crref && std::is_constructible_v); - } + if ( from_type.is_pointer() && to_type.is_pointer() ) { + const pointer_type& from_type_ptr = from_type.as_pointer(); + const bool from_type_ptr_readonly = from_type_ptr.get_flags().has(pointer_flags::is_readonly); + + const pointer_type& to_type_ptr = to_type.as_pointer(); + const bool to_type_ptr_readonly = to_type_ptr.get_flags().has(pointer_flags::is_readonly); + + return to_type_ptr_readonly >= from_type_ptr_readonly + && is_a(to_type_ptr.get_data_type(), from_type_ptr.get_data_type()); + } + + return false; + }; + + return check_qualifiers() && check_convertible(); } } @@ -165,25 +158,25 @@ namespace meta_hpp::detail if constexpr ( !std::is_pointer_v && !std::is_reference_v ) { using raw_type = std::remove_cv_t; - if ( get_ref_type() == ref_types::ref ) { + if ( get_ref_type() == ref_types::lvalue ) { if constexpr ( std::is_constructible_v ) { return To{*static_cast(data_)}; } } - if ( get_ref_type() == ref_types::cref ) { + if ( get_ref_type() == ref_types::const_lvalue ) { if constexpr ( std::is_constructible_v ) { return To{std::as_const(*static_cast(data_))}; } } - if ( get_ref_type() == ref_types::rref ) { + if ( get_ref_type() == ref_types::rvalue ) { if constexpr ( std::is_constructible_v ) { return To{std::move(*static_cast(data_))}; } } - if ( get_ref_type() == ref_types::crref ) { + if ( get_ref_type() == ref_types::const_rvalue ) { if constexpr ( std::is_constructible_v ) { return To{std::move(std::as_const(*static_cast(data_)))}; } diff --git a/untests/meta_utilities/arg_tests.cpp b/untests/meta_utilities/arg_tests.cpp index af794ee..1461179 100644 --- a/untests/meta_utilities/arg_tests.cpp +++ b/untests/meta_utilities/arg_tests.cpp @@ -8,1272 +8,1209 @@ namespace { - struct ivec2 { - int x{}; - int y{}; - - [[maybe_unused]] ivec2() = default; - [[maybe_unused]] explicit ivec2(int v): x{v}, y{v} {} - [[maybe_unused]] ivec2(int x, int y): x{x}, y{y} {} - - [[maybe_unused]] ivec2(ivec2&& other) noexcept { - x = other.x; - y = other.y; - other.x = 0; - other.y = 0; - } - - [[maybe_unused]] ivec2(const ivec2& other) noexcept { - x = other.x; - y = other.y; - } - - ivec2& operator=(ivec2&&) = delete; - ivec2& operator=(const ivec2&) = delete; + struct clazz { + [[maybe_unused]] clazz() = default; + [[maybe_unused]] clazz(clazz&&) = default; + [[maybe_unused]] clazz(const clazz&) = default; + clazz& operator=(clazz&&) = delete; + clazz& operator=(const clazz&) = delete; }; - struct ivec3 { - int x{}; - int y{}; - int z{}; - - [[maybe_unused]] ivec3() = default; - [[maybe_unused]] explicit ivec3(int v): x{v}, y{v}, z{v} {} - [[maybe_unused]] ivec3(int x, int y, int z): x{x}, y{y}, z{z} {} - - [[maybe_unused]] ivec3(ivec3&& other) noexcept { - x = other.x; - y = other.y; - z = other.z; - other.x = 0; - other.y = 0; - other.z = 0; - } - - [[maybe_unused]] ivec3(const ivec3& other) noexcept { - x = other.x; - y = other.y; - z = other.z; - } - - ivec3& operator=(ivec3&&) = delete; - ivec3& operator=(const ivec3&) = delete; + struct dclazz : clazz { + [[maybe_unused]] dclazz() = default; + [[maybe_unused]] dclazz(dclazz&&) = default; + [[maybe_unused]] dclazz(const dclazz&) = default; + dclazz& operator=(dclazz&&) = delete; + dclazz& operator=(const dclazz&) = delete; }; - [[maybe_unused]] bool operator==(const ivec2& l, const ivec2& r) noexcept { - return l.x == r.x && l.y == r.y; - } + int f1(clazz) { return 1; } + int f2(const clazz) { return 1; } + int f3(clazz&) { return 1; } + int f4(const clazz&) { return 1; } + int f5(clazz&&) { return 1; } + int f6(const clazz&&) { return 1; } - [[maybe_unused]] bool operator==(const ivec3& l, const ivec3& r) noexcept { - return l.x == r.x && l.y == r.y && l.z == r.z; - } + int f1(clazz*) { return 1; } + int f2(clazz* const) { return 1; } + // int f3(clazz*&) { return 1; } + // int f4(clazz* const&) { return 1; } + // int f5(clazz*&&) { return 1; } + // int f6(clazz* const&&) { return 1; } + + int f1(const clazz*) { return 1; } + int f2(const clazz* const) { return 1; } + // int f3(const clazz*&) { return 1; } + // int f4(const clazz* const&) { return 1; } + // int f5(const clazz*&&) { return 1; } + // int f6(const clazz* const&&) { return 1; } } -TEST_CASE("features/meta_utilities/arg/from_value") { +#define META_HPP_CHECK_INVOCABLE(FromValue, FName, ToType)\ + {\ + using namespace meta::detail;\ + auto function_ptr = meta::select(&FName);\ + meta::function f_state{function_state::make("", function_ptr)};\ + \ + if ( std::is_invocable_v ) {\ + CHECK(arg{FromValue}.can_cast_to());\ + CHECK(arg_base{type_list{}}.can_cast_to());\ + CHECK_NOTHROW(arg{FromValue}.cast());\ + \ + CHECK(f_state.is_invocable_with());\ + CHECK(f_state.invoke(FromValue) == 1);\ + } else {\ + CHECK_FALSE(arg{FromValue}.can_cast_to());\ + CHECK_FALSE(arg_base{type_list{}}.can_cast_to());\ + CHECK_THROWS(arg{FromValue}.cast());\ + \ + CHECK_FALSE(f_state.is_invocable_with());\ + CHECK_THROWS(f_state.invoke(FromValue));\ + }\ + } + +#define META_HPP_CHECK_INVOCABLE_2(FromValue, FName, FromType, ToType)\ + {\ + using namespace meta::detail;\ + auto function_ptr = meta::select(&FName);\ + meta::function f_state{function_state::make("", function_ptr)};\ + \ + if ( std::is_invocable_v ) {\ + CHECK(f_state.is_invocable_with());\ + CHECK(f_state.is_invocable_with(FromValue));\ + CHECK(f_state.invoke(FromValue) == 1);\ + } else {\ + CHECK_FALSE(f_state.is_invocable_with());\ + CHECK_FALSE(f_state.is_invocable_with(FromValue));\ + CHECK_THROWS(f_state.invoke(FromValue));\ + }\ + } + +TEST_CASE("features/meta_utilities/arg2") { namespace meta = meta_hpp; - SUBCASE("ptr") { - ivec2 v{1,2}; - ivec2* vp = &v; - meta::value vvp{vp}; - meta::detail::arg a{vvp}; - - CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::ref); - } - - SUBCASE("rptr") { - ivec2 v{1,2}; - ivec2* vp = &v; - meta::value vvp{vp}; - meta::detail::arg a{std::move(vvp)}; - - CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::rref); - } - - SUBCASE("ptr_c") { - ivec2 v{1,2}; - ivec2* const vp = &v; - const meta::value vvp{vp}; - meta::detail::arg a{vvp}; - - CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::cref); - } - - SUBCASE("rptr_c") { - ivec2 v{1,2}; - ivec2* const vp = &v; - const meta::value vvp{vp}; - meta::detail::arg a{std::move(vvp)}; - - CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::crref); - } - - SUBCASE("cptr") { - const ivec2 v{1,2}; - const ivec2* vp = &v; - meta::value vvp{vp}; - meta::detail::arg a{vvp}; - - CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::ref); - } - - SUBCASE("crptr") { - const ivec2 v{1,2}; - const ivec2* vp = &v; - meta::value vvp{vp}; - meta::detail::arg a{std::move(vvp)}; - - CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::rref); - } - - SUBCASE("cptr_c") { - const ivec2 v{1,2}; - const ivec2* const vp = &v; - const meta::value vvp{vp}; - meta::detail::arg a{vvp}; - - CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::cref); - } - - SUBCASE("crptr_c") { - const ivec2 v{1,2}; - const ivec2* const vp = &v; - const meta::value vvp{vp}; - meta::detail::arg a{std::move(vvp)}; - - CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::crref); - } - - SUBCASE("ref") { - ivec2 v{1,2}; - ivec2& vr = v; - meta::value vvr{vr}; - meta::detail::arg a{vvr}; - - CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::ref); - } - - SUBCASE("cref") { - const ivec2 v{1,2}; - const ivec2& vr = v; - const meta::value vvr{vr}; - meta::detail::arg a{vvr}; - - CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::cref); - } - - SUBCASE("rref") { - ivec2 v{1,2}; - meta::value vv{v}; - meta::detail::arg a{std::move(vv)}; - - CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::rref); - } - - SUBCASE("crref") { - const ivec2 v{1,2}; - const meta::value vv{v}; - meta::detail::arg a{std::move(vv)}; - - CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::crref); - } + meta::class_() + .base_(); } -TEST_CASE("features/meta_utilities/arg/type") { +TEST_CASE("features/meta_utilities/arg2/refs") { namespace meta = meta_hpp; - SUBCASE("ptr") { - ivec2 v{1,2}; - ivec2* vp = &v; - meta::detail::arg a{vp}; + { + // lvalue + auto LV = []() -> clazz& { static clazz v; return v; }; + auto LV2 = []() -> dclazz& { static dclazz v; return v; }; - CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::ref); + meta::detail::arg a{LV()}; + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::lvalue); + + META_HPP_CHECK_INVOCABLE(LV(), f1, clazz) + META_HPP_CHECK_INVOCABLE(LV(), f2, const clazz) + META_HPP_CHECK_INVOCABLE(LV(), f3, clazz&) + META_HPP_CHECK_INVOCABLE(LV(), f4, const clazz&) + META_HPP_CHECK_INVOCABLE(LV(), f5, clazz&&) + META_HPP_CHECK_INVOCABLE(LV(), f6, const clazz&&) + + META_HPP_CHECK_INVOCABLE(LV2(), f1, clazz) + META_HPP_CHECK_INVOCABLE(LV2(), f2, const clazz) + META_HPP_CHECK_INVOCABLE(LV2(), f3, clazz&) + META_HPP_CHECK_INVOCABLE(LV2(), f4, const clazz&) + META_HPP_CHECK_INVOCABLE(LV2(), f5, clazz&&) + META_HPP_CHECK_INVOCABLE(LV2(), f6, const clazz&&) } - SUBCASE("rptr") { - ivec2 v{1,2}; - ivec2* vp = &v; - meta::detail::arg a{std::move(vp)}; + { + // const lvalue + auto CLV = []() -> const clazz& { static clazz v; return v; }; + auto CLV2 = []() -> const dclazz& { static dclazz v; return v; }; - CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::rref); + meta::detail::arg a{CLV()}; + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::const_lvalue); + + META_HPP_CHECK_INVOCABLE(CLV(), f1, clazz) + META_HPP_CHECK_INVOCABLE(CLV(), f2, const clazz) + META_HPP_CHECK_INVOCABLE(CLV(), f3, clazz&) + META_HPP_CHECK_INVOCABLE(CLV(), f4, const clazz&) + META_HPP_CHECK_INVOCABLE(CLV(), f5, clazz&&) + META_HPP_CHECK_INVOCABLE(CLV(), f6, const clazz&&) + + META_HPP_CHECK_INVOCABLE(CLV2(), f1, clazz) + META_HPP_CHECK_INVOCABLE(CLV2(), f2, const clazz) + META_HPP_CHECK_INVOCABLE(CLV2(), f3, clazz&) + META_HPP_CHECK_INVOCABLE(CLV2(), f4, const clazz&) + META_HPP_CHECK_INVOCABLE(CLV2(), f5, clazz&&) + META_HPP_CHECK_INVOCABLE(CLV2(), f6, const clazz&&) } - SUBCASE("ptr_c") { - ivec2 v{1,2}; - ivec2* const vp = &v; - meta::detail::arg a{vp}; + { + // xvalue + auto XV = []() -> clazz&& { static clazz v; return std::move(v); }; + auto XV2 = []() -> dclazz&& { static dclazz v; return std::move(v); }; - CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::cref); + meta::detail::arg a{XV()}; + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::rvalue); + + META_HPP_CHECK_INVOCABLE(XV(), f1, clazz) + META_HPP_CHECK_INVOCABLE(XV(), f2, const clazz) + META_HPP_CHECK_INVOCABLE(XV(), f3, clazz&) + META_HPP_CHECK_INVOCABLE(XV(), f4, const clazz&) + META_HPP_CHECK_INVOCABLE(XV(), f5, clazz&&) + META_HPP_CHECK_INVOCABLE(XV(), f6, const clazz&&) + + META_HPP_CHECK_INVOCABLE(XV2(), f1, clazz) + META_HPP_CHECK_INVOCABLE(XV2(), f2, const clazz) + META_HPP_CHECK_INVOCABLE(XV2(), f3, clazz&) + META_HPP_CHECK_INVOCABLE(XV2(), f4, const clazz&) + META_HPP_CHECK_INVOCABLE(XV2(), f5, clazz&&) + META_HPP_CHECK_INVOCABLE(XV2(), f6, const clazz&&) } - SUBCASE("rptr_c") { - ivec2 v{1,2}; - ivec2* const vp = &v; - meta::detail::arg a{std::move(vp)}; + { + // const xvalue + auto CXV = []() -> const clazz&& { static clazz v; return std::move(v); }; + auto CXV2 = []() -> const dclazz&& { static dclazz v; return std::move(v); }; - CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::crref); + meta::detail::arg a{CXV()}; + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::const_rvalue); + + META_HPP_CHECK_INVOCABLE(CXV(), f1, clazz) + META_HPP_CHECK_INVOCABLE(CXV(), f2, const clazz) + META_HPP_CHECK_INVOCABLE(CXV(), f3, clazz&) + META_HPP_CHECK_INVOCABLE(CXV(), f4, const clazz&) + META_HPP_CHECK_INVOCABLE(CXV(), f5, clazz&&) + META_HPP_CHECK_INVOCABLE(CXV(), f6, const clazz&&) + + META_HPP_CHECK_INVOCABLE(CXV2(), f1, clazz) + META_HPP_CHECK_INVOCABLE(CXV2(), f2, const clazz) + META_HPP_CHECK_INVOCABLE(CXV2(), f3, clazz&) + META_HPP_CHECK_INVOCABLE(CXV2(), f4, const clazz&) + META_HPP_CHECK_INVOCABLE(CXV2(), f5, clazz&&) + META_HPP_CHECK_INVOCABLE(CXV2(), f6, const clazz&&) } - SUBCASE("cptr") { - const ivec2 v{1,2}; - const ivec2* vp = &v; - meta::detail::arg a{vp}; + { + // prvalue + auto PRV = []() -> clazz { return clazz{}; }; + auto PRV2 = []() -> dclazz { return dclazz{}; }; - CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::ref); + meta::detail::arg a{PRV()}; + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::rvalue); + + META_HPP_CHECK_INVOCABLE(PRV(), f1, clazz) + META_HPP_CHECK_INVOCABLE(PRV(), f2, const clazz) + META_HPP_CHECK_INVOCABLE(PRV(), f3, clazz&) + META_HPP_CHECK_INVOCABLE(PRV(), f4, const clazz&) + META_HPP_CHECK_INVOCABLE(PRV(), f5, clazz&&) + META_HPP_CHECK_INVOCABLE(PRV(), f6, const clazz&&) + + META_HPP_CHECK_INVOCABLE(PRV2(), f1, clazz) + META_HPP_CHECK_INVOCABLE(PRV2(), f2, const clazz) + META_HPP_CHECK_INVOCABLE(PRV2(), f3, clazz&) + META_HPP_CHECK_INVOCABLE(PRV2(), f4, const clazz&) + META_HPP_CHECK_INVOCABLE(PRV2(), f5, clazz&&) + META_HPP_CHECK_INVOCABLE(PRV2(), f6, const clazz&&) } - SUBCASE("crptr") { - const ivec2 v{1,2}; - const ivec2* vp = &v; - meta::detail::arg a{std::move(vp)}; + { + // const prvalue + auto CPRV = []() -> const clazz { return clazz{}; }; + auto CPRV2 = []() -> const dclazz { return dclazz{}; }; - CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::rref); - } + meta::detail::arg a{CPRV()}; + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::const_rvalue); - SUBCASE("cptr_c") { - const ivec2 v{1,2}; - const ivec2* const vp = &v; - meta::detail::arg a{vp}; + META_HPP_CHECK_INVOCABLE(CPRV(), f1, clazz) + META_HPP_CHECK_INVOCABLE(CPRV(), f2, const clazz) + META_HPP_CHECK_INVOCABLE(CPRV(), f3, clazz&) + META_HPP_CHECK_INVOCABLE(CPRV(), f4, const clazz&) + META_HPP_CHECK_INVOCABLE(CPRV(), f5, clazz&&) + META_HPP_CHECK_INVOCABLE(CPRV(), f6, const clazz&&) - CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::cref); - } - - SUBCASE("crptr_c") { - const ivec2 v{1,2}; - const ivec2* const vp = &v; - meta::detail::arg a{std::move(vp)}; - - CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::crref); - } - - SUBCASE("ref") { - ivec2 v{1,2}; - ivec2& vr = v; - meta::detail::arg a{vr}; - - CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::ref); - } - - SUBCASE("cref") { - const ivec2 v{1,2}; - const ivec2& vr = v; - meta::detail::arg a{vr}; - - CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::cref); - } - - SUBCASE("rref") { - ivec2 v{1,2}; - meta::detail::arg a{std::move(v)}; - - CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::rref); - } - - SUBCASE("crref") { - const ivec2 v{1,2}; - meta::detail::arg a{std::move(v)}; - - CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::crref); + META_HPP_CHECK_INVOCABLE(CPRV2(), f1, clazz) + META_HPP_CHECK_INVOCABLE(CPRV2(), f2, const clazz) + META_HPP_CHECK_INVOCABLE(CPRV2(), f3, clazz&) + META_HPP_CHECK_INVOCABLE(CPRV2(), f4, const clazz&) + META_HPP_CHECK_INVOCABLE(CPRV2(), f5, clazz&&) + META_HPP_CHECK_INVOCABLE(CPRV2(), f6, const clazz&&) } } -TEST_CASE("features/meta_utilities/arg/can_cast_to") { +TEST_CASE("features/meta_utilities/arg2/ptrs") { namespace meta = meta_hpp; - SUBCASE("ptr") { - ivec2 v{1,2}; - ivec2* vp = &v; - meta::detail::arg a{vp}; - - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - + { + // lvalue { - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); + auto LV_PTR = []() -> clazz*& { static clazz* p{}; return p; }; + auto LV2_PTR = []() -> dclazz*& { static dclazz* p{}; return p; }; + + meta::detail::arg a{LV_PTR()}; + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::lvalue); + + META_HPP_CHECK_INVOCABLE(LV_PTR(), f1, clazz*) + META_HPP_CHECK_INVOCABLE(LV_PTR(), f2, clazz* const) + // META_HPP_CHECK_INVOCABLE(LV_PTR(), f3, clazz*&) + // META_HPP_CHECK_INVOCABLE(LV_PTR(), f4, clazz* const&) + // META_HPP_CHECK_INVOCABLE(LV_PTR(), f5, clazz*&&) + // META_HPP_CHECK_INVOCABLE(LV_PTR(), f6, clazz* const&&) + + META_HPP_CHECK_INVOCABLE(LV_PTR(), f1, const clazz*) + META_HPP_CHECK_INVOCABLE(LV_PTR(), f2, const clazz* const) + // META_HPP_CHECK_INVOCABLE(LV_PTR(), f3, const clazz*&) + // META_HPP_CHECK_INVOCABLE(LV_PTR(), f4, const clazz* const&) + // META_HPP_CHECK_INVOCABLE(LV_PTR(), f5, const clazz*&&) + // META_HPP_CHECK_INVOCABLE(LV_PTR(), f6, const clazz* const&&) + + META_HPP_CHECK_INVOCABLE(LV2_PTR(), f1, clazz*) + META_HPP_CHECK_INVOCABLE(LV2_PTR(), f2, clazz* const) + // META_HPP_CHECK_INVOCABLE(LV2_PTR(), f3, clazz*&) + // META_HPP_CHECK_INVOCABLE(LV2_PTR(), f4, clazz* const&) + // META_HPP_CHECK_INVOCABLE(LV2_PTR(), f5, clazz*&&) + // META_HPP_CHECK_INVOCABLE(LV2_PTR(), f6, clazz* const&&) + + META_HPP_CHECK_INVOCABLE(LV2_PTR(), f1, const clazz*) + META_HPP_CHECK_INVOCABLE(LV2_PTR(), f2, const clazz* const) + // META_HPP_CHECK_INVOCABLE(LV2_PTR(), f3, const clazz*&) + // META_HPP_CHECK_INVOCABLE(LV2_PTR(), f4, const clazz* const&) + // META_HPP_CHECK_INVOCABLE(LV2_PTR(), f5, const clazz*&&) + // META_HPP_CHECK_INVOCABLE(LV2_PTR(), f6, const clazz* const&&) } - { - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); + auto LV_CPTR = []() -> const clazz*& { static const clazz* p{}; return p; }; + auto LV2_CPTR = []() -> const dclazz*& { static const dclazz* p{}; return p; }; - CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); + meta::detail::arg a{LV_CPTR()}; + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::lvalue); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); + META_HPP_CHECK_INVOCABLE(LV_CPTR(), f1, clazz*) + META_HPP_CHECK_INVOCABLE(LV_CPTR(), f2, clazz* const) + // META_HPP_CHECK_INVOCABLE(LV_CPTR(), f3, clazz*&) + // META_HPP_CHECK_INVOCABLE(LV_CPTR(), f4, clazz* const&) + // META_HPP_CHECK_INVOCABLE(LV_CPTR(), f5, clazz*&&) + // META_HPP_CHECK_INVOCABLE(LV_CPTR(), f6, clazz* const&&) - []([[maybe_unused]] ivec2 *){}(vp); - []([[maybe_unused]] const ivec2 *){}(vp); - []([[maybe_unused]] ivec2 *const){}(vp); - []([[maybe_unused]] const ivec2 *const){}(vp); + META_HPP_CHECK_INVOCABLE(LV_CPTR(), f1, const clazz*) + META_HPP_CHECK_INVOCABLE(LV_CPTR(), f2, const clazz* const) + // META_HPP_CHECK_INVOCABLE(LV_CPTR(), f3, const clazz*&) + // META_HPP_CHECK_INVOCABLE(LV_CPTR(), f4, const clazz* const&) + // META_HPP_CHECK_INVOCABLE(LV_CPTR(), f5, const clazz*&&) + // META_HPP_CHECK_INVOCABLE(LV_CPTR(), f6, const clazz* const&&) - []([[maybe_unused]] ivec2 *&){}(vp); - //[]([[maybe_unused]] const ivec2 *&){}(vp); - []([[maybe_unused]] ivec2 *const &){}(vp); - []([[maybe_unused]] const ivec2 *const &){}(vp); + META_HPP_CHECK_INVOCABLE(LV2_CPTR(), f1, clazz*) + META_HPP_CHECK_INVOCABLE(LV2_CPTR(), f2, clazz* const) + // META_HPP_CHECK_INVOCABLE(LV2_CPTR(), f3, clazz*&) + // META_HPP_CHECK_INVOCABLE(LV2_CPTR(), f4, clazz* const&) + // META_HPP_CHECK_INVOCABLE(LV2_CPTR(), f5, clazz*&&) + // META_HPP_CHECK_INVOCABLE(LV2_CPTR(), f6, clazz* const&&) - //[]([[maybe_unused]] ivec2 *&&){}(vp); - //[]([[maybe_unused]] const ivec2 *&&){}(vp); - //[]([[maybe_unused]] ivec2 *const &&){}(vp); - //[]([[maybe_unused]] const ivec2 *const &&){}(vp); + META_HPP_CHECK_INVOCABLE(LV2_CPTR(), f1, const clazz*) + META_HPP_CHECK_INVOCABLE(LV2_CPTR(), f2, const clazz* const) + // META_HPP_CHECK_INVOCABLE(LV2_CPTR(), f3, const clazz*&) + // META_HPP_CHECK_INVOCABLE(LV2_CPTR(), f4, const clazz* const&) + // META_HPP_CHECK_INVOCABLE(LV2_CPTR(), f5, const clazz*&&) + // META_HPP_CHECK_INVOCABLE(LV2_CPTR(), f6, const clazz* const&&) } } - SUBCASE("rptr") { - ivec2 v{1,2}; - ivec2* vp = &v; - meta::detail::arg a{std::move(vp)}; - - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - + { + // const lvalue { - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); + auto CLV_PTR = []() -> clazz* const& { static clazz* p{}; return p; }; + auto CLV2_PTR = []() -> dclazz* const& { static dclazz* p{}; return p; }; + + meta::detail::arg a{CLV_PTR()}; + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::const_lvalue); + + META_HPP_CHECK_INVOCABLE(CLV_PTR(), f1, clazz*) + META_HPP_CHECK_INVOCABLE(CLV_PTR(), f2, clazz* const) + // META_HPP_CHECK_INVOCABLE(CLV_PTR(), f3, clazz*&) + // META_HPP_CHECK_INVOCABLE(CLV_PTR(), f4, clazz* const&) + // META_HPP_CHECK_INVOCABLE(CLV_PTR(), f5, clazz*&&) + // META_HPP_CHECK_INVOCABLE(CLV_PTR(), f6, clazz* const&&) + + META_HPP_CHECK_INVOCABLE(CLV_PTR(), f1, const clazz*) + META_HPP_CHECK_INVOCABLE(CLV_PTR(), f2, const clazz* const) + // META_HPP_CHECK_INVOCABLE(CLV_PTR(), f3, const clazz*&) + // META_HPP_CHECK_INVOCABLE(CLV_PTR(), f4, const clazz* const&) + // META_HPP_CHECK_INVOCABLE(CLV_PTR(), f5, const clazz*&&) + // META_HPP_CHECK_INVOCABLE(CLV_PTR(), f6, const clazz* const&&) + + META_HPP_CHECK_INVOCABLE(CLV2_PTR(), f1, clazz*) + META_HPP_CHECK_INVOCABLE(CLV2_PTR(), f2, clazz* const) + // META_HPP_CHECK_INVOCABLE(CLV2_PTR(), f3, clazz*&) + // META_HPP_CHECK_INVOCABLE(CLV2_PTR(), f4, clazz* const&) + // META_HPP_CHECK_INVOCABLE(CLV2_PTR(), f5, clazz*&&) + // META_HPP_CHECK_INVOCABLE(CLV2_PTR(), f6, clazz* const&&) + + META_HPP_CHECK_INVOCABLE(CLV2_PTR(), f1, const clazz*) + META_HPP_CHECK_INVOCABLE(CLV2_PTR(), f2, const clazz* const) + // META_HPP_CHECK_INVOCABLE(CLV2_PTR(), f3, const clazz*&) + // META_HPP_CHECK_INVOCABLE(CLV2_PTR(), f4, const clazz* const&) + // META_HPP_CHECK_INVOCABLE(CLV2_PTR(), f5, const clazz*&&) + // META_HPP_CHECK_INVOCABLE(CLV2_PTR(), f6, const clazz* const&&) } - { - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); + auto CLV_CPTR = []() -> const clazz* const& { static const clazz* p{}; return p; }; + auto CLV2_CPTR = []() -> const dclazz* const& { static const dclazz* p{}; return p; }; - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); + meta::detail::arg a{CLV_CPTR()}; + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::const_lvalue); - CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); + META_HPP_CHECK_INVOCABLE(CLV_CPTR(), f1, clazz*) + META_HPP_CHECK_INVOCABLE(CLV_CPTR(), f2, clazz* const) + // META_HPP_CHECK_INVOCABLE(CLV_CPTR(), f3, clazz*&) + // META_HPP_CHECK_INVOCABLE(CLV_CPTR(), f4, clazz* const&) + // META_HPP_CHECK_INVOCABLE(CLV_CPTR(), f5, clazz*&&) + // META_HPP_CHECK_INVOCABLE(CLV_CPTR(), f6, clazz* const&&) - []([[maybe_unused]] ivec2 *){}(std::move(vp)); - []([[maybe_unused]] const ivec2 *){}(std::move(vp)); - []([[maybe_unused]] ivec2 *const){}(std::move(vp)); - []([[maybe_unused]] const ivec2 *const){}(std::move(vp)); + META_HPP_CHECK_INVOCABLE(CLV_CPTR(), f1, const clazz*) + META_HPP_CHECK_INVOCABLE(CLV_CPTR(), f2, const clazz* const) + // META_HPP_CHECK_INVOCABLE(CLV_CPTR(), f3, const clazz*&) + // META_HPP_CHECK_INVOCABLE(CLV_CPTR(), f4, const clazz* const&) + // META_HPP_CHECK_INVOCABLE(CLV_CPTR(), f5, const clazz*&&) + // META_HPP_CHECK_INVOCABLE(CLV_CPTR(), f6, const clazz* const&&) - //[]([[maybe_unused]] ivec2 *&){}(std::move(vp)); - //[]([[maybe_unused]] const ivec2 *&){}(std::move(vp)); - []([[maybe_unused]] ivec2 *const &){}(std::move(vp)); - []([[maybe_unused]] const ivec2 *const &){}(std::move(vp)); + META_HPP_CHECK_INVOCABLE(CLV2_CPTR(), f1, clazz*) + META_HPP_CHECK_INVOCABLE(CLV2_CPTR(), f2, clazz* const) + // META_HPP_CHECK_INVOCABLE(CLV2_CPTR(), f3, clazz*&) + // META_HPP_CHECK_INVOCABLE(CLV2_CPTR(), f4, clazz* const&) + // META_HPP_CHECK_INVOCABLE(CLV2_CPTR(), f5, clazz*&&) + // META_HPP_CHECK_INVOCABLE(CLV2_CPTR(), f6, clazz* const&&) - []([[maybe_unused]] ivec2 *&&){}(std::move(vp)); - //[]([[maybe_unused]] const ivec2 *&&){}(std::move(vp)); - []([[maybe_unused]] ivec2 *const &&){}(std::move(vp)); - []([[maybe_unused]] const ivec2 *const &&){}(std::move(vp)); + META_HPP_CHECK_INVOCABLE(CLV2_CPTR(), f1, const clazz*) + META_HPP_CHECK_INVOCABLE(CLV2_CPTR(), f2, const clazz* const) + // META_HPP_CHECK_INVOCABLE(CLV2_CPTR(), f3, const clazz*&) + // META_HPP_CHECK_INVOCABLE(CLV2_CPTR(), f4, const clazz* const&) + // META_HPP_CHECK_INVOCABLE(CLV2_CPTR(), f5, const clazz*&&) + // META_HPP_CHECK_INVOCABLE(CLV2_CPTR(), f6, const clazz* const&&) } } - SUBCASE("ptr_c") { - ivec2 v{1,2}; - ivec2* const vp = &v; - meta::detail::arg a{vp}; - - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - + { + // xvalue { - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); + auto XV_PTR = []() -> clazz*&& { static clazz* p{}; return std::move(p); }; + auto XV2_PTR = []() -> dclazz*&& { static dclazz* p{}; return std::move(p); }; + + meta::detail::arg a{XV_PTR()}; + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::rvalue); + + META_HPP_CHECK_INVOCABLE(XV_PTR(), f1, clazz*) + META_HPP_CHECK_INVOCABLE(XV_PTR(), f2, clazz* const) + // META_HPP_CHECK_INVOCABLE(XV_PTR(), f3, clazz*&) + // META_HPP_CHECK_INVOCABLE(XV_PTR(), f4, clazz* const&) + // META_HPP_CHECK_INVOCABLE(XV_PTR(), f5, clazz*&&) + // META_HPP_CHECK_INVOCABLE(XV_PTR(), f6, clazz* const&&) + + META_HPP_CHECK_INVOCABLE(XV_PTR(), f1, const clazz*) + META_HPP_CHECK_INVOCABLE(XV_PTR(), f2, const clazz* const) + // META_HPP_CHECK_INVOCABLE(XV_PTR(), f3, const clazz*&) + // META_HPP_CHECK_INVOCABLE(XV_PTR(), f4, const clazz* const&) + // META_HPP_CHECK_INVOCABLE(XV_PTR(), f5, const clazz*&&) + // META_HPP_CHECK_INVOCABLE(XV_PTR(), f6, const clazz* const&&) + + META_HPP_CHECK_INVOCABLE(XV2_PTR(), f1, clazz*) + META_HPP_CHECK_INVOCABLE(XV2_PTR(), f2, clazz* const) + // META_HPP_CHECK_INVOCABLE(XV2_PTR(), f3, clazz*&) + // META_HPP_CHECK_INVOCABLE(XV2_PTR(), f4, clazz* const&) + // META_HPP_CHECK_INVOCABLE(XV2_PTR(), f5, clazz*&&) + // META_HPP_CHECK_INVOCABLE(XV2_PTR(), f6, clazz* const&&) + + META_HPP_CHECK_INVOCABLE(XV2_PTR(), f1, const clazz*) + META_HPP_CHECK_INVOCABLE(XV2_PTR(), f2, const clazz* const) + // META_HPP_CHECK_INVOCABLE(XV2_PTR(), f3, const clazz*&) + // META_HPP_CHECK_INVOCABLE(XV2_PTR(), f4, const clazz* const&) + // META_HPP_CHECK_INVOCABLE(XV2_PTR(), f5, const clazz*&&) + // META_HPP_CHECK_INVOCABLE(XV2_PTR(), f6, const clazz* const&&) } - { - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); + auto XV_CPTR = []() -> const clazz*&& { static const clazz* p{}; return std::move(p); }; + auto XV2_CPTR = []() -> const dclazz*&& { static const dclazz* p{}; return std::move(p); }; - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); + meta::detail::arg a{XV_CPTR()}; + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::rvalue); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); + META_HPP_CHECK_INVOCABLE(XV_CPTR(), f1, clazz*) + META_HPP_CHECK_INVOCABLE(XV_CPTR(), f2, clazz* const) + // META_HPP_CHECK_INVOCABLE(XV_CPTR(), f3, clazz*&) + // META_HPP_CHECK_INVOCABLE(XV_CPTR(), f4, clazz* const&) + // META_HPP_CHECK_INVOCABLE(XV_CPTR(), f5, clazz*&&) + // META_HPP_CHECK_INVOCABLE(XV_CPTR(), f6, clazz* const&&) - []([[maybe_unused]] ivec2 *){}(vp); - []([[maybe_unused]] const ivec2 *){}(vp); - []([[maybe_unused]] ivec2 *const &){}(vp); - []([[maybe_unused]] const ivec2 *const &){}(vp); + META_HPP_CHECK_INVOCABLE(XV_CPTR(), f1, const clazz*) + META_HPP_CHECK_INVOCABLE(XV_CPTR(), f2, const clazz* const) + // META_HPP_CHECK_INVOCABLE(XV_CPTR(), f3, const clazz*&) + // META_HPP_CHECK_INVOCABLE(XV_CPTR(), f4, const clazz* const&) + // META_HPP_CHECK_INVOCABLE(XV_CPTR(), f5, const clazz*&&) + // META_HPP_CHECK_INVOCABLE(XV_CPTR(), f6, const clazz* const&&) - // []([[maybe_unused]] ivec2 *&){}(vp); - // []([[maybe_unused]] const ivec2 *&){}(vp); - []([[maybe_unused]] ivec2 *const &){}(vp); - []([[maybe_unused]] const ivec2 *const &){}(vp); + META_HPP_CHECK_INVOCABLE(XV2_CPTR(), f1, clazz*) + META_HPP_CHECK_INVOCABLE(XV2_CPTR(), f2, clazz* const) + // META_HPP_CHECK_INVOCABLE(XV2_CPTR(), f3, clazz*&) + // META_HPP_CHECK_INVOCABLE(XV2_CPTR(), f4, clazz* const&) + // META_HPP_CHECK_INVOCABLE(XV2_CPTR(), f5, clazz*&&) + // META_HPP_CHECK_INVOCABLE(XV2_CPTR(), f6, clazz* const&&) - //[]([[maybe_unused]] ivec2 *&&){}(vp); - //[]([[maybe_unused]] const ivec2 *&&){}(vp); - //[]([[maybe_unused]] ivec2 *const &&){}(vp); - //[]([[maybe_unused]] const ivec2 *const &&){}(vp); + META_HPP_CHECK_INVOCABLE(XV2_CPTR(), f1, const clazz*) + META_HPP_CHECK_INVOCABLE(XV2_CPTR(), f2, const clazz* const) + // META_HPP_CHECK_INVOCABLE(XV2_CPTR(), f3, const clazz*&) + // META_HPP_CHECK_INVOCABLE(XV2_CPTR(), f4, const clazz* const&) + // META_HPP_CHECK_INVOCABLE(XV2_CPTR(), f5, const clazz*&&) + // META_HPP_CHECK_INVOCABLE(XV2_CPTR(), f6, const clazz* const&&) } } - SUBCASE("rptr_c") { - ivec2 v{1,2}; - ivec2* const vp = &v; - meta::detail::arg a{std::move(vp)}; - - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - + { + // const xvalue { - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); + auto CXV_PTR = []() -> clazz* const&& { static clazz* p{}; return std::move(p); }; + auto CXV2_PTR = []() -> dclazz* const&& { static dclazz* p{}; return std::move(p); }; + + meta::detail::arg a{CXV_PTR()}; + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::const_rvalue); + + META_HPP_CHECK_INVOCABLE(CXV_PTR(), f1, clazz*) + META_HPP_CHECK_INVOCABLE(CXV_PTR(), f2, clazz* const) + // META_HPP_CHECK_INVOCABLE(CXV_PTR(), f3, clazz*&) + // META_HPP_CHECK_INVOCABLE(CXV_PTR(), f4, clazz* const&) + // META_HPP_CHECK_INVOCABLE(CXV_PTR(), f5, clazz*&&) + // META_HPP_CHECK_INVOCABLE(CXV_PTR(), f6, clazz* const&&) + + META_HPP_CHECK_INVOCABLE(CXV_PTR(), f1, const clazz*) + META_HPP_CHECK_INVOCABLE(CXV_PTR(), f2, const clazz* const) + // META_HPP_CHECK_INVOCABLE(CXV_PTR(), f3, const clazz*&) + // META_HPP_CHECK_INVOCABLE(CXV_PTR(), f4, const clazz* const&) + // META_HPP_CHECK_INVOCABLE(CXV_PTR(), f5, const clazz*&&) + // META_HPP_CHECK_INVOCABLE(CXV_PTR(), f6, const clazz* const&&) + + META_HPP_CHECK_INVOCABLE(CXV2_PTR(), f1, clazz*) + META_HPP_CHECK_INVOCABLE(CXV2_PTR(), f2, clazz* const) + // META_HPP_CHECK_INVOCABLE(CXV2_PTR(), f3, clazz*&) + // META_HPP_CHECK_INVOCABLE(CXV2_PTR(), f4, clazz* const&) + // META_HPP_CHECK_INVOCABLE(CXV2_PTR(), f5, clazz*&&) + // META_HPP_CHECK_INVOCABLE(CXV2_PTR(), f6, clazz* const&&) + + META_HPP_CHECK_INVOCABLE(CXV2_PTR(), f1, const clazz*) + META_HPP_CHECK_INVOCABLE(CXV2_PTR(), f2, const clazz* const) + // META_HPP_CHECK_INVOCABLE(CXV2_PTR(), f3, const clazz*&) + // META_HPP_CHECK_INVOCABLE(CXV2_PTR(), f4, const clazz* const&) + // META_HPP_CHECK_INVOCABLE(CXV2_PTR(), f5, const clazz*&&) + // META_HPP_CHECK_INVOCABLE(CXV2_PTR(), f6, const clazz* const&&) } - { - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); + auto CXV_CPTR = []() -> const clazz* const&& { static const clazz* p{}; return std::move(p); }; + auto CXV2_CPTR = []() -> const dclazz* const&& { static const dclazz* p{}; return std::move(p); }; - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); + meta::detail::arg a{CXV_CPTR()}; + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::const_rvalue); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); + META_HPP_CHECK_INVOCABLE(CXV_CPTR(), f1, clazz*) + META_HPP_CHECK_INVOCABLE(CXV_CPTR(), f2, clazz* const) + // META_HPP_CHECK_INVOCABLE(CXV_CPTR(), f3, clazz*&) + // META_HPP_CHECK_INVOCABLE(CXV_CPTR(), f4, clazz* const&) + // META_HPP_CHECK_INVOCABLE(CXV_CPTR(), f5, clazz*&&) + // META_HPP_CHECK_INVOCABLE(CXV_CPTR(), f6, clazz* const&&) - []([[maybe_unused]] ivec2 *){}(std::move(vp)); - []([[maybe_unused]] const ivec2 *){}(std::move(vp)); - []([[maybe_unused]] ivec2 *const){}(std::move(vp)); - []([[maybe_unused]] const ivec2 *const){}(std::move(vp)); + META_HPP_CHECK_INVOCABLE(CXV_CPTR(), f1, const clazz*) + META_HPP_CHECK_INVOCABLE(CXV_CPTR(), f2, const clazz* const) + // META_HPP_CHECK_INVOCABLE(CXV_CPTR(), f3, const clazz*&) + // META_HPP_CHECK_INVOCABLE(CXV_CPTR(), f4, const clazz* const&) + // META_HPP_CHECK_INVOCABLE(CXV_CPTR(), f5, const clazz*&&) + // META_HPP_CHECK_INVOCABLE(CXV_CPTR(), f6, const clazz* const&&) - //[]([[maybe_unused]] ivec2 *&){}(std::move(vp)); - //[]([[maybe_unused]] const ivec2 *&){}(std::move(vp)); - []([[maybe_unused]] ivec2 *const &){}(std::move(vp)); - []([[maybe_unused]] const ivec2 *const &){}(std::move(vp)); + META_HPP_CHECK_INVOCABLE(CXV2_CPTR(), f1, clazz*) + META_HPP_CHECK_INVOCABLE(CXV2_CPTR(), f2, clazz* const) + // META_HPP_CHECK_INVOCABLE(CXV2_CPTR(), f3, clazz*&) + // META_HPP_CHECK_INVOCABLE(CXV2_CPTR(), f4, clazz* const&) + // META_HPP_CHECK_INVOCABLE(CXV2_CPTR(), f5, clazz*&&) + // META_HPP_CHECK_INVOCABLE(CXV2_CPTR(), f6, clazz* const&&) - //[]([[maybe_unused]] ivec2 *&&){}(std::move(vp)); - //[]([[maybe_unused]] const ivec2 *&&){}(std::move(vp)); - []([[maybe_unused]] ivec2 *const &&){}(std::move(vp)); - []([[maybe_unused]] const ivec2 *const &&){}(std::move(vp)); + META_HPP_CHECK_INVOCABLE(CXV2_CPTR(), f1, const clazz*) + META_HPP_CHECK_INVOCABLE(CXV2_CPTR(), f2, const clazz* const) + // META_HPP_CHECK_INVOCABLE(CXV2_CPTR(), f3, const clazz*&) + // META_HPP_CHECK_INVOCABLE(CXV2_CPTR(), f4, const clazz* const&) + // META_HPP_CHECK_INVOCABLE(CXV2_CPTR(), f5, const clazz*&&) + // META_HPP_CHECK_INVOCABLE(CXV2_CPTR(), f6, const clazz* const&&) } } - SUBCASE("cptr") { - const ivec2 v{1,2}; - const ivec2* vp = &v; - meta::detail::arg a{vp}; - - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - + { + // prvalue { - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); + auto PRV_PTR = []() -> clazz* { static clazz* p{}; return p; }; + auto PRV2_PTR = []() -> dclazz* { static dclazz* p{}; return p; }; + + meta::detail::arg a{PRV_PTR()}; + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::rvalue); + + META_HPP_CHECK_INVOCABLE(PRV_PTR(), f1, clazz*) + META_HPP_CHECK_INVOCABLE(PRV_PTR(), f2, clazz* const) + // META_HPP_CHECK_INVOCABLE(PRV_PTR(), f3, clazz*&) + // META_HPP_CHECK_INVOCABLE(PRV_PTR(), f4, clazz* const&) + // META_HPP_CHECK_INVOCABLE(PRV_PTR(), f5, clazz*&&) + // META_HPP_CHECK_INVOCABLE(PRV_PTR(), f6, clazz* const&&) + + META_HPP_CHECK_INVOCABLE(PRV_PTR(), f1, const clazz*) + META_HPP_CHECK_INVOCABLE(PRV_PTR(), f2, const clazz* const) + // META_HPP_CHECK_INVOCABLE(PRV_PTR(), f3, const clazz*&) + // META_HPP_CHECK_INVOCABLE(PRV_PTR(), f4, const clazz* const&) + // META_HPP_CHECK_INVOCABLE(PRV_PTR(), f5, const clazz*&&) + // META_HPP_CHECK_INVOCABLE(PRV_PTR(), f6, const clazz* const&&) + + META_HPP_CHECK_INVOCABLE(PRV2_PTR(), f1, clazz*) + META_HPP_CHECK_INVOCABLE(PRV2_PTR(), f2, clazz* const) + // META_HPP_CHECK_INVOCABLE(PRV2_PTR(), f3, clazz*&) + // META_HPP_CHECK_INVOCABLE(PRV2_PTR(), f4, clazz* const&) + // META_HPP_CHECK_INVOCABLE(PRV2_PTR(), f5, clazz*&&) + // META_HPP_CHECK_INVOCABLE(PRV2_PTR(), f6, clazz* const&&) + + META_HPP_CHECK_INVOCABLE(PRV2_PTR(), f1, const clazz*) + META_HPP_CHECK_INVOCABLE(PRV2_PTR(), f2, const clazz* const) + // META_HPP_CHECK_INVOCABLE(PRV2_PTR(), f3, const clazz*&) + // META_HPP_CHECK_INVOCABLE(PRV2_PTR(), f4, const clazz* const&) + // META_HPP_CHECK_INVOCABLE(PRV2_PTR(), f5, const clazz*&&) + // META_HPP_CHECK_INVOCABLE(PRV2_PTR(), f6, const clazz* const&&) } - { - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - - //[]([[maybe_unused]] ivec2 *){}(vp); - []([[maybe_unused]] const ivec2 *){}(vp); - //[]([[maybe_unused]] ivec2 *const){}(vp); - []([[maybe_unused]] const ivec2 *const){}(vp); - - //[]([[maybe_unused]] ivec2 *&){}(vp); - []([[maybe_unused]] const ivec2 *&){}(vp); - //[]([[maybe_unused]] ivec2 *const &){}(vp); - []([[maybe_unused]] const ivec2 *const &){}(vp); - - //[]([[maybe_unused]] ivec2 *&&){}(vp); - //[]([[maybe_unused]] const ivec2 *&&){}(vp); - //[]([[maybe_unused]] ivec2 *const &&){}(vp); - //[]([[maybe_unused]] const ivec2 *const &&){}(vp); - } - } - - SUBCASE("crptr") { - const ivec2 v{1,2}; - const ivec2* vp = &v; - meta::detail::arg a{std::move(vp)}; - - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - - { - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - } - - { - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - - //[]([[maybe_unused]] ivec2 *){}(std::move(vp)); - []([[maybe_unused]] const ivec2 *){}(std::move(vp)); - //[]([[maybe_unused]] ivec2 *const){}(std::move(vp)); - []([[maybe_unused]] const ivec2 *const){}(std::move(vp)); - - //[]([[maybe_unused]] ivec2 *&){}(std::move(vp)); - //[]([[maybe_unused]] const ivec2 *&){}(std::move(vp)); - //[]([[maybe_unused]] ivec2 *const &){}(std::move(vp)); - []([[maybe_unused]] const ivec2 *const &){}(std::move(vp)); - - //[]([[maybe_unused]] ivec2 *&&){}(std::move(vp)); - []([[maybe_unused]] const ivec2 *&&){}(std::move(vp)); - //[]([[maybe_unused]] ivec2 *const &&){}(std::move(vp)); - []([[maybe_unused]] const ivec2 *const &&){}(std::move(vp)); - } - } - - SUBCASE("cptr_c") { - const ivec2 v{1,2}; - const ivec2* const vp = &v; - meta::detail::arg a{vp}; - - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - - { - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - } - - { - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - - //[]([[maybe_unused]] ivec2 *){}(vp); - []([[maybe_unused]] const ivec2 *){}(vp); - //[]([[maybe_unused]] ivec2 *const){}(vp); - []([[maybe_unused]] const ivec2 *const){}(vp); - - //[]([[maybe_unused]] ivec2 *&){}(vp); - //[]([[maybe_unused]] const ivec2 *&){}(vp); - //[]([[maybe_unused]] ivec2 *const &){}(vp); - []([[maybe_unused]] const ivec2 *const &){}(vp); - - //[]([[maybe_unused]] ivec2 *&&){}(vp); - //[]([[maybe_unused]] const ivec2 *&&){}(vp); - //[]([[maybe_unused]] ivec2 *const &&){}(vp); - //[]([[maybe_unused]] const ivec2 *const &&){}(vp); - } - } - - SUBCASE("crptr_c") { - const ivec2 v{1,2}; - const ivec2* const vp = &v; - meta::detail::arg a{std::move(vp)}; - - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - - { - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - } - - { - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - - //[]([[maybe_unused]] ivec2 *){}(std::move(vp)); - []([[maybe_unused]] const ivec2 *){}(std::move(vp)); - //[]([[maybe_unused]] ivec2 *const){}(std::move(vp)); - []([[maybe_unused]] const ivec2 *const){}(std::move(vp)); - - //[]([[maybe_unused]] ivec2 *&){}(std::move(vp)); - //[]([[maybe_unused]] const ivec2 *&){}(std::move(vp)); - //[]([[maybe_unused]] ivec2 *const &){}(std::move(vp)); - []([[maybe_unused]] const ivec2 *const &){}(std::move(vp)); - - //[]([[maybe_unused]] ivec2 *&&){}(std::move(vp)); - //[]([[maybe_unused]] const ivec2 *&&){}(std::move(vp)); - //[]([[maybe_unused]] ivec2 *const &&){}(std::move(vp)); - []([[maybe_unused]] const ivec2 *const &&){}(std::move(vp)); - } - } - - SUBCASE("ref") { - ivec2 v{1,2}; - ivec2& vr = v; - meta::detail::arg a{vr}; - - { - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - - []([[maybe_unused]] ivec2){}(vr); - []([[maybe_unused]] const ivec2){}(vr); - []([[maybe_unused]] ivec2&){}(vr); - []([[maybe_unused]] const ivec2&){}(vr); - //[]([[maybe_unused]] ivec2&&){}(vr); - //[]([[maybe_unused]] const ivec2&&){}(vr); - } - - { - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - } - - { - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - - //[]([[maybe_unused]] ivec2*){}(vr); - //[]([[maybe_unused]] const ivec2*){}(vr); - //[]([[maybe_unused]] ivec2* const){}(vr); - //[]([[maybe_unused]] const ivec2* const){}(vr); - - //[]([[maybe_unused]] ivec2 *&){}(vr); - //[]([[maybe_unused]] const ivec2 *&){}(vr); - //[]([[maybe_unused]] ivec2 *const &){}(vr); - //[]([[maybe_unused]] const ivec2 *const &){}(vr); - - //[]([[maybe_unused]] ivec2 *&&){}(vr); - //[]([[maybe_unused]] const ivec2 *&&){}(vr); - //[]([[maybe_unused]] ivec2 *const &&){}(vr); - //[]([[maybe_unused]] const ivec2 *const &&){}(vr); - } - } - - SUBCASE("cref") { - const ivec2 v{1,2}; - const ivec2& vr = v; - meta::detail::arg a{vr}; - - { - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - - []([[maybe_unused]] ivec2){}(vr); - []([[maybe_unused]] const ivec2){}(vr); - //[]([[maybe_unused]] ivec2&){}(vr); - []([[maybe_unused]] const ivec2&){}(vr); - //[]([[maybe_unused]] ivec2&&){}(vr); - //[]([[maybe_unused]] const ivec2&&){}(vr); - } - - { - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - } - - { - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - - //[]([[maybe_unused]] ivec2*){}(vr); - //[]([[maybe_unused]] const ivec2*){}(vr); - //[]([[maybe_unused]] ivec2* const){}(vr); - //[]([[maybe_unused]] const ivec2* const){}(vr); - - //[]([[maybe_unused]] ivec2 *&){}(vr); - //[]([[maybe_unused]] const ivec2 *&){}(vr); - //[]([[maybe_unused]] ivec2 *const &){}(vr); - //[]([[maybe_unused]] const ivec2 *const &){}(vr); - - //[]([[maybe_unused]] ivec2 *&&){}(vr); - //[]([[maybe_unused]] const ivec2 *&&){}(vr); - //[]([[maybe_unused]] ivec2 *const &&){}(vr); - //[]([[maybe_unused]] const ivec2 *const &&){}(vr); - } - } - - SUBCASE("rref") { - ivec2 v{1,2}; - meta::detail::arg a{std::move(v)}; - - { - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - - []([[maybe_unused]] ivec2){}(std::move(v)); - []([[maybe_unused]] const ivec2){}(std::move(v)); - //[]([[maybe_unused]] ivec2&){}(std::move(v)); - []([[maybe_unused]] const ivec2&){}(std::move(v)); - []([[maybe_unused]] ivec2&&){}(std::move(v)); - []([[maybe_unused]] const ivec2&&){}(std::move(v)); - } - - { - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - } - - { - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - - //[]([[maybe_unused]] ivec2*){}(std::move(v)); - //[]([[maybe_unused]] const ivec2*){}(std::move(v)); - //[]([[maybe_unused]] ivec2* const){}(std::move(v)); - //[]([[maybe_unused]] const ivec2* const){}(std::move(v)); - - //[]([[maybe_unused]] ivec2 *&){}(std::move(v)); - //[]([[maybe_unused]] const ivec2 *&){}(std::move(v)); - //[]([[maybe_unused]] ivec2 *const &){}(std::move(v)); - //[]([[maybe_unused]] const ivec2 *const &){}(std::move(v)); - - //[]([[maybe_unused]] ivec2 *&&){}(std::move(v)); - //[]([[maybe_unused]] const ivec2 *&&){}(std::move(v)); - //[]([[maybe_unused]] ivec2 *const &&){}(std::move(v)); - //[]([[maybe_unused]] const ivec2 *const &&){}(std::move(v)); - } - } - - SUBCASE("crref") { - const ivec2 v{1,2}; - meta::detail::arg a{std::move(v)}; - - { - CHECK(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK(a.can_cast_to()); - - []([[maybe_unused]] ivec2){}(std::move(v)); - []([[maybe_unused]] const ivec2){}(std::move(v)); - //[]([[maybe_unused]] ivec2&){}(std::move(v)); - []([[maybe_unused]] const ivec2&){}(std::move(v)); - //[]([[maybe_unused]] ivec2&&){}(std::move(v)); - []([[maybe_unused]] const ivec2&&){}(std::move(v)); - } - - { - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - } - - { - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - CHECK_FALSE(a.can_cast_to()); - - //[]([[maybe_unused]] ivec2*){}(std::move(v)); - //[]([[maybe_unused]] const ivec2*){}(std::move(v)); - //[]([[maybe_unused]] ivec2* const){}(std::move(v)); - //[]([[maybe_unused]] const ivec2* const){}(std::move(v)); - - //[]([[maybe_unused]] ivec2 *&){}(std::move(v)); - //[]([[maybe_unused]] const ivec2 *&){}(std::move(v)); - //[]([[maybe_unused]] ivec2 *const &){}(std::move(v)); - //[]([[maybe_unused]] const ivec2 *const &){}(std::move(v)); - - //[]([[maybe_unused]] ivec2 *&&){}(std::move(v)); - //[]([[maybe_unused]] const ivec2 *&&){}(std::move(v)); - //[]([[maybe_unused]] ivec2 *const &&){}(std::move(v)); - //[]([[maybe_unused]] const ivec2 *const &&){}(std::move(v)); + auto PRV_CPTR = []() -> const clazz* { static const clazz* p{}; return p; }; + auto PRV2_CPTR = []() -> const dclazz* { static const dclazz* p{}; return p; }; + + meta::detail::arg a{PRV_CPTR()}; + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::rvalue); + + META_HPP_CHECK_INVOCABLE(PRV_CPTR(), f1, clazz*) + META_HPP_CHECK_INVOCABLE(PRV_CPTR(), f2, clazz* const) + // META_HPP_CHECK_INVOCABLE(PRV_CPTR(), f3, clazz*&) + // META_HPP_CHECK_INVOCABLE(PRV_CPTR(), f4, clazz* const&) + // META_HPP_CHECK_INVOCABLE(PRV_CPTR(), f5, clazz*&&) + // META_HPP_CHECK_INVOCABLE(PRV_CPTR(), f6, clazz* const&&) + + META_HPP_CHECK_INVOCABLE(PRV_CPTR(), f1, const clazz*) + META_HPP_CHECK_INVOCABLE(PRV_CPTR(), f2, const clazz* const) + // META_HPP_CHECK_INVOCABLE(PRV_CPTR(), f3, const clazz*&) + // META_HPP_CHECK_INVOCABLE(PRV_CPTR(), f4, const clazz* const&) + // META_HPP_CHECK_INVOCABLE(PRV_CPTR(), f5, const clazz*&&) + // META_HPP_CHECK_INVOCABLE(PRV_CPTR(), f6, const clazz* const&&) + + META_HPP_CHECK_INVOCABLE(PRV2_CPTR(), f1, clazz*) + META_HPP_CHECK_INVOCABLE(PRV2_CPTR(), f2, clazz* const) + // META_HPP_CHECK_INVOCABLE(PRV2_CPTR(), f3, clazz*&) + // META_HPP_CHECK_INVOCABLE(PRV2_CPTR(), f4, clazz* const&) + // META_HPP_CHECK_INVOCABLE(PRV2_CPTR(), f5, clazz*&&) + // META_HPP_CHECK_INVOCABLE(PRV2_CPTR(), f6, clazz* const&&) + + META_HPP_CHECK_INVOCABLE(PRV2_CPTR(), f1, const clazz*) + META_HPP_CHECK_INVOCABLE(PRV2_CPTR(), f2, const clazz* const) + // META_HPP_CHECK_INVOCABLE(PRV2_CPTR(), f3, const clazz*&) + // META_HPP_CHECK_INVOCABLE(PRV2_CPTR(), f4, const clazz* const&) + // META_HPP_CHECK_INVOCABLE(PRV2_CPTR(), f5, const clazz*&&) + // META_HPP_CHECK_INVOCABLE(PRV2_CPTR(), f6, const clazz* const&&) } } } -TEST_CASE("features/meta_utilities/arg/cast") { +TEST_CASE("features/meta_utilities/arg2/values") { namespace meta = meta_hpp; - SUBCASE("ptr") { - ivec2 v{1,2}; - ivec2* vp = &v; - meta::detail::arg a{vp}; + { + auto LV = []() -> meta::value& { static meta::value v{clazz{}}; return v; }; + auto LV2 = []() -> meta::value& { static meta::value v{dclazz{}}; return v; }; - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); + meta::detail::arg a{LV()}; + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::lvalue); - { - CHECK(a.cast() == vp); - CHECK(a.cast() == vp); - CHECK(a.cast() == vp); - CHECK(a.cast() == vp); + META_HPP_CHECK_INVOCABLE_2(LV(), f1, clazz&, clazz) + META_HPP_CHECK_INVOCABLE_2(LV(), f2, clazz&, const clazz) + META_HPP_CHECK_INVOCABLE_2(LV(), f3, clazz&, clazz&) + META_HPP_CHECK_INVOCABLE_2(LV(), f4, clazz&, const clazz&) + META_HPP_CHECK_INVOCABLE_2(LV(), f5, clazz&, clazz&&) + META_HPP_CHECK_INVOCABLE_2(LV(), f6, clazz&, const clazz&&) - CHECK(a.cast() == vp); - CHECK_THROWS(a.cast()); - CHECK(a.cast() == vp); - CHECK(a.cast() == vp); - - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - } + META_HPP_CHECK_INVOCABLE_2(LV2(), f1, dclazz&, clazz) + META_HPP_CHECK_INVOCABLE_2(LV2(), f2, dclazz&, const clazz) + META_HPP_CHECK_INVOCABLE_2(LV2(), f3, dclazz&, clazz&) + META_HPP_CHECK_INVOCABLE_2(LV2(), f4, dclazz&, const clazz&) + META_HPP_CHECK_INVOCABLE_2(LV2(), f5, dclazz&, clazz&&) + META_HPP_CHECK_INVOCABLE_2(LV2(), f6, dclazz&, const clazz&&) } - SUBCASE("rptr") { - ivec2 v{1,2}; - ivec2* vp = &v; + { + auto CLV = []() -> const meta::value& { static meta::value v{clazz{}}; return v; }; + auto CLV2 = []() -> const meta::value& { static meta::value v{dclazz{}}; return v; }; - CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); - CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); - CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); - CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); - CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); - CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); + meta::detail::arg a{CLV()}; + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::const_lvalue); - { - CHECK(meta::detail::arg{std::move(vp)}.cast() == vp); - CHECK(meta::detail::arg{std::move(vp)}.cast() == vp); - CHECK(meta::detail::arg{std::move(vp)}.cast() == vp); - CHECK(meta::detail::arg{std::move(vp)}.cast() == vp); + META_HPP_CHECK_INVOCABLE_2(CLV(), f1, const clazz&, clazz) + META_HPP_CHECK_INVOCABLE_2(CLV(), f2, const clazz&, const clazz) + META_HPP_CHECK_INVOCABLE_2(CLV(), f3, const clazz&, clazz&) + META_HPP_CHECK_INVOCABLE_2(CLV(), f4, const clazz&, const clazz&) + META_HPP_CHECK_INVOCABLE_2(CLV(), f5, const clazz&, clazz&&) + META_HPP_CHECK_INVOCABLE_2(CLV(), f6, const clazz&, const clazz&&) - CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); - CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); - CHECK(meta::detail::arg{std::move(vp)}.cast() == vp); - CHECK(meta::detail::arg{std::move(vp)}.cast() == vp); - - CHECK(meta::detail::arg{std::move(vp)}.cast() == vp); - CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); - CHECK(meta::detail::arg{std::move(vp)}.cast() == vp); - CHECK(meta::detail::arg{std::move(vp)}.cast() == vp); - } + META_HPP_CHECK_INVOCABLE_2(CLV2(), f1, const dclazz&, clazz) + META_HPP_CHECK_INVOCABLE_2(CLV2(), f2, const dclazz&, const clazz) + META_HPP_CHECK_INVOCABLE_2(CLV2(), f3, const dclazz&, clazz&) + META_HPP_CHECK_INVOCABLE_2(CLV2(), f4, const dclazz&, const clazz&) + META_HPP_CHECK_INVOCABLE_2(CLV2(), f5, const dclazz&, clazz&&) + META_HPP_CHECK_INVOCABLE_2(CLV2(), f6, const dclazz&, const clazz&&) } - SUBCASE("ptr_c") { - ivec2 v{1,2}; - ivec2* const vp = &v; - meta::detail::arg a{vp}; + { + auto XV = []() -> meta::value&& { static meta::value v{clazz{}}; return std::move(v); }; + auto XV2 = []() -> meta::value&& { static meta::value v{dclazz{}}; return std::move(v); }; - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); + meta::detail::arg a{XV()}; + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::rvalue); - { - CHECK(a.cast() == vp); - CHECK(a.cast() == vp); - CHECK(a.cast() == vp); - CHECK(a.cast() == vp); + META_HPP_CHECK_INVOCABLE_2(XV(), f1, clazz&&, clazz) + META_HPP_CHECK_INVOCABLE_2(XV(), f2, clazz&&, const clazz) + META_HPP_CHECK_INVOCABLE_2(XV(), f3, clazz&&, clazz&) + META_HPP_CHECK_INVOCABLE_2(XV(), f4, clazz&&, const clazz&) + META_HPP_CHECK_INVOCABLE_2(XV(), f5, clazz&&, clazz&&) + META_HPP_CHECK_INVOCABLE_2(XV(), f6, clazz&&, const clazz&&) - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK(a.cast() == vp); - CHECK(a.cast() == vp); - - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - } + META_HPP_CHECK_INVOCABLE_2(XV2(), f1, dclazz&&, clazz) + META_HPP_CHECK_INVOCABLE_2(XV2(), f2, dclazz&&, const clazz) + META_HPP_CHECK_INVOCABLE_2(XV2(), f3, dclazz&&, clazz&) + META_HPP_CHECK_INVOCABLE_2(XV2(), f4, dclazz&&, const clazz&) + META_HPP_CHECK_INVOCABLE_2(XV2(), f5, dclazz&&, clazz&&) + META_HPP_CHECK_INVOCABLE_2(XV2(), f6, dclazz&&, const clazz&&) } - SUBCASE("rptr_c") { - ivec2 v{1,2}; - ivec2* const vp = &v; + { + auto CXV = []() -> const meta::value&& { static meta::value v{clazz{}}; return std::move(v); }; + auto CXV2 = []() -> const meta::value&& { static meta::value v{dclazz{}}; return std::move(v); }; - CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); - CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); - CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); - CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); - CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); - CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); + meta::detail::arg a{CXV()}; + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::const_rvalue); - { - CHECK(meta::detail::arg{std::move(vp)}.cast() == vp); - CHECK(meta::detail::arg{std::move(vp)}.cast() == vp); - CHECK(meta::detail::arg{std::move(vp)}.cast() == vp); - CHECK(meta::detail::arg{std::move(vp)}.cast() == vp); + META_HPP_CHECK_INVOCABLE_2(CXV(), f1, const clazz&&, clazz) + META_HPP_CHECK_INVOCABLE_2(CXV(), f2, const clazz&&, const clazz) + META_HPP_CHECK_INVOCABLE_2(CXV(), f3, const clazz&&, clazz&) + META_HPP_CHECK_INVOCABLE_2(CXV(), f4, const clazz&&, const clazz&) + META_HPP_CHECK_INVOCABLE_2(CXV(), f5, const clazz&&, clazz&&) + META_HPP_CHECK_INVOCABLE_2(CXV(), f6, const clazz&&, const clazz&&) - CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); - CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); - CHECK(meta::detail::arg{std::move(vp)}.cast() == vp); - CHECK(meta::detail::arg{std::move(vp)}.cast() == vp); - - CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); - CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); - CHECK(meta::detail::arg{std::move(vp)}.cast() == vp); - CHECK(meta::detail::arg{std::move(vp)}.cast() == vp); - } + META_HPP_CHECK_INVOCABLE_2(CXV2(), f1, const dclazz&&, clazz) + META_HPP_CHECK_INVOCABLE_2(CXV2(), f2, const dclazz&&, const clazz) + META_HPP_CHECK_INVOCABLE_2(CXV2(), f3, const dclazz&&, clazz&) + META_HPP_CHECK_INVOCABLE_2(CXV2(), f4, const dclazz&&, const clazz&) + META_HPP_CHECK_INVOCABLE_2(CXV2(), f5, const dclazz&&, clazz&&) + META_HPP_CHECK_INVOCABLE_2(CXV2(), f6, const dclazz&&, const clazz&&) } - SUBCASE("cptr") { - const ivec2 v{1,2}; - const ivec2* vp = &v; - meta::detail::arg a{vp}; + { + auto PRV = []() -> meta::value { return meta::value{clazz{}}; }; + auto PRV2 = []() -> meta::value { return meta::value{dclazz{}}; }; - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); + meta::detail::arg a{PRV()}; + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::rvalue); - { - CHECK_THROWS(a.cast()); - CHECK(a.cast() == vp); - CHECK_THROWS(a.cast()); - CHECK(a.cast() == vp); + META_HPP_CHECK_INVOCABLE_2(PRV(), f1, clazz, clazz) + META_HPP_CHECK_INVOCABLE_2(PRV(), f2, clazz, const clazz) + META_HPP_CHECK_INVOCABLE_2(PRV(), f3, clazz, clazz&) + META_HPP_CHECK_INVOCABLE_2(PRV(), f4, clazz, const clazz&) + META_HPP_CHECK_INVOCABLE_2(PRV(), f5, clazz, clazz&&) + META_HPP_CHECK_INVOCABLE_2(PRV(), f6, clazz, const clazz&&) - CHECK_THROWS(a.cast()); - CHECK(a.cast() == vp); - CHECK_THROWS(a.cast()); - CHECK(a.cast() == vp); - - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - } + META_HPP_CHECK_INVOCABLE_2(PRV2(), f1, dclazz, clazz) + META_HPP_CHECK_INVOCABLE_2(PRV2(), f2, dclazz, const clazz) + META_HPP_CHECK_INVOCABLE_2(PRV2(), f3, dclazz, clazz&) + META_HPP_CHECK_INVOCABLE_2(PRV2(), f4, dclazz, const clazz&) + META_HPP_CHECK_INVOCABLE_2(PRV2(), f5, dclazz, clazz&&) + META_HPP_CHECK_INVOCABLE_2(PRV2(), f6, dclazz, const clazz&&) } - SUBCASE("crptr") { - const ivec2 v{1,2}; - const ivec2* vp = &v; + { + auto CPRV = []() -> const meta::value { return meta::value{clazz{}}; }; + auto CPRV2 = []() -> const meta::value { return meta::value{dclazz{}}; }; - CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); - CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); - CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); - CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); - CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); - CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); + meta::detail::arg a{CPRV()}; + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::const_rvalue); - { - CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); - CHECK(meta::detail::arg{std::move(vp)}.cast() == vp); - CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); - CHECK(meta::detail::arg{std::move(vp)}.cast() == vp); + META_HPP_CHECK_INVOCABLE_2(CPRV(), f1, const clazz, clazz) + META_HPP_CHECK_INVOCABLE_2(CPRV(), f2, const clazz, const clazz) + META_HPP_CHECK_INVOCABLE_2(CPRV(), f3, const clazz, clazz&) + META_HPP_CHECK_INVOCABLE_2(CPRV(), f4, const clazz, const clazz&) + META_HPP_CHECK_INVOCABLE_2(CPRV(), f5, const clazz, clazz&&) + META_HPP_CHECK_INVOCABLE_2(CPRV(), f6, const clazz, const clazz&&) - CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); - CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); - CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); - CHECK(meta::detail::arg{std::move(vp)}.cast() == vp); - - CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); - CHECK(meta::detail::arg{std::move(vp)}.cast() == vp); - CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); - CHECK(meta::detail::arg{std::move(vp)}.cast() == vp); - } - } - - SUBCASE("cptr_c") { - const ivec2 v{1,2}; - const ivec2* const vp = &v; - meta::detail::arg a{vp}; - - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - - { - CHECK_THROWS(a.cast()); - CHECK(a.cast() == vp); - CHECK_THROWS(a.cast()); - CHECK(a.cast() == vp); - - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK(a.cast() == vp); - - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - } - } - - SUBCASE("crptr_c") { - const ivec2 v{1,2}; - const ivec2* const vp = &v; - - CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); - CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); - CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); - CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); - CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); - CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); - - { - CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); - CHECK(meta::detail::arg{std::move(vp)}.cast() == vp); - CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); - CHECK(meta::detail::arg{std::move(vp)}.cast() == vp); - - CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); - CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); - CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); - CHECK(meta::detail::arg{std::move(vp)}.cast() == vp); - - CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); - CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); - CHECK_THROWS(meta::detail::arg{std::move(vp)}.cast()); - CHECK(meta::detail::arg{std::move(vp)}.cast() == vp); - } - } - - SUBCASE("ref") { - ivec2 v{1,2}; - ivec2& vr = v; - meta::detail::arg a{vr}; - - CHECK(a.cast() == ivec2{1,2}); - CHECK(a.cast() == ivec2{1,2}); - CHECK(&a.cast() == &v); - CHECK(&a.cast() == &vr); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - } - - SUBCASE("cref") { - const ivec2 v{1,2}; - const ivec2& vr = v; - meta::detail::arg a{vr}; - - CHECK(a.cast() == v); - CHECK(a.cast() == v); - CHECK_THROWS(a.cast()); - CHECK(&a.cast() == &vr); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - } - - SUBCASE("rref") { - CHECK(meta::detail::arg{ivec2{1,2}}.cast() == ivec2{1,2}); - CHECK(meta::detail::arg{ivec2{1,2}}.cast() == ivec2{1,2}); - CHECK_THROWS(meta::detail::arg{ivec2{1,2}}.cast()); - CHECK(meta::detail::arg{ivec2{1,2}}.cast() == ivec2{1,2}); - CHECK(meta::detail::arg{ivec2{1,2}}.cast() == ivec2{1,2}); - CHECK(meta::detail::arg{ivec2{1,2}}.cast() == ivec2{1,2}); - - CHECK_THROWS(meta::detail::arg{ivec2{1,2}}.cast()); - CHECK_THROWS(meta::detail::arg{ivec2{1,2}}.cast()); - CHECK_THROWS(meta::detail::arg{ivec2{1,2}}.cast()); - CHECK_THROWS(meta::detail::arg{ivec2{1,2}}.cast()); - } - - SUBCASE("crref") { - const ivec2 v{1,2}; - meta::detail::arg a{std::move(v)}; - - CHECK(a.cast() == ivec2{1,2}); - CHECK(a.cast() == ivec2{1,2}); - CHECK_THROWS(a.cast()); - CHECK(&a.cast() == &v); - CHECK_THROWS(a.cast()); - CHECK(a.cast() == v); - - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); - CHECK_THROWS(a.cast()); + META_HPP_CHECK_INVOCABLE_2(CPRV2(), f1, const dclazz, clazz) + META_HPP_CHECK_INVOCABLE_2(CPRV2(), f2, const dclazz, const clazz) + META_HPP_CHECK_INVOCABLE_2(CPRV2(), f3, const dclazz, clazz&) + META_HPP_CHECK_INVOCABLE_2(CPRV2(), f4, const dclazz, const clazz&) + META_HPP_CHECK_INVOCABLE_2(CPRV2(), f5, const dclazz, clazz&&) + META_HPP_CHECK_INVOCABLE_2(CPRV2(), f6, const dclazz, const clazz&&) + } +} + +TEST_CASE("features/meta_utilities/arg2/ptr_values") { + namespace meta = meta_hpp; + + { + auto LV_PTR = []() -> meta::value& { static clazz* p{}; static meta::value v{p}; return v; }; + auto LV2_PTR = []() -> meta::value& { static dclazz* p{}; static meta::value v{p}; return v; }; + + meta::detail::arg a{LV_PTR()}; + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::lvalue); + + META_HPP_CHECK_INVOCABLE_2(LV_PTR(), f1, clazz*&, clazz*) + META_HPP_CHECK_INVOCABLE_2(LV_PTR(), f2, clazz*&, clazz* const) + // META_HPP_CHECK_INVOCABLE_2(LV_PTR(), f3, clazz*&, clazz*&) + // META_HPP_CHECK_INVOCABLE_2(LV_PTR(), f4, clazz*&, clazz* const&) + // META_HPP_CHECK_INVOCABLE_2(LV_PTR(), f5, clazz*&, clazz*&&) + // META_HPP_CHECK_INVOCABLE_2(LV_PTR(), f6, clazz*&, clazz* const&&) + + META_HPP_CHECK_INVOCABLE_2(LV_PTR(), f1, clazz*&, const clazz*) + META_HPP_CHECK_INVOCABLE_2(LV_PTR(), f2, clazz*&, const clazz* const) + // META_HPP_CHECK_INVOCABLE_2(LV_PTR(), f3, clazz*&, const clazz*&) + // META_HPP_CHECK_INVOCABLE_2(LV_PTR(), f4, clazz*&, const clazz* const&) + // META_HPP_CHECK_INVOCABLE_2(LV_PTR(), f5, clazz*&, const clazz*&&) + // META_HPP_CHECK_INVOCABLE_2(LV_PTR(), f6, clazz*&, const clazz* const&&) + + META_HPP_CHECK_INVOCABLE_2(LV2_PTR(), f1, dclazz*&, clazz*) + META_HPP_CHECK_INVOCABLE_2(LV2_PTR(), f2, dclazz*&, clazz* const) + // META_HPP_CHECK_INVOCABLE_2(LV2_PTR(), f3, dclazz*&, clazz*&) + // META_HPP_CHECK_INVOCABLE_2(LV2_PTR(), f4, dclazz*&, clazz* const&) + // META_HPP_CHECK_INVOCABLE_2(LV2_PTR(), f5, dclazz*&, clazz*&&) + // META_HPP_CHECK_INVOCABLE_2(LV2_PTR(), f6, dclazz*&, clazz* const&&) + + META_HPP_CHECK_INVOCABLE_2(LV2_PTR(), f1, dclazz*&, const clazz*) + META_HPP_CHECK_INVOCABLE_2(LV2_PTR(), f2, dclazz*&, const clazz* const) + // META_HPP_CHECK_INVOCABLE_2(LV2_PTR(), f3, dclazz*&, const clazz*&) + // META_HPP_CHECK_INVOCABLE_2(LV2_PTR(), f4, dclazz*&, const clazz* const&) + // META_HPP_CHECK_INVOCABLE_2(LV2_PTR(), f5, dclazz*&, const clazz*&&) + // META_HPP_CHECK_INVOCABLE_2(LV2_PTR(), f6, dclazz*&, const clazz* const&&) + } + + { + auto LV_CPTR = []() -> meta::value& { static const clazz* p{}; static meta::value v{p}; return v; }; + auto LV2_CPTR = []() -> meta::value& { static const dclazz* p{}; static meta::value v{p}; return v; }; + + meta::detail::arg a{LV_CPTR()}; + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::lvalue); + + META_HPP_CHECK_INVOCABLE_2(LV_CPTR(), f1, const clazz*&, clazz*) + META_HPP_CHECK_INVOCABLE_2(LV_CPTR(), f2, const clazz*&, clazz* const) + // META_HPP_CHECK_INVOCABLE_2(LV_CPTR(), f3, const clazz*&, clazz*&) + // META_HPP_CHECK_INVOCABLE_2(LV_CPTR(), f4, const clazz*&, clazz* const&) + // META_HPP_CHECK_INVOCABLE_2(LV_CPTR(), f5, const clazz*&, clazz*&&) + // META_HPP_CHECK_INVOCABLE_2(LV_CPTR(), f6, const clazz*&, clazz* const&&) + + META_HPP_CHECK_INVOCABLE_2(LV_CPTR(), f1, const clazz*&, const clazz*) + META_HPP_CHECK_INVOCABLE_2(LV_CPTR(), f2, const clazz*&, const clazz* const) + // META_HPP_CHECK_INVOCABLE_2(LV_CPTR(), f3, const clazz*&, const clazz*&) + // META_HPP_CHECK_INVOCABLE_2(LV_CPTR(), f4, const clazz*&, const clazz* const&) + // META_HPP_CHECK_INVOCABLE_2(LV_CPTR(), f5, const clazz*&, const clazz*&&) + // META_HPP_CHECK_INVOCABLE_2(LV_CPTR(), f6, const clazz*&, const clazz* const&&) + + META_HPP_CHECK_INVOCABLE_2(LV2_CPTR(), f1, const dclazz*&, clazz*) + META_HPP_CHECK_INVOCABLE_2(LV2_CPTR(), f2, const dclazz*&, clazz* const) + // META_HPP_CHECK_INVOCABLE_2(LV2_CPTR(), f3, const dclazz*&, clazz*&) + // META_HPP_CHECK_INVOCABLE_2(LV2_CPTR(), f4, const dclazz*&, clazz* const&) + // META_HPP_CHECK_INVOCABLE_2(LV2_CPTR(), f5, const dclazz*&, clazz*&&) + // META_HPP_CHECK_INVOCABLE_2(LV2_CPTR(), f6, const dclazz*&, clazz* const&&) + + META_HPP_CHECK_INVOCABLE_2(LV2_CPTR(), f1, const dclazz*&, const clazz*) + META_HPP_CHECK_INVOCABLE_2(LV2_CPTR(), f2, const dclazz*&, const clazz* const) + // META_HPP_CHECK_INVOCABLE_2(LV2_CPTR(), f3, const dclazz*&, const clazz*&) + // META_HPP_CHECK_INVOCABLE_2(LV2_CPTR(), f4, const dclazz*&, const clazz* const&) + // META_HPP_CHECK_INVOCABLE_2(LV2_CPTR(), f5, const dclazz*&, const clazz*&&) + // META_HPP_CHECK_INVOCABLE_2(LV2_CPTR(), f6, const dclazz*&, const clazz* const&&) + } + + { + auto CLV_PTR = []() -> const meta::value& { static clazz* p{}; static meta::value v{p}; return v; }; + auto CLV2_PTR = []() -> const meta::value& { static dclazz* p{}; static meta::value v{p}; return v; }; + + meta::detail::arg a{CLV_PTR()}; + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::const_lvalue); + + META_HPP_CHECK_INVOCABLE_2(CLV_PTR(), f1, clazz* const&, clazz*) + META_HPP_CHECK_INVOCABLE_2(CLV_PTR(), f2, clazz* const&, clazz* const) + // META_HPP_CHECK_INVOCABLE_2(CLV_PTR(), f3, clazz* const&, clazz*&) + // META_HPP_CHECK_INVOCABLE_2(CLV_PTR(), f4, clazz* const&, clazz* const&) + // META_HPP_CHECK_INVOCABLE_2(CLV_PTR(), f5, clazz* const&, clazz*&&) + // META_HPP_CHECK_INVOCABLE_2(CLV_PTR(), f6, clazz* const&, clazz* const&&) + + META_HPP_CHECK_INVOCABLE_2(CLV_PTR(), f1, clazz* const&, const clazz*) + META_HPP_CHECK_INVOCABLE_2(CLV_PTR(), f2, clazz* const&, const clazz* const) + // META_HPP_CHECK_INVOCABLE_2(CLV_PTR(), f3, clazz* const&, const clazz*&) + // META_HPP_CHECK_INVOCABLE_2(CLV_PTR(), f4, clazz* const&, const clazz* const&) + // META_HPP_CHECK_INVOCABLE_2(CLV_PTR(), f5, clazz* const&, const clazz*&&) + // META_HPP_CHECK_INVOCABLE_2(CLV_PTR(), f6, clazz* const&, const clazz* const&&) + + META_HPP_CHECK_INVOCABLE_2(CLV2_PTR(), f1, dclazz* const&, clazz*) + META_HPP_CHECK_INVOCABLE_2(CLV2_PTR(), f2, dclazz* const&, clazz* const) + // META_HPP_CHECK_INVOCABLE_2(CLV2_PTR(), f3, dclazz* const&, clazz*&) + // META_HPP_CHECK_INVOCABLE_2(CLV2_PTR(), f4, dclazz* const&, clazz* const&) + // META_HPP_CHECK_INVOCABLE_2(CLV2_PTR(), f5, dclazz* const&, clazz*&&) + // META_HPP_CHECK_INVOCABLE_2(CLV2_PTR(), f6, dclazz* const&, clazz* const&&) + + META_HPP_CHECK_INVOCABLE_2(CLV2_PTR(), f1, dclazz* const&, const clazz*) + META_HPP_CHECK_INVOCABLE_2(CLV2_PTR(), f2, dclazz* const&, const clazz* const) + // META_HPP_CHECK_INVOCABLE_2(CLV2_PTR(), f3, dclazz* const&, const clazz*&) + // META_HPP_CHECK_INVOCABLE_2(CLV2_PTR(), f4, dclazz* const&, const clazz* const&) + // META_HPP_CHECK_INVOCABLE_2(CLV2_PTR(), f5, dclazz* const&, const clazz*&&) + // META_HPP_CHECK_INVOCABLE_2(CLV2_PTR(), f6, dclazz* const&, const clazz* const&&) + } + + { + auto CLV_CPTR = []() -> const meta::value& { static const clazz* p{}; static meta::value v{p}; return v; }; + auto CLV2_CPTR = []() -> const meta::value& { static const dclazz* p{}; static meta::value v{p}; return v; }; + + meta::detail::arg a{CLV_CPTR()}; + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::const_lvalue); + + META_HPP_CHECK_INVOCABLE_2(CLV_CPTR(), f1, const clazz* const&, clazz*) + META_HPP_CHECK_INVOCABLE_2(CLV_CPTR(), f2, const clazz* const&, clazz* const) + // META_HPP_CHECK_INVOCABLE_2(CLV_CPTR(), f3, const clazz* const&, clazz*&) + // META_HPP_CHECK_INVOCABLE_2(CLV_CPTR(), f4, const clazz* const&, clazz* const&) + // META_HPP_CHECK_INVOCABLE_2(CLV_CPTR(), f5, const clazz* const&, clazz*&&) + // META_HPP_CHECK_INVOCABLE_2(CLV_CPTR(), f6, const clazz* const&, clazz* const&&) + + META_HPP_CHECK_INVOCABLE_2(CLV_CPTR(), f1, const clazz* const&, const clazz*) + META_HPP_CHECK_INVOCABLE_2(CLV_CPTR(), f2, const clazz* const&, const clazz* const) + // META_HPP_CHECK_INVOCABLE_2(CLV_CPTR(), f3, const clazz* const&, const clazz*&) + // META_HPP_CHECK_INVOCABLE_2(CLV_CPTR(), f4, const clazz* const&, const clazz* const&) + // META_HPP_CHECK_INVOCABLE_2(CLV_CPTR(), f5, const clazz* const&, const clazz*&&) + // META_HPP_CHECK_INVOCABLE_2(CLV_CPTR(), f6, const clazz* const&, const clazz* const&&) + + META_HPP_CHECK_INVOCABLE_2(CLV2_CPTR(), f1, const dclazz* const&, clazz*) + META_HPP_CHECK_INVOCABLE_2(CLV2_CPTR(), f2, const dclazz* const&, clazz* const) + // META_HPP_CHECK_INVOCABLE_2(CLV2_CPTR(), f3, const dclazz* const&, clazz*&) + // META_HPP_CHECK_INVOCABLE_2(CLV2_CPTR(), f4, const dclazz* const&, clazz* const&) + // META_HPP_CHECK_INVOCABLE_2(CLV2_CPTR(), f5, const dclazz* const&, clazz*&&) + // META_HPP_CHECK_INVOCABLE_2(CLV2_CPTR(), f6, const dclazz* const&, clazz* const&&) + + META_HPP_CHECK_INVOCABLE_2(CLV2_CPTR(), f1, const dclazz* const&, const clazz*) + META_HPP_CHECK_INVOCABLE_2(CLV2_CPTR(), f2, const dclazz* const&, const clazz* const) + // META_HPP_CHECK_INVOCABLE_2(CLV2_CPTR(), f3, const dclazz* const&, const clazz*&) + // META_HPP_CHECK_INVOCABLE_2(CLV2_CPTR(), f4, const dclazz* const&, const clazz* const&) + // META_HPP_CHECK_INVOCABLE_2(CLV2_CPTR(), f5, const dclazz* const&, const clazz*&&) + // META_HPP_CHECK_INVOCABLE_2(CLV2_CPTR(), f6, const dclazz* const&, const clazz* const&&) + } + + { + auto XV_PTR = []() -> meta::value&& { static clazz* p{}; static meta::value v{std::move(p)}; return std::move(v); }; + auto XV2_PTR = []() -> meta::value&& { static dclazz* p{}; static meta::value v{std::move(p)}; return std::move(v); }; + + meta::detail::arg a{XV_PTR()}; + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::rvalue); + + META_HPP_CHECK_INVOCABLE_2(XV_PTR(), f1, clazz*&&, clazz*) + META_HPP_CHECK_INVOCABLE_2(XV_PTR(), f2, clazz*&&, clazz* const) + // META_HPP_CHECK_INVOCABLE_2(XV_PTR(), f3, clazz*&&, clazz*&) + // META_HPP_CHECK_INVOCABLE_2(XV_PTR(), f4, clazz*&&, clazz* const&) + // META_HPP_CHECK_INVOCABLE_2(XV_PTR(), f5, clazz*&&, clazz*&&) + // META_HPP_CHECK_INVOCABLE_2(XV_PTR(), f6, clazz*&&, clazz* const&&) + + META_HPP_CHECK_INVOCABLE_2(XV_PTR(), f1, clazz*&&, const clazz*) + META_HPP_CHECK_INVOCABLE_2(XV_PTR(), f2, clazz*&&, const clazz* const) + // META_HPP_CHECK_INVOCABLE_2(XV_PTR(), f3, clazz*&&, const clazz*&) + // META_HPP_CHECK_INVOCABLE_2(XV_PTR(), f4, clazz*&&, const clazz* const&) + // META_HPP_CHECK_INVOCABLE_2(XV_PTR(), f5, clazz*&&, const clazz*&&) + // META_HPP_CHECK_INVOCABLE_2(XV_PTR(), f6, clazz*&&, const clazz* const&&) + + META_HPP_CHECK_INVOCABLE_2(XV2_PTR(), f1, dclazz*&&, clazz*) + META_HPP_CHECK_INVOCABLE_2(XV2_PTR(), f2, dclazz*&&, clazz* const) + // META_HPP_CHECK_INVOCABLE_2(XV2_PTR(), f3, dclazz*&&, clazz*&) + // META_HPP_CHECK_INVOCABLE_2(XV2_PTR(), f4, dclazz*&&, clazz* const&) + // META_HPP_CHECK_INVOCABLE_2(XV2_PTR(), f5, dclazz*&&, clazz*&&) + // META_HPP_CHECK_INVOCABLE_2(XV2_PTR(), f6, dclazz*&&, clazz* const&&) + + META_HPP_CHECK_INVOCABLE_2(XV2_PTR(), f1, dclazz*&&, const clazz*) + META_HPP_CHECK_INVOCABLE_2(XV2_PTR(), f2, dclazz*&&, const clazz* const) + // META_HPP_CHECK_INVOCABLE_2(XV2_PTR(), f3, dclazz*&&, const clazz*&) + // META_HPP_CHECK_INVOCABLE_2(XV2_PTR(), f4, dclazz*&&, const clazz* const&) + // META_HPP_CHECK_INVOCABLE_2(XV2_PTR(), f5, dclazz*&&, const clazz*&&) + // META_HPP_CHECK_INVOCABLE_2(XV2_PTR(), f6, dclazz*&&, const clazz* const&&) + } + + { + auto XV_CPTR = []() -> meta::value&& { static const clazz* p{}; static meta::value v{std::move(p)}; return std::move(v); }; + auto XV2_CPTR = []() -> meta::value&& { static const dclazz* p{}; static meta::value v{std::move(p)}; return std::move(v); }; + + meta::detail::arg a{XV_CPTR()}; + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::rvalue); + + META_HPP_CHECK_INVOCABLE_2(XV_CPTR(), f1, const clazz*&&, clazz*) + META_HPP_CHECK_INVOCABLE_2(XV_CPTR(), f2, const clazz*&&, clazz* const) + // META_HPP_CHECK_INVOCABLE_2(XV_CPTR(), f3, const clazz*&&, clazz*&) + // META_HPP_CHECK_INVOCABLE_2(XV_CPTR(), f4, const clazz*&&, clazz* const&) + // META_HPP_CHECK_INVOCABLE_2(XV_CPTR(), f5, const clazz*&&, clazz*&&) + // META_HPP_CHECK_INVOCABLE_2(XV_CPTR(), f6, const clazz*&&, clazz* const&&) + + META_HPP_CHECK_INVOCABLE_2(XV_CPTR(), f1, const clazz*&&, const clazz*) + META_HPP_CHECK_INVOCABLE_2(XV_CPTR(), f2, const clazz*&&, const clazz* const) + // META_HPP_CHECK_INVOCABLE_2(XV_CPTR(), f3, const clazz*&&, const clazz*&) + // META_HPP_CHECK_INVOCABLE_2(XV_CPTR(), f4, const clazz*&&, const clazz* const&) + // META_HPP_CHECK_INVOCABLE_2(XV_CPTR(), f5, const clazz*&&, const clazz*&&) + // META_HPP_CHECK_INVOCABLE_2(XV_CPTR(), f6, const clazz*&&, const clazz* const&&) + + META_HPP_CHECK_INVOCABLE_2(XV2_CPTR(), f1, const dclazz*&&, clazz*) + META_HPP_CHECK_INVOCABLE_2(XV2_CPTR(), f2, const dclazz*&&, clazz* const) + // META_HPP_CHECK_INVOCABLE_2(XV2_CPTR(), f3, const dclazz*&&, clazz*&) + // META_HPP_CHECK_INVOCABLE_2(XV2_CPTR(), f4, const dclazz*&&, clazz* const&) + // META_HPP_CHECK_INVOCABLE_2(XV2_CPTR(), f5, const dclazz*&&, clazz*&&) + // META_HPP_CHECK_INVOCABLE_2(XV2_CPTR(), f6, const dclazz*&&, clazz* const&&) + + META_HPP_CHECK_INVOCABLE_2(XV2_CPTR(), f1, const dclazz*&&, const clazz*) + META_HPP_CHECK_INVOCABLE_2(XV2_CPTR(), f2, const dclazz*&&, const clazz* const) + // META_HPP_CHECK_INVOCABLE_2(XV2_CPTR(), f3, const dclazz*&&, const clazz*&) + // META_HPP_CHECK_INVOCABLE_2(XV2_CPTR(), f4, const dclazz*&&, const clazz* const&) + // META_HPP_CHECK_INVOCABLE_2(XV2_CPTR(), f5, const dclazz*&&, const clazz*&&) + // META_HPP_CHECK_INVOCABLE_2(XV2_CPTR(), f6, const dclazz*&&, const clazz* const&&) + } + + { + auto CXV_PTR = []() -> const meta::value&& { static clazz* p{}; static meta::value v{std::move(p)}; return std::move(v); }; + auto CXV2_PTR = []() -> const meta::value&& { static dclazz* p{}; static meta::value v{std::move(p)}; return std::move(v); }; + + meta::detail::arg a{CXV_PTR()}; + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::const_rvalue); + + META_HPP_CHECK_INVOCABLE_2(CXV_PTR(), f1, clazz* const&&, clazz*) + META_HPP_CHECK_INVOCABLE_2(CXV_PTR(), f2, clazz* const&&, clazz* const) + // META_HPP_CHECK_INVOCABLE_2(CXV_PTR(), f3, clazz* const&&, clazz*&) + // META_HPP_CHECK_INVOCABLE_2(CXV_PTR(), f4, clazz* const&&, clazz* const&) + // META_HPP_CHECK_INVOCABLE_2(CXV_PTR(), f5, clazz* const&&, clazz*&&) + // META_HPP_CHECK_INVOCABLE_2(CXV_PTR(), f6, clazz* const&&, clazz* const&&) + + META_HPP_CHECK_INVOCABLE_2(CXV_PTR(), f1, clazz* const&&, const clazz*) + META_HPP_CHECK_INVOCABLE_2(CXV_PTR(), f2, clazz* const&&, const clazz* const) + // META_HPP_CHECK_INVOCABLE_2(CXV_PTR(), f3, clazz* const&&, const clazz*&) + // META_HPP_CHECK_INVOCABLE_2(CXV_PTR(), f4, clazz* const&&, const clazz* const&) + // META_HPP_CHECK_INVOCABLE_2(CXV_PTR(), f5, clazz* const&&, const clazz*&&) + // META_HPP_CHECK_INVOCABLE_2(CXV_PTR(), f6, clazz* const&&, const clazz* const&&) + + META_HPP_CHECK_INVOCABLE_2(CXV2_PTR(), f1, dclazz* const&&, clazz*) + META_HPP_CHECK_INVOCABLE_2(CXV2_PTR(), f2, dclazz* const&&, clazz* const) + // META_HPP_CHECK_INVOCABLE_2(CXV2_PTR(), f3, dclazz* const&&, clazz*&) + // META_HPP_CHECK_INVOCABLE_2(CXV2_PTR(), f4, dclazz* const&&, clazz* const&) + // META_HPP_CHECK_INVOCABLE_2(CXV2_PTR(), f5, dclazz* const&&, clazz*&&) + // META_HPP_CHECK_INVOCABLE_2(CXV2_PTR(), f6, dclazz* const&&, clazz* const&&) + + META_HPP_CHECK_INVOCABLE_2(CXV2_PTR(), f1, dclazz* const&&, const clazz*) + META_HPP_CHECK_INVOCABLE_2(CXV2_PTR(), f2, dclazz* const&&, const clazz* const) + // META_HPP_CHECK_INVOCABLE_2(CXV2_PTR(), f3, dclazz* const&&, const clazz*&) + // META_HPP_CHECK_INVOCABLE_2(CXV2_PTR(), f4, dclazz* const&&, const clazz* const&) + // META_HPP_CHECK_INVOCABLE_2(CXV2_PTR(), f5, dclazz* const&&, const clazz*&&) + // META_HPP_CHECK_INVOCABLE_2(CXV2_PTR(), f6, dclazz* const&&, const clazz* const&&) + } + + { + auto CXV_CPTR = []() -> const meta::value&& { static const clazz* p{}; static meta::value v{std::move(p)}; return std::move(v); }; + auto CXV2_CPTR = []() -> const meta::value&& { static const dclazz* p{}; static meta::value v{std::move(p)}; return std::move(v); }; + + meta::detail::arg a{CXV_CPTR()}; + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::const_rvalue); + + META_HPP_CHECK_INVOCABLE_2(CXV_CPTR(), f1, const clazz* const&&, clazz*) + META_HPP_CHECK_INVOCABLE_2(CXV_CPTR(), f2, const clazz* const&&, clazz* const) + // META_HPP_CHECK_INVOCABLE_2(CXV_CPTR(), f3, const clazz* const&&, clazz*&) + // META_HPP_CHECK_INVOCABLE_2(CXV_CPTR(), f4, const clazz* const&&, clazz* const&) + // META_HPP_CHECK_INVOCABLE_2(CXV_CPTR(), f5, const clazz* const&&, clazz*&&) + // META_HPP_CHECK_INVOCABLE_2(CXV_CPTR(), f6, const clazz* const&&, clazz* const&&) + + META_HPP_CHECK_INVOCABLE_2(CXV_CPTR(), f1, const clazz* const&&, const clazz*) + META_HPP_CHECK_INVOCABLE_2(CXV_CPTR(), f2, const clazz* const&&, const clazz* const) + // META_HPP_CHECK_INVOCABLE_2(CXV_CPTR(), f3, const clazz* const&&, const clazz*&) + // META_HPP_CHECK_INVOCABLE_2(CXV_CPTR(), f4, const clazz* const&&, const clazz* const&) + // META_HPP_CHECK_INVOCABLE_2(CXV_CPTR(), f5, const clazz* const&&, const clazz*&&) + // META_HPP_CHECK_INVOCABLE_2(CXV_CPTR(), f6, const clazz* const&&, const clazz* const&&) + + META_HPP_CHECK_INVOCABLE_2(CXV2_CPTR(), f1, const dclazz* const&&, clazz*) + META_HPP_CHECK_INVOCABLE_2(CXV2_CPTR(), f2, const dclazz* const&&, clazz* const) + // META_HPP_CHECK_INVOCABLE_2(CXV2_CPTR(), f3, const dclazz* const&&, clazz*&) + // META_HPP_CHECK_INVOCABLE_2(CXV2_CPTR(), f4, const dclazz* const&&, clazz* const&) + // META_HPP_CHECK_INVOCABLE_2(CXV2_CPTR(), f5, const dclazz* const&&, clazz*&&) + // META_HPP_CHECK_INVOCABLE_2(CXV2_CPTR(), f6, const dclazz* const&&, clazz* const&&) + + META_HPP_CHECK_INVOCABLE_2(CXV2_CPTR(), f1, const dclazz* const&&, const clazz*) + META_HPP_CHECK_INVOCABLE_2(CXV2_CPTR(), f2, const dclazz* const&&, const clazz* const) + // META_HPP_CHECK_INVOCABLE_2(CXV2_CPTR(), f3, const dclazz* const&&, const clazz*&) + // META_HPP_CHECK_INVOCABLE_2(CXV2_CPTR(), f4, const dclazz* const&&, const clazz* const&) + // META_HPP_CHECK_INVOCABLE_2(CXV2_CPTR(), f5, const dclazz* const&&, const clazz*&&) + // META_HPP_CHECK_INVOCABLE_2(CXV2_CPTR(), f6, const dclazz* const&&, const clazz* const&&) + } + + { + auto PRV_PTR = []() -> meta::value { static clazz* p{}; static meta::value v{p}; return v; }; + auto PRV2_PTR = []() -> meta::value { static dclazz* p{}; static meta::value v{p}; return v; }; + + meta::detail::arg a{PRV_PTR()}; + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::rvalue); + + META_HPP_CHECK_INVOCABLE_2(PRV_PTR(), f1, clazz*, clazz*) + META_HPP_CHECK_INVOCABLE_2(PRV_PTR(), f2, clazz*, clazz* const) + // META_HPP_CHECK_INVOCABLE_2(PRV_PTR(), f3, clazz*, clazz*&) + // META_HPP_CHECK_INVOCABLE_2(PRV_PTR(), f4, clazz*, clazz* const&) + // META_HPP_CHECK_INVOCABLE_2(PRV_PTR(), f5, clazz*, clazz*&&) + // META_HPP_CHECK_INVOCABLE_2(PRV_PTR(), f6, clazz*, clazz* const&&) + + META_HPP_CHECK_INVOCABLE_2(PRV_PTR(), f1, clazz*, const clazz*) + META_HPP_CHECK_INVOCABLE_2(PRV_PTR(), f2, clazz*, const clazz* const) + // META_HPP_CHECK_INVOCABLE_2(PRV_PTR(), f3, clazz*, const clazz*&) + // META_HPP_CHECK_INVOCABLE_2(PRV_PTR(), f4, clazz*, const clazz* const&) + // META_HPP_CHECK_INVOCABLE_2(PRV_PTR(), f5, clazz*, const clazz*&&) + // META_HPP_CHECK_INVOCABLE_2(PRV_PTR(), f6, clazz*, const clazz* const&&) + + META_HPP_CHECK_INVOCABLE_2(PRV2_PTR(), f1, dclazz*, clazz*) + META_HPP_CHECK_INVOCABLE_2(PRV2_PTR(), f2, dclazz*, clazz* const) + // META_HPP_CHECK_INVOCABLE_2(PRV2_PTR(), f3, dclazz*, clazz*&) + // META_HPP_CHECK_INVOCABLE_2(PRV2_PTR(), f4, dclazz*, clazz* const&) + // META_HPP_CHECK_INVOCABLE_2(PRV2_PTR(), f5, dclazz*, clazz*&&) + // META_HPP_CHECK_INVOCABLE_2(PRV2_PTR(), f6, dclazz*, clazz* const&&) + + META_HPP_CHECK_INVOCABLE_2(PRV2_PTR(), f1, dclazz*, const clazz*) + META_HPP_CHECK_INVOCABLE_2(PRV2_PTR(), f2, dclazz*, const clazz* const) + // META_HPP_CHECK_INVOCABLE_2(PRV2_PTR(), f3, dclazz*, const clazz*&) + // META_HPP_CHECK_INVOCABLE_2(PRV2_PTR(), f4, dclazz*, const clazz* const&) + // META_HPP_CHECK_INVOCABLE_2(PRV2_PTR(), f5, dclazz*, const clazz*&&) + // META_HPP_CHECK_INVOCABLE_2(PRV2_PTR(), f6, dclazz*, const clazz* const&&) + } + + { + auto PRV_CPTR = []() -> meta::value { static const clazz* p{}; static meta::value v{p}; return v; }; + auto PRV2_CPTR = []() -> meta::value { static const dclazz* p{}; static meta::value v{p}; return v; }; + + meta::detail::arg a{PRV_CPTR()}; + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::rvalue); + + META_HPP_CHECK_INVOCABLE_2(PRV_CPTR(), f1, const clazz*, clazz*) + META_HPP_CHECK_INVOCABLE_2(PRV_CPTR(), f2, const clazz*, clazz* const) + // META_HPP_CHECK_INVOCABLE_2(PRV_CPTR(), f3, const clazz*, clazz*&) + // META_HPP_CHECK_INVOCABLE_2(PRV_CPTR(), f4, const clazz*, clazz* const&) + // META_HPP_CHECK_INVOCABLE_2(PRV_CPTR(), f5, const clazz*, clazz*&&) + // META_HPP_CHECK_INVOCABLE_2(PRV_CPTR(), f6, const clazz*, clazz* const&&) + + META_HPP_CHECK_INVOCABLE_2(PRV_CPTR(), f1, const clazz*, const clazz*) + META_HPP_CHECK_INVOCABLE_2(PRV_CPTR(), f2, const clazz*, const clazz* const) + // META_HPP_CHECK_INVOCABLE_2(PRV_CPTR(), f3, const clazz*, const clazz*&) + // META_HPP_CHECK_INVOCABLE_2(PRV_CPTR(), f4, const clazz*, const clazz* const&) + // META_HPP_CHECK_INVOCABLE_2(PRV_CPTR(), f5, const clazz*, const clazz*&&) + // META_HPP_CHECK_INVOCABLE_2(PRV_CPTR(), f6, const clazz*, const clazz* const&&) + + META_HPP_CHECK_INVOCABLE_2(PRV2_CPTR(), f1, const dclazz*, clazz*) + META_HPP_CHECK_INVOCABLE_2(PRV2_CPTR(), f2, const dclazz*, clazz* const) + // META_HPP_CHECK_INVOCABLE_2(PRV2_CPTR(), f3, const dclazz*, clazz*&) + // META_HPP_CHECK_INVOCABLE_2(PRV2_CPTR(), f4, const dclazz*, clazz* const&) + // META_HPP_CHECK_INVOCABLE_2(PRV2_CPTR(), f5, const dclazz*, clazz*&&) + // META_HPP_CHECK_INVOCABLE_2(PRV2_CPTR(), f6, const dclazz*, clazz* const&&) + + META_HPP_CHECK_INVOCABLE_2(PRV2_CPTR(), f1, const dclazz*, const clazz*) + META_HPP_CHECK_INVOCABLE_2(PRV2_CPTR(), f2, const dclazz*, const clazz* const) + // META_HPP_CHECK_INVOCABLE_2(PRV2_CPTR(), f3, const dclazz*, const clazz*&) + // META_HPP_CHECK_INVOCABLE_2(PRV2_CPTR(), f4, const dclazz*, const clazz* const&) + // META_HPP_CHECK_INVOCABLE_2(PRV2_CPTR(), f5, const dclazz*, const clazz*&&) + // META_HPP_CHECK_INVOCABLE_2(PRV2_CPTR(), f6, const dclazz*, const clazz* const&&) + } + + { + auto CPRV_PTR = []() -> const meta::value { static clazz* p{}; static meta::value v{p}; return v; }; + auto CPRV2_PTR = []() -> const meta::value { static dclazz* p{}; static meta::value v{p}; return v; }; + + meta::detail::arg a{CPRV_PTR()}; + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::const_rvalue); + + META_HPP_CHECK_INVOCABLE_2(CPRV_PTR(), f1, clazz* const, clazz*) + META_HPP_CHECK_INVOCABLE_2(CPRV_PTR(), f2, clazz* const, clazz* const) + // META_HPP_CHECK_INVOCABLE_2(CPRV_PTR(), f3, clazz* const, clazz*&) + // META_HPP_CHECK_INVOCABLE_2(CPRV_PTR(), f4, clazz* const, clazz* const&) + // META_HPP_CHECK_INVOCABLE_2(CPRV_PTR(), f5, clazz* const, clazz*&&) + // META_HPP_CHECK_INVOCABLE_2(CPRV_PTR(), f6, clazz* const, clazz* const&&) + + META_HPP_CHECK_INVOCABLE_2(CPRV_PTR(), f1, clazz* const, const clazz*) + META_HPP_CHECK_INVOCABLE_2(CPRV_PTR(), f2, clazz* const, const clazz* const) + // META_HPP_CHECK_INVOCABLE_2(CPRV_PTR(), f3, clazz* const, const clazz*&) + // META_HPP_CHECK_INVOCABLE_2(CPRV_PTR(), f4, clazz* const, const clazz* const&) + // META_HPP_CHECK_INVOCABLE_2(CPRV_PTR(), f5, clazz* const, const clazz*&&) + // META_HPP_CHECK_INVOCABLE_2(CPRV_PTR(), f6, clazz* const, const clazz* const&&) + + META_HPP_CHECK_INVOCABLE_2(CPRV2_PTR(), f1, dclazz* const, clazz*) + META_HPP_CHECK_INVOCABLE_2(CPRV2_PTR(), f2, dclazz* const, clazz* const) + // META_HPP_CHECK_INVOCABLE_2(CPRV2_PTR(), f3, dclazz* const, clazz*&) + // META_HPP_CHECK_INVOCABLE_2(CPRV2_PTR(), f4, dclazz* const, clazz* const&) + // META_HPP_CHECK_INVOCABLE_2(CPRV2_PTR(), f5, dclazz* const, clazz*&&) + // META_HPP_CHECK_INVOCABLE_2(CPRV2_PTR(), f6, dclazz* const, clazz* const&&) + + META_HPP_CHECK_INVOCABLE_2(CPRV2_PTR(), f1, dclazz* const, const clazz*) + META_HPP_CHECK_INVOCABLE_2(CPRV2_PTR(), f2, dclazz* const, const clazz* const) + // META_HPP_CHECK_INVOCABLE_2(CPRV2_PTR(), f3, dclazz* const, const clazz*&) + // META_HPP_CHECK_INVOCABLE_2(CPRV2_PTR(), f4, dclazz* const, const clazz* const&) + // META_HPP_CHECK_INVOCABLE_2(CPRV2_PTR(), f5, dclazz* const, const clazz*&&) + // META_HPP_CHECK_INVOCABLE_2(CPRV2_PTR(), f6, dclazz* const, const clazz* const&&) + } + + { + auto CPRV_CPTR = []() -> const meta::value { static const clazz* p{}; static meta::value v{p}; return v; }; + auto CPRV2_CPTR = []() -> const meta::value { static const dclazz* p{}; static meta::value v{p}; return v; }; + + meta::detail::arg a{CPRV_CPTR()}; + CHECK(a.get_raw_type() == meta::resolve_type()); + CHECK(a.get_ref_type() == meta::detail::arg::ref_types::const_rvalue); + + META_HPP_CHECK_INVOCABLE_2(CPRV_CPTR(), f1, const clazz* const, clazz*) + META_HPP_CHECK_INVOCABLE_2(CPRV_CPTR(), f2, const clazz* const, clazz* const) + // META_HPP_CHECK_INVOCABLE_2(CPRV_CPTR(), f3, const clazz* const, clazz*&) + // META_HPP_CHECK_INVOCABLE_2(CPRV_CPTR(), f4, const clazz* const, clazz* const&) + // META_HPP_CHECK_INVOCABLE_2(CPRV_CPTR(), f5, const clazz* const, clazz*&&) + // META_HPP_CHECK_INVOCABLE_2(CPRV_CPTR(), f6, const clazz* const, clazz* const&&) + + META_HPP_CHECK_INVOCABLE_2(CPRV_CPTR(), f1, const clazz* const, const clazz*) + META_HPP_CHECK_INVOCABLE_2(CPRV_CPTR(), f2, const clazz* const, const clazz* const) + // META_HPP_CHECK_INVOCABLE_2(CPRV_CPTR(), f3, const clazz* const, const clazz*&) + // META_HPP_CHECK_INVOCABLE_2(CPRV_CPTR(), f4, const clazz* const, const clazz* const&) + // META_HPP_CHECK_INVOCABLE_2(CPRV_CPTR(), f5, const clazz* const, const clazz*&&) + // META_HPP_CHECK_INVOCABLE_2(CPRV_CPTR(), f6, const clazz* const, const clazz* const&&) + + META_HPP_CHECK_INVOCABLE_2(CPRV2_CPTR(), f1, const dclazz* const, clazz*) + META_HPP_CHECK_INVOCABLE_2(CPRV2_CPTR(), f2, const dclazz* const, clazz* const) + // META_HPP_CHECK_INVOCABLE_2(CPRV2_CPTR(), f3, const dclazz* const, clazz*&) + // META_HPP_CHECK_INVOCABLE_2(CPRV2_CPTR(), f4, const dclazz* const, clazz* const&) + // META_HPP_CHECK_INVOCABLE_2(CPRV2_CPTR(), f5, const dclazz* const, clazz*&&) + // META_HPP_CHECK_INVOCABLE_2(CPRV2_CPTR(), f6, const dclazz* const, clazz* const&&) + + META_HPP_CHECK_INVOCABLE_2(CPRV2_CPTR(), f1, const dclazz* const, const clazz*) + META_HPP_CHECK_INVOCABLE_2(CPRV2_CPTR(), f2, const dclazz* const, const clazz* const) + // META_HPP_CHECK_INVOCABLE_2(CPRV2_CPTR(), f3, const dclazz* const, const clazz*&) + // META_HPP_CHECK_INVOCABLE_2(CPRV2_CPTR(), f4, const dclazz* const, const clazz* const&) + // META_HPP_CHECK_INVOCABLE_2(CPRV2_CPTR(), f5, const dclazz* const, const clazz*&&) + // META_HPP_CHECK_INVOCABLE_2(CPRV2_CPTR(), f6, const dclazz* const, const clazz* const&&) } } From d7526cc20d54c11060931e94a1884e7a354f9d83 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sun, 5 Dec 2021 06:02:30 +0700 Subject: [PATCH 129/233] universal type data access --- headers/meta.hpp/meta_types.hpp | 28 ++++++++++++++---------- headers/meta.hpp/meta_types/any_type.hpp | 22 +++++++++---------- 2 files changed, 28 insertions(+), 22 deletions(-) diff --git a/headers/meta.hpp/meta_types.hpp b/headers/meta.hpp/meta_types.hpp index d4ba9ac..6a309f9 100644 --- a/headers/meta.hpp/meta_types.hpp +++ b/headers/meta.hpp/meta_types.hpp @@ -73,6 +73,11 @@ namespace meta_hpp std::same_as || std::same_as || std::same_as; + + template < type_family T > + auto data_access(const T& type) { + return type.data_; + } } template < detail::type_family T, detail::type_family U > @@ -157,6 +162,7 @@ namespace meta_hpp void_type as_void() const noexcept; private: detail::type_data_base_ptr data_; + friend auto detail::data_access(const any_type&); }; class array_type final { @@ -173,8 +179,8 @@ namespace meta_hpp std::size_t get_extent() const noexcept; any_type get_data_type() const noexcept; private: - friend class any_type; detail::array_type_data_ptr data_; + friend auto detail::data_access(const array_type&); }; class class_type final { @@ -235,8 +241,8 @@ namespace meta_hpp method get_method_with(std::string_view name, std::vector args) const noexcept; method get_method_with(std::string_view name, std::initializer_list args) const noexcept; private: - friend class any_type; detail::class_type_data_ptr data_; + friend auto detail::data_access(const class_type&); }; class ctor_type final { @@ -255,8 +261,8 @@ namespace meta_hpp any_type get_argument_type(std::size_t index) const noexcept; const std::vector& get_argument_types() const noexcept; private: - friend class any_type; detail::ctor_type_data_ptr data_; + friend auto detail::data_access(const ctor_type&); }; class enum_type final { @@ -280,8 +286,8 @@ namespace meta_hpp std::optional value_to_name(Value&& value) const noexcept; std::optional name_to_value(std::string_view name) const noexcept; private: - friend class any_type; detail::enum_type_data_ptr data_; + friend auto detail::data_access(const enum_type&); }; class function_type final { @@ -300,8 +306,8 @@ namespace meta_hpp any_type get_argument_type(std::size_t index) const noexcept; const std::vector& get_argument_types() const noexcept; private: - friend class any_type; detail::function_type_data_ptr data_; + friend auto detail::data_access(const function_type&); }; class member_type final { @@ -318,8 +324,8 @@ namespace meta_hpp class_type get_owner_type() const noexcept; any_type get_value_type() const noexcept; private: - friend class any_type; detail::member_type_data_ptr data_; + friend auto detail::data_access(const member_type&); }; class method_type final { @@ -339,8 +345,8 @@ namespace meta_hpp any_type get_argument_type(std::size_t index) const noexcept; const std::vector& get_argument_types() const noexcept; private: - friend class any_type; detail::method_type_data_ptr data_; + friend auto detail::data_access(const method_type&); }; class number_type final { @@ -356,8 +362,8 @@ namespace meta_hpp std::size_t get_size() const noexcept; private: - friend class any_type; detail::number_type_data_ptr data_; + friend auto detail::data_access(const number_type&); }; class pointer_type final { @@ -373,8 +379,8 @@ namespace meta_hpp any_type get_data_type() const noexcept; private: - friend class any_type; detail::pointer_type_data_ptr data_; + friend auto detail::data_access(const pointer_type&); }; class reference_type final { @@ -390,8 +396,8 @@ namespace meta_hpp any_type get_data_type() const noexcept; private: - friend class any_type; detail::reference_type_data_ptr data_; + friend auto detail::data_access(const reference_type&); }; class void_type final { @@ -405,8 +411,8 @@ namespace meta_hpp type_id get_id() const noexcept; bitflags get_flags() const noexcept; private: - friend class any_type; detail::void_type_data_ptr data_; + friend auto detail::data_access(const void_type&); }; } diff --git a/headers/meta.hpp/meta_types/any_type.hpp b/headers/meta.hpp/meta_types/any_type.hpp index e876d21..d5ff2ff 100644 --- a/headers/meta.hpp/meta_types/any_type.hpp +++ b/headers/meta.hpp/meta_types/any_type.hpp @@ -31,37 +31,37 @@ namespace meta_hpp } inline any_type::any_type(const array_type& other) noexcept - : data_{other.data_} {} + : data_{detail::data_access(other)} {} inline any_type::any_type(const class_type& other) noexcept - : data_{other.data_} {} + : data_{detail::data_access(other)} {} inline any_type::any_type(const ctor_type& other) noexcept - : data_{other.data_} {} + : data_{detail::data_access(other)} {} inline any_type::any_type(const enum_type& other) noexcept - : data_{other.data_} {} + : data_{detail::data_access(other)} {} inline any_type::any_type(const function_type& other) noexcept - : data_{other.data_} {} + : data_{detail::data_access(other)} {} inline any_type::any_type(const member_type& other) noexcept - : data_{other.data_} {} + : data_{detail::data_access(other)} {} inline any_type::any_type(const method_type& other) noexcept - : data_{other.data_} {} + : data_{detail::data_access(other)} {} inline any_type::any_type(const number_type& other) noexcept - : data_{other.data_} {} + : data_{detail::data_access(other)} {} inline any_type::any_type(const pointer_type& other) noexcept - : data_{other.data_} {} + : data_{detail::data_access(other)} {} inline any_type::any_type(const reference_type& other) noexcept - : data_{other.data_} {} + : data_{detail::data_access(other)} {} inline any_type::any_type(const void_type& other) noexcept - : data_{other.data_} {} + : data_{detail::data_access(other)} {} inline bool any_type::is_array() const noexcept { return data_ && data_->kind == type_kind::array_; From 5dc361f8269eebfa34ba597a7cc7f64f8fe3d7d1 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Tue, 14 Dec 2021 06:46:55 +0700 Subject: [PATCH 130/233] fix some misstypings --- headers/meta.hpp/meta_states.hpp | 2 +- headers/meta.hpp/meta_states/ctor.hpp | 2 +- headers/meta.hpp/meta_states/function.hpp | 2 +- headers/meta.hpp/meta_states/method.hpp | 2 +- headers/meta.hpp/meta_states/scope.hpp | 2 +- headers/meta.hpp/meta_types.hpp | 6 ++--- headers/meta.hpp/meta_types/class_type.hpp | 8 +++--- untests/meta_utilities/arg_tests.cpp | 10 ++++---- untests/meta_utilities/value_tests.cpp | 29 +++++++++++++++------- 9 files changed, 37 insertions(+), 26 deletions(-) diff --git a/headers/meta.hpp/meta_states.hpp b/headers/meta.hpp/meta_states.hpp index b614952..a03f4f4 100644 --- a/headers/meta.hpp/meta_states.hpp +++ b/headers/meta.hpp/meta_states.hpp @@ -200,7 +200,7 @@ namespace meta_hpp template < typename... Args > function get_function_with(std::string_view name) const noexcept; - function get_function_with(std::string_view name, std::vector args) const noexcept; + function get_function_with(std::string_view name, const std::vector& args) const noexcept; function get_function_with(std::string_view name, std::initializer_list args) const noexcept; private: detail::scope_state_ptr state_; diff --git a/headers/meta.hpp/meta_states/ctor.hpp b/headers/meta.hpp/meta_states/ctor.hpp index c6f3b51..0fe3d31 100644 --- a/headers/meta.hpp/meta_states/ctor.hpp +++ b/headers/meta.hpp/meta_states/ctor.hpp @@ -155,7 +155,7 @@ namespace meta_hpp bool ctor::is_invocable_with(Args&&... args) const noexcept { using namespace detail; if constexpr ( sizeof...(Args) > 0 ) { - std::array vargs{arg{std::forward(args)}...}; + std::array vargs{arg{std::forward(args)}...}; return state_->is_invocable_with(vargs.data(), vargs.size()); } else { return state_->is_invocable_with(nullptr, 0); diff --git a/headers/meta.hpp/meta_states/function.hpp b/headers/meta.hpp/meta_states/function.hpp index 71ae5b6..3aa5da6 100644 --- a/headers/meta.hpp/meta_states/function.hpp +++ b/headers/meta.hpp/meta_states/function.hpp @@ -169,7 +169,7 @@ namespace meta_hpp bool function::is_invocable_with(Args&&... args) const noexcept { using namespace detail; if constexpr ( sizeof...(Args) > 0 ) { - std::array vargs{arg{std::forward(args)}...}; + std::array vargs{arg{std::forward(args)}...}; return state_->is_invocable_with(vargs.data(), vargs.size()); } else { return state_->is_invocable_with(nullptr, 0); diff --git a/headers/meta.hpp/meta_states/method.hpp b/headers/meta.hpp/meta_states/method.hpp index 85a9756..3689af6 100644 --- a/headers/meta.hpp/meta_states/method.hpp +++ b/headers/meta.hpp/meta_states/method.hpp @@ -185,7 +185,7 @@ namespace meta_hpp bool method::is_invocable_with(Instance&& instance, Args&&... args) const noexcept { using namespace detail; if constexpr ( sizeof...(Args) > 0 ) { - std::array vargs{arg{std::forward(args)}...}; + std::array vargs{arg{std::forward(args)}...}; return state_->is_invocable_with(inst{std::forward(instance)}, vargs.data(), vargs.size()); } else { return state_->is_invocable_with(inst{std::forward(instance)}, nullptr, 0); diff --git a/headers/meta.hpp/meta_states/scope.hpp b/headers/meta.hpp/meta_states/scope.hpp index 7f889ed..ca021e2 100644 --- a/headers/meta.hpp/meta_states/scope.hpp +++ b/headers/meta.hpp/meta_states/scope.hpp @@ -104,7 +104,7 @@ namespace meta_hpp return get_function_with(name, {resolve_type()...}); } - inline function scope::get_function_with(std::string_view name, std::vector args) const noexcept { + inline function scope::get_function_with(std::string_view name, const std::vector& args) const noexcept { for ( auto&& [index, function] : state_->functions ) { if ( index.name != name ) { continue; diff --git a/headers/meta.hpp/meta_types.hpp b/headers/meta.hpp/meta_types.hpp index 6a309f9..aacb439 100644 --- a/headers/meta.hpp/meta_types.hpp +++ b/headers/meta.hpp/meta_types.hpp @@ -228,17 +228,17 @@ namespace meta_hpp template < typename... Args > ctor get_ctor_with() const noexcept; - ctor get_ctor_with(std::vector args) const noexcept; + ctor get_ctor_with(const std::vector& args) const noexcept; ctor get_ctor_with(std::initializer_list args) const noexcept; template < typename... Args > function get_function_with(std::string_view name) const noexcept; - function get_function_with(std::string_view name, std::vector args) const noexcept; + function get_function_with(std::string_view name, const std::vector& args) const noexcept; function get_function_with(std::string_view name, std::initializer_list args) const noexcept; template < typename... Args > method get_method_with(std::string_view name) const noexcept; - method get_method_with(std::string_view name, std::vector args) const noexcept; + method get_method_with(std::string_view name, const std::vector& args) const noexcept; method get_method_with(std::string_view name, std::initializer_list args) const noexcept; private: detail::class_type_data_ptr data_; diff --git a/headers/meta.hpp/meta_types/class_type.hpp b/headers/meta.hpp/meta_types/class_type.hpp index 5d88614..d27b570 100644 --- a/headers/meta.hpp/meta_types/class_type.hpp +++ b/headers/meta.hpp/meta_types/class_type.hpp @@ -94,7 +94,7 @@ namespace meta_hpp template < typename... Args > std::optional class_type::create(Args&&... args) const { for ( auto&& ctor : data_->ctors ) { - if ( ctor.second.is_invocable_with() ) { + if ( ctor.second.is_invocable_with(std::forward(args)...) ) { return ctor.second.invoke(std::forward(args)...); } } @@ -225,7 +225,7 @@ namespace meta_hpp return get_ctor_with({resolve_type()...}); } - inline ctor class_type::get_ctor_with(std::vector args) const noexcept { + inline ctor class_type::get_ctor_with(const std::vector& args) const noexcept { for ( auto&& [index, ctor] : data_->ctors ) { if ( ctor.get_type().get_arity() != args.size() ) { continue; @@ -264,7 +264,7 @@ namespace meta_hpp return get_function_with(name, {resolve_type()...}); } - inline function class_type::get_function_with(std::string_view name, std::vector args) const noexcept { + inline function class_type::get_function_with(std::string_view name, const std::vector& args) const noexcept { for ( auto&& [index, function] : data_->functions ) { if ( index.name != name ) { continue; @@ -323,7 +323,7 @@ namespace meta_hpp return get_method_with(name, {resolve_type()...}); } - inline method class_type::get_method_with(std::string_view name, std::vector args) const noexcept { + inline method class_type::get_method_with(std::string_view name, const std::vector& args) const noexcept { for ( auto&& [index, method] : data_->methods ) { if ( index.name != name ) { continue; diff --git a/untests/meta_utilities/arg_tests.cpp b/untests/meta_utilities/arg_tests.cpp index 1461179..a6f0ed1 100644 --- a/untests/meta_utilities/arg_tests.cpp +++ b/untests/meta_utilities/arg_tests.cpp @@ -86,14 +86,14 @@ namespace }\ } -TEST_CASE("features/meta_utilities/arg2") { +TEST_CASE("features/meta_utilities/arg") { namespace meta = meta_hpp; meta::class_() .base_(); } -TEST_CASE("features/meta_utilities/arg2/refs") { +TEST_CASE("features/meta_utilities/arg/refs") { namespace meta = meta_hpp; { @@ -241,7 +241,7 @@ TEST_CASE("features/meta_utilities/arg2/refs") { } } -TEST_CASE("features/meta_utilities/arg2/ptrs") { +TEST_CASE("features/meta_utilities/arg/ptrs") { namespace meta = meta_hpp; { @@ -625,7 +625,7 @@ TEST_CASE("features/meta_utilities/arg2/ptrs") { } } -TEST_CASE("features/meta_utilities/arg2/values") { +TEST_CASE("features/meta_utilities/arg/values") { namespace meta = meta_hpp; { @@ -767,7 +767,7 @@ TEST_CASE("features/meta_utilities/arg2/values") { } } -TEST_CASE("features/meta_utilities/arg2/ptr_values") { +TEST_CASE("features/meta_utilities/arg/ptr_values") { namespace meta = meta_hpp; { diff --git a/untests/meta_utilities/value_tests.cpp b/untests/meta_utilities/value_tests.cpp index 1444ba3..740bcac 100644 --- a/untests/meta_utilities/value_tests.cpp +++ b/untests/meta_utilities/value_tests.cpp @@ -51,6 +51,7 @@ namespace TEST_CASE("meta/meta_utilities/value") { namespace meta = meta_hpp; + using namespace std::string_literals; ivec2::move_ctor_counter = 0; ivec2::copy_ctor_counter = 0; @@ -197,16 +198,26 @@ TEST_CASE("meta/meta_utilities/value") { CHECK(val_src.data() != val_dst.data()); } + SUBCASE("value& operator=(T&&)") { + meta::value val{10}; + + val = 20; + CHECK(val == 20); + + val = "hello"s; + CHECK(val == "hello"s); + } + SUBCASE("value& operator=(value&&)") { - meta::value val_src1{std::string("world")}; + meta::value val_src1{"world"s}; meta::value val_src2{ivec2{1,2}}; CHECK(ivec2::move_ctor_counter == 1); CHECK(ivec2::copy_ctor_counter == 0); - meta::value val_dst{std::string("hello")}; + meta::value val_dst{"hello"s}; val_dst = std::move(val_src1); - CHECK(val_dst == std::string("world")); + CHECK(val_dst == "world"s); CHECK(ivec2::move_ctor_counter == 1); CHECK(ivec2::copy_ctor_counter == 0); @@ -220,15 +231,15 @@ TEST_CASE("meta/meta_utilities/value") { } SUBCASE("value& operator=(const meta::value&)") { - meta::value val_src1{std::string("world")}; + meta::value val_src1{"world"s}; meta::value val_src2{ivec2{1,2}}; CHECK(ivec2::move_ctor_counter == 1); CHECK(ivec2::copy_ctor_counter == 0); - meta::value val_dst{std::string("hello")}; + meta::value val_dst{"hello"s}; val_dst = val_src1; - CHECK(val_dst == std::string("world")); + CHECK(val_dst == "world"s); CHECK(ivec2::move_ctor_counter == 1); CHECK(ivec2::copy_ctor_counter == 0); @@ -242,19 +253,19 @@ TEST_CASE("meta/meta_utilities/value") { } SUBCASE("swap") { - meta::value val1{std::string("world")}; + meta::value val1{"world"s}; meta::value val2{ivec2{1,2}}; CHECK(ivec2::move_ctor_counter == 1); CHECK(ivec2::copy_ctor_counter == 0); val1.swap(val2); CHECK(val1 == ivec2{1,2}); - CHECK(val2 == std::string("world")); + CHECK(val2 == "world"s); CHECK((ivec2::move_ctor_counter == 2 || ivec2::move_ctor_counter == 3)); CHECK(ivec2::copy_ctor_counter == 0); swap(val1, val2); - CHECK(val1 == std::string("world")); + CHECK(val1 == "world"s); CHECK(val2 == ivec2{1,2}); } From 63f66baff9d5ff90c9c2ac3bc01ee731388211ea Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Mon, 3 Jan 2022 14:20:32 +0700 Subject: [PATCH 131/233] add enum_flags::is_scoped --- headers/meta.hpp/meta_traits.hpp | 1 + headers/meta.hpp/meta_traits/enum_traits.hpp | 6 +- untests/meta_types/enum_type_tests.cpp | 94 +++++++++++++++++++- 3 files changed, 97 insertions(+), 4 deletions(-) diff --git a/headers/meta.hpp/meta_traits.hpp b/headers/meta.hpp/meta_traits.hpp index 86bb82e..e960680 100644 --- a/headers/meta.hpp/meta_traits.hpp +++ b/headers/meta.hpp/meta_traits.hpp @@ -65,6 +65,7 @@ namespace meta_hpp }; enum class enum_flags : std::uint32_t { + is_scoped = 1 << 0, }; enum class function_flags : std::uint32_t { diff --git a/headers/meta.hpp/meta_traits/enum_traits.hpp b/headers/meta.hpp/meta_traits/enum_traits.hpp index ba77ce3..1d6112c 100644 --- a/headers/meta.hpp/meta_traits/enum_traits.hpp +++ b/headers/meta.hpp/meta_traits/enum_traits.hpp @@ -16,7 +16,11 @@ namespace meta_hpp::detail using underlying_type = std::underlying_type_t; static bitflags make_flags() noexcept { - return {}; + bitflags flags; + if constexpr ( !std::is_convertible_v ) { + flags.set(enum_flags::is_scoped); + } + return flags; } }; } diff --git a/untests/meta_types/enum_type_tests.cpp b/untests/meta_types/enum_type_tests.cpp index 76ec642..5561bb2 100644 --- a/untests/meta_types/enum_type_tests.cpp +++ b/untests/meta_types/enum_type_tests.cpp @@ -14,6 +14,13 @@ namespace blue = 0x0000FF, white = red | green | blue, }; + + enum ecolor : int { + ecolor_red = 0xFF0000, + ecolor_green = 0x00FF00, + ecolor_blue = 0x0000FF, + ecolor_white = ecolor_red | ecolor_green | ecolor_blue, + }; } TEST_CASE("meta/meta_types/enum_type") { @@ -25,27 +32,57 @@ TEST_CASE("meta/meta_types/enum_type") { .evalue_("blue", color::blue) .evalue_("white", color::white); + meta::enum_() + .evalue_("red", ecolor_red) + .evalue_("green", ecolor_green) + .evalue_("blue", ecolor_blue) + .evalue_("white", ecolor_white); + SUBCASE("color") { const meta::enum_type color_type = meta::resolve_type(); REQUIRE(color_type); CHECK(color_type.get_id() == meta::resolve_type(color{}).get_id()); + CHECK(color_type.get_flags() == meta::enum_flags::is_scoped); CHECK(color_type.get_underlying_type() == meta::resolve_type()); CHECK(color_type.get_evalues().size() == 4); } + SUBCASE("ecolor") { + const meta::enum_type ecolor_type = meta::resolve_type(); + REQUIRE(ecolor_type); + + CHECK(ecolor_type.get_id() == meta::resolve_type(ecolor{}).get_id()); + CHECK(ecolor_type.get_flags() == meta::enum_flags{}); + CHECK(ecolor_type.get_underlying_type() == meta::resolve_type()); + + CHECK(ecolor_type.get_evalues().size() == 4); + } + SUBCASE("const color") { const meta::enum_type color_type = meta::resolve_type(); REQUIRE(color_type); CHECK(color_type.get_id() == meta::resolve_type(color{}).get_id()); + CHECK(color_type.get_flags() == meta::enum_flags::is_scoped); CHECK(color_type.get_underlying_type() == meta::resolve_type()); CHECK(color_type.get_evalues().size() == 4); } - SUBCASE("get_evalue") { + SUBCASE("const ecolor") { + const meta::enum_type ecolor_type = meta::resolve_type(); + REQUIRE(ecolor_type); + + CHECK(ecolor_type.get_id() == meta::resolve_type(ecolor{}).get_id()); + CHECK(ecolor_type.get_flags() == meta::enum_flags{}); + CHECK(ecolor_type.get_underlying_type() == meta::resolve_type()); + + CHECK(ecolor_type.get_evalues().size() == 4); + } + + SUBCASE("color/get_evalue") { const meta::enum_type color_type = meta::resolve_type(); REQUIRE(color_type); @@ -61,7 +98,23 @@ TEST_CASE("meta/meta_types/enum_type") { } } - SUBCASE("value_to_name") { + SUBCASE("ecolor/get_evalue") { + const meta::enum_type ecolor_type = meta::resolve_type(); + REQUIRE(ecolor_type); + + { + const meta::evalue green_value = ecolor_type.get_evalue("green"); + REQUIRE(green_value); + CHECK(green_value.get_value() == ecolor_green); + } + + { + const meta::evalue yellow_value = ecolor_type.get_evalue("yellow"); + CHECK_FALSE(yellow_value); + } + } + + SUBCASE("color/value_to_name") { const meta::enum_type color_type = meta::resolve_type(); REQUIRE(color_type); @@ -82,7 +135,28 @@ TEST_CASE("meta/meta_types/enum_type") { } } - SUBCASE("name_to_value") { + SUBCASE("ecolor/value_to_name") { + const meta::enum_type ecolor_type = meta::resolve_type(); + REQUIRE(ecolor_type); + + { + REQUIRE(ecolor_type.value_to_name(ecolor_red)); + CHECK(ecolor_type.value_to_name(ecolor_red) == "red"); + } + + { + + REQUIRE(ecolor_type.value_to_name(meta::value{ecolor_blue})); + CHECK(ecolor_type.value_to_name(ecolor_blue) == "blue"); + } + + { + REQUIRE_FALSE(ecolor_type.value_to_name(100500)); + REQUIRE_FALSE(ecolor_type.value_to_name(ecolor{100500})); + } + } + + SUBCASE("color/name_to_value") { const meta::enum_type color_type = meta::resolve_type(); REQUIRE(color_type); @@ -95,4 +169,18 @@ TEST_CASE("meta/meta_types/enum_type") { REQUIRE_FALSE(color_type.name_to_value("yellow")); } } + + SUBCASE("ecolor/name_to_value") { + const meta::enum_type ecolor_type = meta::resolve_type(); + REQUIRE(ecolor_type); + + { + REQUIRE(ecolor_type.name_to_value("blue")); + CHECK(ecolor_type.name_to_value("blue") == ecolor_blue); + } + + { + REQUIRE_FALSE(ecolor_type.name_to_value("yellow")); + } + } } From ab1f78124e8abc84ae5a59a6340012c88d3fad20 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Mon, 3 Jan 2022 14:29:29 +0700 Subject: [PATCH 132/233] fix traits code style --- headers/meta.hpp/meta_traits/array_traits.hpp | 11 ++++++++-- headers/meta.hpp/meta_traits/class_traits.hpp | 21 +++++++++++++++---- headers/meta.hpp/meta_traits/ctor_traits.hpp | 6 +++++- headers/meta.hpp/meta_traits/enum_traits.hpp | 2 ++ .../meta.hpp/meta_traits/number_traits.hpp | 21 +++++++++++++++---- .../meta.hpp/meta_traits/pointer_traits.hpp | 6 +++++- .../meta.hpp/meta_traits/reference_traits.hpp | 16 +++++++++++--- 7 files changed, 68 insertions(+), 15 deletions(-) diff --git a/headers/meta.hpp/meta_traits/array_traits.hpp b/headers/meta.hpp/meta_traits/array_traits.hpp index e979661..b6c5144 100644 --- a/headers/meta.hpp/meta_traits/array_traits.hpp +++ b/headers/meta.hpp/meta_traits/array_traits.hpp @@ -19,8 +19,15 @@ namespace meta_hpp::detail static bitflags make_flags() noexcept { bitflags flags; - if ( std::is_bounded_array_v ) flags.set(array_flags::is_bounded); - if ( std::is_unbounded_array_v ) flags.set(array_flags::is_unbounded); + + if ( std::is_bounded_array_v ) { + flags.set(array_flags::is_bounded); + } + + if ( std::is_unbounded_array_v ) { + flags.set(array_flags::is_unbounded); + } + return flags; } }; diff --git a/headers/meta.hpp/meta_traits/class_traits.hpp b/headers/meta.hpp/meta_traits/class_traits.hpp index 9b06334..7e0e0ba 100644 --- a/headers/meta.hpp/meta_traits/class_traits.hpp +++ b/headers/meta.hpp/meta_traits/class_traits.hpp @@ -50,10 +50,23 @@ namespace meta_hpp::detail static bitflags make_flags() noexcept { bitflags flags; - if constexpr ( std::is_empty_v ) flags.set(class_flags::is_empty); - if constexpr ( std::is_final_v ) flags.set(class_flags::is_final); - if constexpr ( std::is_abstract_v ) flags.set(class_flags::is_abstract); - if constexpr ( std::is_polymorphic_v ) flags.set(class_flags::is_polymorphic); + + if constexpr ( std::is_empty_v ) { + flags.set(class_flags::is_empty); + } + + if constexpr ( std::is_final_v ) { + flags.set(class_flags::is_final); + } + + if constexpr ( std::is_abstract_v ) { + flags.set(class_flags::is_abstract); + } + + if constexpr ( std::is_polymorphic_v ) { + flags.set(class_flags::is_polymorphic); + } + return flags | impl::class_traits_base::make_flags(); } }; diff --git a/headers/meta.hpp/meta_traits/ctor_traits.hpp b/headers/meta.hpp/meta_traits/ctor_traits.hpp index 745f1e0..ba88573 100644 --- a/headers/meta.hpp/meta_traits/ctor_traits.hpp +++ b/headers/meta.hpp/meta_traits/ctor_traits.hpp @@ -20,7 +20,11 @@ namespace meta_hpp::detail static bitflags make_flags() noexcept { bitflags flags; - if constexpr ( std::is_nothrow_constructible_v ) flags.set(ctor_flags::is_noexcept); + + if constexpr ( std::is_nothrow_constructible_v ) { + flags.set(ctor_flags::is_noexcept); + } + return flags; } diff --git a/headers/meta.hpp/meta_traits/enum_traits.hpp b/headers/meta.hpp/meta_traits/enum_traits.hpp index 1d6112c..babcb68 100644 --- a/headers/meta.hpp/meta_traits/enum_traits.hpp +++ b/headers/meta.hpp/meta_traits/enum_traits.hpp @@ -17,9 +17,11 @@ namespace meta_hpp::detail static bitflags make_flags() noexcept { bitflags flags; + if constexpr ( !std::is_convertible_v ) { flags.set(enum_flags::is_scoped); } + return flags; } }; diff --git a/headers/meta.hpp/meta_traits/number_traits.hpp b/headers/meta.hpp/meta_traits/number_traits.hpp index eb69abc..35f3e91 100644 --- a/headers/meta.hpp/meta_traits/number_traits.hpp +++ b/headers/meta.hpp/meta_traits/number_traits.hpp @@ -17,10 +17,23 @@ namespace meta_hpp::detail static bitflags make_flags() noexcept { bitflags flags; - if ( std::is_signed_v ) flags.set(number_flags::is_signed); - if ( std::is_unsigned_v ) flags.set(number_flags::is_unsigned); - if ( std::is_integral_v ) flags.set(number_flags::is_integral); - if ( std::is_floating_point_v ) flags.set(number_flags::is_floating_point); + + if ( std::is_signed_v ) { + flags.set(number_flags::is_signed); + } + + if ( std::is_unsigned_v ) { + flags.set(number_flags::is_unsigned); + } + + if ( std::is_integral_v ) { + flags.set(number_flags::is_integral); + } + + if ( std::is_floating_point_v ) { + flags.set(number_flags::is_floating_point); + } + return flags; } }; diff --git a/headers/meta.hpp/meta_traits/pointer_traits.hpp b/headers/meta.hpp/meta_traits/pointer_traits.hpp index 5b66ea3..74c1cf5 100644 --- a/headers/meta.hpp/meta_traits/pointer_traits.hpp +++ b/headers/meta.hpp/meta_traits/pointer_traits.hpp @@ -17,7 +17,11 @@ namespace meta_hpp::detail static bitflags make_flags() noexcept { bitflags flags; - if constexpr ( std::is_const_v ) flags.set(pointer_flags::is_readonly); + + if constexpr ( std::is_const_v ) { + flags.set(pointer_flags::is_readonly); + } + return flags; } }; diff --git a/headers/meta.hpp/meta_traits/reference_traits.hpp b/headers/meta.hpp/meta_traits/reference_traits.hpp index 4eef018..ca395d2 100644 --- a/headers/meta.hpp/meta_traits/reference_traits.hpp +++ b/headers/meta.hpp/meta_traits/reference_traits.hpp @@ -17,9 +17,19 @@ namespace meta_hpp::detail static bitflags make_flags() noexcept { bitflags flags; - if constexpr ( std::is_const_v ) flags.set(reference_flags::is_readonly); - if constexpr ( std::is_lvalue_reference_v ) flags.set(reference_flags::is_lvalue); - if constexpr ( std::is_rvalue_reference_v ) flags.set(reference_flags::is_rvalue); + + if constexpr ( std::is_const_v ) { + flags.set(reference_flags::is_readonly); + } + + if constexpr ( std::is_lvalue_reference_v ) { + flags.set(reference_flags::is_lvalue); + } + + if constexpr ( std::is_rvalue_reference_v ) { + flags.set(reference_flags::is_rvalue); + } + return flags; } }; From ee518b4da21cface664c55c29698eb4810407b34 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Mon, 3 Jan 2022 15:20:08 +0700 Subject: [PATCH 133/233] requires instead static_assert for registry binds --- .clang-tidy | 18 +++++++++++++++++ CMakeLists.txt | 2 ++ headers/meta.hpp/meta_registry.hpp | 18 ++++++++++------- headers/meta.hpp/meta_registry/class_bind.hpp | 20 +++++++++++-------- headers/meta.hpp/meta_registry/scope_bind.hpp | 6 ++++-- 5 files changed, 47 insertions(+), 17 deletions(-) create mode 100644 .clang-tidy diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 0000000..e0619a2 --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,18 @@ +Checks: '-*, + + clang-analyzer-*, + + concurrency-*, + + cppcoreguidelines-*, + + modernize-*, + -modernize-use-trailing-return-type, + + performance-*, + + portability-*, + + readability-*, + -readability-use-anyofallof, + ' diff --git a/CMakeLists.txt b/CMakeLists.txt index d4d87f3..9cf65da 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,8 +29,10 @@ target_compile_options(${PROJECT_NAME} -Wno-c++98-compat-pedantic -Wno-ctad-maybe-unsupported -Wno-exit-time-destructors + -Wno-extra-semi-stmt -Wno-float-equal -Wno-padded + -Wno-reserved-identifier -Wno-shadow-field -Wno-shadow-field-in-constructor -Wno-unknown-warning-option diff --git a/headers/meta.hpp/meta_registry.hpp b/headers/meta.hpp/meta_registry.hpp index d09fcf2..fbc89c9 100644 --- a/headers/meta.hpp/meta_registry.hpp +++ b/headers/meta.hpp/meta_registry.hpp @@ -18,19 +18,23 @@ namespace meta_hpp operator class_type() const noexcept; template < typename... Args > - class_bind& ctor_(); + class_bind& ctor_() + requires std::is_constructible_v; template < detail::class_kind Base > - class_bind& base_(); + class_bind& base_() + requires std::is_base_of_v; template < detail::function_kind Function > class_bind& function_(std::string name, Function function); template < detail::member_kind Member > - class_bind& member_(std::string name, Member member); + class_bind& member_(std::string name, Member member) + requires std::same_as::class_type>; template < detail::method_kind Method > - class_bind& method_(std::string name, Method method); + class_bind& method_(std::string name, Method method) + requires std::same_as::class_type>; template < detail::pointer_kind Pointer > class_bind& variable_(std::string name, Pointer pointer); @@ -60,7 +64,7 @@ namespace meta_hpp struct local_tag {}; struct static_tag {}; - explicit scope_bind(std::string_view name, local_tag); + explicit scope_bind(std::string name, local_tag); explicit scope_bind(std::string_view name, static_tag); operator scope() const noexcept; @@ -96,7 +100,7 @@ namespace meta_hpp return scope_bind{std::move(name), scope_bind::local_tag()}; } - inline scope_bind static_scope_(std::string name) { - return scope_bind{std::move(name), scope_bind::static_tag()}; + inline scope_bind static_scope_(std::string_view name) { + return scope_bind{name, scope_bind::static_tag()}; } } diff --git a/headers/meta.hpp/meta_registry/class_bind.hpp b/headers/meta.hpp/meta_registry/class_bind.hpp index 952562f..6682cc5 100644 --- a/headers/meta.hpp/meta_registry/class_bind.hpp +++ b/headers/meta.hpp/meta_registry/class_bind.hpp @@ -22,8 +22,9 @@ namespace meta_hpp template < detail::class_kind Class > template < typename... Args > - class_bind& class_bind::ctor_() { - static_assert(std::is_constructible_v); + class_bind& class_bind::ctor_() + requires std::is_constructible_v + { auto ctor_state = detail::ctor_state::make(); data_->ctors.emplace(ctor_state->index, std::move(ctor_state)); return *this; @@ -31,8 +32,9 @@ namespace meta_hpp template < detail::class_kind Class > template < detail::class_kind Base > - class_bind& class_bind::base_() { - static_assert(std::is_base_of_v); + class_bind& class_bind::base_() + requires std::is_base_of_v + { data_->bases.emplace(resolve_type()); return *this; } @@ -47,8 +49,9 @@ namespace meta_hpp template < detail::class_kind Class > template < detail::member_kind Member > - class_bind& class_bind::member_(std::string name, Member member) { - static_assert(std::same_as::class_type>); + class_bind& class_bind::member_(std::string name, Member member) + requires std::same_as::class_type> + { 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; @@ -56,8 +59,9 @@ namespace meta_hpp template < detail::class_kind Class > template < detail::method_kind Method > - class_bind& class_bind::method_(std::string name, Method method) { - static_assert(std::same_as::class_type>); + class_bind& class_bind::method_(std::string name, Method method) + requires std::same_as::class_type> + { 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; diff --git a/headers/meta.hpp/meta_registry/scope_bind.hpp b/headers/meta.hpp/meta_registry/scope_bind.hpp index 32cfe84..453a19a 100644 --- a/headers/meta.hpp/meta_registry/scope_bind.hpp +++ b/headers/meta.hpp/meta_registry/scope_bind.hpp @@ -11,9 +11,11 @@ namespace meta_hpp { - inline scope_bind::scope_bind(std::string_view name, local_tag) - : state_{detail::scope_state::make(std::string{name})} {} + // NOLINTNEXTLINE(readability-named-parameter) + inline scope_bind::scope_bind(std::string name, local_tag) + : state_{detail::scope_state::make(std::move(name))} {} + // NOLINTNEXTLINE(readability-named-parameter) inline scope_bind::scope_bind(std::string_view name, static_tag) : state_{detail::scope_state::get_static(name)} {} From a7e7b31ce542841b874cd3b8c44a67b649a3813e Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Mon, 3 Jan 2022 18:39:16 +0700 Subject: [PATCH 134/233] fix some clang-tidy traits and types warnings --- .clang-tidy | 1 + headers/meta.hpp/meta_registry.hpp | 12 +- headers/meta.hpp/meta_registry/class_bind.hpp | 20 +- headers/meta.hpp/meta_traits.hpp | 2 +- headers/meta.hpp/meta_traits/array_traits.hpp | 6 +- headers/meta.hpp/meta_traits/class_traits.hpp | 32 +- headers/meta.hpp/meta_traits/ctor_traits.hpp | 4 +- headers/meta.hpp/meta_traits/enum_traits.hpp | 2 +- .../meta.hpp/meta_traits/function_traits.hpp | 6 +- .../meta.hpp/meta_traits/member_traits.hpp | 2 +- .../meta.hpp/meta_traits/method_traits.hpp | 37 ++- .../meta.hpp/meta_traits/number_traits.hpp | 10 +- .../meta.hpp/meta_traits/pointer_traits.hpp | 2 +- .../meta.hpp/meta_traits/reference_traits.hpp | 2 +- headers/meta.hpp/meta_traits/void_traits.hpp | 2 +- headers/meta.hpp/meta_types.hpp | 308 +++++++++--------- headers/meta.hpp/meta_types/array_type.hpp | 1 + headers/meta.hpp/meta_types/class_type.hpp | 7 + headers/meta.hpp/meta_types/ctor_type.hpp | 1 + headers/meta.hpp/meta_types/enum_type.hpp | 3 + headers/meta.hpp/meta_types/function_type.hpp | 1 + headers/meta.hpp/meta_types/member_type.hpp | 1 + headers/meta.hpp/meta_types/method_type.hpp | 1 + headers/meta.hpp/meta_types/number_type.hpp | 1 + headers/meta.hpp/meta_types/pointer_type.hpp | 1 + .../meta.hpp/meta_types/reference_type.hpp | 1 + headers/meta.hpp/meta_types/void_type.hpp | 1 + headers/meta.hpp/meta_utilities.hpp | 23 ++ 28 files changed, 270 insertions(+), 220 deletions(-) diff --git a/.clang-tidy b/.clang-tidy index e0619a2..a094b38 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -14,5 +14,6 @@ Checks: '-*, portability-*, readability-*, + -readability-redundant-access-specifiers, -readability-use-anyofallof, ' diff --git a/headers/meta.hpp/meta_registry.hpp b/headers/meta.hpp/meta_registry.hpp index fbc89c9..a5b8448 100644 --- a/headers/meta.hpp/meta_registry.hpp +++ b/headers/meta.hpp/meta_registry.hpp @@ -18,23 +18,19 @@ namespace meta_hpp operator class_type() const noexcept; template < typename... Args > - class_bind& ctor_() - requires std::is_constructible_v; + class_bind& ctor_(); template < detail::class_kind Base > - class_bind& base_() - requires std::is_base_of_v; + class_bind& base_(); template < detail::function_kind Function > class_bind& function_(std::string name, Function function); template < detail::member_kind Member > - class_bind& member_(std::string name, Member member) - requires std::same_as::class_type>; + class_bind& member_(std::string name, Member member); template < detail::method_kind Method > - class_bind& method_(std::string name, Method method) - requires std::same_as::class_type>; + class_bind& method_(std::string name, Method method); template < detail::pointer_kind Pointer > class_bind& variable_(std::string name, Pointer pointer); diff --git a/headers/meta.hpp/meta_registry/class_bind.hpp b/headers/meta.hpp/meta_registry/class_bind.hpp index 6682cc5..09fcd10 100644 --- a/headers/meta.hpp/meta_registry/class_bind.hpp +++ b/headers/meta.hpp/meta_registry/class_bind.hpp @@ -22,9 +22,8 @@ namespace meta_hpp template < detail::class_kind Class > template < typename... Args > - class_bind& class_bind::ctor_() - requires std::is_constructible_v - { + class_bind& class_bind::ctor_() { + static_assert(detail::constructible_from); auto ctor_state = detail::ctor_state::make(); data_->ctors.emplace(ctor_state->index, std::move(ctor_state)); return *this; @@ -32,9 +31,8 @@ namespace meta_hpp template < detail::class_kind Class > template < detail::class_kind Base > - class_bind& class_bind::base_() - requires std::is_base_of_v - { + class_bind& class_bind::base_() { + static_assert(detail::derived_from); data_->bases.emplace(resolve_type()); return *this; } @@ -49,9 +47,8 @@ namespace meta_hpp template < detail::class_kind Class > template < detail::member_kind Member > - class_bind& class_bind::member_(std::string name, Member member) - requires std::same_as::class_type> - { + class_bind& class_bind::member_(std::string name, Member member) { + static_assert(std::same_as::class_type>); 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; @@ -59,9 +56,8 @@ namespace meta_hpp template < detail::class_kind Class > template < detail::method_kind Method > - class_bind& class_bind::method_(std::string name, Method method) - requires std::same_as::class_type> - { + class_bind& class_bind::method_(std::string name, Method method) { + static_assert(std::same_as::class_type>); 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; diff --git a/headers/meta.hpp/meta_traits.hpp b/headers/meta.hpp/meta_traits.hpp index e960680..7e3888f 100644 --- a/headers/meta.hpp/meta_traits.hpp +++ b/headers/meta.hpp/meta_traits.hpp @@ -14,7 +14,7 @@ namespace meta_hpp::detail template < array_kind Array > struct array_traits; - template < class_kind T > + template < class_kind Class > struct class_traits; template < class_kind Class, typename... Args > diff --git a/headers/meta.hpp/meta_traits/array_traits.hpp b/headers/meta.hpp/meta_traits/array_traits.hpp index b6c5144..ce73e58 100644 --- a/headers/meta.hpp/meta_traits/array_traits.hpp +++ b/headers/meta.hpp/meta_traits/array_traits.hpp @@ -17,14 +17,14 @@ namespace meta_hpp::detail using data_type = std::remove_extent_t; - static bitflags make_flags() noexcept { + [[nodiscard]] static constexpr bitflags make_flags() noexcept { bitflags flags; - if ( std::is_bounded_array_v ) { + if constexpr ( std::is_bounded_array_v ) { flags.set(array_flags::is_bounded); } - if ( std::is_unbounded_array_v ) { + if constexpr ( std::is_unbounded_array_v ) { flags.set(array_flags::is_unbounded); } diff --git a/headers/meta.hpp/meta_traits/class_traits.hpp b/headers/meta.hpp/meta_traits/class_traits.hpp index 7e0e0ba..e95665b 100644 --- a/headers/meta.hpp/meta_traits/class_traits.hpp +++ b/headers/meta.hpp/meta_traits/class_traits.hpp @@ -13,61 +13,61 @@ namespace meta_hpp::detail { namespace impl { - template < class_kind T > + template < class_kind Class > struct class_traits_base { static constexpr std::size_t arity{0}; using argument_types = type_list<>; - static bitflags make_flags() noexcept { + [[nodiscard]] static constexpr bitflags make_flags() noexcept { return {}; } - static std::vector make_argument_types() { + [[nodiscard]] static std::vector make_argument_types() { return {}; } }; - template < template < typename... > typename T, typename... Args > - struct class_traits_base> { + template < template < typename... > typename Class, typename... Args > + struct class_traits_base> { static constexpr std::size_t arity{sizeof...(Args)}; using argument_types = type_list; - static bitflags make_flags() noexcept { + [[nodiscard]] static constexpr bitflags make_flags() noexcept { return class_flags::is_template_instantiation; } - static std::vector make_argument_types() { + [[nodiscard]] static std::vector make_argument_types() { return { resolve_type()... }; } }; } - template < class_kind T > - struct class_traits : impl::class_traits_base { - static constexpr std::size_t size{sizeof(T)}; + template < class_kind Class > + struct class_traits : impl::class_traits_base { + static constexpr std::size_t size{sizeof(Class)}; - static bitflags make_flags() noexcept { + [[nodiscard]] static constexpr bitflags make_flags() noexcept { bitflags flags; - if constexpr ( std::is_empty_v ) { + if constexpr ( std::is_empty_v ) { flags.set(class_flags::is_empty); } - if constexpr ( std::is_final_v ) { + if constexpr ( std::is_final_v ) { flags.set(class_flags::is_final); } - if constexpr ( std::is_abstract_v ) { + if constexpr ( std::is_abstract_v ) { flags.set(class_flags::is_abstract); } - if constexpr ( std::is_polymorphic_v ) { + if constexpr ( std::is_polymorphic_v ) { flags.set(class_flags::is_polymorphic); } - return flags | impl::class_traits_base::make_flags(); + return flags | impl::class_traits_base::make_flags(); } }; } diff --git a/headers/meta.hpp/meta_traits/ctor_traits.hpp b/headers/meta.hpp/meta_traits/ctor_traits.hpp index ba88573..e80e899 100644 --- a/headers/meta.hpp/meta_traits/ctor_traits.hpp +++ b/headers/meta.hpp/meta_traits/ctor_traits.hpp @@ -18,7 +18,7 @@ namespace meta_hpp::detail using class_type = Class; using argument_types = type_list; - static bitflags make_flags() noexcept { + [[nodiscard]] static constexpr bitflags make_flags() noexcept { bitflags flags; if constexpr ( std::is_nothrow_constructible_v ) { @@ -28,7 +28,7 @@ namespace meta_hpp::detail return flags; } - static std::vector make_argument_types() { + [[nodiscard]] static std::vector make_argument_types() { return { resolve_type()... }; } }; diff --git a/headers/meta.hpp/meta_traits/enum_traits.hpp b/headers/meta.hpp/meta_traits/enum_traits.hpp index babcb68..45265a6 100644 --- a/headers/meta.hpp/meta_traits/enum_traits.hpp +++ b/headers/meta.hpp/meta_traits/enum_traits.hpp @@ -15,7 +15,7 @@ namespace meta_hpp::detail struct enum_traits { using underlying_type = std::underlying_type_t; - static bitflags make_flags() noexcept { + [[nodiscard]] static constexpr bitflags make_flags() noexcept { bitflags flags; if constexpr ( !std::is_convertible_v ) { diff --git a/headers/meta.hpp/meta_traits/function_traits.hpp b/headers/meta.hpp/meta_traits/function_traits.hpp index 709e6a7..0046345 100644 --- a/headers/meta.hpp/meta_traits/function_traits.hpp +++ b/headers/meta.hpp/meta_traits/function_traits.hpp @@ -21,18 +21,18 @@ namespace meta_hpp::detail using return_type = R; using argument_types = type_list; - static bitflags make_flags() noexcept { + [[nodiscard]] static constexpr bitflags make_flags() noexcept { return {}; } - static std::vector make_argument_types() { + [[nodiscard]] static std::vector make_argument_types() { return { resolve_type()... }; } }; template < typename R, typename... Args > struct function_traits : function_traits { - static bitflags make_flags() noexcept { + [[nodiscard]] static constexpr bitflags make_flags() noexcept { return function_flags::is_noexcept; } }; diff --git a/headers/meta.hpp/meta_traits/member_traits.hpp b/headers/meta.hpp/meta_traits/member_traits.hpp index 0500082..78cee42 100644 --- a/headers/meta.hpp/meta_traits/member_traits.hpp +++ b/headers/meta.hpp/meta_traits/member_traits.hpp @@ -19,7 +19,7 @@ namespace meta_hpp::detail using class_type = C; using value_type = V; - static bitflags make_flags() noexcept { + [[nodiscard]] static constexpr bitflags make_flags() noexcept { return {}; } }; diff --git a/headers/meta.hpp/meta_traits/method_traits.hpp b/headers/meta.hpp/meta_traits/method_traits.hpp index e75ddf4..c82eea8 100644 --- a/headers/meta.hpp/meta_traits/method_traits.hpp +++ b/headers/meta.hpp/meta_traits/method_traits.hpp @@ -23,11 +23,11 @@ namespace meta_hpp::detail using qualified_type = C; using argument_types = type_list; - static bitflags make_flags() noexcept { + [[nodiscard]] static constexpr bitflags make_flags() noexcept { return {}; } - static std::vector make_argument_types() { + [[nodiscard]] static std::vector make_argument_types() { return { resolve_type()... }; } }; @@ -35,7 +35,8 @@ namespace meta_hpp::detail template < typename R, typename C, typename... Args > struct method_traits : method_traits { using qualified_type = const C; - static bitflags make_flags() noexcept { + + [[nodiscard]] static constexpr bitflags make_flags() noexcept { return method_flags::is_const; } }; @@ -43,7 +44,8 @@ namespace meta_hpp::detail template < typename R, typename C, typename... Args > struct method_traits : method_traits { using qualified_type = C; - static bitflags make_flags() noexcept { + + [[nodiscard]] static constexpr bitflags make_flags() noexcept { return method_flags::is_noexcept; } }; @@ -51,7 +53,8 @@ namespace meta_hpp::detail template < typename R, typename C, typename... Args > struct method_traits : method_traits { using qualified_type = const C; - static bitflags make_flags() noexcept { + + [[nodiscard]] static constexpr bitflags make_flags() noexcept { return method_flags::is_const | method_flags::is_noexcept; } }; @@ -59,7 +62,8 @@ namespace meta_hpp::detail template < typename R, typename C, typename... Args > struct method_traits : method_traits { using qualified_type = C&; - static bitflags make_flags() noexcept { + + [[nodiscard]] static constexpr bitflags make_flags() noexcept { return method_flags::is_lvalue_qualified; } }; @@ -67,7 +71,8 @@ namespace meta_hpp::detail template < typename R, typename C, typename... Args > struct method_traits : method_traits { using qualified_type = C&; - static bitflags make_flags() noexcept { + + [[nodiscard]] static constexpr bitflags make_flags() noexcept { return method_flags::is_noexcept | method_flags::is_lvalue_qualified; } }; @@ -75,7 +80,8 @@ namespace meta_hpp::detail template < typename R, typename C, typename... Args > struct method_traits : method_traits { using qualified_type = const C&; - static bitflags make_flags() noexcept { + + [[nodiscard]] static constexpr bitflags make_flags() noexcept { return method_flags::is_const | method_flags::is_lvalue_qualified; } }; @@ -83,7 +89,8 @@ namespace meta_hpp::detail template < typename R, typename C, typename... Args > struct method_traits : method_traits { using qualified_type = const C&; - static bitflags make_flags() noexcept { + + [[nodiscard]] static constexpr bitflags make_flags() noexcept { return method_flags::is_const | method_flags::is_noexcept | method_flags::is_lvalue_qualified; } }; @@ -91,7 +98,8 @@ namespace meta_hpp::detail template < typename R, typename C, typename... Args > struct method_traits : method_traits { using qualified_type = C&&; - static bitflags make_flags() noexcept { + + [[nodiscard]] static constexpr bitflags make_flags() noexcept { return method_flags::is_rvalue_qualified; } }; @@ -99,7 +107,8 @@ namespace meta_hpp::detail template < typename R, typename C, typename... Args > struct method_traits : method_traits { using qualified_type = C&&; - static bitflags make_flags() noexcept { + + [[nodiscard]] static constexpr bitflags make_flags() noexcept { return method_flags::is_noexcept | method_flags::is_rvalue_qualified; } }; @@ -107,7 +116,8 @@ namespace meta_hpp::detail template < typename R, typename C, typename... Args > struct method_traits : method_traits { using qualified_type = const C&&; - static bitflags make_flags() noexcept { + + [[nodiscard]] static constexpr bitflags make_flags() noexcept { return method_flags::is_const | method_flags::is_rvalue_qualified; } }; @@ -115,7 +125,8 @@ namespace meta_hpp::detail template < typename R, typename C, typename... Args > struct method_traits : method_traits { using qualified_type = const C&&; - static bitflags make_flags() noexcept { + + [[nodiscard]] static constexpr bitflags make_flags() noexcept { return method_flags::is_const | method_flags::is_noexcept | method_flags::is_rvalue_qualified; } }; diff --git a/headers/meta.hpp/meta_traits/number_traits.hpp b/headers/meta.hpp/meta_traits/number_traits.hpp index 35f3e91..d6ec6df 100644 --- a/headers/meta.hpp/meta_traits/number_traits.hpp +++ b/headers/meta.hpp/meta_traits/number_traits.hpp @@ -15,22 +15,22 @@ namespace meta_hpp::detail struct number_traits { static constexpr std::size_t size{sizeof(Number)}; - static bitflags make_flags() noexcept { + [[nodiscard]] static constexpr bitflags make_flags() noexcept { bitflags flags; - if ( std::is_signed_v ) { + if constexpr ( std::is_signed_v ) { flags.set(number_flags::is_signed); } - if ( std::is_unsigned_v ) { + if constexpr ( std::is_unsigned_v ) { flags.set(number_flags::is_unsigned); } - if ( std::is_integral_v ) { + if constexpr ( std::is_integral_v ) { flags.set(number_flags::is_integral); } - if ( std::is_floating_point_v ) { + if constexpr ( std::is_floating_point_v ) { flags.set(number_flags::is_floating_point); } diff --git a/headers/meta.hpp/meta_traits/pointer_traits.hpp b/headers/meta.hpp/meta_traits/pointer_traits.hpp index 74c1cf5..f33682e 100644 --- a/headers/meta.hpp/meta_traits/pointer_traits.hpp +++ b/headers/meta.hpp/meta_traits/pointer_traits.hpp @@ -15,7 +15,7 @@ namespace meta_hpp::detail struct pointer_traits { using data_type = std::remove_pointer_t; - static bitflags make_flags() noexcept { + [[nodiscard]] static constexpr bitflags make_flags() noexcept { bitflags flags; if constexpr ( std::is_const_v ) { diff --git a/headers/meta.hpp/meta_traits/reference_traits.hpp b/headers/meta.hpp/meta_traits/reference_traits.hpp index ca395d2..ce04482 100644 --- a/headers/meta.hpp/meta_traits/reference_traits.hpp +++ b/headers/meta.hpp/meta_traits/reference_traits.hpp @@ -15,7 +15,7 @@ namespace meta_hpp::detail struct reference_traits { using data_type = std::remove_reference_t; - static bitflags make_flags() noexcept { + [[nodiscard]] static constexpr bitflags make_flags() noexcept { bitflags flags; if constexpr ( std::is_const_v ) { diff --git a/headers/meta.hpp/meta_traits/void_traits.hpp b/headers/meta.hpp/meta_traits/void_traits.hpp index f3ced24..f1e4f4f 100644 --- a/headers/meta.hpp/meta_traits/void_traits.hpp +++ b/headers/meta.hpp/meta_traits/void_traits.hpp @@ -13,7 +13,7 @@ namespace meta_hpp::detail { template < void_kind Void > struct void_traits { - static bitflags make_flags() noexcept { + [[nodiscard]] static constexpr bitflags make_flags() noexcept { return {}; } }; diff --git a/headers/meta.hpp/meta_types.hpp b/headers/meta.hpp/meta_types.hpp index aacb439..a43bd37 100644 --- a/headers/meta.hpp/meta_types.hpp +++ b/headers/meta.hpp/meta_types.hpp @@ -14,41 +14,44 @@ namespace meta_hpp class type_id final { public: template < typename T > + // NOLINTNEXTLINE(readability-named-parameter) explicit type_id(detail::type_list) noexcept : id_{type_to_id()} {} type_id(type_id&&) = default; - type_id& operator=(type_id&&) = default; - type_id(const type_id&) = default; + + type_id& operator=(type_id&&) = default; type_id& operator=(const type_id&) = default; - std::size_t get_hash() const noexcept { + ~type_id() = default; + + [[nodiscard]] std::size_t get_hash() const noexcept { return std::hash{}(id_); } - friend bool operator<(type_id l, type_id r) noexcept { + [[nodiscard]] friend bool operator<(type_id l, type_id r) noexcept { return l.id_ < r.id_; } - friend bool operator==(type_id l, type_id r) noexcept { + [[nodiscard]] friend bool operator==(type_id l, type_id r) noexcept { return l.id_ == r.id_; } - friend bool operator!=(type_id l, type_id r) noexcept { + [[nodiscard]] friend bool operator!=(type_id l, type_id r) noexcept { return l.id_ != r.id_; } private: using underlying_type = std::uint32_t; underlying_type id_{}; private: - static underlying_type next() noexcept { + [[nodiscard]] static underlying_type next() noexcept { static std::atomic id{}; return ++id; } template < typename T > - static underlying_type type_to_id() noexcept { + [[nodiscard]] static underlying_type type_to_id() noexcept { static const underlying_type id{next()}; return id; } @@ -75,13 +78,13 @@ namespace meta_hpp std::same_as; template < type_family T > - auto data_access(const T& type) { + [[nodiscard]] auto data_access(const T& type) { return type.data_; } } template < detail::type_family T, detail::type_family U > - bool operator<(const T& l, const U& r) noexcept { + [[nodiscard]] bool operator<(const T& l, const U& r) noexcept { if ( !static_cast(r) ) { return false; } @@ -94,7 +97,7 @@ namespace meta_hpp } template < detail::type_family T, detail::type_family U > - bool operator==(const T& l, const U& r) noexcept { + [[nodiscard]] bool operator==(const T& l, const U& r) noexcept { if ( static_cast(l) != static_cast(r) ) { return false; } @@ -107,7 +110,7 @@ namespace meta_hpp } template < detail::type_family T, detail::type_family U > - bool operator!=(const T& l, const U& r) noexcept { + [[nodiscard]] bool operator!=(const T& l, const U& r) noexcept { return !(l == r); } } @@ -119,11 +122,11 @@ namespace meta_hpp explicit any_type() = default; explicit any_type(detail::type_data_base_ptr data); - bool is_valid() const noexcept; - explicit operator bool() const noexcept; + [[nodiscard]] bool is_valid() const noexcept; + [[nodiscard]] explicit operator bool() const noexcept; - type_id get_id() const noexcept; - type_kind get_kind() const noexcept; + [[nodiscard]] type_id get_id() const noexcept; + [[nodiscard]] type_kind get_kind() const noexcept; any_type(const array_type& other) noexcept; any_type(const class_type& other) noexcept; @@ -137,29 +140,29 @@ namespace meta_hpp any_type(const reference_type& other) noexcept; any_type(const void_type& other) noexcept; - bool is_array() const noexcept; - bool is_class() const noexcept; - bool is_ctor() const noexcept; - bool is_enum() const noexcept; - bool is_function() const noexcept; - bool is_member() const noexcept; - bool is_method() const noexcept; - bool is_number() const noexcept; - bool is_pointer() const noexcept; - bool is_reference() const noexcept; - bool is_void() const noexcept; + [[nodiscard]] bool is_array() const noexcept; + [[nodiscard]] bool is_class() const noexcept; + [[nodiscard]] bool is_ctor() const noexcept; + [[nodiscard]] bool is_enum() const noexcept; + [[nodiscard]] bool is_function() const noexcept; + [[nodiscard]] bool is_member() const noexcept; + [[nodiscard]] bool is_method() const noexcept; + [[nodiscard]] bool is_number() const noexcept; + [[nodiscard]] bool is_pointer() const noexcept; + [[nodiscard]] bool is_reference() const noexcept; + [[nodiscard]] bool is_void() const noexcept; - array_type as_array() const noexcept; - class_type as_class() const noexcept; - ctor_type as_ctor() const noexcept; - enum_type as_enum() const noexcept; - function_type as_function() const noexcept; - member_type as_member() const noexcept; - method_type as_method() const noexcept; - number_type as_number() const noexcept; - pointer_type as_pointer() const noexcept; - reference_type as_reference() const noexcept; - void_type as_void() const noexcept; + [[nodiscard]] array_type as_array() const noexcept; + [[nodiscard]] class_type as_class() const noexcept; + [[nodiscard]] ctor_type as_ctor() const noexcept; + [[nodiscard]] enum_type as_enum() const noexcept; + [[nodiscard]] function_type as_function() const noexcept; + [[nodiscard]] member_type as_member() const noexcept; + [[nodiscard]] method_type as_method() const noexcept; + [[nodiscard]] number_type as_number() const noexcept; + [[nodiscard]] pointer_type as_pointer() const noexcept; + [[nodiscard]] reference_type as_reference() const noexcept; + [[nodiscard]] void_type as_void() const noexcept; private: detail::type_data_base_ptr data_; friend auto detail::data_access(const any_type&); @@ -170,14 +173,14 @@ namespace meta_hpp array_type() = default; array_type(detail::array_type_data_ptr data); - bool is_valid() const noexcept; - explicit operator bool() const noexcept; + [[nodiscard]] bool is_valid() const noexcept; + [[nodiscard]] explicit operator bool() const noexcept; - type_id get_id() const noexcept; - bitflags get_flags() const noexcept; + [[nodiscard]] type_id get_id() const noexcept; + [[nodiscard]] bitflags get_flags() const noexcept; - std::size_t get_extent() const noexcept; - any_type get_data_type() const noexcept; + [[nodiscard]] std::size_t get_extent() const noexcept; + [[nodiscard]] any_type get_data_type() const noexcept; private: detail::array_type_data_ptr data_; friend auto detail::data_access(const array_type&); @@ -188,58 +191,58 @@ namespace meta_hpp class_type() = default; class_type(detail::class_type_data_ptr data); - bool is_valid() const noexcept; - explicit operator bool() const noexcept; + [[nodiscard]] bool is_valid() const noexcept; + [[nodiscard]] explicit operator bool() const noexcept; - type_id get_id() const noexcept; - bitflags get_flags() const noexcept; + [[nodiscard]] type_id get_id() const noexcept; + [[nodiscard]] bitflags get_flags() const noexcept; - std::size_t get_size() const noexcept; + [[nodiscard]] std::size_t get_size() const noexcept; - std::size_t get_arity() const noexcept; - any_type get_argument_type(std::size_t index) const noexcept; - const std::vector& get_argument_types() const noexcept; + [[nodiscard]] std::size_t get_arity() const noexcept; + [[nodiscard]] any_type get_argument_type(std::size_t index) const noexcept; + [[nodiscard]] const std::vector& get_argument_types() const noexcept; - const ctor_map& get_ctors() const noexcept; - const class_set& get_bases() const noexcept; - const function_map& get_functions() const noexcept; - const member_map& get_members() const noexcept; - const method_map& get_methods() const noexcept; - const variable_map& get_variables() const noexcept; + [[nodiscard]] const ctor_map& get_ctors() const noexcept; + [[nodiscard]] const class_set& get_bases() const noexcept; + [[nodiscard]] const function_map& get_functions() const noexcept; + [[nodiscard]] const member_map& get_members() const noexcept; + [[nodiscard]] const method_map& get_methods() const noexcept; + [[nodiscard]] const variable_map& get_variables() const noexcept; template < typename... Args > - std::optional create(Args&&... args) const; + [[nodiscard]] std::optional create(Args&&... args) const; template < typename... Args > - std::optional operator()(Args&&... args) const; + [[nodiscard]] std::optional operator()(Args&&... args) const; template < detail::class_kind Derived > - bool is_base_of() const noexcept; - bool is_base_of(const class_type& derived) const noexcept; + [[nodiscard]] bool is_base_of() const noexcept; + [[nodiscard]] bool is_base_of(const class_type& derived) const noexcept; template < detail::class_kind Base > - bool is_derived_from() const noexcept; - bool is_derived_from(const class_type& base) const noexcept; + [[nodiscard]] bool is_derived_from() const noexcept; + [[nodiscard]] bool is_derived_from(const class_type& base) const noexcept; - function get_function(std::string_view name) const noexcept; - member get_member(std::string_view name) const noexcept; - method get_method(std::string_view name) const noexcept; - variable get_variable(std::string_view name) const noexcept; + [[nodiscard]] function get_function(std::string_view name) const noexcept; + [[nodiscard]] member get_member(std::string_view name) const noexcept; + [[nodiscard]] method get_method(std::string_view name) const noexcept; + [[nodiscard]] variable get_variable(std::string_view name) const noexcept; template < typename... Args > - ctor get_ctor_with() const noexcept; - ctor get_ctor_with(const std::vector& args) const noexcept; - ctor get_ctor_with(std::initializer_list args) const noexcept; + [[nodiscard]] ctor get_ctor_with() const noexcept; + [[nodiscard]] ctor get_ctor_with(const std::vector& args) const noexcept; + [[nodiscard]] ctor get_ctor_with(std::initializer_list args) const noexcept; template < typename... Args > - function get_function_with(std::string_view name) const noexcept; - function get_function_with(std::string_view name, const std::vector& args) const noexcept; - function get_function_with(std::string_view name, std::initializer_list args) const noexcept; + [[nodiscard]] function get_function_with(std::string_view name) const noexcept; + [[nodiscard]] function get_function_with(std::string_view name, const std::vector& args) const noexcept; + [[nodiscard]] function get_function_with(std::string_view name, std::initializer_list args) const noexcept; template < typename... Args > - method get_method_with(std::string_view name) const noexcept; - method get_method_with(std::string_view name, const std::vector& args) const noexcept; - method get_method_with(std::string_view name, std::initializer_list args) const noexcept; + [[nodiscard]] method get_method_with(std::string_view name) const noexcept; + [[nodiscard]] method get_method_with(std::string_view name, const std::vector& args) const noexcept; + [[nodiscard]] method get_method_with(std::string_view name, std::initializer_list args) const noexcept; private: detail::class_type_data_ptr data_; friend auto detail::data_access(const class_type&); @@ -250,16 +253,16 @@ namespace meta_hpp ctor_type() = default; ctor_type(detail::ctor_type_data_ptr data); - bool is_valid() const noexcept; - explicit operator bool() const noexcept; + [[nodiscard]] bool is_valid() const noexcept; + [[nodiscard]] explicit operator bool() const noexcept; - type_id get_id() const noexcept; - bitflags get_flags() const noexcept; + [[nodiscard]] type_id get_id() const noexcept; + [[nodiscard]] bitflags get_flags() const noexcept; - std::size_t get_arity() const noexcept; - any_type get_class_type() const noexcept; - any_type get_argument_type(std::size_t index) const noexcept; - const std::vector& get_argument_types() const noexcept; + [[nodiscard]] std::size_t get_arity() const noexcept; + [[nodiscard]] any_type get_class_type() const noexcept; + [[nodiscard]] any_type get_argument_type(std::size_t index) const noexcept; + [[nodiscard]] const std::vector& get_argument_types() const noexcept; private: detail::ctor_type_data_ptr data_; friend auto detail::data_access(const ctor_type&); @@ -270,21 +273,21 @@ namespace meta_hpp enum_type() = default; enum_type(detail::enum_type_data_ptr data); - bool is_valid() const noexcept; - explicit operator bool() const noexcept; + [[nodiscard]] bool is_valid() const noexcept; + [[nodiscard]] explicit operator bool() const noexcept; - type_id get_id() const noexcept; - bitflags get_flags() const noexcept; + [[nodiscard]] type_id get_id() const noexcept; + [[nodiscard]] bitflags get_flags() const noexcept; - number_type get_underlying_type() const noexcept; + [[nodiscard]] number_type get_underlying_type() const noexcept; - const evalue_map& get_evalues() const noexcept; + [[nodiscard]] const evalue_map& get_evalues() const noexcept; - evalue get_evalue(std::string_view name) const noexcept; + [[nodiscard]] evalue get_evalue(std::string_view name) const noexcept; template < typename Value > - std::optional value_to_name(Value&& value) const noexcept; - std::optional name_to_value(std::string_view name) const noexcept; + [[nodiscard]] std::optional value_to_name(Value&& value) const noexcept; + [[nodiscard]] std::optional name_to_value(std::string_view name) const noexcept; private: detail::enum_type_data_ptr data_; friend auto detail::data_access(const enum_type&); @@ -295,16 +298,16 @@ namespace meta_hpp function_type() = default; function_type(detail::function_type_data_ptr data); - bool is_valid() const noexcept; - explicit operator bool() const noexcept; + [[nodiscard]] bool is_valid() const noexcept; + [[nodiscard]] explicit operator bool() const noexcept; - type_id get_id() const noexcept; - bitflags get_flags() const noexcept; + [[nodiscard]] type_id get_id() const noexcept; + [[nodiscard]] bitflags get_flags() const noexcept; - std::size_t get_arity() const noexcept; - any_type get_return_type() const noexcept; - any_type get_argument_type(std::size_t index) const noexcept; - const std::vector& get_argument_types() const noexcept; + [[nodiscard]] std::size_t get_arity() const noexcept; + [[nodiscard]] any_type get_return_type() const noexcept; + [[nodiscard]] any_type get_argument_type(std::size_t index) const noexcept; + [[nodiscard]] const std::vector& get_argument_types() const noexcept; private: detail::function_type_data_ptr data_; friend auto detail::data_access(const function_type&); @@ -315,14 +318,14 @@ namespace meta_hpp member_type() = default; member_type(detail::member_type_data_ptr data); - bool is_valid() const noexcept; - explicit operator bool() const noexcept; + [[nodiscard]] bool is_valid() const noexcept; + [[nodiscard]] explicit operator bool() const noexcept; - type_id get_id() const noexcept; - bitflags get_flags() const noexcept; + [[nodiscard]] type_id get_id() const noexcept; + [[nodiscard]] bitflags get_flags() const noexcept; - class_type get_owner_type() const noexcept; - any_type get_value_type() const noexcept; + [[nodiscard]] class_type get_owner_type() const noexcept; + [[nodiscard]] any_type get_value_type() const noexcept; private: detail::member_type_data_ptr data_; friend auto detail::data_access(const member_type&); @@ -333,17 +336,17 @@ namespace meta_hpp method_type() = default; method_type(detail::method_type_data_ptr data); - bool is_valid() const noexcept; - explicit operator bool() const noexcept; + [[nodiscard]] bool is_valid() const noexcept; + [[nodiscard]] explicit operator bool() const noexcept; - type_id get_id() const noexcept; - bitflags get_flags() const noexcept; + [[nodiscard]] type_id get_id() const noexcept; + [[nodiscard]] bitflags get_flags() const noexcept; - std::size_t get_arity() const noexcept; - class_type get_owner_type() const noexcept; - any_type get_return_type() const noexcept; - any_type get_argument_type(std::size_t index) const noexcept; - const std::vector& get_argument_types() const noexcept; + [[nodiscard]] std::size_t get_arity() const noexcept; + [[nodiscard]] class_type get_owner_type() const noexcept; + [[nodiscard]] any_type get_return_type() const noexcept; + [[nodiscard]] any_type get_argument_type(std::size_t index) const noexcept; + [[nodiscard]] const std::vector& get_argument_types() const noexcept; private: detail::method_type_data_ptr data_; friend auto detail::data_access(const method_type&); @@ -354,13 +357,13 @@ namespace meta_hpp number_type() = default; number_type(detail::number_type_data_ptr data); - bool is_valid() const noexcept; - explicit operator bool() const noexcept; + [[nodiscard]] bool is_valid() const noexcept; + [[nodiscard]] explicit operator bool() const noexcept; - type_id get_id() const noexcept; - bitflags get_flags() const noexcept; + [[nodiscard]] type_id get_id() const noexcept; + [[nodiscard]] bitflags get_flags() const noexcept; - std::size_t get_size() const noexcept; + [[nodiscard]] std::size_t get_size() const noexcept; private: detail::number_type_data_ptr data_; friend auto detail::data_access(const number_type&); @@ -371,13 +374,13 @@ namespace meta_hpp pointer_type() = default; pointer_type(detail::pointer_type_data_ptr data); - bool is_valid() const noexcept; - explicit operator bool() const noexcept; + [[nodiscard]] bool is_valid() const noexcept; + [[nodiscard]] explicit operator bool() const noexcept; - type_id get_id() const noexcept; - bitflags get_flags() const noexcept; + [[nodiscard]] type_id get_id() const noexcept; + [[nodiscard]] bitflags get_flags() const noexcept; - any_type get_data_type() const noexcept; + [[nodiscard]] any_type get_data_type() const noexcept; private: detail::pointer_type_data_ptr data_; friend auto detail::data_access(const pointer_type&); @@ -388,13 +391,13 @@ namespace meta_hpp reference_type() = default; reference_type(detail::reference_type_data_ptr data); - bool is_valid() const noexcept; - explicit operator bool() const noexcept; + [[nodiscard]] bool is_valid() const noexcept; + [[nodiscard]] explicit operator bool() const noexcept; - type_id get_id() const noexcept; - bitflags get_flags() const noexcept; + [[nodiscard]] type_id get_id() const noexcept; + [[nodiscard]] bitflags get_flags() const noexcept; - any_type get_data_type() const noexcept; + [[nodiscard]] any_type get_data_type() const noexcept; private: detail::reference_type_data_ptr data_; friend auto detail::data_access(const reference_type&); @@ -405,11 +408,11 @@ namespace meta_hpp void_type() = default; void_type(detail::void_type_data_ptr data); - bool is_valid() const noexcept; - explicit operator bool() const noexcept; + [[nodiscard]] bool is_valid() const noexcept; + [[nodiscard]] explicit operator bool() const noexcept; - type_id get_id() const noexcept; - bitflags get_flags() const noexcept; + [[nodiscard]] type_id get_id() const noexcept; + [[nodiscard]] bitflags get_flags() const noexcept; private: detail::void_type_data_ptr data_; friend auto detail::data_access(const void_type&); @@ -572,11 +575,11 @@ namespace meta_hpp explicit ctor_index(ctor_type type) : type{std::move(type)} {} - friend bool operator<(const ctor_index& l, const ctor_index& r) noexcept { + [[nodiscard]] friend bool operator<(const ctor_index& l, const ctor_index& r) noexcept { return l.type < r.type; } - friend bool operator==(const ctor_index& l, const ctor_index& r) noexcept { + [[nodiscard]] friend bool operator==(const ctor_index& l, const ctor_index& r) noexcept { return l.type == r.type; } }; @@ -589,11 +592,11 @@ namespace meta_hpp : type{std::move(type)} , name{std::move(name)} {} - friend bool operator<(const evalue_index& l, const evalue_index& r) noexcept { + [[nodiscard]] friend bool operator<(const evalue_index& l, const evalue_index& r) noexcept { return std::tie(l.type, l.name) < std::tie(r.type, r.name); } - friend bool operator==(const evalue_index& l, const evalue_index& r) noexcept { + [[nodiscard]] friend bool operator==(const evalue_index& l, const evalue_index& r) noexcept { return std::tie(l.type, l.name) == std::tie(r.type, r.name); } }; @@ -606,11 +609,11 @@ namespace meta_hpp : type{std::move(type)} , name{std::move(name)} {} - friend bool operator<(const function_index& l, const function_index& r) noexcept { + [[nodiscard]] friend bool operator<(const function_index& l, const function_index& r) noexcept { return std::tie(l.type, l.name) < std::tie(r.type, r.name); } - friend bool operator==(const function_index& l, const function_index& r) noexcept { + [[nodiscard]] friend bool operator==(const function_index& l, const function_index& r) noexcept { return std::tie(l.type, l.name) == std::tie(r.type, r.name); } }; @@ -623,11 +626,11 @@ namespace meta_hpp : type{std::move(type)} , name{std::move(name)} {} - friend bool operator<(const member_index& l, const member_index& r) noexcept { + [[nodiscard]] friend bool operator<(const member_index& l, const member_index& r) noexcept { return std::tie(l.type, l.name) < std::tie(r.type, r.name); } - friend bool operator==(const member_index& l, const member_index& r) noexcept { + [[nodiscard]] friend bool operator==(const member_index& l, const member_index& r) noexcept { return std::tie(l.type, l.name) == std::tie(r.type, r.name); } }; @@ -640,11 +643,11 @@ namespace meta_hpp : type{std::move(type)} , name{std::move(name)} {} - friend bool operator<(const method_index& l, const method_index& r) noexcept { + [[nodiscard]] friend bool operator<(const method_index& l, const method_index& r) noexcept { return std::tie(l.type, l.name) < std::tie(r.type, r.name); } - friend bool operator==(const method_index& l, const method_index& r) noexcept { + [[nodiscard]] friend bool operator==(const method_index& l, const method_index& r) noexcept { return std::tie(l.type, l.name) == std::tie(r.type, r.name); } }; @@ -655,11 +658,11 @@ namespace meta_hpp explicit scope_index(std::string name) : name{std::move(name)} {} - friend bool operator<(const scope_index& l, const scope_index& r) noexcept { + [[nodiscard]] friend bool operator<(const scope_index& l, const scope_index& r) noexcept { return l.name < r.name; } - friend bool operator==(const scope_index& l, const scope_index& r) noexcept { + [[nodiscard]] friend bool operator==(const scope_index& l, const scope_index& r) noexcept { return l.name == r.name; } }; @@ -672,11 +675,11 @@ namespace meta_hpp : type{std::move(type)} , name{std::move(name)} {} - friend bool operator<(const variable_index& l, const variable_index& r) noexcept { + [[nodiscard]] friend bool operator<(const variable_index& l, const variable_index& r) noexcept { return std::tie(l.type, l.name) < std::tie(r.type, r.name); } - friend bool operator==(const variable_index& l, const variable_index& r) noexcept { + [[nodiscard]] friend bool operator==(const variable_index& l, const variable_index& r) noexcept { return std::tie(l.type, l.name) == std::tie(r.type, r.name); } }; @@ -685,7 +688,7 @@ namespace meta_hpp namespace meta_hpp { template < typename T > - auto resolve_type() { + [[nodiscard]] auto resolve_type() { using raw_type = std::remove_cv_t; using kind_type = detail::kind_type; @@ -695,7 +698,8 @@ namespace meta_hpp } template < typename T > - auto resolve_type(T&&) { + // NOLINTNEXTLINE(readability-named-parameter) + [[nodiscard]] auto resolve_type(const T&) { return resolve_type>(); }; } diff --git a/headers/meta.hpp/meta_types/array_type.hpp b/headers/meta.hpp/meta_types/array_type.hpp index 4dedd7e..effa4b5 100644 --- a/headers/meta.hpp/meta_types/array_type.hpp +++ b/headers/meta.hpp/meta_types/array_type.hpp @@ -23,6 +23,7 @@ namespace meta_hpp::detail } template < array_kind Array > + // NOLINTNEXTLINE(readability-named-parameter) array_type_data::array_type_data(type_list) : type_data_base{type_id{type_list>{}}, type_kind::array_} , flags{array_traits::make_flags()} diff --git a/headers/meta.hpp/meta_types/class_type.hpp b/headers/meta.hpp/meta_types/class_type.hpp index d27b570..3ec543a 100644 --- a/headers/meta.hpp/meta_types/class_type.hpp +++ b/headers/meta.hpp/meta_types/class_type.hpp @@ -9,6 +9,12 @@ #include "../meta_base.hpp" #include "../meta_types.hpp" +#include "../meta_states/ctor.hpp" +#include "../meta_states/function.hpp" +#include "../meta_states/member.hpp" +#include "../meta_states/method.hpp" +#include "../meta_states/variable.hpp" + #include "../meta_traits/class_traits.hpp" namespace meta_hpp::detail @@ -23,6 +29,7 @@ namespace meta_hpp::detail } template < class_kind Class > + // NOLINTNEXTLINE(readability-named-parameter) class_type_data::class_type_data(type_list) : type_data_base{type_id{type_list>{}}, type_kind::class_} , flags{class_traits::make_flags()} diff --git a/headers/meta.hpp/meta_types/ctor_type.hpp b/headers/meta.hpp/meta_types/ctor_type.hpp index d05458d..9244770 100644 --- a/headers/meta.hpp/meta_types/ctor_type.hpp +++ b/headers/meta.hpp/meta_types/ctor_type.hpp @@ -23,6 +23,7 @@ namespace meta_hpp::detail } template < class_kind Class, typename... Args > + // NOLINTNEXTLINE(readability-named-parameter) ctor_type_data::ctor_type_data(type_list, type_list) : type_data_base{type_id{type_list>{}}, type_kind::ctor_} , flags{ctor_traits::make_flags()} diff --git a/headers/meta.hpp/meta_types/enum_type.hpp b/headers/meta.hpp/meta_types/enum_type.hpp index 506567e..616d2aa 100644 --- a/headers/meta.hpp/meta_types/enum_type.hpp +++ b/headers/meta.hpp/meta_types/enum_type.hpp @@ -9,6 +9,8 @@ #include "../meta_base.hpp" #include "../meta_types.hpp" +#include "../meta_states/evalue.hpp" + #include "../meta_traits/enum_traits.hpp" namespace meta_hpp::detail @@ -23,6 +25,7 @@ namespace meta_hpp::detail } template < enum_kind Enum > + // NOLINTNEXTLINE(readability-named-parameter) enum_type_data::enum_type_data(type_list) : type_data_base{type_id{type_list>{}}, type_kind::enum_} , flags{enum_traits::make_flags()} diff --git a/headers/meta.hpp/meta_types/function_type.hpp b/headers/meta.hpp/meta_types/function_type.hpp index 433d0cb..c8474da 100644 --- a/headers/meta.hpp/meta_types/function_type.hpp +++ b/headers/meta.hpp/meta_types/function_type.hpp @@ -23,6 +23,7 @@ namespace meta_hpp::detail } template < function_kind Function > + // NOLINTNEXTLINE(readability-named-parameter) function_type_data::function_type_data(type_list) : type_data_base{type_id{type_list>{}}, type_kind::function_} , flags{function_traits::make_flags()} diff --git a/headers/meta.hpp/meta_types/member_type.hpp b/headers/meta.hpp/meta_types/member_type.hpp index 432d155..7e21181 100644 --- a/headers/meta.hpp/meta_types/member_type.hpp +++ b/headers/meta.hpp/meta_types/member_type.hpp @@ -23,6 +23,7 @@ namespace meta_hpp::detail } template < member_kind Member > + // NOLINTNEXTLINE(readability-named-parameter) member_type_data::member_type_data(type_list) : type_data_base{type_id{type_list>{}}, type_kind::member_} , flags{member_traits::make_flags()} diff --git a/headers/meta.hpp/meta_types/method_type.hpp b/headers/meta.hpp/meta_types/method_type.hpp index 9bfd4fe..d06d6a5 100644 --- a/headers/meta.hpp/meta_types/method_type.hpp +++ b/headers/meta.hpp/meta_types/method_type.hpp @@ -23,6 +23,7 @@ namespace meta_hpp::detail } template < method_kind Method > + // NOLINTNEXTLINE(readability-named-parameter) method_type_data::method_type_data(type_list) : type_data_base{type_id{type_list>{}}, type_kind::method_} , flags{method_traits::make_flags()} diff --git a/headers/meta.hpp/meta_types/number_type.hpp b/headers/meta.hpp/meta_types/number_type.hpp index 9eef28b..d06db7e 100644 --- a/headers/meta.hpp/meta_types/number_type.hpp +++ b/headers/meta.hpp/meta_types/number_type.hpp @@ -23,6 +23,7 @@ namespace meta_hpp::detail } template < number_kind Number > + // NOLINTNEXTLINE(readability-named-parameter) number_type_data::number_type_data(type_list) : type_data_base{type_id{type_list>{}}, type_kind::number_} , flags{number_traits::make_flags()} diff --git a/headers/meta.hpp/meta_types/pointer_type.hpp b/headers/meta.hpp/meta_types/pointer_type.hpp index e7e16ec..95889b2 100644 --- a/headers/meta.hpp/meta_types/pointer_type.hpp +++ b/headers/meta.hpp/meta_types/pointer_type.hpp @@ -23,6 +23,7 @@ namespace meta_hpp::detail } template < pointer_kind Pointer > + // NOLINTNEXTLINE(readability-named-parameter) pointer_type_data::pointer_type_data(type_list) : type_data_base{type_id{type_list>{}}, type_kind::pointer_} , flags{pointer_traits::make_flags()} diff --git a/headers/meta.hpp/meta_types/reference_type.hpp b/headers/meta.hpp/meta_types/reference_type.hpp index e0dda8d..2725773 100644 --- a/headers/meta.hpp/meta_types/reference_type.hpp +++ b/headers/meta.hpp/meta_types/reference_type.hpp @@ -23,6 +23,7 @@ namespace meta_hpp::detail } template < reference_kind Reference > + // NOLINTNEXTLINE(readability-named-parameter) reference_type_data::reference_type_data(type_list) : type_data_base{type_id{type_list>{}}, type_kind::reference_} , flags{reference_traits::make_flags()} diff --git a/headers/meta.hpp/meta_types/void_type.hpp b/headers/meta.hpp/meta_types/void_type.hpp index c6e204a..ce5a1f5 100644 --- a/headers/meta.hpp/meta_types/void_type.hpp +++ b/headers/meta.hpp/meta_types/void_type.hpp @@ -23,6 +23,7 @@ namespace meta_hpp::detail } template < void_kind Void > + // NOLINTNEXTLINE(readability-named-parameter) void_type_data::void_type_data(type_list) : type_data_base{type_id{type_list>{}}, type_kind::void_} , flags{void_traits::make_flags()} {} diff --git a/headers/meta.hpp/meta_utilities.hpp b/headers/meta.hpp/meta_utilities.hpp index 845ac86..3058542 100644 --- a/headers/meta.hpp/meta_utilities.hpp +++ b/headers/meta.hpp/meta_utilities.hpp @@ -7,6 +7,29 @@ #pragma once #include "meta_base.hpp" +#include "meta_types.hpp" + +namespace meta_hpp::detail +{ + template < typename T > + concept destructible = + std::is_nothrow_destructible_v; + + template < typename T, typename... Args > + concept constructible_from = + destructible && + std::is_constructible_v; + + template < typename Derived, typename Base > + concept derived_from = + std::is_base_of_v && + std::is_convertible_v; + + template < typename From, typename To > + concept convertible_to = + std::is_convertible_v && + requires { static_cast(std::declval()); }; +} namespace meta_hpp { From f0ba3b9d4d9ce67c07cede4cd6242f7499ebc555 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Tue, 4 Jan 2022 01:54:59 +0700 Subject: [PATCH 135/233] add upcast info to class_data_type --- headers/meta.hpp/meta_registry/class_bind.hpp | 5 +++++ headers/meta.hpp/meta_types.hpp | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/headers/meta.hpp/meta_registry/class_bind.hpp b/headers/meta.hpp/meta_registry/class_bind.hpp index 09fcd10..d2da779 100644 --- a/headers/meta.hpp/meta_registry/class_bind.hpp +++ b/headers/meta.hpp/meta_registry/class_bind.hpp @@ -34,6 +34,11 @@ namespace meta_hpp class_bind& class_bind::base_() { static_assert(detail::derived_from); data_->bases.emplace(resolve_type()); + data_->bases_info.emplace(resolve_type(), detail::class_type_data::base_info{ + .upcast = +[](void* derived) -> void* { + return static_cast(static_cast(derived)); + } + }); return *this; } diff --git a/headers/meta.hpp/meta_types.hpp b/headers/meta.hpp/meta_types.hpp index a43bd37..facdbad 100644 --- a/headers/meta.hpp/meta_types.hpp +++ b/headers/meta.hpp/meta_types.hpp @@ -454,6 +454,14 @@ namespace meta_hpp::detail method_map methods; variable_map variables; + struct base_info final { + using upcast_fptr = void*(*)(void*); + const upcast_fptr upcast; + }; + + using base_info_map = std::map>; + base_info_map bases_info; + template < class_kind Class > static class_type_data_ptr get_static(); From b73cf18fea77fe77aed8dda11e8d7ea1d44bd6ff Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Tue, 4 Jan 2022 02:21:06 +0700 Subject: [PATCH 136/233] more nodiscards --- headers/meta.hpp/meta_states.hpp | 144 +++++++++--------- headers/meta.hpp/meta_states/ctor.hpp | 12 +- headers/meta.hpp/meta_states/evalue.hpp | 10 +- headers/meta.hpp/meta_states/function.hpp | 12 +- headers/meta.hpp/meta_states/member.hpp | 12 +- headers/meta.hpp/meta_states/method.hpp | 12 +- headers/meta.hpp/meta_states/scope.hpp | 6 +- headers/meta.hpp/meta_states/variable.hpp | 12 +- headers/meta.hpp/meta_types.hpp | 44 +++--- headers/meta.hpp/meta_types/array_type.hpp | 12 +- headers/meta.hpp/meta_types/class_type.hpp | 12 +- headers/meta.hpp/meta_types/ctor_type.hpp | 12 +- headers/meta.hpp/meta_types/enum_type.hpp | 12 +- headers/meta.hpp/meta_types/function_type.hpp | 12 +- headers/meta.hpp/meta_types/member_type.hpp | 12 +- headers/meta.hpp/meta_types/method_type.hpp | 12 +- headers/meta.hpp/meta_types/number_type.hpp | 12 +- headers/meta.hpp/meta_types/pointer_type.hpp | 12 +- .../meta.hpp/meta_types/reference_type.hpp | 12 +- headers/meta.hpp/meta_types/void_type.hpp | 12 +- 20 files changed, 198 insertions(+), 198 deletions(-) diff --git a/headers/meta.hpp/meta_states.hpp b/headers/meta.hpp/meta_states.hpp index a03f4f4..cda291a 100644 --- a/headers/meta.hpp/meta_states.hpp +++ b/headers/meta.hpp/meta_states.hpp @@ -26,7 +26,7 @@ namespace meta_hpp } template < detail::state_family T, detail::state_family U > - bool operator<(const T& l, const U& r) noexcept { + [[nodiscard]] bool operator<(const T& l, const U& r) noexcept { if ( !static_cast(r) ) { return false; } @@ -39,7 +39,7 @@ namespace meta_hpp } template < detail::state_family T, detail::state_family U > - bool operator==(const T& l, const U& r) noexcept { + [[nodiscard]] bool operator==(const T& l, const U& r) noexcept { if ( static_cast(l) != static_cast(r) ) { return false; } @@ -52,7 +52,7 @@ namespace meta_hpp } template < detail::state_family T, detail::state_family U > - bool operator!=(const T& l, const U& r) noexcept { + [[nodiscard]] bool operator!=(const T& l, const U& r) noexcept { return !(l == r); } } @@ -64,11 +64,11 @@ namespace meta_hpp explicit ctor() = default; explicit ctor(detail::ctor_state_ptr state); - bool is_valid() const noexcept; - explicit operator bool() const noexcept; + [[nodiscard]] bool is_valid() const noexcept; + [[nodiscard]] explicit operator bool() const noexcept; - const ctor_index& get_index() const noexcept; - const ctor_type& get_type() const noexcept; + [[nodiscard]] const ctor_index& get_index() const noexcept; + [[nodiscard]] const ctor_type& get_type() const noexcept; template < typename... Args > value invoke(Args&&... args) const; @@ -77,10 +77,10 @@ namespace meta_hpp value operator()(Args&&... args) const; template < typename... Args > - bool is_invocable_with() const noexcept; + [[nodiscard]] bool is_invocable_with() const noexcept; template < typename... Args > - bool is_invocable_with(Args&&... args) const noexcept; + [[nodiscard]] bool is_invocable_with(Args&&... args) const noexcept; private: detail::ctor_state_ptr state_; }; @@ -90,14 +90,14 @@ namespace meta_hpp explicit evalue() = default; explicit evalue(detail::evalue_state_ptr state); - bool is_valid() const noexcept; - explicit operator bool() const noexcept; + [[nodiscard]] bool is_valid() const noexcept; + [[nodiscard]] explicit operator bool() const noexcept; - const evalue_index& get_index() const noexcept; - const enum_type& get_type() const noexcept; - const std::string& get_name() const noexcept; + [[nodiscard]] const evalue_index& get_index() const noexcept; + [[nodiscard]] const enum_type& get_type() const noexcept; + [[nodiscard]] const std::string& get_name() const noexcept; - const value& get_value() const noexcept; + [[nodiscard]] const value& get_value() const noexcept; private: detail::evalue_state_ptr state_; }; @@ -107,12 +107,12 @@ namespace meta_hpp explicit function() = default; explicit function(detail::function_state_ptr state); - bool is_valid() const noexcept; - explicit operator bool() const noexcept; + [[nodiscard]] bool is_valid() const noexcept; + [[nodiscard]] explicit operator bool() const noexcept; - const function_index& get_index() const noexcept; - const function_type& get_type() const noexcept; - const std::string& get_name() const noexcept; + [[nodiscard]] const function_index& get_index() const noexcept; + [[nodiscard]] const function_type& get_type() const noexcept; + [[nodiscard]] const std::string& get_name() const noexcept; template < typename... Args > std::optional invoke(Args&&... args) const; @@ -121,10 +121,10 @@ namespace meta_hpp std::optional operator()(Args&&... args) const; template < typename... Args > - bool is_invocable_with() const noexcept; + [[nodiscard]] bool is_invocable_with() const noexcept; template < typename... Args > - bool is_invocable_with(Args&&... args) const noexcept; + [[nodiscard]] bool is_invocable_with(Args&&... args) const noexcept; private: detail::function_state_ptr state_; }; @@ -134,15 +134,15 @@ namespace meta_hpp explicit member() = default; explicit member(detail::member_state_ptr state); - bool is_valid() const noexcept; - explicit operator bool() const noexcept; + [[nodiscard]] bool is_valid() const noexcept; + [[nodiscard]] explicit operator bool() const noexcept; - const member_index& get_index() const noexcept; - const member_type& get_type() const noexcept; - const std::string& get_name() const noexcept; + [[nodiscard]] const member_index& get_index() const noexcept; + [[nodiscard]] const member_type& get_type() const noexcept; + [[nodiscard]] const std::string& get_name() const noexcept; template < typename Instance > - value get(Instance&& instance) const; + [[nodiscard]] value get(Instance&& instance) const; template < typename Instance, typename Value > void set(Instance&& instance, Value&& value) const; @@ -155,12 +155,12 @@ namespace meta_hpp explicit method() = default; explicit method(detail::method_state_ptr state); - bool is_valid() const noexcept; - explicit operator bool() const noexcept; + [[nodiscard]] bool is_valid() const noexcept; + [[nodiscard]] explicit operator bool() const noexcept; - const method_index& get_index() const noexcept; - const method_type& get_type() const noexcept; - const std::string& get_name() const noexcept; + [[nodiscard]] const method_index& get_index() const noexcept; + [[nodiscard]] const method_type& get_type() const noexcept; + [[nodiscard]] const std::string& get_name() const noexcept; template < typename Instance, typename... Args > std::optional invoke(Instance&& instance, Args&&... args) const; @@ -169,10 +169,10 @@ namespace meta_hpp std::optional operator()(Instance&& instance, Args&&... args) const; template < typename Instance, typename... Args > - bool is_invocable_with() const noexcept; + [[nodiscard]] bool is_invocable_with() const noexcept; template < typename Instance, typename... Args > - bool is_invocable_with(Instance&& instance, Args&&... args) const noexcept; + [[nodiscard]] bool is_invocable_with(Instance&& instance, Args&&... args) const noexcept; private: detail::method_state_ptr state_; }; @@ -182,26 +182,26 @@ namespace meta_hpp explicit scope() = default; explicit scope(detail::scope_state_ptr state); - bool is_valid() const noexcept; - explicit operator bool() const noexcept; + [[nodiscard]] bool is_valid() const noexcept; + [[nodiscard]] explicit operator bool() const noexcept; - const scope_index& get_index() const noexcept; - const std::string& get_name() const noexcept; + [[nodiscard]] const scope_index& get_index() const noexcept; + [[nodiscard]] const std::string& get_name() const noexcept; - const class_map& get_classes() const noexcept; - const enum_map& get_enums() const noexcept; - const function_map& get_functions() const noexcept; - const variable_map& get_variables() const noexcept; + [[nodiscard]] const class_map& get_classes() const noexcept; + [[nodiscard]] const enum_map& get_enums() const noexcept; + [[nodiscard]] const function_map& get_functions() const noexcept; + [[nodiscard]] const variable_map& get_variables() const noexcept; - class_type get_class(std::string_view name) const noexcept; - enum_type get_enum(std::string_view name) const noexcept; - function get_function(std::string_view name) const noexcept; - variable get_variable(std::string_view name) const noexcept; + [[nodiscard]] class_type get_class(std::string_view name) const noexcept; + [[nodiscard]] enum_type get_enum(std::string_view name) const noexcept; + [[nodiscard]] function get_function(std::string_view name) const noexcept; + [[nodiscard]] variable get_variable(std::string_view name) const noexcept; template < typename... Args > - function get_function_with(std::string_view name) const noexcept; - function get_function_with(std::string_view name, const std::vector& args) const noexcept; - function get_function_with(std::string_view name, std::initializer_list args) const noexcept; + [[nodiscard]] function get_function_with(std::string_view name) const noexcept; + [[nodiscard]] function get_function_with(std::string_view name, const std::vector& args) const noexcept; + [[nodiscard]] function get_function_with(std::string_view name, std::initializer_list args) const noexcept; private: detail::scope_state_ptr state_; }; @@ -211,14 +211,14 @@ namespace meta_hpp explicit variable() = default; explicit variable(detail::variable_state_ptr state); - bool is_valid() const noexcept; - explicit operator bool() const noexcept; + [[nodiscard]] bool is_valid() const noexcept; + [[nodiscard]] explicit operator bool() const noexcept; - const variable_index& get_index() const noexcept; - const pointer_type& get_type() const noexcept; - const std::string& get_name() const noexcept; + [[nodiscard]] const variable_index& get_index() const noexcept; + [[nodiscard]] const pointer_type& get_type() const noexcept; + [[nodiscard]] const std::string& get_name() const noexcept; - value get() const; + [[nodiscard]] value get() const; template < typename Value > void set(Value&& value) const; @@ -239,10 +239,10 @@ namespace meta_hpp::detail is_invocable_with_impl is_invocable_with; template < class_kind Class, typename... Args > - static ctor_state_ptr make(); + explicit ctor_state(ctor_index index, type_list, type_list); template < class_kind Class, typename... Args > - explicit ctor_state(ctor_index index, type_list, type_list); + [[nodiscard]] static ctor_state_ptr make(); }; struct evalue_state final { @@ -251,10 +251,10 @@ namespace meta_hpp::detail class value value; template < enum_kind Enum > - static evalue_state_ptr make(std::string name, Enum value); + explicit evalue_state(evalue_index index, Enum value); template < enum_kind Enum > - explicit evalue_state(evalue_index index, Enum value); + [[nodiscard]] static evalue_state_ptr make(std::string name, Enum value); }; struct function_state final { @@ -267,10 +267,10 @@ namespace meta_hpp::detail is_invocable_with_impl is_invocable_with; template < function_kind Function > - static function_state_ptr make(std::string name, Function function); + explicit function_state(function_index index, Function function); template < function_kind Function > - explicit function_state(function_index index, Function function); + [[nodiscard]] static function_state_ptr make(std::string name, Function function); }; struct member_state final { @@ -283,10 +283,10 @@ namespace meta_hpp::detail setter_impl setter; template < member_kind Member > - static member_state_ptr make(std::string name, Member member); + explicit member_state(member_index index, Member member); template < member_kind Member > - explicit member_state(member_index index, Member member); + [[nodiscard]] static member_state_ptr make(std::string name, Member member); }; struct method_state final { @@ -299,10 +299,10 @@ namespace meta_hpp::detail is_invocable_with_impl is_invocable_with; template < method_kind Method > - static method_state_ptr make(std::string name, Method method); + explicit method_state(method_index index, Method method); template < method_kind Method > - explicit method_state(method_index index, Method method); + [[nodiscard]] static method_state_ptr make(std::string name, Method method); }; struct scope_state final { @@ -313,10 +313,10 @@ namespace meta_hpp::detail function_map functions; variable_map variables; - static scope_state_ptr make(std::string name); - static scope_state_ptr get_static(std::string_view name); - 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); }; struct variable_state final { @@ -329,16 +329,16 @@ namespace meta_hpp::detail setter_impl setter; template < pointer_kind Pointer > - static variable_state_ptr make(std::string name, Pointer pointer); + explicit variable_state(variable_index index, Pointer pointer); template < pointer_kind Pointer > - explicit variable_state(variable_index index, Pointer pointer); + [[nodiscard]] static variable_state_ptr make(std::string name, Pointer pointer); }; } namespace meta_hpp { - inline scope resolve_scope(std::string_view name) { + [[nodiscard]] inline scope resolve_scope(std::string_view name) { return scope{detail::scope_state::get_static(name)}; } } diff --git a/headers/meta.hpp/meta_states/ctor.hpp b/headers/meta.hpp/meta_states/ctor.hpp index 0fe3d31..b004c81 100644 --- a/headers/meta.hpp/meta_states/ctor.hpp +++ b/headers/meta.hpp/meta_states/ctor.hpp @@ -90,17 +90,17 @@ namespace meta_hpp::detail namespace meta_hpp::detail { - template < 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{}); - } - template < class_kind Class, typename... Args > 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 > + 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{}); + } } namespace meta_hpp diff --git a/headers/meta.hpp/meta_states/evalue.hpp b/headers/meta.hpp/meta_states/evalue.hpp index 3db728f..a27ba80 100644 --- a/headers/meta.hpp/meta_states/evalue.hpp +++ b/headers/meta.hpp/meta_states/evalue.hpp @@ -13,16 +13,16 @@ namespace meta_hpp::detail { + template < enum_kind Enum > + evalue_state::evalue_state(evalue_index index, Enum value) + : index{std::move(index)} + , value{std::move(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)); } - - template < enum_kind Enum > - evalue_state::evalue_state(evalue_index index, Enum value) - : index{std::move(index)} - , value{std::move(value)} {} } namespace meta_hpp diff --git a/headers/meta.hpp/meta_states/function.hpp b/headers/meta.hpp/meta_states/function.hpp index 3aa5da6..48578ec 100644 --- a/headers/meta.hpp/meta_states/function.hpp +++ b/headers/meta.hpp/meta_states/function.hpp @@ -100,17 +100,17 @@ namespace meta_hpp::detail namespace meta_hpp::detail { - template < 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)); - } - template < function_kind Function > function_state::function_state(function_index index, Function function) : index{std::move(index)} , invoke{make_function_invoke(function)} , is_invocable_with{make_function_is_invocable_with()} {} + + template < 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)); + } } namespace meta_hpp diff --git a/headers/meta.hpp/meta_states/member.hpp b/headers/meta.hpp/meta_states/member.hpp index de1f4f6..8490c3f 100644 --- a/headers/meta.hpp/meta_states/member.hpp +++ b/headers/meta.hpp/meta_states/member.hpp @@ -74,17 +74,17 @@ namespace meta_hpp::detail namespace meta_hpp::detail { - template < 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)); - } - template < member_kind Member > member_state::member_state(member_index index, Member member) : index{std::move(index)} , getter{make_member_getter(member)} , setter{make_member_setter(member)} {} + + template < 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)); + } } namespace meta_hpp diff --git a/headers/meta.hpp/meta_states/method.hpp b/headers/meta.hpp/meta_states/method.hpp index 3689af6..9ed1c64 100644 --- a/headers/meta.hpp/meta_states/method.hpp +++ b/headers/meta.hpp/meta_states/method.hpp @@ -116,17 +116,17 @@ namespace meta_hpp::detail namespace meta_hpp::detail { - template < 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)); - } - template < method_kind Method > method_state::method_state(method_index index, Method method) : index{std::move(index)} , invoke{make_method_invoke(method)} , is_invocable_with{make_method_is_invocable_with()} {} + + template < 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)); + } } namespace meta_hpp diff --git a/headers/meta.hpp/meta_states/scope.hpp b/headers/meta.hpp/meta_states/scope.hpp index ca021e2..2a04f19 100644 --- a/headers/meta.hpp/meta_states/scope.hpp +++ b/headers/meta.hpp/meta_states/scope.hpp @@ -11,6 +11,9 @@ 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)); @@ -25,9 +28,6 @@ namespace meta_hpp::detail return states.emplace(std::string{name}, make(std::string{name})).first->second; } - - inline scope_state::scope_state(scope_index index) - : index{std::move(index)} {} } namespace meta_hpp diff --git a/headers/meta.hpp/meta_states/variable.hpp b/headers/meta.hpp/meta_states/variable.hpp index 38ae51f..87d3c01 100644 --- a/headers/meta.hpp/meta_states/variable.hpp +++ b/headers/meta.hpp/meta_states/variable.hpp @@ -56,17 +56,17 @@ namespace meta_hpp::detail namespace meta_hpp::detail { - template < 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); - } - 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)} {} + + template < 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); + } } namespace meta_hpp diff --git a/headers/meta.hpp/meta_types.hpp b/headers/meta.hpp/meta_types.hpp index facdbad..5469bba 100644 --- a/headers/meta.hpp/meta_types.hpp +++ b/headers/meta.hpp/meta_types.hpp @@ -436,10 +436,10 @@ namespace meta_hpp::detail const any_type data_type; template < array_kind Array > - static array_type_data_ptr get_static(); + explicit array_type_data(type_list); template < array_kind Array > - explicit array_type_data(type_list); + [[nodiscard]] static array_type_data_ptr get_static(); }; struct class_type_data final : type_data_base { @@ -463,10 +463,10 @@ namespace meta_hpp::detail base_info_map bases_info; template < class_kind Class > - static class_type_data_ptr get_static(); + explicit class_type_data(type_list); template < class_kind Class > - explicit class_type_data(type_list); + [[nodiscard]] static class_type_data_ptr get_static(); }; struct ctor_type_data final : type_data_base { @@ -475,10 +475,10 @@ namespace meta_hpp::detail const std::vector argument_types; template < class_kind Class, typename... Args > - static ctor_type_data_ptr get_static(); + explicit ctor_type_data(type_list, type_list); template < class_kind Class, typename... Args > - explicit ctor_type_data(type_list, type_list); + [[nodiscard]] static ctor_type_data_ptr get_static(); }; struct enum_type_data final : type_data_base { @@ -488,10 +488,10 @@ namespace meta_hpp::detail evalue_map evalues; template < enum_kind Enum > - static enum_type_data_ptr get_static(); + explicit enum_type_data(type_list); template < enum_kind Enum > - explicit enum_type_data(type_list); + [[nodiscard]] static enum_type_data_ptr get_static(); }; struct function_type_data final : type_data_base { @@ -500,10 +500,10 @@ namespace meta_hpp::detail const std::vector argument_types; template < function_kind Function > - static function_type_data_ptr get_static(); + explicit function_type_data(type_list); template < function_kind Function > - explicit function_type_data(type_list); + [[nodiscard]] static function_type_data_ptr get_static(); }; struct member_type_data final : type_data_base { @@ -512,10 +512,10 @@ namespace meta_hpp::detail const any_type value_type; template < member_kind Member > - static member_type_data_ptr get_static(); + explicit member_type_data(type_list); template < member_kind Member > - explicit member_type_data(type_list); + [[nodiscard]] static member_type_data_ptr get_static(); }; struct method_type_data final : type_data_base { @@ -525,10 +525,10 @@ namespace meta_hpp::detail const std::vector argument_types; template < method_kind Method > - static method_type_data_ptr get_static(); + explicit method_type_data(type_list); template < method_kind Method > - explicit method_type_data(type_list); + [[nodiscard]] static method_type_data_ptr get_static(); }; struct number_type_data final : type_data_base { @@ -536,10 +536,10 @@ namespace meta_hpp::detail const std::size_t size; template < number_kind Number > - static number_type_data_ptr get_static(); + explicit number_type_data(type_list); template < number_kind Number > - explicit number_type_data(type_list); + [[nodiscard]] static number_type_data_ptr get_static(); }; struct pointer_type_data final : type_data_base { @@ -547,10 +547,10 @@ namespace meta_hpp::detail const any_type data_type; template < pointer_kind Pointer > - static pointer_type_data_ptr get_static(); + explicit pointer_type_data(type_list); template < pointer_kind Pointer > - explicit pointer_type_data(type_list); + [[nodiscard]] static pointer_type_data_ptr get_static(); }; struct reference_type_data final : type_data_base { @@ -558,20 +558,20 @@ namespace meta_hpp::detail const any_type data_type; template < reference_kind Reference > - static reference_type_data_ptr get_static(); + explicit reference_type_data(type_list); template < reference_kind Reference > - explicit reference_type_data(type_list); + [[nodiscard]] static reference_type_data_ptr get_static(); }; struct void_type_data final : type_data_base { const bitflags flags; template < void_kind Void > - static void_type_data_ptr get_static(); + explicit void_type_data(type_list); template < void_kind Void > - explicit void_type_data(type_list); + [[nodiscard]] static void_type_data_ptr get_static(); }; } diff --git a/headers/meta.hpp/meta_types/array_type.hpp b/headers/meta.hpp/meta_types/array_type.hpp index effa4b5..f9db315 100644 --- a/headers/meta.hpp/meta_types/array_type.hpp +++ b/headers/meta.hpp/meta_types/array_type.hpp @@ -16,12 +16,6 @@ namespace meta_hpp::detail template < array_kind Array > struct array_tag {}; - template < array_kind Array > - array_type_data_ptr array_type_data::get_static() { - static array_type_data_ptr data = std::make_shared(type_list{}); - return data; - } - template < array_kind Array > // NOLINTNEXTLINE(readability-named-parameter) array_type_data::array_type_data(type_list) @@ -29,6 +23,12 @@ namespace meta_hpp::detail , flags{array_traits::make_flags()} , extent{array_traits::extent} , data_type{resolve_type::data_type>()} {} + + template < array_kind Array > + array_type_data_ptr array_type_data::get_static() { + static array_type_data_ptr data = std::make_shared(type_list{}); + return data; + } } namespace meta_hpp diff --git a/headers/meta.hpp/meta_types/class_type.hpp b/headers/meta.hpp/meta_types/class_type.hpp index 3ec543a..d2bb6bf 100644 --- a/headers/meta.hpp/meta_types/class_type.hpp +++ b/headers/meta.hpp/meta_types/class_type.hpp @@ -22,12 +22,6 @@ namespace meta_hpp::detail template < class_kind Class > struct class_tag {}; - template < class_kind Class > - class_type_data_ptr class_type_data::get_static() { - static class_type_data_ptr data = std::make_shared(type_list{}); - return data; - } - template < class_kind Class > // NOLINTNEXTLINE(readability-named-parameter) class_type_data::class_type_data(type_list) @@ -35,6 +29,12 @@ namespace meta_hpp::detail , flags{class_traits::make_flags()} , size{class_traits::size} , argument_types{class_traits::make_argument_types()} {} + + template < class_kind Class > + class_type_data_ptr class_type_data::get_static() { + static class_type_data_ptr data = std::make_shared(type_list{}); + return data; + } } namespace meta_hpp diff --git a/headers/meta.hpp/meta_types/ctor_type.hpp b/headers/meta.hpp/meta_types/ctor_type.hpp index 9244770..893c2f3 100644 --- a/headers/meta.hpp/meta_types/ctor_type.hpp +++ b/headers/meta.hpp/meta_types/ctor_type.hpp @@ -16,12 +16,6 @@ namespace meta_hpp::detail template < class_kind Class, typename... Args > struct ctor_tag {}; - template < class_kind Class, typename... Args > - ctor_type_data_ptr ctor_type_data::get_static() { - static ctor_type_data_ptr data = std::make_shared(type_list{}, type_list{}); - return data; - } - template < class_kind Class, typename... Args > // NOLINTNEXTLINE(readability-named-parameter) ctor_type_data::ctor_type_data(type_list, type_list) @@ -29,6 +23,12 @@ namespace meta_hpp::detail , flags{ctor_traits::make_flags()} , class_type{resolve_type::class_type>()} , argument_types{ctor_traits::make_argument_types()} {} + + template < class_kind Class, typename... Args > + ctor_type_data_ptr ctor_type_data::get_static() { + static ctor_type_data_ptr data = std::make_shared(type_list{}, type_list{}); + return data; + } } namespace meta_hpp diff --git a/headers/meta.hpp/meta_types/enum_type.hpp b/headers/meta.hpp/meta_types/enum_type.hpp index 616d2aa..f2088a5 100644 --- a/headers/meta.hpp/meta_types/enum_type.hpp +++ b/headers/meta.hpp/meta_types/enum_type.hpp @@ -18,18 +18,18 @@ namespace meta_hpp::detail template < enum_kind Enum > struct enum_tag {}; - template < enum_kind Enum > - enum_type_data_ptr enum_type_data::get_static() { - static enum_type_data_ptr data = std::make_shared(type_list{}); - return data; - } - template < enum_kind Enum > // NOLINTNEXTLINE(readability-named-parameter) enum_type_data::enum_type_data(type_list) : type_data_base{type_id{type_list>{}}, type_kind::enum_} , flags{enum_traits::make_flags()} , underlying_type{resolve_type::underlying_type>()} {} + + template < enum_kind Enum > + enum_type_data_ptr enum_type_data::get_static() { + static enum_type_data_ptr data = std::make_shared(type_list{}); + return data; + } } namespace meta_hpp diff --git a/headers/meta.hpp/meta_types/function_type.hpp b/headers/meta.hpp/meta_types/function_type.hpp index c8474da..2580b9e 100644 --- a/headers/meta.hpp/meta_types/function_type.hpp +++ b/headers/meta.hpp/meta_types/function_type.hpp @@ -16,12 +16,6 @@ namespace meta_hpp::detail template < function_kind Function > struct function_tag {}; - template < function_kind Function > - function_type_data_ptr function_type_data::get_static() { - static function_type_data_ptr data = std::make_shared(type_list{}); - return data; - } - template < function_kind Function > // NOLINTNEXTLINE(readability-named-parameter) function_type_data::function_type_data(type_list) @@ -29,6 +23,12 @@ namespace meta_hpp::detail , flags{function_traits::make_flags()} , return_type{resolve_type::return_type>()} , argument_types{function_traits::make_argument_types()} {} + + template < function_kind Function > + function_type_data_ptr function_type_data::get_static() { + static function_type_data_ptr data = std::make_shared(type_list{}); + return data; + } } namespace meta_hpp diff --git a/headers/meta.hpp/meta_types/member_type.hpp b/headers/meta.hpp/meta_types/member_type.hpp index 7e21181..7935e22 100644 --- a/headers/meta.hpp/meta_types/member_type.hpp +++ b/headers/meta.hpp/meta_types/member_type.hpp @@ -16,12 +16,6 @@ namespace meta_hpp::detail template < member_kind Member > struct member_tag {}; - template < member_kind Member > - member_type_data_ptr member_type_data::get_static() { - static member_type_data_ptr data = std::make_shared(type_list{}); - return data; - } - template < member_kind Member > // NOLINTNEXTLINE(readability-named-parameter) member_type_data::member_type_data(type_list) @@ -29,6 +23,12 @@ namespace meta_hpp::detail , flags{member_traits::make_flags()} , owner_type{resolve_type::class_type>()} , value_type{resolve_type::value_type>()} {} + + template < member_kind Member > + member_type_data_ptr member_type_data::get_static() { + static member_type_data_ptr data = std::make_shared(type_list{}); + return data; + } } namespace meta_hpp diff --git a/headers/meta.hpp/meta_types/method_type.hpp b/headers/meta.hpp/meta_types/method_type.hpp index d06d6a5..7fdaa1c 100644 --- a/headers/meta.hpp/meta_types/method_type.hpp +++ b/headers/meta.hpp/meta_types/method_type.hpp @@ -16,12 +16,6 @@ namespace meta_hpp::detail template < method_kind Method > struct method_tag {}; - template < method_kind Method > - method_type_data_ptr method_type_data::get_static() { - static method_type_data_ptr data = std::make_shared(type_list{}); - return data; - } - template < method_kind Method > // NOLINTNEXTLINE(readability-named-parameter) method_type_data::method_type_data(type_list) @@ -30,6 +24,12 @@ namespace meta_hpp::detail , owner_type{resolve_type::class_type>()} , return_type{resolve_type::return_type>()} , argument_types{method_traits::make_argument_types()} {} + + template < method_kind Method > + method_type_data_ptr method_type_data::get_static() { + static method_type_data_ptr data = std::make_shared(type_list{}); + return data; + } } namespace meta_hpp diff --git a/headers/meta.hpp/meta_types/number_type.hpp b/headers/meta.hpp/meta_types/number_type.hpp index d06db7e..066e78c 100644 --- a/headers/meta.hpp/meta_types/number_type.hpp +++ b/headers/meta.hpp/meta_types/number_type.hpp @@ -16,18 +16,18 @@ namespace meta_hpp::detail template < number_kind Number > struct number_tag {}; - template < number_kind Number > - number_type_data_ptr number_type_data::get_static() { - static number_type_data_ptr data = std::make_shared(type_list{}); - return data; - } - template < number_kind Number > // NOLINTNEXTLINE(readability-named-parameter) number_type_data::number_type_data(type_list) : type_data_base{type_id{type_list>{}}, type_kind::number_} , flags{number_traits::make_flags()} , size{number_traits::size} {} + + template < number_kind Number > + number_type_data_ptr number_type_data::get_static() { + static number_type_data_ptr data = std::make_shared(type_list{}); + return data; + } } namespace meta_hpp diff --git a/headers/meta.hpp/meta_types/pointer_type.hpp b/headers/meta.hpp/meta_types/pointer_type.hpp index 95889b2..b9b763a 100644 --- a/headers/meta.hpp/meta_types/pointer_type.hpp +++ b/headers/meta.hpp/meta_types/pointer_type.hpp @@ -16,18 +16,18 @@ namespace meta_hpp::detail template < pointer_kind Pointer > struct pointer_tag {}; - template < pointer_kind Pointer > - pointer_type_data_ptr pointer_type_data::get_static() { - static pointer_type_data_ptr data = std::make_shared(type_list{}); - return data; - } - template < pointer_kind Pointer > // NOLINTNEXTLINE(readability-named-parameter) pointer_type_data::pointer_type_data(type_list) : type_data_base{type_id{type_list>{}}, type_kind::pointer_} , flags{pointer_traits::make_flags()} , data_type{resolve_type::data_type>()} {} + + template < pointer_kind Pointer > + pointer_type_data_ptr pointer_type_data::get_static() { + static pointer_type_data_ptr data = std::make_shared(type_list{}); + return data; + } } namespace meta_hpp diff --git a/headers/meta.hpp/meta_types/reference_type.hpp b/headers/meta.hpp/meta_types/reference_type.hpp index 2725773..e7c04b8 100644 --- a/headers/meta.hpp/meta_types/reference_type.hpp +++ b/headers/meta.hpp/meta_types/reference_type.hpp @@ -16,18 +16,18 @@ namespace meta_hpp::detail template < reference_kind Reference > struct reference_tag {}; - template < reference_kind Reference > - reference_type_data_ptr reference_type_data::get_static() { - static reference_type_data_ptr data = std::make_shared(type_list{}); - return data; - } - template < reference_kind Reference > // NOLINTNEXTLINE(readability-named-parameter) reference_type_data::reference_type_data(type_list) : type_data_base{type_id{type_list>{}}, type_kind::reference_} , flags{reference_traits::make_flags()} , data_type{resolve_type::data_type>()} {} + + template < reference_kind Reference > + reference_type_data_ptr reference_type_data::get_static() { + static reference_type_data_ptr data = std::make_shared(type_list{}); + return data; + } } namespace meta_hpp diff --git a/headers/meta.hpp/meta_types/void_type.hpp b/headers/meta.hpp/meta_types/void_type.hpp index ce5a1f5..0ca40e9 100644 --- a/headers/meta.hpp/meta_types/void_type.hpp +++ b/headers/meta.hpp/meta_types/void_type.hpp @@ -16,17 +16,17 @@ namespace meta_hpp::detail template < void_kind Void > struct void_tag {}; - template < void_kind Void > - void_type_data_ptr void_type_data::get_static() { - static void_type_data_ptr data = std::make_shared(type_list{}); - return data; - } - template < void_kind Void > // NOLINTNEXTLINE(readability-named-parameter) void_type_data::void_type_data(type_list) : type_data_base{type_id{type_list>{}}, type_kind::void_} , flags{void_traits::make_flags()} {} + + template < void_kind Void > + void_type_data_ptr void_type_data::get_static() { + static void_type_data_ptr data = std::make_shared(type_list{}); + return data; + } } namespace meta_hpp From 0b8ce9a1645226f3f867c5b7102fd90b32530c17 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Tue, 4 Jan 2022 05:31:44 +0700 Subject: [PATCH 137/233] use span instead raw pointer of argument list --- headers/meta.hpp/meta_base.hpp | 1 + headers/meta.hpp/meta_states.hpp | 12 +-- headers/meta.hpp/meta_states/ctor.hpp | 78 ++++++--------- headers/meta.hpp/meta_states/function.hpp | 96 +++++++----------- headers/meta.hpp/meta_states/method.hpp | 116 ++++++++-------------- headers/meta.hpp/meta_states/variable.hpp | 3 +- 6 files changed, 117 insertions(+), 189 deletions(-) diff --git a/headers/meta.hpp/meta_base.hpp b/headers/meta.hpp/meta_base.hpp index e69e458..1e2aa17 100644 --- a/headers/meta.hpp/meta_base.hpp +++ b/headers/meta.hpp/meta_base.hpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include diff --git a/headers/meta.hpp/meta_states.hpp b/headers/meta.hpp/meta_states.hpp index cda291a..15d1079 100644 --- a/headers/meta.hpp/meta_states.hpp +++ b/headers/meta.hpp/meta_states.hpp @@ -230,8 +230,8 @@ namespace meta_hpp namespace meta_hpp::detail { struct ctor_state final { - using invoke_impl = std::function; - using is_invocable_with_impl = std::function; + using invoke_impl = std::function)>; + using is_invocable_with_impl = std::function)>; ctor_index index; @@ -258,8 +258,8 @@ namespace meta_hpp::detail }; struct function_state final { - using invoke_impl = std::function(const arg*, std::size_t)>; - using is_invocable_with_impl = std::function; + using invoke_impl = std::function(std::span)>; + using is_invocable_with_impl = std::function)>; function_index index; @@ -290,8 +290,8 @@ namespace meta_hpp::detail }; struct method_state final { - using invoke_impl = std::function(const inst&, const arg*, std::size_t)>; - using is_invocable_with_impl = std::function; + using invoke_impl = std::function(const inst&, std::span)>; + using is_invocable_with_impl = std::function)>; method_index index; diff --git a/headers/meta.hpp/meta_states/ctor.hpp b/headers/meta.hpp/meta_states/ctor.hpp index b004c81..2175fe0 100644 --- a/headers/meta.hpp/meta_states/ctor.hpp +++ b/headers/meta.hpp/meta_states/ctor.hpp @@ -13,84 +13,62 @@ namespace meta_hpp::detail { - template < class_kind Class, typename... Args, std::size_t... Is > - value raw_ctor_invoke_impl( - const arg* args, - std::index_sequence) - { + template < 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; - if ( !(... && (args + Is)->can_cast_to>()) ) { - throw std::logic_error("an attempt to call a constructor with an incorrect argument types"); - } - - class_type return_value{(args + Is)->cast>()...}; - return value{std::forward(return_value)}; - } - - template < class_kind Class, typename... Args > - value raw_ctor_invoke( - const arg* args, - std::size_t arg_count) - { - using ct = ctor_traits; - - if ( arg_count != ct::arity ) { + if ( args.size() != ct::arity ) { throw std::logic_error("an attempt to call a constructor with an incorrect arity"); } - return raw_ctor_invoke_impl( - args, - std::make_index_sequence()); + // NOLINTNEXTLINE(readability-named-parameter) + return std::invoke([&args](std::index_sequence){ + 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)}; + }, std::make_index_sequence()); } template < class_kind Class, typename... Args > ctor_state::invoke_impl make_ctor_invoke() { using namespace std::placeholders; - return std::bind(&raw_ctor_invoke, _1, _2); + return std::bind(&raw_ctor_invoke, _1); } } namespace meta_hpp::detail { - template < class_kind Class, typename... Args, std::size_t... Is > - bool raw_ctor_is_invocable_with_impl( - const arg_base* args, - std::index_sequence) - { + template < class_kind Class, typename... Args > + bool raw_ctor_is_invocable_with(std::span args) { using ct = ctor_traits; using argument_types = typename ct::argument_types; - return (... && (args + Is)->can_cast_to>() ); - } - template < class_kind Class, typename... Args > - bool raw_ctor_is_invocable_with( - const arg_base* args, - std::size_t arg_count) - { - using ct = ctor_traits; - - if ( arg_count != ct::arity ) { + if ( args.size() != ct::arity ) { return false; } - return raw_ctor_is_invocable_with_impl( - args, - std::make_index_sequence()); + // NOLINTNEXTLINE(readability-named-parameter) + return std::invoke([&args](std::index_sequence){ + return (... && (args.data() + Is)->can_cast_to>()); + }, std::make_index_sequence()); } template < class_kind Class, typename... Args > ctor_state::is_invocable_with_impl make_ctor_is_invocable_with() { using namespace std::placeholders; - return std::bind(&raw_ctor_is_invocable_with, _1, _2); + 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()} @@ -129,9 +107,9 @@ namespace meta_hpp using namespace detail; if constexpr ( sizeof...(Args) > 0 ) { std::array vargs{arg{std::forward(args)}...}; - return state_->invoke(vargs.data(), vargs.size()); + return state_->invoke(vargs); } else { - return state_->invoke(nullptr, 0); + return state_->invoke({}); } } @@ -145,9 +123,9 @@ namespace meta_hpp using namespace detail; if constexpr ( sizeof...(Args) > 0 ) { std::array vargs{arg_base{type_list{}}...}; - return state_->is_invocable_with(vargs.data(), vargs.size()); + return state_->is_invocable_with(vargs); } else { - return state_->is_invocable_with(nullptr, 0); + return state_->is_invocable_with({}); } } @@ -156,9 +134,9 @@ namespace meta_hpp using namespace detail; if constexpr ( sizeof...(Args) > 0 ) { std::array vargs{arg{std::forward(args)}...}; - return state_->is_invocable_with(vargs.data(), vargs.size()); + return state_->is_invocable_with(vargs); } else { - return state_->is_invocable_with(nullptr, 0); + return state_->is_invocable_with({}); } } } diff --git a/headers/meta.hpp/meta_states/function.hpp b/headers/meta.hpp/meta_states/function.hpp index 48578ec..f40c6f0 100644 --- a/headers/meta.hpp/meta_states/function.hpp +++ b/headers/meta.hpp/meta_states/function.hpp @@ -13,88 +13,64 @@ namespace meta_hpp::detail { - template < function_kind Function, std::size_t... Is > - std::optional raw_function_invoke_impl( - Function function, - const arg* args, - std::index_sequence) - { + template < 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; - if ( !(... && (args + Is)->can_cast_to>()) ) { - throw std::logic_error("an attempt to call a function with an incorrect argument types"); - } - - if constexpr ( std::is_void_v ) { - std::invoke(function, - (args + Is)->cast>()...); - return std::nullopt; - } else { - return_type return_value{std::invoke(function, - (args + Is)->cast>()...)}; - return value{std::forward(return_value)}; - } - } - - template < function_kind Function > - std::optional raw_function_invoke( - Function function, - const arg* args, - std::size_t arg_count) - { - using ft = function_traits; - - if ( arg_count != ft::arity ) { + if ( args.size() != ft::arity ) { throw std::logic_error("an attempt to call a function with an incorrect arity"); } - return raw_function_invoke_impl( - function, - args, - std::make_index_sequence()); + // NOLINTNEXTLINE(readability-named-parameter) + return std::invoke([&function, &args](std::index_sequence){ + 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( + std::move(function), + (args.data() + Is)->cast>()...); + return std::nullopt; + } else { + return_type return_value{std::invoke( + std::move(function), + (args.data() + Is)->cast>()...)}; + return value{std::forward(return_value)}; + } + }, std::make_index_sequence()); } template < function_kind Function > function_state::invoke_impl make_function_invoke(Function function) { using namespace std::placeholders; - return std::bind(&raw_function_invoke, function, _1, _2); + return std::bind(&raw_function_invoke, function, _1); } } namespace meta_hpp::detail { - template < function_kind Function, std::size_t... Is > - bool raw_function_is_invocable_with_impl( - const arg_base* args, - std::index_sequence) - { + template < function_kind Function > + bool raw_function_is_invocable_with(std::span args) { using ft = function_traits; using argument_types = typename ft::argument_types; - return (... && (args + Is)->can_cast_to>() ); - } - template < function_kind Function > - bool raw_function_is_invocable_with( - const arg_base* args, - std::size_t arg_count) - { - using ft = function_traits; - - if ( arg_count != ft::arity ) { + if ( args.size() != ft::arity ) { return false; } - return raw_function_is_invocable_with_impl( - args, - std::make_index_sequence()); + // NOLINTNEXTLINE(readability-named-parameter) + return std::invoke([&args](std::index_sequence){ + return (... && (args.data() + Is)->can_cast_to>()); + }, std::make_index_sequence()); } template < function_kind Function > function_state::is_invocable_with_impl make_function_is_invocable_with() { using namespace std::placeholders; - return std::bind(&raw_function_is_invocable_with, _1, _2); + return std::bind(&raw_function_is_invocable_with, _1); } } @@ -143,9 +119,9 @@ namespace meta_hpp using namespace detail; if constexpr ( sizeof...(Args) > 0 ) { std::array vargs{arg{std::forward(args)}...}; - return state_->invoke(vargs.data(), vargs.size()); + return state_->invoke(vargs); } else { - return state_->invoke(nullptr, 0); + return state_->invoke({}); } } @@ -159,9 +135,9 @@ namespace meta_hpp using namespace detail; if constexpr ( sizeof...(Args) > 0 ) { std::array vargs{arg_base{type_list{}}...}; - return state_->is_invocable_with(vargs.data(), vargs.size()); + return state_->is_invocable_with(vargs); } else { - return state_->is_invocable_with(nullptr, 0); + return state_->is_invocable_with({}); } } @@ -170,9 +146,9 @@ namespace meta_hpp using namespace detail; if constexpr ( sizeof...(Args) > 0 ) { std::array vargs{arg{std::forward(args)}...}; - return state_->is_invocable_with(vargs.data(), vargs.size()); + return state_->is_invocable_with(vargs); } else { - return state_->is_invocable_with(nullptr, 0); + return state_->is_invocable_with({}); } } } diff --git a/headers/meta.hpp/meta_states/method.hpp b/headers/meta.hpp/meta_states/method.hpp index 9ed1c64..2d303bb 100644 --- a/headers/meta.hpp/meta_states/method.hpp +++ b/headers/meta.hpp/meta_states/method.hpp @@ -13,104 +13,76 @@ namespace meta_hpp::detail { - template < method_kind Method, std::size_t... Is > - std::optional raw_method_invoke_impl( - Method method, - const inst& inst, - const arg* args, - std::index_sequence) - { + template < 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; + if ( args.size() != mt::arity ) { + throw std::logic_error("an attempt to call a method with an incorrect arity"); + } + if ( !inst.can_cast_to() ) { throw std::logic_error("an attempt to call a method with an incorrect instance type"); } - if ( !(... && (args + Is)->can_cast_to>()) ) { - throw std::logic_error("an attempt to call a method with an incorrect argument types"); - } + // NOLINTNEXTLINE(readability-named-parameter) + return std::invoke([&method, &inst, &args](std::index_sequence){ + 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(method, - inst.cast(), - (args + Is)->cast>()...); - return std::nullopt; - } else { - return_type return_value{std::invoke(method, - inst.cast(), - (args + Is)->cast>()...)}; - return value{std::forward(return_value)}; - } - } - - template < method_kind Method > - std::optional raw_method_invoke( - Method method, - const inst& inst, - const arg* args, - std::size_t arg_count) - { - using mt = method_traits; - - if ( arg_count != mt::arity ) { - throw std::logic_error("an attempt to call a method with an incorrect arity"); - } - - return raw_method_invoke_impl( - method, - inst, - args, - std::make_index_sequence()); + if constexpr ( std::is_void_v ) { + std::invoke( + std::move(method), + inst.cast(), + (args.data() + Is)->cast>()...); + return std::nullopt; + } else { + return_type return_value{std::invoke( + std::move(method), + inst.cast(), + (args.data() + Is)->cast>()...)}; + return value{std::forward(return_value)}; + } + }, std::make_index_sequence()); } template < method_kind Method > method_state::invoke_impl make_method_invoke(Method method) { using namespace std::placeholders; - return std::bind(&raw_method_invoke, method, _1, _2, _3); + return std::bind(&raw_method_invoke, method, _1, _2); } } namespace meta_hpp::detail { - template < method_kind Method, std::size_t... Is > - bool raw_method_is_invocable_with_impl( - const inst_base& inst, - const arg_base* args, - std::index_sequence) - { + template < method_kind Method > + 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; - return inst.can_cast_to() - && (... && (args + Is)->can_cast_to>() ); - } - - template < method_kind Method > - bool raw_method_is_invocable_with( - const inst_base& inst, - const arg_base* args, - std::size_t arg_count) - { - using mt = method_traits; - - if ( arg_count != mt::arity ) { + if ( args.size() != mt::arity ) { return false; } - return raw_method_is_invocable_with_impl( - inst, - args, - std::make_index_sequence()); + if ( !inst.can_cast_to() ) { + return false; + } + + // NOLINTNEXTLINE(readability-named-parameter) + return std::invoke([&args](std::index_sequence){ + return (... && (args.data() + Is)->can_cast_to>()); + }, std::make_index_sequence()); } template < method_kind Method > method_state::is_invocable_with_impl make_method_is_invocable_with() { using namespace std::placeholders; - return std::bind(&raw_method_is_invocable_with, _1, _2, _3); + return std::bind(&raw_method_is_invocable_with, _1, _2); } } @@ -159,9 +131,9 @@ namespace meta_hpp using namespace detail; if constexpr ( sizeof...(Args) > 0 ) { std::array vargs{arg{std::forward(args)}...}; - return state_->invoke(inst{std::forward(instance)}, vargs.data(), vargs.size()); + return state_->invoke(inst{std::forward(instance)}, vargs); } else { - return state_->invoke(inst{std::forward(instance)}, nullptr, 0); + return state_->invoke(inst{std::forward(instance)}, {}); } } @@ -175,9 +147,9 @@ namespace meta_hpp using namespace detail; if constexpr ( sizeof...(Args) > 0 ) { std::array vargs{arg_base{type_list{}}...}; - return state_->is_invocable_with(inst_base{type_list{}}, vargs.data(), vargs.size()); + return state_->is_invocable_with(inst_base{type_list{}}, vargs); } else { - return state_->is_invocable_with(inst_base{type_list{}}, nullptr, 0); + return state_->is_invocable_with(inst_base{type_list{}}, {}); } } @@ -186,9 +158,9 @@ namespace meta_hpp using namespace detail; if constexpr ( sizeof...(Args) > 0 ) { std::array vargs{arg{std::forward(args)}...}; - return state_->is_invocable_with(inst{std::forward(instance)}, vargs.data(), vargs.size()); + return state_->is_invocable_with(inst{std::forward(instance)}, vargs); } else { - return state_->is_invocable_with(inst{std::forward(instance)}, nullptr, 0); + return state_->is_invocable_with(inst{std::forward(instance)}, {}); } } } diff --git a/headers/meta.hpp/meta_states/variable.hpp b/headers/meta.hpp/meta_states/variable.hpp index 87d3c01..044fdf8 100644 --- a/headers/meta.hpp/meta_states/variable.hpp +++ b/headers/meta.hpp/meta_states/variable.hpp @@ -100,6 +100,7 @@ namespace meta_hpp template < typename Value > void variable::set(Value&& value) const { - state_->setter(detail::arg{std::forward(value)}); + using namespace detail; + state_->setter(arg{std::forward(value)}); } } From ff1fb1fbd775fa860ee486d5e86e154a79f4f242 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Tue, 4 Jan 2022 08:30:10 +0700 Subject: [PATCH 138/233] cleanup value class --- headers/meta.hpp/meta_utilities.hpp | 117 +++++++++++++++----- headers/meta.hpp/meta_utilities/value.hpp | 124 +++++++--------------- untests/meta_utilities/value_tests.cpp | 4 +- 3 files changed, 130 insertions(+), 115 deletions(-) diff --git a/headers/meta.hpp/meta_utilities.hpp b/headers/meta.hpp/meta_utilities.hpp index 3058542..33610c8 100644 --- a/headers/meta.hpp/meta_utilities.hpp +++ b/headers/meta.hpp/meta_utilities.hpp @@ -31,69 +31,128 @@ namespace meta_hpp::detail requires { static_cast(std::declval()); }; } +namespace meta_hpp::detail +{ + template < typename T > + concept value_kind = + std::same_as; + + template < typename T > + concept decay_value_kind = + value_kind>; + + template < typename T > + concept uvalue_kind = + std::same_as || + std::same_as || + std::same_as; + + template < typename T > + concept decay_uvalue_kind = + uvalue_kind>; + + template < typename T > + concept decay_non_uvalue_kind = + (!decay_uvalue_kind); + + template < typename T > + concept arg_lvalue_ref_kind = + (std::is_lvalue_reference_v); + + template < typename T > + concept arg_rvalue_ref_kind = + (!std::is_reference_v) || + (std::is_rvalue_reference_v); + + template < typename T > + concept inst_class_ref_kind = + (std::is_class_v) || + (std::is_reference_v && std::is_class_v>); + + template < typename T > + concept inst_class_lvalue_ref_kind = + (std::is_lvalue_reference_v && std::is_class_v>); + + template < typename T > + concept inst_class_rvalue_ref_kind = + (std::is_class_v) || + (std::is_rvalue_reference_v && std::is_class_v>); +} + +namespace meta_hpp::detail +{ + template < typename T > + concept has_less_op_kind = requires(const T& v) { + { v < v } -> convertible_to; + }; + + template < typename T > + concept has_equals_op_kind = requires(const T& v) { + { v == v } -> convertible_to; + }; + + template < typename T > + concept has_istream_op_kind = requires(std::istream& is, T& v) { + { is >> v } -> convertible_to; + }; + + template < typename T > + concept has_ostream_op_kind = requires(std::ostream& os, const T& v) { + { os << v } -> convertible_to; + }; +} + namespace meta_hpp { class value final { public: value() = delete; + // NOLINTNEXTLINE(performance-noexcept-move-constructor) value(value&& other); value(const value& other); + // NOLINTNEXTLINE(performance-noexcept-move-constructor) value& operator=(value&& other); value& operator=(const value& other); - template < typename T, typename Tp = std::decay_t - , std::enable_if_t, int> = 0 - , std::enable_if_t, int> = 0 - , std::enable_if_t, int> = 0 > + ~value() = default; + + template < detail::decay_non_uvalue_kind T > explicit value(T&& val); - template < typename T, typename Tp = std::decay_t - , std::enable_if_t, int> = 0 - , std::enable_if_t, int> = 0 - , std::enable_if_t, int> = 0 > + template < detail::decay_non_uvalue_kind T > value& operator=(T&& val); void swap(value& other) noexcept; - const any_type& get_type() const noexcept; + [[nodiscard]] const any_type& get_type() const noexcept; - void* data() noexcept; - const void* data() const noexcept; - const void* cdata() const noexcept; + [[nodiscard]] void* data() noexcept; + [[nodiscard]] const void* data() const noexcept; + [[nodiscard]] const void* cdata() const noexcept; template < typename T, typename Tp = std::decay_t > - Tp& cast() &; + [[nodiscard]] Tp& cast() &; template < typename T, typename Tp = std::decay_t > - Tp&& cast() &&; + [[nodiscard]] Tp&& cast() &&; template < typename T, typename Tp = std::decay_t > - const Tp& cast() const &; + [[nodiscard]] const Tp& cast() const &; template < typename T, typename Tp = std::decay_t > - const Tp&& cast() const &&; + [[nodiscard]] const Tp&& cast() const &&; template < typename T, typename Tp = std::decay_t > - Tp* try_cast() noexcept; + [[nodiscard]] Tp* try_cast() noexcept; template < typename T, typename Tp = std::decay_t > - const Tp* try_cast() const noexcept; + [[nodiscard]] const Tp* try_cast() const noexcept; - template < typename T > - friend bool operator<(const value& l, const T& r); - template < typename T > - friend bool operator<(const T& l, const value& r); friend bool operator<(const value& l, const value& r); - - template < typename T > - friend bool operator==(const value& l, const T& r); - template < typename T > - friend bool operator==(const T& l, const value& r); friend bool operator==(const value& l, const value& r); - - friend std::istream& operator>>(std::istream& os, value& v); + friend std::istream& operator>>(std::istream& is, value& v); friend std::ostream& operator<<(std::ostream& os, const value& v); private: struct traits; diff --git a/headers/meta.hpp/meta_utilities/value.hpp b/headers/meta.hpp/meta_utilities/value.hpp index 2f6cd54..7be7bad 100644 --- a/headers/meta.hpp/meta_utilities/value.hpp +++ b/headers/meta.hpp/meta_utilities/value.hpp @@ -9,50 +9,6 @@ #include "../meta_base.hpp" #include "../meta_utilities.hpp" -namespace meta_hpp::detail -{ - template < typename T, typename = void > - struct has_value_type_less_op : std::false_type {}; - - template < typename T > - struct has_value_type_less_op() < std::declval() - )>> : std::true_type {}; -} - -namespace meta_hpp::detail -{ - template < typename T, typename = void > - struct has_value_type_equals_op : std::false_type {}; - - template < typename T > - struct has_value_type_equals_op() == std::declval() - )>> : std::true_type {}; -} - -namespace meta_hpp::detail -{ - template < typename T, typename = void > - struct has_value_type_istream_op : std::false_type {}; - - template < typename T > - struct has_value_type_istream_op() >> std::declval() - )>> : std::true_type {}; -} - -namespace meta_hpp::detail -{ - template < typename T, typename = void > - struct has_value_type_ostream_op : std::false_type {}; - - template < typename T > - struct has_value_type_ostream_op() << std::declval() - )>> : std::true_type {}; -} - namespace meta_hpp { struct value::traits final { @@ -87,23 +43,23 @@ namespace meta_hpp return v.try_cast(); }, - .less = +[](const value& l, const value& r) -> bool { - if constexpr ( detail::has_value_type_less_op::value ) { + .less = +[]([[maybe_unused]] const value& l, [[maybe_unused]] const value& r) -> bool { + if constexpr ( detail::has_less_op_kind ) { return l.cast() < r.cast(); } else { throw std::logic_error("value type doesn't have less operator"); } }, - .equals = +[](const value& l, const value& r) -> bool { - if constexpr ( detail::has_value_type_equals_op::value ) { + .equals = +[]([[maybe_unused]] const value& l, [[maybe_unused]] const value& r) -> bool { + if constexpr ( detail::has_equals_op_kind ) { return l.cast() == r.cast(); } else { throw std::logic_error("value type doesn't have equality operator"); } }, - .move_ctor = +[](std::any& dst, value&& src) { + .move_ctor = +[]([[maybe_unused]] std::any& dst, [[maybe_unused]] value&& src) { if constexpr ( std::is_move_constructible_v ) { dst.emplace(std::move(src).cast()); } else { @@ -111,7 +67,7 @@ namespace meta_hpp } }, - .copy_ctor = +[](std::any& dst, const value& src) { + .copy_ctor = +[]([[maybe_unused]] std::any& dst, [[maybe_unused]] const value& src) { if constexpr ( std::is_copy_constructible_v ) { dst.emplace(src.cast()); } else { @@ -119,16 +75,16 @@ namespace meta_hpp } }, - .istream = +[](std::istream& os, value& v) -> std::istream& { - if constexpr ( detail::has_value_type_istream_op::value ) { - return os >> v.cast(); + .istream = +[]([[maybe_unused]] std::istream& is, [[maybe_unused]] value& v) -> std::istream& { + if constexpr ( detail::has_istream_op_kind ) { + return is >> v.cast(); } else { throw std::logic_error("value type doesn't have istream operator"); } }, - .ostream = +[](std::ostream& os, const value& v) -> std::ostream& { - if constexpr ( detail::has_value_type_ostream_op::value ) { + .ostream = +[]([[maybe_unused]] std::ostream& os, [[maybe_unused]] const value& v) -> std::ostream& { + if constexpr ( detail::has_ostream_op_kind ) { return os << v.cast(); } else { throw std::logic_error("value type doesn't have ostream operator"); @@ -141,16 +97,18 @@ namespace meta_hpp namespace meta_hpp { - inline value::value(value&& other) { - traits_ = other.traits_; + // NOLINTNEXTLINE(performance-noexcept-move-constructor) + inline value::value(value&& other) + : traits_{other.traits_} { traits_->move_ctor(raw_, std::move(other)); } - inline value::value(const value& other) { - traits_ = other.traits_; + inline value::value(const value& other) + : traits_{other.traits_} { traits_->copy_ctor(raw_, other); } + // NOLINTNEXTLINE(performance-noexcept-move-constructor) inline value& value::operator=(value&& other) { if ( this != &other ) { traits_ = other.traits_; @@ -167,21 +125,15 @@ namespace meta_hpp return *this; } - template < typename T, typename Tp - , std::enable_if_t, int> - , std::enable_if_t, int> - , std::enable_if_t, int> > + template < detail::decay_non_uvalue_kind T > value::value(T&& val) : raw_{std::forward(val)} - , traits_{traits::get()} {} + , traits_{traits::get>()} {} - template < typename T, typename Tp - , std::enable_if_t, int> - , std::enable_if_t, int> - , std::enable_if_t, int> > + template < detail::decay_non_uvalue_kind T > value& value::operator=(T&& val) { - raw_ = std::forward(val); - traits_ = resolve_type(); + value temp{std::forward(val)}; + swap(temp); return *this; } @@ -253,38 +205,42 @@ namespace meta_hpp namespace meta_hpp { template < typename T > - bool operator<(const value& l, const T& r) { + [[nodiscard]] bool operator<(const value& l, const T& r) { const any_type& r_type = resolve_type(); - return (l.get_type() < r_type) || (l.get_type() == r_type && std::less<>{}(l.cast(), r)); + return (l.get_type() < r_type) + || (l.get_type() == r_type && std::less<>{}(l.cast(), r)); } template < typename T > - bool operator<(const T& l, const value& r) { + [[nodiscard]] bool operator<(const T& l, const value& r) { const any_type& l_type = resolve_type(); - return (l_type < r.get_type()) || (l_type == r.get_type() && std::less<>{}(l, r.cast())); + return (l_type < r.get_type()) + || (l_type == r.get_type() && std::less<>{}(l, r.cast())); } - inline bool operator<(const value& l, const value& r) { - return (l.get_type() < r.get_type()) || (l.get_type() == r.get_type() && l.traits_->less(l, r)); + [[nodiscard]] inline bool operator<(const value& l, const value& r) { + return (l.get_type() < r.get_type()) + || (l.get_type() == r.get_type() && l.traits_->less(l, r)); } } namespace meta_hpp { template < typename T > - bool operator==(const value& l, const T& r) { - const any_type& r_type = resolve_type(); - return l.get_type() == r_type && std::equal_to<>{}(l.cast(), r); + [[nodiscard]] bool operator==(const value& l, const T& r) { + return l.get_type() == resolve_type() + && std::equal_to<>{}(l.cast(), r); } template < typename T > - bool operator==(const T& l, const value& r) { - const any_type& l_type = resolve_type(); - return l_type == r.get_type() && std::equal_to<>{}(l, r.cast()); + [[nodiscard]] bool operator==(const T& l, const value& r) { + return resolve_type() == r.get_type() + && std::equal_to<>{}(l, r.cast()); } - inline bool operator==(const value& l, const value& r) { - return l.get_type() == r.get_type() && l.traits_->equals(l, r); + [[nodiscard]] inline bool operator==(const value& l, const value& r) { + return l.get_type() == r.get_type() + && l.traits_->equals(l, r); } } diff --git a/untests/meta_utilities/value_tests.cpp b/untests/meta_utilities/value_tests.cpp index 740bcac..72f212c 100644 --- a/untests/meta_utilities/value_tests.cpp +++ b/untests/meta_utilities/value_tests.cpp @@ -304,7 +304,7 @@ TEST_CASE("meta/meta_utilities/value") { class empty_class2 {}; CHECK(operator<(meta::value{empty_class1{}}, meta::value{empty_class2{}})); - CHECK_THROWS(operator<(meta::value{empty_class1{}}, meta::value{empty_class1{}})); + CHECK_THROWS(std::ignore = operator<(meta::value{empty_class1{}}, meta::value{empty_class1{}})); } } @@ -323,7 +323,7 @@ TEST_CASE("meta/meta_utilities/value") { class empty_class2 {}; CHECK_FALSE(operator==(meta::value{empty_class1{}}, meta::value{empty_class2{}})); - CHECK_THROWS(operator==(meta::value{empty_class1{}}, meta::value{empty_class1{}})); + CHECK_THROWS(std::ignore = operator==(meta::value{empty_class1{}}, meta::value{empty_class1{}})); } } } From ee273b1f5538c83f294e16d128205deb9af0dd2b Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 7 Jan 2022 13:54:37 +0700 Subject: [PATCH 139/233] add cvref_traits utility --- headers/meta.hpp/meta_utilities.hpp | 25 ++++++++ untests/meta_utilities/detail_tests.cpp | 84 +++++++++++++++++++++++++ 2 files changed, 109 insertions(+) create mode 100644 untests/meta_utilities/detail_tests.cpp diff --git a/headers/meta.hpp/meta_utilities.hpp b/headers/meta.hpp/meta_utilities.hpp index 33610c8..2d585dc 100644 --- a/headers/meta.hpp/meta_utilities.hpp +++ b/headers/meta.hpp/meta_utilities.hpp @@ -9,6 +9,31 @@ #include "meta_base.hpp" #include "meta_types.hpp" +namespace meta_hpp::detail +{ + template < typename From > + struct cvref_traits { + static constexpr bool is_lvalue = std::is_lvalue_reference_v; + static constexpr bool is_rvalue = std::is_rvalue_reference_v; + static constexpr bool is_const = std::is_const_v>; + static constexpr bool is_volatile = std::is_volatile_v>; + + template < bool yesno, template < typename > typename Q, typename V > + using apply_t_if = std::conditional_t, V>; + + template < typename To > + using copy_to = + apply_t_if>>>>; + }; + + template < typename From, typename To > + using copy_cvref_t = typename cvref_traits::template copy_to; +} + namespace meta_hpp::detail { template < typename T > diff --git a/untests/meta_utilities/detail_tests.cpp b/untests/meta_utilities/detail_tests.cpp new file mode 100644 index 0000000..2669d0d --- /dev/null +++ b/untests/meta_utilities/detail_tests.cpp @@ -0,0 +1,84 @@ +/******************************************************************************* + * 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_tests.hpp" + +TEST_CASE("features/meta_utilities/detail") { + namespace meta = meta_hpp; + + SUBCASE("cvref_traits") { + static_assert(!meta::detail::cvref_traits::is_lvalue); + static_assert(!meta::detail::cvref_traits::is_rvalue); + static_assert(!meta::detail::cvref_traits::is_const); + static_assert(!meta::detail::cvref_traits::is_volatile); + + static_assert(!meta::detail::cvref_traits::is_lvalue); + static_assert(!meta::detail::cvref_traits::is_rvalue); + static_assert(meta::detail::cvref_traits::is_const); + static_assert(!meta::detail::cvref_traits::is_volatile); + + static_assert(!meta::detail::cvref_traits::is_lvalue); + static_assert(!meta::detail::cvref_traits::is_rvalue); + static_assert(meta::detail::cvref_traits::is_const); + static_assert(meta::detail::cvref_traits::is_volatile); + + static_assert(meta::detail::cvref_traits::is_lvalue); + static_assert(!meta::detail::cvref_traits::is_rvalue); + static_assert(!meta::detail::cvref_traits::is_const); + static_assert(!meta::detail::cvref_traits::is_volatile); + + static_assert(meta::detail::cvref_traits::is_lvalue); + static_assert(!meta::detail::cvref_traits::is_rvalue); + static_assert(meta::detail::cvref_traits::is_const); + static_assert(!meta::detail::cvref_traits::is_volatile); + + static_assert(meta::detail::cvref_traits::is_lvalue); + static_assert(!meta::detail::cvref_traits::is_rvalue); + static_assert(meta::detail::cvref_traits::is_const); + static_assert(meta::detail::cvref_traits::is_volatile); + + static_assert(!meta::detail::cvref_traits::is_lvalue); + static_assert(meta::detail::cvref_traits::is_rvalue); + static_assert(!meta::detail::cvref_traits::is_const); + static_assert(!meta::detail::cvref_traits::is_volatile); + + static_assert(!meta::detail::cvref_traits::is_lvalue); + static_assert(meta::detail::cvref_traits::is_rvalue); + static_assert(meta::detail::cvref_traits::is_const); + static_assert(!meta::detail::cvref_traits::is_volatile); + + static_assert(!meta::detail::cvref_traits::is_lvalue); + static_assert(meta::detail::cvref_traits::is_rvalue); + static_assert(meta::detail::cvref_traits::is_const); + static_assert(meta::detail::cvref_traits::is_volatile); + } + + SUBCASE("cvref_traits::copy_to") { + static_assert(std::same_as::copy_to, int>); + static_assert(std::same_as::copy_to, const int>); + static_assert(std::same_as::copy_to, const volatile int>); + static_assert(std::same_as::copy_to, int&>); + static_assert(std::same_as::copy_to, const int&>); + static_assert(std::same_as::copy_to, volatile int&>); + static_assert(std::same_as::copy_to, const volatile int&&>); + + static_assert(std::same_as::copy_to, int>); + static_assert(std::same_as::copy_to, const int>); + static_assert(std::same_as::copy_to, const volatile int>); + static_assert(std::same_as::copy_to, int&>); + static_assert(std::same_as::copy_to, const int&>); + static_assert(std::same_as::copy_to, volatile int&>); + static_assert(std::same_as::copy_to, const volatile int&&>); + + static_assert(std::same_as::copy_to, int>); + static_assert(std::same_as::copy_to, const int>); + static_assert(std::same_as::copy_to, const volatile int>); + static_assert(std::same_as::copy_to, int&>); + static_assert(std::same_as::copy_to, const int&>); + static_assert(std::same_as::copy_to, volatile int&>); + static_assert(std::same_as::copy_to, const volatile int&&>); + } +} From c491e3bdca3d15b71c85cde648d3f24afc69519f Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 7 Jan 2022 13:56:56 +0700 Subject: [PATCH 140/233] separated clang-tidy for untests --- .clang-tidy | 2 ++ untests/.clang-tidy | 17 +++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 untests/.clang-tidy diff --git a/.clang-tidy b/.clang-tidy index a094b38..71ae3bb 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,3 +1,4 @@ +--- Checks: '-*, clang-analyzer-*, @@ -17,3 +18,4 @@ Checks: '-*, -readability-redundant-access-specifiers, -readability-use-anyofallof, ' +... diff --git a/untests/.clang-tidy b/untests/.clang-tidy new file mode 100644 index 0000000..7c32625 --- /dev/null +++ b/untests/.clang-tidy @@ -0,0 +1,17 @@ +--- +Checks: '-*, + + clang-analyzer-*, + + concurrency-*, + + cppcoreguidelines-*, + -cppcoreguidelines-avoid-magic-numbers, + -cppcoreguidelines-avoid-non-const-global-variables, + + modernize-*, + -modernize-use-trailing-return-type, + + portability-*, + ' +... From c37e7e5f43b1fc109253f2b8a3877148bd53ad79 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 7 Jan 2022 13:57:30 +0700 Subject: [PATCH 141/233] add noncopyable utility class --- headers/meta.hpp/meta_utilities.hpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/headers/meta.hpp/meta_utilities.hpp b/headers/meta.hpp/meta_utilities.hpp index 2d585dc..f056f48 100644 --- a/headers/meta.hpp/meta_utilities.hpp +++ b/headers/meta.hpp/meta_utilities.hpp @@ -127,6 +127,21 @@ namespace meta_hpp::detail }; } +namespace meta_hpp::detail +{ + class noncopyable { + protected: + noncopyable() = default; + ~noncopyable() = default; + public: + noncopyable(noncopyable&&) = delete; + noncopyable(const noncopyable&) = delete; + + noncopyable& operator=(noncopyable&&) = delete; + noncopyable& operator=(const noncopyable&) = delete; + }; +} + namespace meta_hpp { class value final { From c1a21dca147ccd934f33c18001d4834965724ac1 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 7 Jan 2022 14:40:16 +0700 Subject: [PATCH 142/233] add pointer_upcast utility --- headers/meta.hpp/meta_types.hpp | 41 +++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/headers/meta.hpp/meta_types.hpp b/headers/meta.hpp/meta_types.hpp index 5469bba..3fecedc 100644 --- a/headers/meta.hpp/meta_types.hpp +++ b/headers/meta.hpp/meta_types.hpp @@ -711,3 +711,44 @@ namespace meta_hpp return resolve_type>(); }; } + +namespace meta_hpp +{ + namespace detail + { + [[nodiscard]] inline void* pointer_upcast(void* ptr, const class_type& from, const class_type& to) { + if ( nullptr == ptr || !from || !to ) { + return nullptr; + } + + if ( from == to ) { + return ptr; + } + + for ( auto&& [base, base_info] : data_access(from)->bases_info ) { + if ( base == to ) { + return base_info.upcast(ptr); + } + + if ( base.is_derived_from(to) ) { + return pointer_upcast(base_info.upcast(ptr), base, to); + } + } + + return nullptr; + } + } + + template < detail::class_kind Base, detail::class_kind Derived > + [[nodiscard]] Base* pointer_upcast(Derived* ptr) { + const class_type& base = resolve_type(); + const class_type& derived = resolve_type(); + return static_cast(detail::pointer_upcast(ptr, derived, base)); + } + + template < detail::class_kind Base, detail::class_kind Derived > + [[nodiscard]] const Base* pointer_upcast(const Derived* ptr) { + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast) + return pointer_upcast(const_cast(ptr)); + } +} From b806ac748516e1f53113812782c96b49efbd3583 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 7 Jan 2022 14:51:47 +0700 Subject: [PATCH 143/233] fix some example warnings --- untests/.clang-tidy | 1 + untests/examples/class_example.cpp | 48 +++++++++++++++++----------- untests/examples/complex_example.cpp | 6 ++-- untests/examples/method_example.cpp | 4 +-- 4 files changed, 36 insertions(+), 23 deletions(-) diff --git a/untests/.clang-tidy b/untests/.clang-tidy index 7c32625..76b1ec4 100644 --- a/untests/.clang-tidy +++ b/untests/.clang-tidy @@ -8,6 +8,7 @@ Checks: '-*, cppcoreguidelines-*, -cppcoreguidelines-avoid-magic-numbers, -cppcoreguidelines-avoid-non-const-global-variables, + -cppcoreguidelines-special-member-functions, modernize-*, -modernize-use-trailing-return-type, diff --git a/untests/examples/class_example.cpp b/untests/examples/class_example.cpp index 7e7a0fb..f0cb81d 100644 --- a/untests/examples/class_example.cpp +++ b/untests/examples/class_example.cpp @@ -8,40 +8,52 @@ namespace { + constexpr double pi_v = 3.1415926536; + class shape { public: shape() = default; - shape(const shape&) = default; - shape& operator=(const shape&) = default; + virtual ~shape() = default; - virtual ~shape() {} - virtual double area() const = 0; + [[nodiscard]] virtual double area() const = 0; }; class circle : public shape { - double radius_; public: - circle(const circle&) = default; - circle& operator=(const circle&) = default; + explicit circle(double radius) + : radius_{radius} {} - explicit circle(double radius) : radius_{radius} {} - double area() const override { return 3.1415926536 * radius_ * radius_; } + [[nodiscard]] double area() const override { + return pi_v * radius_ * radius_; + } - double radius() const { return radius_; } + [[nodiscard]] double radius() const { + return radius_; + } + private: + double radius_{}; }; class rectangle : public shape { - double width_; - double height_; public: - rectangle(const rectangle&) = default; - rectangle& operator=(const rectangle&) = default; + explicit rectangle(double width, double height) + : width_{width} + , height_{height} {} - explicit rectangle(double width, double height) : width_{width}, height_{height} {} - double area() const override { return width_ * height_; } + [[nodiscard]] double area() const override { + return width_ * height_; + } - double width() const { return width_; } - double height() const { return height_; } + [[nodiscard]] double width() const { + return width_; + } + + [[nodiscard]] double height() const { + return height_; + } + private: + double width_{}; + double height_{}; }; } diff --git a/untests/examples/complex_example.cpp b/untests/examples/complex_example.cpp index 47ebd85..5bee1c3 100644 --- a/untests/examples/complex_example.cpp +++ b/untests/examples/complex_example.cpp @@ -16,15 +16,15 @@ namespace ivec2(int v) : x{v}, y{v} {} ivec2(int x, int y) : x{x}, y{y} {} - int dot(const ivec2& other) const noexcept { + [[nodiscard]] int dot(const ivec2& other) const noexcept { return x * other.x + y * other.y; } - int length2() const noexcept { + [[nodiscard]] int length2() const noexcept { return dot(*this); } - friend bool operator==(const ivec2& l, const ivec2& r) noexcept { + [[nodiscard]] friend bool operator==(const ivec2& l, const ivec2& r) noexcept { return l.x == r.x && l.y == r.y; } }; diff --git a/untests/examples/method_example.cpp b/untests/examples/method_example.cpp index 308876b..b51d70b 100644 --- a/untests/examples/method_example.cpp +++ b/untests/examples/method_example.cpp @@ -12,11 +12,11 @@ namespace int x{}; int y{}; - int dot(const ivec2& other) const noexcept { + [[nodiscard]] int dot(const ivec2& other) const noexcept { return x * other.x + y * other.y; } - int length2() const noexcept { + [[nodiscard]] int length2() const noexcept { return dot(*this); } }; From 4ec160d292ab825ea8b02a48454beb1e57cc6602 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 7 Jan 2022 18:25:26 +0700 Subject: [PATCH 144/233] new arg and inst conversions --- headers/meta.hpp/meta_utilities.hpp | 107 ++++++------ headers/meta.hpp/meta_utilities/arg.hpp | 203 +++++++++++++++-------- headers/meta.hpp/meta_utilities/inst.hpp | 161 +++++++++++------- 3 files changed, 287 insertions(+), 184 deletions(-) diff --git a/headers/meta.hpp/meta_utilities.hpp b/headers/meta.hpp/meta_utilities.hpp index f056f48..109590b 100644 --- a/headers/meta.hpp/meta_utilities.hpp +++ b/headers/meta.hpp/meta_utilities.hpp @@ -68,7 +68,9 @@ namespace meta_hpp::detail template < typename T > concept uvalue_kind = + std::same_as || std::same_as || + std::same_as || std::same_as || std::same_as; @@ -218,20 +220,20 @@ namespace meta_hpp::detail public: arg_base() = delete; - arg_base(arg_base&&) = delete; - arg_base& operator=(arg_base&&) = delete; + arg_base(arg_base&&) = default; + arg_base(const arg_base&) = default; - arg_base(const arg_base&) = delete; + arg_base& operator=(arg_base&&) = delete; arg_base& operator=(const arg_base&) = delete; - template < typename T, std::enable_if_t< - (std::is_lvalue_reference_v) - , int> = 0 > + virtual ~arg_base() = default; + + template < arg_lvalue_ref_kind T > + requires decay_non_uvalue_kind explicit arg_base(type_list); - template < typename T, std::enable_if_t< - (std::is_rvalue_reference_v || !std::is_reference_v) - , int> = 0 > + template < arg_rvalue_ref_kind T > + requires decay_non_uvalue_kind explicit arg_base(type_list); explicit arg_base(value& v); @@ -240,15 +242,15 @@ namespace meta_hpp::detail explicit arg_base(value&& v); explicit arg_base(const value&& v); - bool is_const() const noexcept; - bool is_lvalue() const noexcept; - bool is_rvalue() const noexcept; + [[nodiscard]] bool is_const() const noexcept; + [[nodiscard]] bool is_lvalue() const noexcept; + [[nodiscard]] bool is_rvalue() const noexcept; - ref_types get_ref_type() const noexcept; - const any_type& get_raw_type() const noexcept; + [[nodiscard]] ref_types get_ref_type() const noexcept; + [[nodiscard]] const any_type& get_raw_type() const noexcept; template < typename To > - bool can_cast_to() const noexcept; + [[nodiscard]] bool can_cast_to() const noexcept; private: ref_types ref_type_{}; any_type raw_type_{}; @@ -261,24 +263,22 @@ namespace meta_hpp::detail public: arg() = delete; - arg(arg&&) = delete; - arg& operator=(arg&&) = delete; + arg(arg&&) = default; + arg(const arg&) = default; - arg(const arg&) = delete; + arg& operator=(arg&&) = delete; arg& operator=(const arg&) = delete; - template < typename T, typename Tp = std::decay_t - , std::enable_if_t, int> = 0 > + ~arg() override = default; + + template < decay_value_kind T > explicit arg(T&& v); - template < typename T, typename Tp = std::decay_t - , std::enable_if_t, int> = 0 - , std::enable_if_t, int> = 0 - , std::enable_if_t, int> = 0 > + template < decay_non_uvalue_kind T > explicit arg(T&& v); template < typename To > - To cast() const; + [[nodiscard]] To cast() const; private: void* data_{}; }; @@ -297,21 +297,18 @@ namespace meta_hpp::detail public: inst_base() = delete; - inst_base(inst_base&&) = delete; - inst_base& operator=(inst_base&&) = delete; + inst_base(inst_base&&) = default; + inst_base(const inst_base&) = default; - inst_base(const inst_base&) = delete; + inst_base& operator=(inst_base&&) = delete; inst_base& operator=(const inst_base&) = delete; - template < typename T, std::enable_if_t< - (std::is_lvalue_reference_v && std::is_class_v>) - , int> = 0> + virtual ~inst_base() = default; + + template < inst_class_lvalue_ref_kind T > explicit inst_base(type_list); - template < typename T, std::enable_if_t< - (std::is_class_v) || - (std::is_rvalue_reference_v && std::is_class_v>) - , int> = 0> + template < inst_class_rvalue_ref_kind T > explicit inst_base(type_list); explicit inst_base(value& v); @@ -320,18 +317,15 @@ namespace meta_hpp::detail explicit inst_base(value&& v); explicit inst_base(const value&& v); - bool is_const() const noexcept; - bool is_lvalue() const noexcept; - bool is_rvalue() const noexcept; + [[nodiscard]] bool is_const() const noexcept; + [[nodiscard]] bool is_lvalue() const noexcept; + [[nodiscard]] bool is_rvalue() const noexcept; - ref_types get_ref_type() const noexcept; - const class_type& get_raw_type() const noexcept; + [[nodiscard]] ref_types get_ref_type() const noexcept; + [[nodiscard]] const class_type& get_raw_type() const noexcept; - template < typename To, std::enable_if_t< - (std::is_class_v) || - (std::is_reference_v && std::is_class_v>) - , int> = 0> - bool can_cast_to() const noexcept; + template < inst_class_ref_kind Q > + [[nodiscard]] bool can_cast_to() const noexcept; private: ref_types ref_type_{}; class_type raw_type_{}; @@ -344,27 +338,22 @@ namespace meta_hpp::detail public: inst() = delete; - inst(inst&&) = delete; - inst& operator=(inst&&) = delete; + inst(inst&&) = default; + inst(const inst&) = default; - inst(const inst&) = delete; + inst& operator=(inst&&) = delete; inst& operator=(const inst&) = delete; - template < typename T, typename Tp = std::decay_t - , std::enable_if_t, int> = 0 > + ~inst() override = default; + + template < decay_value_kind T > explicit inst(T&& v); - template < typename T, class_kind Tp = std::decay_t - , std::enable_if_t, int> = 0 - , std::enable_if_t, int> = 0 - , std::enable_if_t, int> = 0 > + template < decay_non_uvalue_kind T > explicit inst(T&& v); - template < typename To, std::enable_if_t< - (std::is_class_v) || - (std::is_reference_v && std::is_class_v>) - , int> = 0> - decltype(auto) cast() const; + template < inst_class_ref_kind Q > + [[nodiscard]] decltype(auto) cast() const; private: void* data_{}; }; diff --git a/headers/meta.hpp/meta_utilities/arg.hpp b/headers/meta.hpp/meta_utilities/arg.hpp index 19450fa..65bd5f8 100644 --- a/headers/meta.hpp/meta_utilities/arg.hpp +++ b/headers/meta.hpp/meta_utilities/arg.hpp @@ -11,18 +11,22 @@ namespace meta_hpp::detail { - template < typename T, std::enable_if_t< - (std::is_lvalue_reference_v) - , int> > + template < arg_lvalue_ref_kind T > + requires decay_non_uvalue_kind + // NOLINTNEXTLINE(readability-named-parameter) arg_base::arg_base(type_list) - : ref_type_{std::is_const_v> ? ref_types::const_lvalue : ref_types::lvalue} + : ref_type_{std::is_const_v> + ? ref_types::const_lvalue + : ref_types::lvalue} , raw_type_{resolve_type>()} {} - template < typename T, std::enable_if_t< - (std::is_rvalue_reference_v || !std::is_reference_v) - , int> > + template < arg_rvalue_ref_kind T > + requires decay_non_uvalue_kind + // NOLINTNEXTLINE(readability-named-parameter) arg_base::arg_base(type_list) - : ref_type_{std::is_const_v> ? ref_types::const_rvalue : ref_types::rvalue} + : ref_type_{std::is_const_v> + ? ref_types::const_rvalue + : ref_types::rvalue} , raw_type_{resolve_type>()} {} inline arg_base::arg_base(value& v) @@ -65,6 +69,7 @@ namespace meta_hpp::detail } template < typename To > + // NOLINTNEXTLINE(readability-function-cognitive-complexity) bool arg_base::can_cast_to() const noexcept { using to_raw_type_cv = std::remove_reference_t; using to_raw_type = std::remove_cv_t; @@ -73,112 +78,176 @@ namespace meta_hpp::detail !(std::is_reference_v && std::is_pointer_v), "references to pointers are not supported yet"); - const auto check_qualifiers = [this](){ - switch ( get_ref_type() ) { - case ref_types::lvalue: return std::is_convertible_v; - case ref_types::const_lvalue: return std::is_convertible_v; - case ref_types::rvalue: return std::is_convertible_v; - case ref_types::const_rvalue: return std::is_convertible_v; - } + const any_type& from_type = get_raw_type(); + const any_type& to_type = resolve_type(); + + const auto is_a = [](const any_type& base, const any_type& derived){ + return (base == derived) + || (base.is_class() && derived.is_class() && base.as_class().is_base_of(derived.as_class())); }; - const auto check_convertible = [this](){ - const auto is_a = [](const any_type& base, const any_type& derived){ - return (base == derived) - || (base.is_class() && derived.is_class() && base.as_class().is_base_of(derived.as_class())); - }; - - const any_type& from_type = get_raw_type(); - const any_type& to_type = resolve_type(); - - if ( is_a(to_type, from_type) ) { - return true; - } - - if ( std::is_lvalue_reference_v && !std::is_const_v ) { - return false; - } - - if ( from_type.is_pointer() && to_type.is_pointer() ) { - const pointer_type& from_type_ptr = from_type.as_pointer(); - const bool from_type_ptr_readonly = from_type_ptr.get_flags().has(pointer_flags::is_readonly); - + if constexpr ( std::is_pointer_v ) { + if ( to_type.is_pointer() && from_type.is_pointer() ) { const pointer_type& to_type_ptr = to_type.as_pointer(); const bool to_type_ptr_readonly = to_type_ptr.get_flags().has(pointer_flags::is_readonly); - return to_type_ptr_readonly >= from_type_ptr_readonly - && is_a(to_type_ptr.get_data_type(), from_type_ptr.get_data_type()); + const pointer_type& from_type_ptr = from_type.as_pointer(); + const bool from_type_ptr_readonly = from_type_ptr.get_flags().has(pointer_flags::is_readonly); + + const any_type& to_data_type = to_type_ptr.get_data_type(); + const any_type& from_data_type = from_type_ptr.get_data_type(); + + if ( is_a(to_data_type, from_data_type) && to_type_ptr_readonly >= from_type_ptr_readonly ) { + return true; + } } + } - return false; - }; + if constexpr ( std::is_reference_v ) { + const auto is_convertible = [this](){ + switch ( get_ref_type() ) { + case ref_types::lvalue: + return std::is_convertible_v>; + case ref_types::const_lvalue: + return std::is_convertible_v>; + case ref_types::rvalue: + return std::is_convertible_v>; + case ref_types::const_rvalue: + return std::is_convertible_v>; + } + }; - return check_qualifiers() && check_convertible(); + if ( is_a(to_type, from_type) && is_convertible() ) { + return true; + } + } + + if constexpr ( !std::is_pointer_v && !std::is_reference_v ) { + const auto is_constructible = [this](){ + switch ( get_ref_type() ) { + case ref_types::lvalue: + return std::is_constructible_v && can_cast_to(); + case ref_types::const_lvalue: + return std::is_constructible_v && can_cast_to(); + case ref_types::rvalue: + return std::is_constructible_v && can_cast_to(); + case ref_types::const_rvalue: + return std::is_constructible_v && can_cast_to(); + } + }; + + if ( is_a(to_type, from_type) && is_constructible() ) { + return true; + } + } + + return false; } } namespace meta_hpp::detail { - template < typename T, typename Tp - , std::enable_if_t, int> > + template < decay_value_kind T > arg::arg(T&& v) : arg_base{std::forward(v)} + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast) , data_{const_cast(v.data())} {} - template < typename T, typename Tp - , std::enable_if_t, int> - , std::enable_if_t, int> - , std::enable_if_t, int> > + template < decay_non_uvalue_kind T > arg::arg(T&& v) : arg_base{type_list{}} + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast) , data_{const_cast*>(std::addressof(v))} {} template < typename To > + // NOLINTNEXTLINE(readability-function-cognitive-complexity) To arg::cast() const { if ( !can_cast_to() ) { throw std::logic_error("bad argument cast"); } + using to_raw_type_cv = std::remove_reference_t; + using to_raw_type = std::remove_cv_t; + + const any_type& from_type = get_raw_type(); + const any_type& to_type = resolve_type(); + if constexpr ( std::is_pointer_v ) { - return *static_cast(data_); + if ( to_type.is_pointer() && from_type.is_pointer() ) { + const pointer_type& to_type_ptr = to_type.as_pointer(); + const pointer_type& from_type_ptr = from_type.as_pointer(); + + const any_type& to_data_type = to_type_ptr.get_data_type(); + const any_type& from_data_type = from_type_ptr.get_data_type(); + + void** from_data_ptr = static_cast(data_); + + if ( to_data_type == from_data_type ) { + void* to_data_ptr = *from_data_ptr; + return static_cast(to_data_ptr); + } + + if ( to_data_type.is_class() && from_data_type.is_class() ) { + const class_type& to_data_class = to_data_type.as_class(); + const class_type& from_data_class = from_data_type.as_class(); + + void* to_data_ptr = detail::pointer_upcast(*from_data_ptr, from_data_class, to_data_class); + return static_cast(to_data_ptr); + } + } } if constexpr ( std::is_reference_v ) { - using raw_type = std::remove_cvref_t; + if ( to_type == from_type ) { + void* to_ptr = static_cast(data_); - if constexpr ( std::is_lvalue_reference_v ) { - return *static_cast(data_); + if constexpr ( std::is_lvalue_reference_v ) { + return *static_cast(to_ptr); + } + + if constexpr ( std::is_rvalue_reference_v ) { + return std::move(*static_cast(to_ptr)); + } } - if constexpr ( std::is_rvalue_reference_v ) { - return std::move(*static_cast(data_)); + if ( to_type.is_class() && from_type.is_class() ) { + const class_type& to_class = to_type.as_class(); + const class_type& from_class = from_type.as_class(); + + void* to_ptr = detail::pointer_upcast(data_, from_class, to_class); + + if constexpr ( std::is_lvalue_reference_v ) { + return *static_cast(to_ptr); + } + + if constexpr ( std::is_rvalue_reference_v ) { + return std::move(*static_cast(to_ptr)); + } } } if constexpr ( !std::is_pointer_v && !std::is_reference_v ) { - using raw_type = std::remove_cv_t; - - if ( get_ref_type() == ref_types::lvalue ) { - if constexpr ( std::is_constructible_v ) { - return To{*static_cast(data_)}; + if constexpr ( std::is_constructible_v ) { + if ( get_ref_type() == ref_types::lvalue ) { + return To{cast()}; } } - if ( get_ref_type() == ref_types::const_lvalue ) { - if constexpr ( std::is_constructible_v ) { - return To{std::as_const(*static_cast(data_))}; + if constexpr ( std::is_constructible_v ) { + if ( get_ref_type() == ref_types::const_lvalue ) { + return To{cast()}; } } - if ( get_ref_type() == ref_types::rvalue ) { - if constexpr ( std::is_constructible_v ) { - return To{std::move(*static_cast(data_))}; + if constexpr ( std::is_constructible_v ) { + if ( get_ref_type() == ref_types::rvalue ) { + return To{cast()}; } } - if ( get_ref_type() == ref_types::const_rvalue ) { - if constexpr ( std::is_constructible_v ) { - return To{std::move(std::as_const(*static_cast(data_)))}; + if constexpr ( std::is_constructible_v ) { + if ( get_ref_type() == ref_types::const_rvalue ) { + return To{cast()}; } } } diff --git a/headers/meta.hpp/meta_utilities/inst.hpp b/headers/meta.hpp/meta_utilities/inst.hpp index 754140e..d982371 100644 --- a/headers/meta.hpp/meta_utilities/inst.hpp +++ b/headers/meta.hpp/meta_utilities/inst.hpp @@ -11,19 +11,71 @@ namespace meta_hpp::detail { - template < typename T, std::enable_if_t< - (std::is_lvalue_reference_v && std::is_class_v>) - , int> > + namespace impl + { + template < inst_class_ref_kind Q, bool is_const, bool is_lvalue, bool is_rvalue > + struct inst_traits_impl; + + template < inst_class_ref_kind Q > + struct inst_traits_impl { + using class_type = std::remove_cvref_t; + using method_type = void(class_type::*)(); + }; + + template < inst_class_ref_kind Q > + struct inst_traits_impl { + using class_type = std::remove_cvref_t; + using method_type = void(class_type::*)() &; + }; + + template < inst_class_ref_kind Q > + struct inst_traits_impl { + using class_type = std::remove_cvref_t; + using method_type = void(class_type::*)() &&; + }; + + template < inst_class_ref_kind Q > + struct inst_traits_impl { + using class_type = std::remove_cvref_t; + using method_type = void(class_type::*)() const; + }; + + template < inst_class_ref_kind Q > + struct inst_traits_impl { + using class_type = std::remove_cvref_t; + using method_type = void(class_type::*)() const &; + }; + + template < inst_class_ref_kind Q > + struct inst_traits_impl { + using class_type = std::remove_cvref_t; + using method_type = void(class_type::*)() const &&; + }; + } + + template < inst_class_ref_kind Q > + struct inst_traits final : impl::inst_traits_impl::is_const, + cvref_traits::is_lvalue, + cvref_traits::is_rvalue> {}; +} + +namespace meta_hpp::detail +{ + template < inst_class_lvalue_ref_kind T > + // NOLINTNEXTLINE(readability-named-parameter) inst_base::inst_base(type_list) - : ref_type_{std::is_const_v> ? ref_types::const_lvalue : ref_types::lvalue} + : ref_type_{std::is_const_v> + ? ref_types::const_lvalue + : ref_types::lvalue} , raw_type_{resolve_type>()} {} - template < typename T, std::enable_if_t< - (std::is_class_v) || - (std::is_rvalue_reference_v && std::is_class_v>) - , int> > + template < inst_class_rvalue_ref_kind T > + // NOLINTNEXTLINE(readability-named-parameter) inst_base::inst_base(type_list) - : ref_type_{std::is_const_v> ? ref_types::const_rvalue : ref_types::rvalue} + : ref_type_{std::is_const_v> + ? ref_types::const_rvalue + : ref_types::rvalue} , raw_type_{resolve_type>()} {} inline inst_base::inst_base(value& v) @@ -81,80 +133,73 @@ namespace meta_hpp::detail return raw_type_; } - template < typename To, std::enable_if_t< - (std::is_class_v) || - (std::is_reference_v && std::is_class_v>) - , int> > + template < inst_class_ref_kind Q > bool inst_base::can_cast_to() const noexcept { - using to_raw_type = std::remove_cvref_t; - using to_raw_type_cv = std::remove_reference_t; + using inst_class = typename inst_traits::class_type; + using inst_method = typename inst_traits::method_type; - if constexpr ( !std::is_const_v ) { - if ( is_const() ) { - return false; + const class_type& from_type = get_raw_type(); + const class_type& to_type = resolve_type(); + + const auto is_a = [](const class_type& base, const class_type& derived){ + return base == derived || base.is_base_of(derived); + }; + + const auto is_invocable = [this](){ + switch ( get_ref_type() ) { + case ref_types::lvalue: + return std::is_invocable_v; + case ref_types::const_lvalue: + return std::is_invocable_v; + case ref_types::rvalue: + return std::is_invocable_v; + case ref_types::const_rvalue: + return std::is_invocable_v; } - } + }; - if constexpr ( std::is_reference_v ) { - const auto check_qualifiers = [](ref_types self_ref_type){ - switch ( self_ref_type ) { - case ref_types::lvalue: return std::is_convertible_v; - case ref_types::const_lvalue: return std::is_convertible_v; - case ref_types::rvalue: return std::is_convertible_v; - case ref_types::const_rvalue: return std::is_convertible_v; - } - }; - - if ( !check_qualifiers(get_ref_type()) ) { - return false; - } - } - - return get_raw_type() == resolve_type() - || get_raw_type().is_derived_from(resolve_type()); + return is_a(to_type, from_type) && is_invocable(); } } namespace meta_hpp::detail { - template < typename T, typename Tp - , std::enable_if_t, int> > + template < decay_value_kind T > inst::inst(T&& v) : inst_base{std::forward(v)} + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast) , data_{const_cast(v.data())} {} - template < typename T, class_kind Tp - , std::enable_if_t, int> - , std::enable_if_t, int> - , std::enable_if_t, int> > + template < decay_non_uvalue_kind T > inst::inst(T&& v) : inst_base{type_list{}} + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast) , data_{const_cast*>(std::addressof(v))} {} - template < typename To, std::enable_if_t< - (std::is_class_v) || - (std::is_reference_v && std::is_class_v>) - , int> > + template < inst_class_ref_kind Q > decltype(auto) inst::cast() const { - if ( !can_cast_to() ) { + if ( !can_cast_to() ) { throw std::logic_error("bad instance cast"); } - if constexpr ( std::is_reference_v ) { - using raw_type_with_cv = std::remove_reference_t; + using inst_class_cv = std::remove_reference_t; + using inst_class = std::remove_cv_t; - if constexpr ( std::is_lvalue_reference_v ) { - return *static_cast(data_); - } + const class_type& from_type = get_raw_type(); + const class_type& to_type = resolve_type(); - if constexpr ( std::is_rvalue_reference_v ) { - return std::move(*static_cast(data_)); - } + void* to_ptr = detail::pointer_upcast(data_, from_type, to_type); + + if constexpr ( !std::is_reference_v ) { + return *static_cast(to_ptr); } - if constexpr ( !std::is_reference_v) { - using raw_type_with_cv = To; - return *static_cast(data_); + if constexpr ( std::is_lvalue_reference_v ) { + return *static_cast(to_ptr); + } + + if constexpr ( std::is_rvalue_reference_v ) { + return std::move(*static_cast(to_ptr)); } } } From 856ffc8cdc4c03f4050474c5a7c3f05ff88d1e85 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 7 Jan 2022 18:28:36 +0700 Subject: [PATCH 145/233] new arg ind inst tests --- untests/meta_features/diamond_tests.cpp | 318 ++++++++++++++++++ untests/meta_utilities/arg2_tests.cpp | 352 ++++++++++++++++++++ untests/meta_utilities/arg3_tests.cpp | 127 ++++++++ untests/meta_utilities/arg4_tests.cpp | 144 +++++++++ untests/meta_utilities/arg_tests.cpp | 414 +++++++++++++++++++----- untests/meta_utilities/inst_tests.cpp | 32 +- 6 files changed, 1298 insertions(+), 89 deletions(-) create mode 100644 untests/meta_features/diamond_tests.cpp create mode 100644 untests/meta_utilities/arg2_tests.cpp create mode 100644 untests/meta_utilities/arg3_tests.cpp create mode 100644 untests/meta_utilities/arg4_tests.cpp diff --git a/untests/meta_features/diamond_tests.cpp b/untests/meta_features/diamond_tests.cpp new file mode 100644 index 0000000..008a5ca --- /dev/null +++ b/untests/meta_features/diamond_tests.cpp @@ -0,0 +1,318 @@ +/******************************************************************************* + * 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_tests.hpp" + +namespace +{ + struct A { + A() = default; + + A(A&&) = default; + A(const A&) = default; + + A& operator=(A&&) = delete; + A& operator=(const A&) = delete; + + virtual ~A() = default; + }; + + struct B : virtual A {}; + struct C : virtual A {}; + struct D : B, C {}; + struct E {}; +} + +TEST_CASE("features/features/diamond_inheritance") { + namespace meta = meta_hpp; + + meta::class_(); + meta::class_().base_(); + meta::class_().base_(); + meta::class_().base_().base_(); + meta::class_(); + + // * <- B <- * + // A D + // * <- C <- * + + const meta::class_type A_type = meta::resolve_type(); + const meta::class_type B_type = meta::resolve_type(); + const meta::class_type C_type = meta::resolve_type(); + const meta::class_type D_type = meta::resolve_type(); + const meta::class_type E_type = meta::resolve_type(); + + REQUIRE(A_type); + REQUIRE(B_type); + REQUIRE(C_type); + REQUIRE(D_type); + REQUIRE(E_type); + + SUBCASE("is_base_of") { + CHECK(!A_type.is_base_of(A_type)); + CHECK(A_type.is_base_of(B_type)); + CHECK(A_type.is_base_of(C_type)); + CHECK(A_type.is_base_of(D_type)); + CHECK(!A_type.is_base_of(E_type)); + + CHECK(!B_type.is_base_of(A_type)); + CHECK(!B_type.is_base_of(B_type)); + CHECK(!B_type.is_base_of(C_type)); + CHECK(B_type.is_base_of(D_type)); + CHECK(!B_type.is_base_of(E_type)); + + CHECK(!C_type.is_base_of(A_type)); + CHECK(!C_type.is_base_of(B_type)); + CHECK(!C_type.is_base_of(C_type)); + CHECK(C_type.is_base_of(D_type)); + CHECK(!C_type.is_base_of(E_type)); + + CHECK(!D_type.is_base_of(A_type)); + CHECK(!D_type.is_base_of(B_type)); + CHECK(!D_type.is_base_of(C_type)); + CHECK(!D_type.is_base_of(D_type)); + CHECK(!D_type.is_base_of(E_type)); + + CHECK(!E_type.is_base_of(A_type)); + CHECK(!E_type.is_base_of(B_type)); + CHECK(!E_type.is_base_of(C_type)); + CHECK(!E_type.is_base_of(D_type)); + CHECK(!E_type.is_base_of(E_type)); + } + + SUBCASE("is_derived_from") { + CHECK(!A_type.is_derived_from(A_type)); + CHECK(!A_type.is_derived_from(B_type)); + CHECK(!A_type.is_derived_from(C_type)); + CHECK(!A_type.is_derived_from(D_type)); + CHECK(!A_type.is_derived_from(E_type)); + + CHECK(B_type.is_derived_from(A_type)); + CHECK(!B_type.is_derived_from(B_type)); + CHECK(!B_type.is_derived_from(C_type)); + CHECK(!B_type.is_derived_from(D_type)); + CHECK(!B_type.is_derived_from(E_type)); + + CHECK(C_type.is_derived_from(A_type)); + CHECK(!C_type.is_derived_from(B_type)); + CHECK(!C_type.is_derived_from(C_type)); + CHECK(!C_type.is_derived_from(D_type)); + CHECK(!C_type.is_derived_from(E_type)); + + CHECK(D_type.is_derived_from(A_type)); + CHECK(D_type.is_derived_from(B_type)); + CHECK(D_type.is_derived_from(C_type)); + CHECK(!D_type.is_derived_from(D_type)); + CHECK(!D_type.is_derived_from(E_type)); + + CHECK(!E_type.is_derived_from(A_type)); + CHECK(!E_type.is_derived_from(B_type)); + CHECK(!E_type.is_derived_from(C_type)); + CHECK(!E_type.is_derived_from(D_type)); + CHECK(!E_type.is_derived_from(E_type)); + } + + SUBCASE("pointer_upcast") { + { + A a; + CHECK(meta::pointer_upcast(&a) == &a); + CHECK_FALSE(meta::pointer_upcast(&a)); + CHECK_FALSE(meta::pointer_upcast(&a)); + CHECK_FALSE(meta::pointer_upcast(&a)); + CHECK_FALSE(meta::pointer_upcast(&a)); + } + { + B b; + CHECK(meta::pointer_upcast(&b) == &b); + CHECK(meta::pointer_upcast(&b) == &b); + CHECK_FALSE(meta::pointer_upcast(&b)); + CHECK_FALSE(meta::pointer_upcast(&b)); + CHECK_FALSE(meta::pointer_upcast(&b)); + } + { + C c; + CHECK(meta::pointer_upcast(&c) == &c); + CHECK_FALSE(meta::pointer_upcast(&c)); + CHECK(meta::pointer_upcast(&c) == &c); + CHECK_FALSE(meta::pointer_upcast(&c)); + CHECK_FALSE(meta::pointer_upcast(&c)); + } + { + D d; + CHECK(meta::pointer_upcast(&d) == &d); + CHECK(meta::pointer_upcast(&d) == &d); + CHECK(meta::pointer_upcast(&d) == &d); + CHECK(meta::pointer_upcast(&d) == &d); + CHECK_FALSE(meta::pointer_upcast(&d)); + } + { + E e; + CHECK_FALSE(meta::pointer_upcast(&e)); + CHECK_FALSE(meta::pointer_upcast(&e)); + CHECK_FALSE(meta::pointer_upcast(&e)); + CHECK_FALSE(meta::pointer_upcast(&e)); + CHECK(meta::pointer_upcast(&e) == &e); + } + } + + SUBCASE("arg/cast") { + { + A a; + meta::value a_val{&a}; + CHECK(*static_cast(a_val.data()) == &a); + + meta::detail::arg a_arg{a_val}; + + CHECK(a_arg.can_cast_to()); + CHECK(!a_arg.can_cast_to()); + CHECK(!a_arg.can_cast_to()); + CHECK(!a_arg.can_cast_to()); + CHECK(!a_arg.can_cast_to()); + + CHECK(a_arg.cast() == static_cast(&a)); + } + { + B b; + meta::value b_val{&b}; + CHECK(*static_cast(b_val.data()) == &b); + + meta::detail::arg b_arg{b_val}; + + CHECK(b_arg.can_cast_to()); + CHECK(b_arg.can_cast_to()); + CHECK(!b_arg.can_cast_to()); + CHECK(!b_arg.can_cast_to()); + CHECK(!b_arg.can_cast_to()); + + CHECK(b_arg.cast() == static_cast(&b)); + CHECK(b_arg.cast() == static_cast(&b)); + } + { + C c; + meta::value c_val{&c}; + CHECK(*static_cast(c_val.data()) == &c); + + meta::detail::arg c_arg{c_val}; + + CHECK(c_arg.can_cast_to()); + CHECK(!c_arg.can_cast_to()); + CHECK(c_arg.can_cast_to()); + CHECK(!c_arg.can_cast_to()); + CHECK(!c_arg.can_cast_to()); + + CHECK(c_arg.cast() == static_cast(&c)); + CHECK(c_arg.cast() == static_cast(&c)); + } + { + D d; + meta::value d_val{&d}; + CHECK(*static_cast(d_val.data()) == &d); + + meta::detail::arg d_arg{d_val}; + + CHECK(d_arg.can_cast_to()); + CHECK(d_arg.can_cast_to()); + CHECK(d_arg.can_cast_to()); + CHECK(d_arg.can_cast_to()); + CHECK(!d_arg.can_cast_to()); + + CHECK(d_arg.cast() == static_cast(&d)); + CHECK(d_arg.cast() == static_cast(&d)); + CHECK(d_arg.cast() == static_cast(&d)); + CHECK(d_arg.cast() == static_cast(&d)); + } + { + E e; + meta::value e_val{&e}; + CHECK(*static_cast(e_val.data()) == &e); + + meta::detail::arg e_arg{e_val}; + + CHECK(!e_arg.can_cast_to()); + CHECK(!e_arg.can_cast_to()); + CHECK(!e_arg.can_cast_to()); + CHECK(!e_arg.can_cast_to()); + CHECK(e_arg.can_cast_to()); + + CHECK(e_arg.cast() == static_cast(&e)); + } + } + + SUBCASE("inst/cast") { + { + meta::value a_val{A{}}; + meta::detail::inst a_inst{a_val}; + + CHECK(a_inst.can_cast_to()); + CHECK_FALSE(a_inst.can_cast_to()); + CHECK_FALSE(a_inst.can_cast_to()); + CHECK_FALSE(a_inst.can_cast_to()); + CHECK_FALSE(a_inst.can_cast_to()); + + CHECK(&a_inst.cast() == a_val.try_cast()); + } + { + meta::value b_val{B{}}; + meta::detail::inst b_inst{b_val}; + + CHECK(b_inst.can_cast_to()); + CHECK(b_inst.can_cast_to()); + CHECK_FALSE(b_inst.can_cast_to()); + CHECK_FALSE(b_inst.can_cast_to()); + CHECK_FALSE(b_inst.can_cast_to()); + + CHECK(&b_inst.cast() == b_val.try_cast()); + CHECK(&b_inst.cast() == b_val.try_cast()); + + CHECK(&b_inst.cast() == b_val.try_cast()); + } + { + meta::value c_val{C{}}; + meta::detail::inst c_inst{c_val}; + + CHECK(c_inst.can_cast_to()); + CHECK_FALSE(c_inst.can_cast_to()); + CHECK(c_inst.can_cast_to()); + CHECK_FALSE(c_inst.can_cast_to()); + CHECK_FALSE(c_inst.can_cast_to()); + + CHECK(&c_inst.cast() == c_val.try_cast()); + CHECK(&c_inst.cast() == c_val.try_cast()); + } + { + meta::value d_val{D{}}; + meta::detail::inst d_inst{d_val}; + + CHECK(d_inst.can_cast_to()); + CHECK(d_inst.can_cast_to()); + CHECK(d_inst.can_cast_to()); + CHECK(d_inst.can_cast_to()); + CHECK_FALSE(d_inst.can_cast_to()); + + CHECK(&d_inst.cast() == d_val.try_cast()); + CHECK(&d_inst.cast() == d_val.try_cast()); + CHECK(&d_inst.cast() == d_val.try_cast()); + CHECK(&d_inst.cast() == d_val.try_cast()); + + CHECK(&d_inst.cast() == d_val.try_cast()); + CHECK(&d_inst.cast() == d_val.try_cast()); + CHECK(&d_inst.cast() == d_val.try_cast()); + CHECK(&d_inst.cast() == d_val.try_cast()); + } + { + meta::value e_val{E{}}; + meta::detail::inst e_inst{e_val}; + + CHECK_FALSE(e_inst.can_cast_to()); + CHECK_FALSE(e_inst.can_cast_to()); + CHECK_FALSE(e_inst.can_cast_to()); + CHECK_FALSE(e_inst.can_cast_to()); + CHECK(e_inst.can_cast_to()); + + CHECK(&e_inst.cast() == e_val.try_cast()); + } + } +} diff --git a/untests/meta_utilities/arg2_tests.cpp b/untests/meta_utilities/arg2_tests.cpp new file mode 100644 index 0000000..74e6289 --- /dev/null +++ b/untests/meta_utilities/arg2_tests.cpp @@ -0,0 +1,352 @@ +/******************************************************************************* + * 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_tests.hpp" + +namespace +{ + struct A { + A() = default; + virtual ~A() = default; + + A(A&&) noexcept { ++move_ctors_; } + A(const A&) { ++copy_ctors_; } + + A& operator=(A&&) = delete; + A& operator=(const A&) = delete; + + int i = 1; + [[maybe_unused, nodiscard]] int f() const { return i; } + + static int copy_ctors_; + static int move_ctors_; + }; + + int A::copy_ctors_{}; + int A::move_ctors_{}; + + struct B : virtual A { + int i = 2; + [[maybe_unused, nodiscard]] int f() const { return i; } + }; + + struct C : virtual A { + int i = 3; + [[maybe_unused, nodiscard]] int f() const { return i; } + }; + + struct D : B, C { + int i = 4; + [[maybe_unused, nodiscard]] int f() const { return i; } + }; +} + +TEST_CASE("features/meta_utilities/arg2") { + namespace meta = meta_hpp; + + // * <- B <- * + // A D + // * <- C <- * + + meta::class_(); + meta::class_().base_(); + meta::class_().base_(); + meta::class_().base_().base_(); +} + +TEST_CASE("features/meta_utilities/arg2/cast") { + namespace meta = meta_hpp; + using meta::detail::arg; + + auto LV = []() -> D& { static D v; return v; }; + auto CLV = []() -> const D& { static D v; return v; }; + auto XV = []() -> D&& { static D v; return std::move(v); }; + auto CXV = []() -> const D&& { static D v; return std::move(v); }; + auto PRV = []() -> D { return D{}; }; + auto CPRV = []() -> const D { return D{}; }; + + auto LV_PTR = []() -> D*& { static D v; static D* p{&v}; return p; }; + auto LV_CPTR = []() -> const D*& { static D v; static const D* p{&v}; return p; }; + auto CLV_PTR = []() -> D* const& { static D v; static D* p{&v}; return p; }; + auto CLV_CPTR = []() -> const D* const& { static D v; static const D* p{&v}; return p; }; + auto XV_PTR = []() -> D*&& { static D v; static D* p{&v}; return std::move(p); }; + auto XV_CPTR = []() -> const D*&& { static D v; static const D* p{&v}; return std::move(p); }; + auto CXV_PTR = []() -> D* const&& { static D v; static D* p{&v}; return std::move(p); }; + auto CXV_CPTR = []() -> const D* const&& { static D v; static const D* p{&v}; return std::move(p); }; + auto PRV_PTR = []() -> D* { static D v; static D* p{&v}; return p; }; + auto PRV_CPTR = []() -> const D* { static D v; static const D* p{&v}; return p; }; + + // *------------------------------------------------------------* + // | ======> | T, const T | T& | const T& | T&& | const T&& | + // |---------*------------*------*----------*------*------------| + // | LV | Cc | ++ | ++ | | | + // |---------*------------*------*----------*------*------------| + // | CLV | Cc | | ++ | | | + // |---------*------------*------*----------*------*------------| + // | XV | Mc | | ++ | ++ | ++ | + // |---------*------------*------*----------*------*------------| + // | CXV | Cc | | ++ | | ++ | + // |---------*------------*------*----------*------*------------| + // | PRV | ++ | | ++ | ++ | ++ | + // |---------*------------*------*----------*------*------------| + // | CPRV | ++ | | ++ | | ++ | + // *------------------------------------------------------------* + + A::copy_ctors_ = 0; + A::move_ctors_ = 0; + + SUBCASE("LV") { + CHECK(arg{LV()}.can_cast_to()); + CHECK(arg{LV()}.can_cast_to()); + CHECK(arg{LV()}.can_cast_to()); + CHECK(arg{LV()}.can_cast_to()); + CHECK_FALSE(arg{LV()}.can_cast_to()); + CHECK_FALSE(arg{LV()}.can_cast_to()); + + CHECK(A::copy_ctors_ == 0); + CHECK(A::move_ctors_ == 0); + + CHECK(arg{LV()}.cast().f() == 1); + CHECK(arg{LV()}.cast().f() == 1); + CHECK(arg{LV()}.cast().f() == 1); + CHECK(arg{LV()}.cast().f() == 1); + CHECK_THROWS(std::ignore = arg{LV()}.cast()); + CHECK_THROWS(std::ignore = arg{LV()}.cast()); + + CHECK(A::copy_ctors_ == 2); + CHECK(A::move_ctors_ == 0); + } + + SUBCASE("CLV") { + CHECK(arg{CLV()}.can_cast_to()); + CHECK(arg{CLV()}.can_cast_to()); + CHECK_FALSE(arg{CLV()}.can_cast_to()); + CHECK(arg{CLV()}.can_cast_to()); + CHECK_FALSE(arg{CLV()}.can_cast_to()); + CHECK_FALSE(arg{CLV()}.can_cast_to()); + + CHECK(A::copy_ctors_ == 0); + CHECK(A::move_ctors_ == 0); + + CHECK(arg{CLV()}.cast().f() == 1); + CHECK(arg{CLV()}.cast().f() == 1); + CHECK_THROWS(std::ignore = arg{CLV()}.cast()); + CHECK(arg{CLV()}.cast().f() == 1); + CHECK_THROWS(std::ignore = arg{CLV()}.cast()); + CHECK_THROWS(std::ignore = arg{CLV()}.cast()); + + CHECK(A::copy_ctors_ == 2); + CHECK(A::move_ctors_ == 0); + } + + SUBCASE("XV") { + CHECK(arg{XV()}.can_cast_to()); + CHECK(arg{XV()}.can_cast_to()); + CHECK_FALSE(arg{XV()}.can_cast_to()); + CHECK(arg{XV()}.can_cast_to()); + CHECK(arg{XV()}.can_cast_to()); + CHECK(arg{XV()}.can_cast_to()); + + CHECK(A::copy_ctors_ == 0); + CHECK(A::move_ctors_ == 0); + + CHECK(arg{XV()}.cast().f() == 1); + CHECK(arg{XV()}.cast().f() == 1); + CHECK_THROWS(std::ignore = arg{XV()}.cast()); + CHECK(arg{XV()}.cast().f() == 1); + CHECK(arg{XV()}.cast().f() == 1); + CHECK(arg{XV()}.cast().f() == 1); + + CHECK(A::copy_ctors_ == 0); + CHECK(A::move_ctors_ == 2); + } + + SUBCASE("CXV") { + CHECK(arg{CXV()}.can_cast_to()); + CHECK(arg{CXV()}.can_cast_to()); + CHECK_FALSE(arg{CXV()}.can_cast_to()); + CHECK(arg{CXV()}.can_cast_to()); + CHECK_FALSE(arg{CXV()}.can_cast_to()); + CHECK(arg{CXV()}.can_cast_to()); + + CHECK(A::copy_ctors_ == 0); + CHECK(A::move_ctors_ == 0); + + CHECK(arg{CXV()}.cast().f() == 1); + CHECK(arg{CXV()}.cast().f() == 1); + CHECK_THROWS(std::ignore = arg{CXV()}.cast()); + CHECK(arg{CXV()}.cast().f() == 1); + CHECK_THROWS(std::ignore = arg{CXV()}.cast()); + CHECK(arg{CXV()}.cast().f() == 1); + + CHECK(A::copy_ctors_ == 2); + CHECK(A::move_ctors_ == 0); + } + + SUBCASE("PRV") { + CHECK(arg{PRV()}.can_cast_to()); + CHECK(arg{PRV()}.can_cast_to()); + CHECK_FALSE(arg{PRV()}.can_cast_to()); + CHECK(arg{PRV()}.can_cast_to()); + CHECK(arg{PRV()}.can_cast_to()); + CHECK(arg{PRV()}.can_cast_to()); + + CHECK(A::copy_ctors_ == 0); + CHECK(A::move_ctors_ == 0); + + CHECK(arg{PRV()}.cast().f() == 1); + CHECK(arg{PRV()}.cast().f() == 1); + CHECK_THROWS(std::ignore = arg{PRV()}.cast()); + CHECK(arg{PRV()}.cast().f() == 1); + CHECK(arg{PRV()}.cast().f() == 1); + CHECK(arg{PRV()}.cast().f() == 1); + + CHECK(A::copy_ctors_ == 0); + CHECK(A::move_ctors_ == 2); + } + + SUBCASE("CPRV") { + CHECK(arg{CPRV()}.can_cast_to()); + CHECK(arg{CPRV()}.can_cast_to()); + CHECK_FALSE(arg{CPRV()}.can_cast_to()); + CHECK(arg{CPRV()}.can_cast_to()); + CHECK_FALSE(arg{CPRV()}.can_cast_to()); + CHECK(arg{CPRV()}.can_cast_to()); + + CHECK(A::copy_ctors_ == 0); + CHECK(A::move_ctors_ == 0); + + CHECK(arg{CPRV()}.cast().f() == 1); + CHECK(arg{CPRV()}.cast().f() == 1); + CHECK_THROWS(std::ignore = arg{CPRV()}.cast()); + CHECK(arg{CPRV()}.cast().f() == 1); + CHECK_THROWS(std::ignore = arg{CPRV()}.cast()); + CHECK(arg{CPRV()}.cast().f() == 1); + + CHECK(A::copy_ctors_ == 2); + CHECK(A::move_ctors_ == 0); + } + + SUBCASE("LV_PTR") { + CHECK(arg{LV_PTR()}.can_cast_to()); + CHECK(arg{LV_PTR()}.can_cast_to()); + CHECK(arg{LV_PTR()}.can_cast_to()); + CHECK(arg{LV_PTR()}.can_cast_to()); + + CHECK(arg{LV_PTR()}.cast()->f() == 1); + CHECK(arg{LV_PTR()}.cast()->f() == 1); + CHECK(arg{LV_PTR()}.cast()->f() == 1); + CHECK(arg{LV_PTR()}.cast()->f() == 1); + } + + SUBCASE("LV_CPTR") { + CHECK_FALSE(arg{LV_CPTR()}.can_cast_to()); + CHECK_FALSE(arg{LV_CPTR()}.can_cast_to()); + CHECK(arg{LV_CPTR()}.can_cast_to()); + CHECK(arg{LV_CPTR()}.can_cast_to()); + + CHECK_THROWS(std::ignore = arg{LV_CPTR()}.cast()); + CHECK_THROWS(std::ignore = arg{LV_CPTR()}.cast()); + CHECK(arg{LV_CPTR()}.cast()->f() == 1); + CHECK(arg{LV_CPTR()}.cast()->f() == 1); + } + + SUBCASE("CLV_PTR") { + CHECK(arg{CLV_PTR()}.can_cast_to()); + CHECK(arg{CLV_PTR()}.can_cast_to()); + CHECK(arg{CLV_PTR()}.can_cast_to()); + CHECK(arg{CLV_PTR()}.can_cast_to()); + + CHECK(arg{CLV_PTR()}.cast()->f() == 1); + CHECK(arg{CLV_PTR()}.cast()->f() == 1); + CHECK(arg{CLV_PTR()}.cast()->f() == 1); + CHECK(arg{CLV_PTR()}.cast()->f() == 1); + } + + SUBCASE("CLV_CPTR") { + CHECK_FALSE(arg{CLV_CPTR()}.can_cast_to()); + CHECK_FALSE(arg{CLV_CPTR()}.can_cast_to()); + CHECK(arg{CLV_CPTR()}.can_cast_to()); + CHECK(arg{CLV_CPTR()}.can_cast_to()); + + CHECK_THROWS(std::ignore = arg{CLV_CPTR()}.cast()); + CHECK_THROWS(std::ignore = arg{CLV_CPTR()}.cast()); + CHECK(arg{CLV_CPTR()}.cast()->f() == 1); + CHECK(arg{CLV_CPTR()}.cast()->f() == 1); + } + + SUBCASE("XV_PTR") { + CHECK(arg{XV_PTR()}.can_cast_to()); + CHECK(arg{XV_PTR()}.can_cast_to()); + CHECK(arg{XV_PTR()}.can_cast_to()); + CHECK(arg{XV_PTR()}.can_cast_to()); + + CHECK(arg{XV_PTR()}.cast()->f() == 1); + CHECK(arg{XV_PTR()}.cast()->f() == 1); + CHECK(arg{XV_PTR()}.cast()->f() == 1); + CHECK(arg{XV_PTR()}.cast()->f() == 1); + } + + SUBCASE("XV_CPTR") { + CHECK_FALSE(arg{XV_CPTR()}.can_cast_to()); + CHECK_FALSE(arg{XV_CPTR()}.can_cast_to()); + CHECK(arg{XV_CPTR()}.can_cast_to()); + CHECK(arg{XV_CPTR()}.can_cast_to()); + + CHECK_THROWS(std::ignore = arg{XV_CPTR()}.cast()); + CHECK_THROWS(std::ignore = arg{XV_CPTR()}.cast()); + CHECK(arg{XV_CPTR()}.cast()->f() == 1); + CHECK(arg{XV_CPTR()}.cast()->f() == 1); + } + + SUBCASE("CXV_PTR") { + CHECK(arg{CXV_PTR()}.can_cast_to()); + CHECK(arg{CXV_PTR()}.can_cast_to()); + CHECK(arg{CXV_PTR()}.can_cast_to()); + CHECK(arg{CXV_PTR()}.can_cast_to()); + + CHECK(arg{CXV_PTR()}.cast()->f() == 1); + CHECK(arg{CXV_PTR()}.cast()->f() == 1); + CHECK(arg{CXV_PTR()}.cast()->f() == 1); + CHECK(arg{CXV_PTR()}.cast()->f() == 1); + } + + SUBCASE("CXV_CPTR") { + CHECK_FALSE(arg{CXV_CPTR()}.can_cast_to()); + CHECK_FALSE(arg{CXV_CPTR()}.can_cast_to()); + CHECK(arg{CXV_CPTR()}.can_cast_to()); + CHECK(arg{CXV_CPTR()}.can_cast_to()); + + CHECK_THROWS(std::ignore = arg{CXV_CPTR()}.cast()); + CHECK_THROWS(std::ignore = arg{CXV_CPTR()}.cast()); + CHECK(arg{CXV_CPTR()}.cast()->f() == 1); + CHECK(arg{CXV_CPTR()}.cast()->f() == 1); + } + + SUBCASE("PRV_PTR") { + CHECK(arg{PRV_PTR()}.can_cast_to()); + CHECK(arg{PRV_PTR()}.can_cast_to()); + CHECK(arg{PRV_PTR()}.can_cast_to()); + CHECK(arg{PRV_PTR()}.can_cast_to()); + + CHECK(arg{PRV_PTR()}.cast()->f() == 1); + CHECK(arg{PRV_PTR()}.cast()->f() == 1); + CHECK(arg{PRV_PTR()}.cast()->f() == 1); + CHECK(arg{PRV_PTR()}.cast()->f() == 1); + } + + SUBCASE("PRV_CPTR") { + CHECK_FALSE(arg{PRV_CPTR()}.can_cast_to()); + CHECK_FALSE(arg{PRV_CPTR()}.can_cast_to()); + CHECK(arg{PRV_CPTR()}.can_cast_to()); + CHECK(arg{PRV_CPTR()}.can_cast_to()); + + CHECK_THROWS(std::ignore = arg{PRV_CPTR()}.cast()); + CHECK_THROWS(std::ignore = arg{PRV_CPTR()}.cast()); + CHECK(arg{PRV_CPTR()}.cast()->f() == 1); + CHECK(arg{PRV_CPTR()}.cast()->f() == 1); + } +} diff --git a/untests/meta_utilities/arg3_tests.cpp b/untests/meta_utilities/arg3_tests.cpp new file mode 100644 index 0000000..0506a36 --- /dev/null +++ b/untests/meta_utilities/arg3_tests.cpp @@ -0,0 +1,127 @@ +/******************************************************************************* + * 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_tests.hpp" + +namespace +{ + struct A { + A() = default; + virtual ~A() = default; + + A(A&&) = delete; + A(const A&) = delete; + A& operator=(A&&) = delete; + A& operator=(const A&) = delete; + + int i = 1; + [[maybe_unused, nodiscard]] int f() const { return i; } + }; + + struct B : virtual A { + int i = 2; + [[maybe_unused, nodiscard]] int f() const { return i; } + }; + + struct C : virtual A { + int i = 3; + [[maybe_unused, nodiscard]] int f() const { return i; } + }; + + struct D : B, C { + int i = 4; + [[maybe_unused, nodiscard]] int f() const { return i; } + }; +} + +TEST_CASE("features/meta_utilities/arg3") { + namespace meta = meta_hpp; + + // * <- B <- * + // A D + // * <- C <- * + + meta::class_(); + meta::class_().base_(); + meta::class_().base_(); + meta::class_().base_().base_(); +} + +TEST_CASE("features/meta_utilities/arg3/cast") { + namespace meta = meta_hpp; + using meta::detail::arg; + + auto LV = []() -> D& { static D v; return v; }; + auto CLV = []() -> const D& { static D v; return v; }; + auto XV = []() -> D&& { static D v; return std::move(v); }; + auto CXV = []() -> const D&& { static D v; return std::move(v); }; + auto PRV = []() -> D { return D{}; }; + auto CPRV = []() -> const D { return D{}; }; + + // *------------------------------------------------------------* + // | ======> | T, const T | T& | const T& | T&& | const T&& | + // |---------*------------*------*----------*------*------------| + // | LV | Cc | ++ | ++ | | | + // |---------*------------*------*----------*------*------------| + // | CLV | Cc | | ++ | | | + // |---------*------------*------*----------*------*------------| + // | XV | Mc | | ++ | ++ | ++ | + // |---------*------------*------*----------*------*------------| + // | CXV | Cc | | ++ | | ++ | + // |---------*------------*------*----------*------*------------| + // | PRV | ++ | | ++ | ++ | ++ | + // |---------*------------*------*----------*------*------------| + // | CPRV | ++ | | ++ | | ++ | + // *------------------------------------------------------------* + + SUBCASE("LV") { + CHECK_FALSE(arg{LV()}.can_cast_to()); + CHECK_FALSE(arg{LV()}.can_cast_to()); + + CHECK_THROWS(std::ignore = arg{LV()}.cast()); + CHECK_THROWS(std::ignore = arg{LV()}.cast()); + } + + SUBCASE("CLV") { + CHECK_FALSE(arg{CLV()}.can_cast_to()); + CHECK_FALSE(arg{CLV()}.can_cast_to()); + + CHECK_THROWS(std::ignore = arg{CLV()}.cast()); + CHECK_THROWS(std::ignore = arg{CLV()}.cast()); + } + + SUBCASE("XV") { + CHECK_FALSE(arg{XV()}.can_cast_to()); + CHECK_FALSE(arg{XV()}.can_cast_to()); + + CHECK_THROWS(std::ignore = arg{XV()}.cast()); + CHECK_THROWS(std::ignore = arg{XV()}.cast()); + } + + SUBCASE("CXV") { + CHECK_FALSE(arg{CXV()}.can_cast_to()); + CHECK_FALSE(arg{CXV()}.can_cast_to()); + + CHECK_THROWS(std::ignore = arg{CXV()}.cast()); + CHECK_THROWS(std::ignore = arg{CXV()}.cast()); + } + + SUBCASE("PRV") { + CHECK_FALSE(arg{PRV()}.can_cast_to()); + CHECK_FALSE(arg{PRV()}.can_cast_to()); + + CHECK_THROWS(std::ignore = arg{PRV()}.cast()); + CHECK_THROWS(std::ignore = arg{PRV()}.cast()); + } + + SUBCASE("CPRV") { + CHECK_FALSE(arg{CPRV()}.can_cast_to()); + CHECK_FALSE(arg{CPRV()}.can_cast_to()); + + CHECK_THROWS(std::ignore = arg{CPRV()}.cast()); + CHECK_THROWS(std::ignore = arg{CPRV()}.cast()); + } +} diff --git a/untests/meta_utilities/arg4_tests.cpp b/untests/meta_utilities/arg4_tests.cpp new file mode 100644 index 0000000..51ea113 --- /dev/null +++ b/untests/meta_utilities/arg4_tests.cpp @@ -0,0 +1,144 @@ +/******************************************************************************* + * 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_tests.hpp" + +TEST_CASE("features/meta_utilities/arg4/cast") { + namespace meta = meta_hpp; + using meta::detail::arg; + + auto LV_PTR = []() -> int*& { static int v{42}; static int* p{&v}; return p; }; + auto CLV_PTR = []() -> int* const& { static int v{42}; static int* p{&v}; return p; }; + auto XV_PTR = []() -> int*&& { static int v{42}; static int* p{&v}; return std::move(p); }; + auto CXV_PTR = []() -> int* const&& { static int v{42}; static int* p{&v}; return std::move(p); }; + auto PRV_PTR = []() -> int* { static int v{42}; static int* p{&v}; return p; }; + + auto LV_CPTR = []() -> const int*& { static int v{42}; static const int* p{&v}; return p; }; + auto CLV_CPTR = []() -> const int* const& { static int v{42}; static const int* p{&v}; return p; }; + auto XV_CPTR = []() -> const int*&& { static int v{42}; static const int* p{&v}; return std::move(p); }; + auto CXV_CPTR = []() -> const int* const&& { static int v{42}; static const int* p{&v}; return std::move(p); }; + auto PRV_CPTR = []() -> const int* { static int v{42}; static const int* p{&v}; return p; }; + + SUBCASE("LV_PTR") { + CHECK(arg{LV_PTR()}.can_cast_to()); + CHECK(arg{LV_PTR()}.can_cast_to()); + CHECK(arg{LV_PTR()}.can_cast_to()); + CHECK(arg{LV_PTR()}.can_cast_to()); + + CHECK(*arg{LV_PTR()}.cast() == 42); + CHECK(*arg{LV_PTR()}.cast() == 42); + CHECK(*arg{LV_PTR()}.cast() == 42); + CHECK(*arg{LV_PTR()}.cast() == 42); + } + + SUBCASE("CLV_PTR") { + CHECK(arg{CLV_PTR()}.can_cast_to()); + CHECK(arg{CLV_PTR()}.can_cast_to()); + CHECK(arg{CLV_PTR()}.can_cast_to()); + CHECK(arg{CLV_PTR()}.can_cast_to()); + + CHECK(*arg{CLV_PTR()}.cast() == 42); + CHECK(*arg{CLV_PTR()}.cast() == 42); + CHECK(*arg{CLV_PTR()}.cast() == 42); + CHECK(*arg{CLV_PTR()}.cast() == 42); + } + + SUBCASE("XV_PTR") { + CHECK(arg{XV_PTR()}.can_cast_to()); + CHECK(arg{XV_PTR()}.can_cast_to()); + CHECK(arg{XV_PTR()}.can_cast_to()); + CHECK(arg{XV_PTR()}.can_cast_to()); + + CHECK(*arg{XV_PTR()}.cast() == 42); + CHECK(*arg{XV_PTR()}.cast() == 42); + CHECK(*arg{XV_PTR()}.cast() == 42); + CHECK(*arg{XV_PTR()}.cast() == 42); + } + + SUBCASE("CXV_PTR") { + CHECK(arg{CXV_PTR()}.can_cast_to()); + CHECK(arg{CXV_PTR()}.can_cast_to()); + CHECK(arg{CXV_PTR()}.can_cast_to()); + CHECK(arg{CXV_PTR()}.can_cast_to()); + + CHECK(*arg{CXV_PTR()}.cast() == 42); + CHECK(*arg{CXV_PTR()}.cast() == 42); + CHECK(*arg{CXV_PTR()}.cast() == 42); + CHECK(*arg{CXV_PTR()}.cast() == 42); + } + + SUBCASE("PRV_PTR") { + CHECK(arg{PRV_PTR()}.can_cast_to()); + CHECK(arg{PRV_PTR()}.can_cast_to()); + CHECK(arg{PRV_PTR()}.can_cast_to()); + CHECK(arg{PRV_PTR()}.can_cast_to()); + + CHECK(*arg{PRV_PTR()}.cast() == 42); + CHECK(*arg{PRV_PTR()}.cast() == 42); + CHECK(*arg{PRV_PTR()}.cast() == 42); + CHECK(*arg{PRV_PTR()}.cast() == 42); + } + + SUBCASE("LV_CPTR") { + CHECK_FALSE(arg{LV_CPTR()}.can_cast_to()); + CHECK_FALSE(arg{LV_CPTR()}.can_cast_to()); + CHECK(arg{LV_CPTR()}.can_cast_to()); + CHECK(arg{LV_CPTR()}.can_cast_to()); + + CHECK_THROWS(std::ignore = arg{LV_CPTR()}.cast()); + CHECK_THROWS(std::ignore = arg{LV_CPTR()}.cast()); + CHECK(*arg{LV_CPTR()}.cast() == 42); + CHECK(*arg{LV_CPTR()}.cast() == 42); + } + + SUBCASE("CLV_CPTR") { + CHECK_FALSE(arg{CLV_CPTR()}.can_cast_to()); + CHECK_FALSE(arg{CLV_CPTR()}.can_cast_to()); + CHECK(arg{CLV_CPTR()}.can_cast_to()); + CHECK(arg{CLV_CPTR()}.can_cast_to()); + + CHECK_THROWS(std::ignore = arg{CLV_CPTR()}.cast()); + CHECK_THROWS(std::ignore = arg{CLV_CPTR()}.cast()); + CHECK(*arg{CLV_CPTR()}.cast() == 42); + CHECK(*arg{CLV_CPTR()}.cast() == 42); + } + + SUBCASE("XV_CPTR") { + CHECK_FALSE(arg{XV_CPTR()}.can_cast_to()); + CHECK_FALSE(arg{XV_CPTR()}.can_cast_to()); + CHECK(arg{XV_CPTR()}.can_cast_to()); + CHECK(arg{XV_CPTR()}.can_cast_to()); + + CHECK_THROWS(std::ignore = arg{XV_CPTR()}.cast()); + CHECK_THROWS(std::ignore = arg{XV_CPTR()}.cast()); + CHECK(*arg{XV_CPTR()}.cast() == 42); + CHECK(*arg{XV_CPTR()}.cast() == 42); + } + + SUBCASE("CXV_CPTR") { + CHECK_FALSE(arg{CXV_CPTR()}.can_cast_to()); + CHECK_FALSE(arg{CXV_CPTR()}.can_cast_to()); + CHECK(arg{CXV_CPTR()}.can_cast_to()); + CHECK(arg{CXV_CPTR()}.can_cast_to()); + + CHECK_THROWS(std::ignore = arg{CXV_CPTR()}.cast()); + CHECK_THROWS(std::ignore = arg{CXV_CPTR()}.cast()); + CHECK(*arg{CXV_CPTR()}.cast() == 42); + CHECK(*arg{CXV_CPTR()}.cast() == 42); + } + + SUBCASE("PRV_CPTR") { + CHECK_FALSE(arg{PRV_CPTR()}.can_cast_to()); + CHECK_FALSE(arg{PRV_CPTR()}.can_cast_to()); + CHECK(arg{PRV_CPTR()}.can_cast_to()); + CHECK(arg{PRV_CPTR()}.can_cast_to()); + + CHECK_THROWS(std::ignore = arg{PRV_CPTR()}.cast()); + CHECK_THROWS(std::ignore = arg{PRV_CPTR()}.cast()); + CHECK(*arg{PRV_CPTR()}.cast() == 42); + CHECK(*arg{PRV_CPTR()}.cast() == 42); + } +} diff --git a/untests/meta_utilities/arg_tests.cpp b/untests/meta_utilities/arg_tests.cpp index a6f0ed1..6fd0222 100644 --- a/untests/meta_utilities/arg_tests.cpp +++ b/untests/meta_utilities/arg_tests.cpp @@ -8,44 +8,64 @@ namespace { + struct clazz; + struct dclazz; + + struct fake { + int i = 10; + }; + struct clazz { - [[maybe_unused]] clazz() = default; - [[maybe_unused]] clazz(clazz&&) = default; - [[maybe_unused]] clazz(const clazz&) = default; - clazz& operator=(clazz&&) = delete; - clazz& operator=(const clazz&) = delete; + int ii = 1; }; - struct dclazz : clazz { - [[maybe_unused]] dclazz() = default; - [[maybe_unused]] dclazz(dclazz&&) = default; - [[maybe_unused]] dclazz(const dclazz&) = default; - dclazz& operator=(dclazz&&) = delete; - dclazz& operator=(const dclazz&) = delete; + struct dclazz : fake, clazz { }; - int f1(clazz) { return 1; } - int f2(const clazz) { return 1; } - int f3(clazz&) { return 1; } - int f4(const clazz&) { return 1; } - int f5(clazz&&) { return 1; } - int f6(const clazz&&) { return 1; } + int f1(int v) { return v; } + int f2(const int v) { return v; } + int f3(int& v) { return v; } + int f4(const int& v) { return v; } + int f5(int&& v) { return v; } + int f6(const int&& v) { return v; } - int f1(clazz*) { return 1; } - int f2(clazz* const) { return 1; } - // int f3(clazz*&) { return 1; } - // int f4(clazz* const&) { return 1; } - // int f5(clazz*&&) { return 1; } - // int f6(clazz* const&&) { return 1; } + int f1(clazz v) { return v.ii; } + int f2(const clazz v) { return v.ii; } + int f3(clazz& v) { return v.ii; } + int f4(const clazz& v) { return v.ii; } + int f5(clazz&& v) { return v.ii; } + int f6(const clazz&& v) { return v.ii; } - int f1(const clazz*) { return 1; } - int f2(const clazz* const) { return 1; } - // int f3(const clazz*&) { return 1; } - // int f4(const clazz* const&) { return 1; } - // int f5(const clazz*&&) { return 1; } - // int f6(const clazz* const&&) { return 1; } + int f1(int* v) { return *v; } + int f2(int* const v) { return *v; } + // int f3(int*&) { return *v; } + // int f4(int* const&) { return *v; } + // int f5(int*&&) { return *v; } + // int f6(int* const&&) { return *v; } + + int f1(clazz* v) { return v->ii; } + int f2(clazz* const v) { return v->ii; } + // int f3(clazz*&) { return v->ii; } + // int f4(clazz* const&) { return v->ii; } + // int f5(clazz*&&) { return v->ii; } + // int f6(clazz* const&&) { return v->ii; } + + int f1(const int* v) { return *v; } + int f2(const int* const v) { return *v; } + // int f3(const int*&) { return *v; } + // int f4(const int* const&) { return *v; } + // int f5(const int*&&) { return *v; } + // int f6(const int* const&&) { return *v; } + + int f1(const clazz* v) { return v->ii; } + int f2(const clazz* const v) { return v->ii; } + // int f3(const clazz*&) { return v->ii; } + // int f4(const clazz* const&) { return v->ii; } + // int f5(const clazz*&&) { return v->ii; } + // int f6(const clazz* const&&) { return v->ii; } } +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define META_HPP_CHECK_INVOCABLE(FromValue, FName, ToType)\ {\ using namespace meta::detail;\ @@ -55,20 +75,21 @@ namespace if ( std::is_invocable_v ) {\ CHECK(arg{FromValue}.can_cast_to());\ CHECK(arg_base{type_list{}}.can_cast_to());\ - CHECK_NOTHROW(arg{FromValue}.cast());\ + CHECK_NOTHROW(std::ignore = arg{FromValue}.cast());\ \ CHECK(f_state.is_invocable_with());\ CHECK(f_state.invoke(FromValue) == 1);\ } else {\ CHECK_FALSE(arg{FromValue}.can_cast_to());\ CHECK_FALSE(arg_base{type_list{}}.can_cast_to());\ - CHECK_THROWS(arg{FromValue}.cast());\ + CHECK_THROWS(std::ignore = arg{FromValue}.cast());\ \ CHECK_FALSE(f_state.is_invocable_with());\ CHECK_THROWS(f_state.invoke(FromValue));\ }\ } +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define META_HPP_CHECK_INVOCABLE_2(FromValue, FName, FromType, ToType)\ {\ using namespace meta::detail;\ @@ -89,8 +110,9 @@ namespace TEST_CASE("features/meta_utilities/arg") { namespace meta = meta_hpp; - meta::class_() - .base_(); + meta::class_(); + meta::class_(); + meta::class_().base_().base_(); } TEST_CASE("features/meta_utilities/arg/refs") { @@ -100,6 +122,7 @@ TEST_CASE("features/meta_utilities/arg/refs") { // lvalue auto LV = []() -> clazz& { static clazz v; return v; }; auto LV2 = []() -> dclazz& { static dclazz v; return v; }; + auto LV3 = []() -> int& { static int v{1}; return v; }; meta::detail::arg a{LV()}; CHECK(a.get_raw_type() == meta::resolve_type()); @@ -118,12 +141,20 @@ TEST_CASE("features/meta_utilities/arg/refs") { META_HPP_CHECK_INVOCABLE(LV2(), f4, const clazz&) META_HPP_CHECK_INVOCABLE(LV2(), f5, clazz&&) META_HPP_CHECK_INVOCABLE(LV2(), f6, const clazz&&) + + META_HPP_CHECK_INVOCABLE(LV3(), f1, int) + META_HPP_CHECK_INVOCABLE(LV3(), f2, const int) + META_HPP_CHECK_INVOCABLE(LV3(), f3, int&) + META_HPP_CHECK_INVOCABLE(LV3(), f4, const int&) + META_HPP_CHECK_INVOCABLE(LV3(), f5, int&&) + META_HPP_CHECK_INVOCABLE(LV3(), f6, const int&&) } { // const lvalue auto CLV = []() -> const clazz& { static clazz v; return v; }; auto CLV2 = []() -> const dclazz& { static dclazz v; return v; }; + auto CLV3 = []() -> const int& { static int v{1}; return v; }; meta::detail::arg a{CLV()}; CHECK(a.get_raw_type() == meta::resolve_type()); @@ -142,12 +173,20 @@ TEST_CASE("features/meta_utilities/arg/refs") { META_HPP_CHECK_INVOCABLE(CLV2(), f4, const clazz&) META_HPP_CHECK_INVOCABLE(CLV2(), f5, clazz&&) META_HPP_CHECK_INVOCABLE(CLV2(), f6, const clazz&&) + + META_HPP_CHECK_INVOCABLE(CLV3(), f1, int) + META_HPP_CHECK_INVOCABLE(CLV3(), f2, const int) + META_HPP_CHECK_INVOCABLE(CLV3(), f3, int&) + META_HPP_CHECK_INVOCABLE(CLV3(), f4, const int&) + META_HPP_CHECK_INVOCABLE(CLV3(), f5, int&&) + META_HPP_CHECK_INVOCABLE(CLV3(), f6, const int&&) } { // xvalue auto XV = []() -> clazz&& { static clazz v; return std::move(v); }; auto XV2 = []() -> dclazz&& { static dclazz v; return std::move(v); }; + auto XV3 = []() -> int&& { static int v{1}; return std::move(v); }; meta::detail::arg a{XV()}; CHECK(a.get_raw_type() == meta::resolve_type()); @@ -166,12 +205,20 @@ TEST_CASE("features/meta_utilities/arg/refs") { META_HPP_CHECK_INVOCABLE(XV2(), f4, const clazz&) META_HPP_CHECK_INVOCABLE(XV2(), f5, clazz&&) META_HPP_CHECK_INVOCABLE(XV2(), f6, const clazz&&) + + META_HPP_CHECK_INVOCABLE(XV3(), f1, int) + META_HPP_CHECK_INVOCABLE(XV3(), f2, const int) + META_HPP_CHECK_INVOCABLE(XV3(), f3, int&) + META_HPP_CHECK_INVOCABLE(XV3(), f4, const int&) + META_HPP_CHECK_INVOCABLE(XV3(), f5, int&&) + META_HPP_CHECK_INVOCABLE(XV3(), f6, const int&&) } { // const xvalue auto CXV = []() -> const clazz&& { static clazz v; return std::move(v); }; auto CXV2 = []() -> const dclazz&& { static dclazz v; return std::move(v); }; + auto CXV3 = []() -> const int&& { static int v{1}; return std::move(v); }; meta::detail::arg a{CXV()}; CHECK(a.get_raw_type() == meta::resolve_type()); @@ -190,12 +237,20 @@ TEST_CASE("features/meta_utilities/arg/refs") { META_HPP_CHECK_INVOCABLE(CXV2(), f4, const clazz&) META_HPP_CHECK_INVOCABLE(CXV2(), f5, clazz&&) META_HPP_CHECK_INVOCABLE(CXV2(), f6, const clazz&&) + + META_HPP_CHECK_INVOCABLE(CXV3(), f1, int) + META_HPP_CHECK_INVOCABLE(CXV3(), f2, const int) + META_HPP_CHECK_INVOCABLE(CXV3(), f3, int&) + META_HPP_CHECK_INVOCABLE(CXV3(), f4, const int&) + META_HPP_CHECK_INVOCABLE(CXV3(), f5, int&&) + META_HPP_CHECK_INVOCABLE(CXV3(), f6, const int&&) } { // prvalue auto PRV = []() -> clazz { return clazz{}; }; auto PRV2 = []() -> dclazz { return dclazz{}; }; + auto PRV3 = []() -> int { return int{1}; }; meta::detail::arg a{PRV()}; CHECK(a.get_raw_type() == meta::resolve_type()); @@ -214,6 +269,13 @@ TEST_CASE("features/meta_utilities/arg/refs") { META_HPP_CHECK_INVOCABLE(PRV2(), f4, const clazz&) META_HPP_CHECK_INVOCABLE(PRV2(), f5, clazz&&) META_HPP_CHECK_INVOCABLE(PRV2(), f6, const clazz&&) + + META_HPP_CHECK_INVOCABLE(PRV3(), f1, int) + META_HPP_CHECK_INVOCABLE(PRV3(), f2, const int) + META_HPP_CHECK_INVOCABLE(PRV3(), f3, int&) + META_HPP_CHECK_INVOCABLE(PRV3(), f4, const int&) + META_HPP_CHECK_INVOCABLE(PRV3(), f5, int&&) + META_HPP_CHECK_INVOCABLE(PRV3(), f6, const int&&) } { @@ -247,8 +309,9 @@ TEST_CASE("features/meta_utilities/arg/ptrs") { { // lvalue { - auto LV_PTR = []() -> clazz*& { static clazz* p{}; return p; }; - auto LV2_PTR = []() -> dclazz*& { static dclazz* p{}; return p; }; + auto LV_PTR = []() -> clazz*& { static clazz v; static clazz* p{&v}; return p; }; + auto LV2_PTR = []() -> dclazz*& { static dclazz v; static dclazz* p{&v}; return p; }; + auto LV3_PTR = []() -> int*& { static int v{1}; static int* p{&v}; return p; }; meta::detail::arg a{LV_PTR()}; CHECK(a.get_raw_type() == meta::resolve_type()); @@ -281,10 +344,25 @@ TEST_CASE("features/meta_utilities/arg/ptrs") { // META_HPP_CHECK_INVOCABLE(LV2_PTR(), f4, const clazz* const&) // META_HPP_CHECK_INVOCABLE(LV2_PTR(), f5, const clazz*&&) // META_HPP_CHECK_INVOCABLE(LV2_PTR(), f6, const clazz* const&&) + + META_HPP_CHECK_INVOCABLE(LV3_PTR(), f1, int*) + META_HPP_CHECK_INVOCABLE(LV3_PTR(), f2, int* const) + // META_HPP_CHECK_INVOCABLE(LV3_PTR(), f3, int*&) + // META_HPP_CHECK_INVOCABLE(LV3_PTR(), f4, int* const&) + // META_HPP_CHECK_INVOCABLE(LV3_PTR(), f5, int*&&) + // META_HPP_CHECK_INVOCABLE(LV3_PTR(), f6, int* const&&) + + META_HPP_CHECK_INVOCABLE(LV3_PTR(), f1, const int*) + META_HPP_CHECK_INVOCABLE(LV3_PTR(), f2, const int* const) + // META_HPP_CHECK_INVOCABLE(LV3_PTR(), f3, const int*&) + // META_HPP_CHECK_INVOCABLE(LV3_PTR(), f4, const int* const&) + // META_HPP_CHECK_INVOCABLE(LV3_PTR(), f5, const int*&&) + // META_HPP_CHECK_INVOCABLE(LV3_PTR(), f6, const int* const&&) } { - auto LV_CPTR = []() -> const clazz*& { static const clazz* p{}; return p; }; - auto LV2_CPTR = []() -> const dclazz*& { static const dclazz* p{}; return p; }; + auto LV_CPTR = []() -> const clazz*& { static clazz v; static const clazz* p{&v}; return p; }; + auto LV2_CPTR = []() -> const dclazz*& { static dclazz v; static const dclazz* p{&v}; return p; }; + auto LV3_CPTR = []() -> const int*& { static int v{1}; static const int* p{&v}; return p; }; meta::detail::arg a{LV_CPTR()}; CHECK(a.get_raw_type() == meta::resolve_type()); @@ -317,14 +395,29 @@ TEST_CASE("features/meta_utilities/arg/ptrs") { // META_HPP_CHECK_INVOCABLE(LV2_CPTR(), f4, const clazz* const&) // META_HPP_CHECK_INVOCABLE(LV2_CPTR(), f5, const clazz*&&) // META_HPP_CHECK_INVOCABLE(LV2_CPTR(), f6, const clazz* const&&) + + META_HPP_CHECK_INVOCABLE(LV3_CPTR(), f1, int*) + META_HPP_CHECK_INVOCABLE(LV3_CPTR(), f2, int* const) + // META_HPP_CHECK_INVOCABLE(LV3_CPTR(), f3, int*&) + // META_HPP_CHECK_INVOCABLE(LV3_CPTR(), f4, int* const&) + // META_HPP_CHECK_INVOCABLE(LV3_CPTR(), f5, int*&&) + // META_HPP_CHECK_INVOCABLE(LV3_CPTR(), f6, int* const&&) + + META_HPP_CHECK_INVOCABLE(LV3_CPTR(), f1, const int*) + META_HPP_CHECK_INVOCABLE(LV3_CPTR(), f2, const int* const) + // META_HPP_CHECK_INVOCABLE(LV3_CPTR(), f3, const int*&) + // META_HPP_CHECK_INVOCABLE(LV3_CPTR(), f4, const int* const&) + // META_HPP_CHECK_INVOCABLE(LV3_CPTR(), f5, const int*&&) + // META_HPP_CHECK_INVOCABLE(LV3_CPTR(), f6, const int* const&&) } } { // const lvalue { - auto CLV_PTR = []() -> clazz* const& { static clazz* p{}; return p; }; - auto CLV2_PTR = []() -> dclazz* const& { static dclazz* p{}; return p; }; + auto CLV_PTR = []() -> clazz* const& { static clazz v; static clazz* p{&v}; return p; }; + auto CLV2_PTR = []() -> dclazz* const& { static dclazz v; static dclazz* p{&v}; return p; }; + auto CLV3_PTR = []() -> int* const& { static int v{1}; static int* p{&v}; return p; }; meta::detail::arg a{CLV_PTR()}; CHECK(a.get_raw_type() == meta::resolve_type()); @@ -357,10 +450,25 @@ TEST_CASE("features/meta_utilities/arg/ptrs") { // META_HPP_CHECK_INVOCABLE(CLV2_PTR(), f4, const clazz* const&) // META_HPP_CHECK_INVOCABLE(CLV2_PTR(), f5, const clazz*&&) // META_HPP_CHECK_INVOCABLE(CLV2_PTR(), f6, const clazz* const&&) + + META_HPP_CHECK_INVOCABLE(CLV3_PTR(), f1, int*) + META_HPP_CHECK_INVOCABLE(CLV3_PTR(), f2, int* const) + // META_HPP_CHECK_INVOCABLE(CLV3_PTR(), f3, int*&) + // META_HPP_CHECK_INVOCABLE(CLV3_PTR(), f4, int* const&) + // META_HPP_CHECK_INVOCABLE(CLV3_PTR(), f5, int*&&) + // META_HPP_CHECK_INVOCABLE(CLV3_PTR(), f6, int* const&&) + + META_HPP_CHECK_INVOCABLE(CLV3_PTR(), f1, const int*) + META_HPP_CHECK_INVOCABLE(CLV3_PTR(), f2, const int* const) + // META_HPP_CHECK_INVOCABLE(CLV3_PTR(), f3, const int*&) + // META_HPP_CHECK_INVOCABLE(CLV3_PTR(), f4, const int* const&) + // META_HPP_CHECK_INVOCABLE(CLV3_PTR(), f5, const int*&&) + // META_HPP_CHECK_INVOCABLE(CLV3_PTR(), f6, const int* const&&) } { - auto CLV_CPTR = []() -> const clazz* const& { static const clazz* p{}; return p; }; - auto CLV2_CPTR = []() -> const dclazz* const& { static const dclazz* p{}; return p; }; + auto CLV_CPTR = []() -> const clazz* const& { static clazz v; static const clazz* p{&v}; return p; }; + auto CLV2_CPTR = []() -> const dclazz* const& { static dclazz v; static const dclazz* p{&v}; return p; }; + auto CLV3_CPTR = []() -> const int* const& { static int v{1}; static const int* p{&v}; return p; }; meta::detail::arg a{CLV_CPTR()}; CHECK(a.get_raw_type() == meta::resolve_type()); @@ -393,14 +501,29 @@ TEST_CASE("features/meta_utilities/arg/ptrs") { // META_HPP_CHECK_INVOCABLE(CLV2_CPTR(), f4, const clazz* const&) // META_HPP_CHECK_INVOCABLE(CLV2_CPTR(), f5, const clazz*&&) // META_HPP_CHECK_INVOCABLE(CLV2_CPTR(), f6, const clazz* const&&) + + META_HPP_CHECK_INVOCABLE(CLV3_CPTR(), f1, int*) + META_HPP_CHECK_INVOCABLE(CLV3_CPTR(), f2, int* const) + // META_HPP_CHECK_INVOCABLE(CLV3_CPTR(), f3, int*&) + // META_HPP_CHECK_INVOCABLE(CLV3_CPTR(), f4, int* const&) + // META_HPP_CHECK_INVOCABLE(CLV3_CPTR(), f5, int*&&) + // META_HPP_CHECK_INVOCABLE(CLV3_CPTR(), f6, int* const&&) + + META_HPP_CHECK_INVOCABLE(CLV3_CPTR(), f1, const int*) + META_HPP_CHECK_INVOCABLE(CLV3_CPTR(), f2, const int* const) + // META_HPP_CHECK_INVOCABLE(CLV3_CPTR(), f3, const int*&) + // META_HPP_CHECK_INVOCABLE(CLV3_CPTR(), f4, const int* const&) + // META_HPP_CHECK_INVOCABLE(CLV3_CPTR(), f5, const int*&&) + // META_HPP_CHECK_INVOCABLE(CLV3_CPTR(), f6, const int* const&&) } } { // xvalue { - auto XV_PTR = []() -> clazz*&& { static clazz* p{}; return std::move(p); }; - auto XV2_PTR = []() -> dclazz*&& { static dclazz* p{}; return std::move(p); }; + auto XV_PTR = []() -> clazz*&& { static clazz v; static clazz* p{&v}; return std::move(p); }; + auto XV2_PTR = []() -> dclazz*&& { static dclazz v; static dclazz* p{&v}; return std::move(p); }; + auto XV3_PTR = []() -> int*&& { static int v{1}; static int* p{&v}; return std::move(p); }; meta::detail::arg a{XV_PTR()}; CHECK(a.get_raw_type() == meta::resolve_type()); @@ -433,10 +556,25 @@ TEST_CASE("features/meta_utilities/arg/ptrs") { // META_HPP_CHECK_INVOCABLE(XV2_PTR(), f4, const clazz* const&) // META_HPP_CHECK_INVOCABLE(XV2_PTR(), f5, const clazz*&&) // META_HPP_CHECK_INVOCABLE(XV2_PTR(), f6, const clazz* const&&) + + META_HPP_CHECK_INVOCABLE(XV3_PTR(), f1, int*) + META_HPP_CHECK_INVOCABLE(XV3_PTR(), f2, int* const) + // META_HPP_CHECK_INVOCABLE(XV3_PTR(), f3, int*&) + // META_HPP_CHECK_INVOCABLE(XV3_PTR(), f4, int* const&) + // META_HPP_CHECK_INVOCABLE(XV3_PTR(), f5, int*&&) + // META_HPP_CHECK_INVOCABLE(XV3_PTR(), f6, int* const&&) + + META_HPP_CHECK_INVOCABLE(XV3_PTR(), f1, const int*) + META_HPP_CHECK_INVOCABLE(XV3_PTR(), f2, const int* const) + // META_HPP_CHECK_INVOCABLE(XV3_PTR(), f3, const int*&) + // META_HPP_CHECK_INVOCABLE(XV3_PTR(), f4, const int* const&) + // META_HPP_CHECK_INVOCABLE(XV3_PTR(), f5, const int*&&) + // META_HPP_CHECK_INVOCABLE(XV3_PTR(), f6, const int* const&&) } { - auto XV_CPTR = []() -> const clazz*&& { static const clazz* p{}; return std::move(p); }; - auto XV2_CPTR = []() -> const dclazz*&& { static const dclazz* p{}; return std::move(p); }; + auto XV_CPTR = []() -> const clazz*&& { static clazz v; static const clazz* p{&v}; return std::move(p); }; + auto XV2_CPTR = []() -> const dclazz*&& { static dclazz v; static const dclazz* p{&v}; return std::move(p); }; + auto XV3_CPTR = []() -> const int*&& { static int v{1}; static const int* p{&v}; return std::move(p); }; meta::detail::arg a{XV_CPTR()}; CHECK(a.get_raw_type() == meta::resolve_type()); @@ -469,14 +607,29 @@ TEST_CASE("features/meta_utilities/arg/ptrs") { // META_HPP_CHECK_INVOCABLE(XV2_CPTR(), f4, const clazz* const&) // META_HPP_CHECK_INVOCABLE(XV2_CPTR(), f5, const clazz*&&) // META_HPP_CHECK_INVOCABLE(XV2_CPTR(), f6, const clazz* const&&) + + META_HPP_CHECK_INVOCABLE(XV3_CPTR(), f1, int*) + META_HPP_CHECK_INVOCABLE(XV3_CPTR(), f2, int* const) + // META_HPP_CHECK_INVOCABLE(XV3_CPTR(), f3, int*&) + // META_HPP_CHECK_INVOCABLE(XV3_CPTR(), f4, int* const&) + // META_HPP_CHECK_INVOCABLE(XV3_CPTR(), f5, int*&&) + // META_HPP_CHECK_INVOCABLE(XV3_CPTR(), f6, int* const&&) + + META_HPP_CHECK_INVOCABLE(XV3_CPTR(), f1, const int*) + META_HPP_CHECK_INVOCABLE(XV3_CPTR(), f2, const int* const) + // META_HPP_CHECK_INVOCABLE(XV3_CPTR(), f3, const int*&) + // META_HPP_CHECK_INVOCABLE(XV3_CPTR(), f4, const int* const&) + // META_HPP_CHECK_INVOCABLE(XV3_CPTR(), f5, const int*&&) + // META_HPP_CHECK_INVOCABLE(XV3_CPTR(), f6, const int* const&&) } } { // const xvalue { - auto CXV_PTR = []() -> clazz* const&& { static clazz* p{}; return std::move(p); }; - auto CXV2_PTR = []() -> dclazz* const&& { static dclazz* p{}; return std::move(p); }; + auto CXV_PTR = []() -> clazz* const&& { static clazz v; static clazz* p{&v}; return std::move(p); }; + auto CXV2_PTR = []() -> dclazz* const&& { static dclazz v; static dclazz* p{&v}; return std::move(p); }; + auto CXV3_PTR = []() -> int* const&& { static int v{1}; static int* p{&v}; return std::move(p); }; meta::detail::arg a{CXV_PTR()}; CHECK(a.get_raw_type() == meta::resolve_type()); @@ -509,10 +662,25 @@ TEST_CASE("features/meta_utilities/arg/ptrs") { // META_HPP_CHECK_INVOCABLE(CXV2_PTR(), f4, const clazz* const&) // META_HPP_CHECK_INVOCABLE(CXV2_PTR(), f5, const clazz*&&) // META_HPP_CHECK_INVOCABLE(CXV2_PTR(), f6, const clazz* const&&) + + META_HPP_CHECK_INVOCABLE(CXV3_PTR(), f1, int*) + META_HPP_CHECK_INVOCABLE(CXV3_PTR(), f2, int* const) + // META_HPP_CHECK_INVOCABLE(CXV3_PTR(), f3, int*&) + // META_HPP_CHECK_INVOCABLE(CXV3_PTR(), f4, int* const&) + // META_HPP_CHECK_INVOCABLE(CXV3_PTR(), f5, int*&&) + // META_HPP_CHECK_INVOCABLE(CXV3_PTR(), f6, int* const&&) + + META_HPP_CHECK_INVOCABLE(CXV3_PTR(), f1, const int*) + META_HPP_CHECK_INVOCABLE(CXV3_PTR(), f2, const int* const) + // META_HPP_CHECK_INVOCABLE(CXV3_PTR(), f3, const int*&) + // META_HPP_CHECK_INVOCABLE(CXV3_PTR(), f4, const int* const&) + // META_HPP_CHECK_INVOCABLE(CXV3_PTR(), f5, const int*&&) + // META_HPP_CHECK_INVOCABLE(CXV3_PTR(), f6, const int* const&&) } { - auto CXV_CPTR = []() -> const clazz* const&& { static const clazz* p{}; return std::move(p); }; - auto CXV2_CPTR = []() -> const dclazz* const&& { static const dclazz* p{}; return std::move(p); }; + auto CXV_CPTR = []() -> const clazz* const&& { static clazz v; static const clazz* p{&v}; return std::move(p); }; + auto CXV2_CPTR = []() -> const dclazz* const&& { static dclazz v; static const dclazz* p{&v}; return std::move(p); }; + auto CXV3_CPTR = []() -> const int* const&& { static int v{1}; static const int* p{&v}; return std::move(p); }; meta::detail::arg a{CXV_CPTR()}; CHECK(a.get_raw_type() == meta::resolve_type()); @@ -545,14 +713,29 @@ TEST_CASE("features/meta_utilities/arg/ptrs") { // META_HPP_CHECK_INVOCABLE(CXV2_CPTR(), f4, const clazz* const&) // META_HPP_CHECK_INVOCABLE(CXV2_CPTR(), f5, const clazz*&&) // META_HPP_CHECK_INVOCABLE(CXV2_CPTR(), f6, const clazz* const&&) + + META_HPP_CHECK_INVOCABLE(CXV3_CPTR(), f1, int*) + META_HPP_CHECK_INVOCABLE(CXV3_CPTR(), f2, int* const) + // META_HPP_CHECK_INVOCABLE(CXV3_CPTR(), f3, int*&) + // META_HPP_CHECK_INVOCABLE(CXV3_CPTR(), f4, int* const&) + // META_HPP_CHECK_INVOCABLE(CXV3_CPTR(), f5, int*&&) + // META_HPP_CHECK_INVOCABLE(CXV3_CPTR(), f6, int* const&&) + + META_HPP_CHECK_INVOCABLE(CXV3_CPTR(), f1, const int*) + META_HPP_CHECK_INVOCABLE(CXV3_CPTR(), f2, const int* const) + // META_HPP_CHECK_INVOCABLE(CXV3_CPTR(), f3, const int*&) + // META_HPP_CHECK_INVOCABLE(CXV3_CPTR(), f4, const int* const&) + // META_HPP_CHECK_INVOCABLE(CXV3_CPTR(), f5, const int*&&) + // META_HPP_CHECK_INVOCABLE(CXV3_CPTR(), f6, const int* const&&) } } { // prvalue { - auto PRV_PTR = []() -> clazz* { static clazz* p{}; return p; }; - auto PRV2_PTR = []() -> dclazz* { static dclazz* p{}; return p; }; + auto PRV_PTR = []() -> clazz* { static clazz v; static clazz* p{&v}; return p; }; + auto PRV2_PTR = []() -> dclazz* { static dclazz v; static dclazz* p{&v}; return p; }; + auto PRV3_PTR = []() -> int* { static int v{1}; static int* p{&v}; return p; }; meta::detail::arg a{PRV_PTR()}; CHECK(a.get_raw_type() == meta::resolve_type()); @@ -585,10 +768,25 @@ TEST_CASE("features/meta_utilities/arg/ptrs") { // META_HPP_CHECK_INVOCABLE(PRV2_PTR(), f4, const clazz* const&) // META_HPP_CHECK_INVOCABLE(PRV2_PTR(), f5, const clazz*&&) // META_HPP_CHECK_INVOCABLE(PRV2_PTR(), f6, const clazz* const&&) + + META_HPP_CHECK_INVOCABLE(PRV3_PTR(), f1, int*) + META_HPP_CHECK_INVOCABLE(PRV3_PTR(), f2, int* const) + // META_HPP_CHECK_INVOCABLE(PRV3_PTR(), f3, int*&) + // META_HPP_CHECK_INVOCABLE(PRV3_PTR(), f4, int* const&) + // META_HPP_CHECK_INVOCABLE(PRV3_PTR(), f5, int*&&) + // META_HPP_CHECK_INVOCABLE(PRV3_PTR(), f6, int* const&&) + + META_HPP_CHECK_INVOCABLE(PRV3_PTR(), f1, const int*) + META_HPP_CHECK_INVOCABLE(PRV3_PTR(), f2, const int* const) + // META_HPP_CHECK_INVOCABLE(PRV3_PTR(), f3, const int*&) + // META_HPP_CHECK_INVOCABLE(PRV3_PTR(), f4, const int* const&) + // META_HPP_CHECK_INVOCABLE(PRV3_PTR(), f5, const int*&&) + // META_HPP_CHECK_INVOCABLE(PRV3_PTR(), f6, const int* const&&) } { - auto PRV_CPTR = []() -> const clazz* { static const clazz* p{}; return p; }; - auto PRV2_CPTR = []() -> const dclazz* { static const dclazz* p{}; return p; }; + auto PRV_CPTR = []() -> const clazz* { static clazz v; static const clazz* p{&v}; return p; }; + auto PRV2_CPTR = []() -> const dclazz* { static dclazz v; static const dclazz* p{&v}; return p; }; + auto PRV3_CPTR = []() -> const int* { static int v{1}; static const int* p{&v}; return p; }; meta::detail::arg a{PRV_CPTR()}; CHECK(a.get_raw_type() == meta::resolve_type()); @@ -621,6 +819,20 @@ TEST_CASE("features/meta_utilities/arg/ptrs") { // META_HPP_CHECK_INVOCABLE(PRV2_CPTR(), f4, const clazz* const&) // META_HPP_CHECK_INVOCABLE(PRV2_CPTR(), f5, const clazz*&&) // META_HPP_CHECK_INVOCABLE(PRV2_CPTR(), f6, const clazz* const&&) + + META_HPP_CHECK_INVOCABLE(PRV3_CPTR(), f1, int*) + META_HPP_CHECK_INVOCABLE(PRV3_CPTR(), f2, int* const) + // META_HPP_CHECK_INVOCABLE(PRV3_CPTR(), f3, int*&) + // META_HPP_CHECK_INVOCABLE(PRV3_CPTR(), f4, int* const&) + // META_HPP_CHECK_INVOCABLE(PRV3_CPTR(), f5, int*&&) + // META_HPP_CHECK_INVOCABLE(PRV3_CPTR(), f6, int* const&&) + + META_HPP_CHECK_INVOCABLE(PRV3_CPTR(), f1, const int*) + META_HPP_CHECK_INVOCABLE(PRV3_CPTR(), f2, const int* const) + // META_HPP_CHECK_INVOCABLE(PRV3_CPTR(), f3, const int*&) + // META_HPP_CHECK_INVOCABLE(PRV3_CPTR(), f4, const int* const&) + // META_HPP_CHECK_INVOCABLE(PRV3_CPTR(), f5, const int*&&) + // META_HPP_CHECK_INVOCABLE(PRV3_CPTR(), f6, const int* const&&) } } } @@ -631,6 +843,7 @@ TEST_CASE("features/meta_utilities/arg/values") { { auto LV = []() -> meta::value& { static meta::value v{clazz{}}; return v; }; auto LV2 = []() -> meta::value& { static meta::value v{dclazz{}}; return v; }; + auto LV3 = []() -> meta::value& { static meta::value v{int{1}}; return v; }; meta::detail::arg a{LV()}; CHECK(a.get_raw_type() == meta::resolve_type()); @@ -649,11 +862,19 @@ TEST_CASE("features/meta_utilities/arg/values") { META_HPP_CHECK_INVOCABLE_2(LV2(), f4, dclazz&, const clazz&) META_HPP_CHECK_INVOCABLE_2(LV2(), f5, dclazz&, clazz&&) META_HPP_CHECK_INVOCABLE_2(LV2(), f6, dclazz&, const clazz&&) + + META_HPP_CHECK_INVOCABLE_2(LV3(), f1, int&, int) + META_HPP_CHECK_INVOCABLE_2(LV3(), f2, int&, const int) + META_HPP_CHECK_INVOCABLE_2(LV3(), f3, int&, int&) + META_HPP_CHECK_INVOCABLE_2(LV3(), f4, int&, const int&) + META_HPP_CHECK_INVOCABLE_2(LV3(), f5, int&, int&&) + META_HPP_CHECK_INVOCABLE_2(LV3(), f6, int&, const int&&) } { auto CLV = []() -> const meta::value& { static meta::value v{clazz{}}; return v; }; auto CLV2 = []() -> const meta::value& { static meta::value v{dclazz{}}; return v; }; + auto CLV3 = []() -> const meta::value& { static meta::value v{int{1}}; return v; }; meta::detail::arg a{CLV()}; CHECK(a.get_raw_type() == meta::resolve_type()); @@ -672,11 +893,19 @@ TEST_CASE("features/meta_utilities/arg/values") { META_HPP_CHECK_INVOCABLE_2(CLV2(), f4, const dclazz&, const clazz&) META_HPP_CHECK_INVOCABLE_2(CLV2(), f5, const dclazz&, clazz&&) META_HPP_CHECK_INVOCABLE_2(CLV2(), f6, const dclazz&, const clazz&&) + + META_HPP_CHECK_INVOCABLE_2(CLV3(), f1, const int&, int) + META_HPP_CHECK_INVOCABLE_2(CLV3(), f2, const int&, const int) + META_HPP_CHECK_INVOCABLE_2(CLV3(), f3, const int&, int&) + META_HPP_CHECK_INVOCABLE_2(CLV3(), f4, const int&, const int&) + META_HPP_CHECK_INVOCABLE_2(CLV3(), f5, const int&, int&&) + META_HPP_CHECK_INVOCABLE_2(CLV3(), f6, const int&, const int&&) } { auto XV = []() -> meta::value&& { static meta::value v{clazz{}}; return std::move(v); }; auto XV2 = []() -> meta::value&& { static meta::value v{dclazz{}}; return std::move(v); }; + auto XV3 = []() -> meta::value&& { static meta::value v{int{1}}; return std::move(v); }; meta::detail::arg a{XV()}; CHECK(a.get_raw_type() == meta::resolve_type()); @@ -695,11 +924,19 @@ TEST_CASE("features/meta_utilities/arg/values") { META_HPP_CHECK_INVOCABLE_2(XV2(), f4, dclazz&&, const clazz&) META_HPP_CHECK_INVOCABLE_2(XV2(), f5, dclazz&&, clazz&&) META_HPP_CHECK_INVOCABLE_2(XV2(), f6, dclazz&&, const clazz&&) + + META_HPP_CHECK_INVOCABLE_2(XV3(), f1, int&&, int) + META_HPP_CHECK_INVOCABLE_2(XV3(), f2, int&&, const int) + META_HPP_CHECK_INVOCABLE_2(XV3(), f3, int&&, int&) + META_HPP_CHECK_INVOCABLE_2(XV3(), f4, int&&, const int&) + META_HPP_CHECK_INVOCABLE_2(XV3(), f5, int&&, int&&) + META_HPP_CHECK_INVOCABLE_2(XV3(), f6, int&&, const int&&) } { auto CXV = []() -> const meta::value&& { static meta::value v{clazz{}}; return std::move(v); }; auto CXV2 = []() -> const meta::value&& { static meta::value v{dclazz{}}; return std::move(v); }; + auto CXV3 = []() -> const meta::value&& { static meta::value v{int{1}}; return std::move(v); }; meta::detail::arg a{CXV()}; CHECK(a.get_raw_type() == meta::resolve_type()); @@ -718,11 +955,19 @@ TEST_CASE("features/meta_utilities/arg/values") { META_HPP_CHECK_INVOCABLE_2(CXV2(), f4, const dclazz&&, const clazz&) META_HPP_CHECK_INVOCABLE_2(CXV2(), f5, const dclazz&&, clazz&&) META_HPP_CHECK_INVOCABLE_2(CXV2(), f6, const dclazz&&, const clazz&&) + + META_HPP_CHECK_INVOCABLE_2(CXV3(), f1, const int&&, int) + META_HPP_CHECK_INVOCABLE_2(CXV3(), f2, const int&&, const int) + META_HPP_CHECK_INVOCABLE_2(CXV3(), f3, const int&&, int&) + META_HPP_CHECK_INVOCABLE_2(CXV3(), f4, const int&&, const int&) + META_HPP_CHECK_INVOCABLE_2(CXV3(), f5, const int&&, int&&) + META_HPP_CHECK_INVOCABLE_2(CXV3(), f6, const int&&, const int&&) } { auto PRV = []() -> meta::value { return meta::value{clazz{}}; }; auto PRV2 = []() -> meta::value { return meta::value{dclazz{}}; }; + auto PRV3 = []() -> meta::value { return meta::value{int{1}}; }; meta::detail::arg a{PRV()}; CHECK(a.get_raw_type() == meta::resolve_type()); @@ -741,11 +986,19 @@ TEST_CASE("features/meta_utilities/arg/values") { META_HPP_CHECK_INVOCABLE_2(PRV2(), f4, dclazz, const clazz&) META_HPP_CHECK_INVOCABLE_2(PRV2(), f5, dclazz, clazz&&) META_HPP_CHECK_INVOCABLE_2(PRV2(), f6, dclazz, const clazz&&) + + META_HPP_CHECK_INVOCABLE_2(PRV3(), f1, int, int) + META_HPP_CHECK_INVOCABLE_2(PRV3(), f2, int, const int) + META_HPP_CHECK_INVOCABLE_2(PRV3(), f3, int, int&) + META_HPP_CHECK_INVOCABLE_2(PRV3(), f4, int, const int&) + META_HPP_CHECK_INVOCABLE_2(PRV3(), f5, int, int&&) + META_HPP_CHECK_INVOCABLE_2(PRV3(), f6, int, const int&&) } { auto CPRV = []() -> const meta::value { return meta::value{clazz{}}; }; auto CPRV2 = []() -> const meta::value { return meta::value{dclazz{}}; }; + auto CPRV3 = []() -> const meta::value { return meta::value{int{1}}; }; meta::detail::arg a{CPRV()}; CHECK(a.get_raw_type() == meta::resolve_type()); @@ -764,6 +1017,13 @@ TEST_CASE("features/meta_utilities/arg/values") { META_HPP_CHECK_INVOCABLE_2(CPRV2(), f4, const dclazz, const clazz&) META_HPP_CHECK_INVOCABLE_2(CPRV2(), f5, const dclazz, clazz&&) META_HPP_CHECK_INVOCABLE_2(CPRV2(), f6, const dclazz, const clazz&&) + + META_HPP_CHECK_INVOCABLE_2(CPRV3(), f1, const int, int) + META_HPP_CHECK_INVOCABLE_2(CPRV3(), f2, const int, const int) + META_HPP_CHECK_INVOCABLE_2(CPRV3(), f3, const int, int&) + META_HPP_CHECK_INVOCABLE_2(CPRV3(), f4, const int, const int&) + META_HPP_CHECK_INVOCABLE_2(CPRV3(), f5, const int, int&&) + META_HPP_CHECK_INVOCABLE_2(CPRV3(), f6, const int, const int&&) } } @@ -771,8 +1031,8 @@ TEST_CASE("features/meta_utilities/arg/ptr_values") { namespace meta = meta_hpp; { - auto LV_PTR = []() -> meta::value& { static clazz* p{}; static meta::value v{p}; return v; }; - auto LV2_PTR = []() -> meta::value& { static dclazz* p{}; static meta::value v{p}; return v; }; + auto LV_PTR = []() -> meta::value& { static clazz v; static clazz* p{&v}; static meta::value vv{p}; return vv; }; + auto LV2_PTR = []() -> meta::value& { static dclazz v; static dclazz* p{&v}; static meta::value vv{p}; return vv; }; meta::detail::arg a{LV_PTR()}; CHECK(a.get_raw_type() == meta::resolve_type()); @@ -808,8 +1068,8 @@ TEST_CASE("features/meta_utilities/arg/ptr_values") { } { - auto LV_CPTR = []() -> meta::value& { static const clazz* p{}; static meta::value v{p}; return v; }; - auto LV2_CPTR = []() -> meta::value& { static const dclazz* p{}; static meta::value v{p}; return v; }; + auto LV_CPTR = []() -> meta::value& { static clazz v; static const clazz* p{&v}; static meta::value vv{p}; return vv; }; + auto LV2_CPTR = []() -> meta::value& { static dclazz v; static const dclazz* p{&v}; static meta::value vv{p}; return vv; }; meta::detail::arg a{LV_CPTR()}; CHECK(a.get_raw_type() == meta::resolve_type()); @@ -845,8 +1105,8 @@ TEST_CASE("features/meta_utilities/arg/ptr_values") { } { - auto CLV_PTR = []() -> const meta::value& { static clazz* p{}; static meta::value v{p}; return v; }; - auto CLV2_PTR = []() -> const meta::value& { static dclazz* p{}; static meta::value v{p}; return v; }; + auto CLV_PTR = []() -> const meta::value& { static clazz v; static clazz* p{&v}; static meta::value vv{p}; return vv; }; + auto CLV2_PTR = []() -> const meta::value& { static dclazz v; static dclazz* p{&v}; static meta::value vv{p}; return vv; }; meta::detail::arg a{CLV_PTR()}; CHECK(a.get_raw_type() == meta::resolve_type()); @@ -882,8 +1142,8 @@ TEST_CASE("features/meta_utilities/arg/ptr_values") { } { - auto CLV_CPTR = []() -> const meta::value& { static const clazz* p{}; static meta::value v{p}; return v; }; - auto CLV2_CPTR = []() -> const meta::value& { static const dclazz* p{}; static meta::value v{p}; return v; }; + auto CLV_CPTR = []() -> const meta::value& { static clazz v; static const clazz* p{&v}; static meta::value vv{p}; return vv; }; + auto CLV2_CPTR = []() -> const meta::value& { static dclazz v; static const dclazz* p{&v}; static meta::value vv{p}; return vv; }; meta::detail::arg a{CLV_CPTR()}; CHECK(a.get_raw_type() == meta::resolve_type()); @@ -919,8 +1179,8 @@ TEST_CASE("features/meta_utilities/arg/ptr_values") { } { - auto XV_PTR = []() -> meta::value&& { static clazz* p{}; static meta::value v{std::move(p)}; return std::move(v); }; - auto XV2_PTR = []() -> meta::value&& { static dclazz* p{}; static meta::value v{std::move(p)}; return std::move(v); }; + auto XV_PTR = []() -> meta::value&& { static clazz v; static clazz* p{&v}; static meta::value vv{std::move(p)}; return std::move(vv); }; + auto XV2_PTR = []() -> meta::value&& { static dclazz v; static dclazz* p{&v}; static meta::value vv{std::move(p)}; return std::move(vv); }; meta::detail::arg a{XV_PTR()}; CHECK(a.get_raw_type() == meta::resolve_type()); @@ -956,8 +1216,8 @@ TEST_CASE("features/meta_utilities/arg/ptr_values") { } { - auto XV_CPTR = []() -> meta::value&& { static const clazz* p{}; static meta::value v{std::move(p)}; return std::move(v); }; - auto XV2_CPTR = []() -> meta::value&& { static const dclazz* p{}; static meta::value v{std::move(p)}; return std::move(v); }; + auto XV_CPTR = []() -> meta::value&& { static clazz v; static const clazz* p{&v}; static meta::value vv{std::move(p)}; return std::move(vv); }; + auto XV2_CPTR = []() -> meta::value&& { static dclazz v; static const dclazz* p{&v}; static meta::value vv{std::move(p)}; return std::move(vv); }; meta::detail::arg a{XV_CPTR()}; CHECK(a.get_raw_type() == meta::resolve_type()); @@ -993,8 +1253,8 @@ TEST_CASE("features/meta_utilities/arg/ptr_values") { } { - auto CXV_PTR = []() -> const meta::value&& { static clazz* p{}; static meta::value v{std::move(p)}; return std::move(v); }; - auto CXV2_PTR = []() -> const meta::value&& { static dclazz* p{}; static meta::value v{std::move(p)}; return std::move(v); }; + auto CXV_PTR = []() -> const meta::value&& { static clazz v; static clazz* p{&v}; static meta::value vv{std::move(p)}; return std::move(vv); }; + auto CXV2_PTR = []() -> const meta::value&& { static dclazz v; static dclazz* p{&v}; static meta::value vv{std::move(p)}; return std::move(vv); }; meta::detail::arg a{CXV_PTR()}; CHECK(a.get_raw_type() == meta::resolve_type()); @@ -1030,8 +1290,8 @@ TEST_CASE("features/meta_utilities/arg/ptr_values") { } { - auto CXV_CPTR = []() -> const meta::value&& { static const clazz* p{}; static meta::value v{std::move(p)}; return std::move(v); }; - auto CXV2_CPTR = []() -> const meta::value&& { static const dclazz* p{}; static meta::value v{std::move(p)}; return std::move(v); }; + auto CXV_CPTR = []() -> const meta::value&& { static clazz v; static const clazz* p{&v}; static meta::value vv{std::move(p)}; return std::move(vv); }; + auto CXV2_CPTR = []() -> const meta::value&& { static dclazz v; static const dclazz* p{&v}; static meta::value vv{std::move(p)}; return std::move(vv); }; meta::detail::arg a{CXV_CPTR()}; CHECK(a.get_raw_type() == meta::resolve_type()); @@ -1067,8 +1327,8 @@ TEST_CASE("features/meta_utilities/arg/ptr_values") { } { - auto PRV_PTR = []() -> meta::value { static clazz* p{}; static meta::value v{p}; return v; }; - auto PRV2_PTR = []() -> meta::value { static dclazz* p{}; static meta::value v{p}; return v; }; + auto PRV_PTR = []() -> meta::value { static clazz v; static clazz* p{&v}; static meta::value vv{p}; return vv; }; + auto PRV2_PTR = []() -> meta::value { static dclazz v; static dclazz* p{&v}; static meta::value vv{p}; return vv; }; meta::detail::arg a{PRV_PTR()}; CHECK(a.get_raw_type() == meta::resolve_type()); @@ -1104,8 +1364,8 @@ TEST_CASE("features/meta_utilities/arg/ptr_values") { } { - auto PRV_CPTR = []() -> meta::value { static const clazz* p{}; static meta::value v{p}; return v; }; - auto PRV2_CPTR = []() -> meta::value { static const dclazz* p{}; static meta::value v{p}; return v; }; + auto PRV_CPTR = []() -> meta::value { static clazz v; static const clazz* p{&v}; static meta::value vv{p}; return vv; }; + auto PRV2_CPTR = []() -> meta::value { static dclazz v; static const dclazz* p{&v}; static meta::value vv{p}; return vv; }; meta::detail::arg a{PRV_CPTR()}; CHECK(a.get_raw_type() == meta::resolve_type()); @@ -1141,8 +1401,8 @@ TEST_CASE("features/meta_utilities/arg/ptr_values") { } { - auto CPRV_PTR = []() -> const meta::value { static clazz* p{}; static meta::value v{p}; return v; }; - auto CPRV2_PTR = []() -> const meta::value { static dclazz* p{}; static meta::value v{p}; return v; }; + auto CPRV_PTR = []() -> const meta::value { static clazz v; static clazz* p{&v}; static meta::value vv{p}; return vv; }; + auto CPRV2_PTR = []() -> const meta::value { static dclazz v; static dclazz* p{&v}; static meta::value vv{p}; return vv; }; meta::detail::arg a{CPRV_PTR()}; CHECK(a.get_raw_type() == meta::resolve_type()); @@ -1178,8 +1438,8 @@ TEST_CASE("features/meta_utilities/arg/ptr_values") { } { - auto CPRV_CPTR = []() -> const meta::value { static const clazz* p{}; static meta::value v{p}; return v; }; - auto CPRV2_CPTR = []() -> const meta::value { static const dclazz* p{}; static meta::value v{p}; return v; }; + auto CPRV_CPTR = []() -> const meta::value { static clazz v; static const clazz* p{&v}; static meta::value vv{p}; return vv; }; + auto CPRV2_CPTR = []() -> const meta::value { static dclazz v; static const dclazz* p{&v}; static meta::value vv{p}; return vv; }; meta::detail::arg a{CPRV_CPTR()}; CHECK(a.get_raw_type() == meta::resolve_type()); diff --git a/untests/meta_utilities/inst_tests.cpp b/untests/meta_utilities/inst_tests.cpp index 0549475..969240a 100644 --- a/untests/meta_utilities/inst_tests.cpp +++ b/untests/meta_utilities/inst_tests.cpp @@ -8,18 +8,24 @@ namespace { - struct clazz { - int m1() { return 1; } - int m2() & { return 1; } - int m3() && { return 1; } - int m4() const { return 1; } - int m5() const & { return 1; } - int m6() const && { return 1; } + struct fake { + int i = 10; }; - struct dclazz : clazz {}; + struct clazz { + int ii = 1; + [[nodiscard]] int m1() { return ii; } + [[nodiscard]] int m2() & { return ii; } + [[nodiscard]] int m3() && { return ii; } + [[nodiscard]] int m4() const { return ii; } + [[nodiscard]] int m5() const & { return ii; } + [[nodiscard]] int m6() const && { return ii; } + }; + + struct dclazz : fake, clazz {}; } +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define META_HPP_CHECK_INVOCABLE(Inst, FName, Qualifiers)\ {\ using namespace meta::detail;\ @@ -29,20 +35,21 @@ namespace if ( std::is_invocable_v ) {\ CHECK(inst{Inst}.can_cast_to());\ CHECK(inst_base{type_list{}}.can_cast_to());\ - CHECK_NOTHROW(inst{Inst}.cast());\ + CHECK_NOTHROW(std::ignore = inst{Inst}.cast());\ \ CHECK(m_state.is_invocable_with());\ CHECK(m_state.invoke(Inst) == 1);\ } else {\ CHECK_FALSE(inst{Inst}.can_cast_to());\ CHECK_FALSE(inst_base{type_list{}}.can_cast_to());\ - CHECK_THROWS(inst{Inst}.cast());\ + CHECK_THROWS(std::ignore = inst{Inst}.cast());\ \ CHECK_FALSE(m_state.is_invocable_with());\ CHECK_THROWS(m_state.invoke(Inst));\ }\ } +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define META_HPP_CHECK_INVOCABLE_2(FromValue, FName, FromType, ToQualifiers)\ {\ using namespace meta::detail;\ @@ -63,8 +70,9 @@ namespace TEST_CASE("features/meta_utilities/inst2") { namespace meta = meta_hpp; - meta::class_() - .base_(); + meta::class_(); + meta::class_(); + meta::class_().base_().base_(); } TEST_CASE("features/meta_utilities/inst2/refs") { From 18a456217cda21e356bfef7fad5f0772f047e21e Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 7 Jan 2022 18:33:14 +0700 Subject: [PATCH 146/233] add todo --- TODO.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 TODO.md diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..0632421 --- /dev/null +++ b/TODO.md @@ -0,0 +1,6 @@ +# meta.hpp + +- add debug type names +- add meta exception class +- add conversion of nullptr to any pointers +- add conversion of any pointers to void pointer ( identically cv-qualified ) From 794868b1b5a71065b27bcf4c0fd1d8433e13c273 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 7 Jan 2022 19:21:47 +0700 Subject: [PATCH 147/233] replace std::same_as to is_same_v --- headers/meta.hpp/meta_base.hpp | 1 - headers/meta.hpp/meta_registry/class_bind.hpp | 4 +- headers/meta.hpp/meta_states.hpp | 14 +++---- headers/meta.hpp/meta_types.hpp | 24 +++++------ headers/meta.hpp/meta_utilities.hpp | 12 +++--- untests/meta_utilities/detail_tests.cpp | 42 +++++++++---------- 6 files changed, 48 insertions(+), 49 deletions(-) diff --git a/headers/meta.hpp/meta_base.hpp b/headers/meta.hpp/meta_base.hpp index 1e2aa17..1ae7f8f 100644 --- a/headers/meta.hpp/meta_base.hpp +++ b/headers/meta.hpp/meta_base.hpp @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include diff --git a/headers/meta.hpp/meta_registry/class_bind.hpp b/headers/meta.hpp/meta_registry/class_bind.hpp index d2da779..36ba7cc 100644 --- a/headers/meta.hpp/meta_registry/class_bind.hpp +++ b/headers/meta.hpp/meta_registry/class_bind.hpp @@ -53,7 +53,7 @@ namespace meta_hpp template < detail::class_kind Class > template < detail::member_kind Member > class_bind& class_bind::member_(std::string name, Member member) { - static_assert(std::same_as::class_type>); + static_assert(std::is_same_v::class_type>); 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; @@ -62,7 +62,7 @@ namespace meta_hpp template < detail::class_kind Class > template < detail::method_kind Method > class_bind& class_bind::method_(std::string name, Method method) { - static_assert(std::same_as::class_type>); + static_assert(std::is_same_v::class_type>); 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; diff --git a/headers/meta.hpp/meta_states.hpp b/headers/meta.hpp/meta_states.hpp index 15d1079..ef4bb2b 100644 --- a/headers/meta.hpp/meta_states.hpp +++ b/headers/meta.hpp/meta_states.hpp @@ -16,13 +16,13 @@ namespace meta_hpp { template < typename T > concept state_family = - std::same_as || - std::same_as || - std::same_as || - std::same_as || - std::same_as || - std::same_as || - std::same_as; + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v; } template < detail::state_family T, detail::state_family U > diff --git a/headers/meta.hpp/meta_types.hpp b/headers/meta.hpp/meta_types.hpp index 3fecedc..db92632 100644 --- a/headers/meta.hpp/meta_types.hpp +++ b/headers/meta.hpp/meta_types.hpp @@ -64,18 +64,18 @@ namespace meta_hpp { template < typename T > concept type_family = - std::same_as || - std::same_as || - std::same_as || - std::same_as || - std::same_as || - std::same_as || - std::same_as || - std::same_as || - std::same_as || - std::same_as || - std::same_as || - std::same_as; + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v; template < type_family T > [[nodiscard]] auto data_access(const T& type) { diff --git a/headers/meta.hpp/meta_utilities.hpp b/headers/meta.hpp/meta_utilities.hpp index 109590b..ef2b588 100644 --- a/headers/meta.hpp/meta_utilities.hpp +++ b/headers/meta.hpp/meta_utilities.hpp @@ -60,7 +60,7 @@ namespace meta_hpp::detail { template < typename T > concept value_kind = - std::same_as; + std::is_same_v; template < typename T > concept decay_value_kind = @@ -68,11 +68,11 @@ namespace meta_hpp::detail template < typename T > concept uvalue_kind = - std::same_as || - std::same_as || - std::same_as || - std::same_as || - std::same_as; + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v; template < typename T > concept decay_uvalue_kind = diff --git a/untests/meta_utilities/detail_tests.cpp b/untests/meta_utilities/detail_tests.cpp index 2669d0d..9e2dd61 100644 --- a/untests/meta_utilities/detail_tests.cpp +++ b/untests/meta_utilities/detail_tests.cpp @@ -57,28 +57,28 @@ TEST_CASE("features/meta_utilities/detail") { } SUBCASE("cvref_traits::copy_to") { - static_assert(std::same_as::copy_to, int>); - static_assert(std::same_as::copy_to, const int>); - static_assert(std::same_as::copy_to, const volatile int>); - static_assert(std::same_as::copy_to, int&>); - static_assert(std::same_as::copy_to, const int&>); - static_assert(std::same_as::copy_to, volatile int&>); - static_assert(std::same_as::copy_to, const volatile int&&>); + static_assert(std::is_same_v::copy_to, int>); + static_assert(std::is_same_v::copy_to, const int>); + static_assert(std::is_same_v::copy_to, const volatile int>); + static_assert(std::is_same_v::copy_to, int&>); + static_assert(std::is_same_v::copy_to, const int&>); + static_assert(std::is_same_v::copy_to, volatile int&>); + static_assert(std::is_same_v::copy_to, const volatile int&&>); - static_assert(std::same_as::copy_to, int>); - static_assert(std::same_as::copy_to, const int>); - static_assert(std::same_as::copy_to, const volatile int>); - static_assert(std::same_as::copy_to, int&>); - static_assert(std::same_as::copy_to, const int&>); - static_assert(std::same_as::copy_to, volatile int&>); - static_assert(std::same_as::copy_to, const volatile int&&>); + static_assert(std::is_same_v::copy_to, int>); + static_assert(std::is_same_v::copy_to, const int>); + static_assert(std::is_same_v::copy_to, const volatile int>); + static_assert(std::is_same_v::copy_to, int&>); + static_assert(std::is_same_v::copy_to, const int&>); + static_assert(std::is_same_v::copy_to, volatile int&>); + static_assert(std::is_same_v::copy_to, const volatile int&&>); - static_assert(std::same_as::copy_to, int>); - static_assert(std::same_as::copy_to, const int>); - static_assert(std::same_as::copy_to, const volatile int>); - static_assert(std::same_as::copy_to, int&>); - static_assert(std::same_as::copy_to, const int&>); - static_assert(std::same_as::copy_to, volatile int&>); - static_assert(std::same_as::copy_to, const volatile int&&>); + static_assert(std::is_same_v::copy_to, int>); + static_assert(std::is_same_v::copy_to, const int>); + static_assert(std::is_same_v::copy_to, const volatile int>); + static_assert(std::is_same_v::copy_to, int&>); + static_assert(std::is_same_v::copy_to, const int&>); + static_assert(std::is_same_v::copy_to, volatile int&>); + static_assert(std::is_same_v::copy_to, const volatile int&&>); } } From c29e23084589b1f95da90d97f54d31d841ebd0f5 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 7 Jan 2022 19:24:09 +0700 Subject: [PATCH 148/233] fix detail::data_access friend for gcc --- headers/meta.hpp/meta_types.hpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/headers/meta.hpp/meta_types.hpp b/headers/meta.hpp/meta_types.hpp index db92632..6f05a6f 100644 --- a/headers/meta.hpp/meta_types.hpp +++ b/headers/meta.hpp/meta_types.hpp @@ -165,7 +165,7 @@ namespace meta_hpp [[nodiscard]] void_type as_void() const noexcept; private: detail::type_data_base_ptr data_; - friend auto detail::data_access(const any_type&); + friend auto detail::data_access(const any_type&); }; class array_type final { @@ -183,7 +183,7 @@ namespace meta_hpp [[nodiscard]] any_type get_data_type() const noexcept; private: detail::array_type_data_ptr data_; - friend auto detail::data_access(const array_type&); + friend auto detail::data_access(const array_type&); }; class class_type final { @@ -245,7 +245,7 @@ namespace meta_hpp [[nodiscard]] method get_method_with(std::string_view name, std::initializer_list args) const noexcept; private: detail::class_type_data_ptr data_; - friend auto detail::data_access(const class_type&); + friend auto detail::data_access(const class_type&); }; class ctor_type final { @@ -265,7 +265,7 @@ namespace meta_hpp [[nodiscard]] const std::vector& get_argument_types() const noexcept; private: detail::ctor_type_data_ptr data_; - friend auto detail::data_access(const ctor_type&); + friend auto detail::data_access(const ctor_type&); }; class enum_type final { @@ -290,7 +290,7 @@ namespace meta_hpp [[nodiscard]] std::optional name_to_value(std::string_view name) const noexcept; private: detail::enum_type_data_ptr data_; - friend auto detail::data_access(const enum_type&); + friend auto detail::data_access(const enum_type&); }; class function_type final { @@ -310,7 +310,7 @@ namespace meta_hpp [[nodiscard]] const std::vector& get_argument_types() const noexcept; private: detail::function_type_data_ptr data_; - friend auto detail::data_access(const function_type&); + friend auto detail::data_access(const function_type&); }; class member_type final { @@ -328,7 +328,7 @@ namespace meta_hpp [[nodiscard]] any_type get_value_type() const noexcept; private: detail::member_type_data_ptr data_; - friend auto detail::data_access(const member_type&); + friend auto detail::data_access(const member_type&); }; class method_type final { @@ -349,7 +349,7 @@ namespace meta_hpp [[nodiscard]] const std::vector& get_argument_types() const noexcept; private: detail::method_type_data_ptr data_; - friend auto detail::data_access(const method_type&); + friend auto detail::data_access(const method_type&); }; class number_type final { @@ -366,7 +366,7 @@ namespace meta_hpp [[nodiscard]] std::size_t get_size() const noexcept; private: detail::number_type_data_ptr data_; - friend auto detail::data_access(const number_type&); + friend auto detail::data_access(const number_type&); }; class pointer_type final { @@ -383,7 +383,7 @@ namespace meta_hpp [[nodiscard]] any_type get_data_type() const noexcept; private: detail::pointer_type_data_ptr data_; - friend auto detail::data_access(const pointer_type&); + friend auto detail::data_access(const pointer_type&); }; class reference_type final { @@ -400,7 +400,7 @@ namespace meta_hpp [[nodiscard]] any_type get_data_type() const noexcept; private: detail::reference_type_data_ptr data_; - friend auto detail::data_access(const reference_type&); + friend auto detail::data_access(const reference_type&); }; class void_type final { @@ -415,7 +415,7 @@ namespace meta_hpp [[nodiscard]] bitflags get_flags() const noexcept; private: detail::void_type_data_ptr data_; - friend auto detail::data_access(const void_type&); + friend auto detail::data_access(const void_type&); }; } From e06fdec7bbeaf9d327a57ef9ece31e593f472dd9 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 7 Jan 2022 19:25:22 +0700 Subject: [PATCH 149/233] fix switch warnings --- headers/meta.hpp/meta_utilities/arg.hpp | 4 ++++ headers/meta.hpp/meta_utilities/inst.hpp | 2 ++ 2 files changed, 6 insertions(+) diff --git a/headers/meta.hpp/meta_utilities/arg.hpp b/headers/meta.hpp/meta_utilities/arg.hpp index 65bd5f8..b987134 100644 --- a/headers/meta.hpp/meta_utilities/arg.hpp +++ b/headers/meta.hpp/meta_utilities/arg.hpp @@ -114,6 +114,8 @@ namespace meta_hpp::detail return std::is_convertible_v>; case ref_types::const_rvalue: return std::is_convertible_v>; + default: + return false; } }; @@ -133,6 +135,8 @@ namespace meta_hpp::detail return std::is_constructible_v && can_cast_to(); case ref_types::const_rvalue: return std::is_constructible_v && can_cast_to(); + default: + return false; } }; diff --git a/headers/meta.hpp/meta_utilities/inst.hpp b/headers/meta.hpp/meta_utilities/inst.hpp index d982371..c52868a 100644 --- a/headers/meta.hpp/meta_utilities/inst.hpp +++ b/headers/meta.hpp/meta_utilities/inst.hpp @@ -155,6 +155,8 @@ namespace meta_hpp::detail return std::is_invocable_v; case ref_types::const_rvalue: return std::is_invocable_v; + default: + return false; } }; From 0dc88b7249f7a4faa5151ae4d2fdc4dc31b67358 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 7 Jan 2022 19:28:02 +0700 Subject: [PATCH 150/233] include for std::memcmp --- untests/meta_tests.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/untests/meta_tests.hpp b/untests/meta_tests.hpp index 62be851..a4555fc 100644 --- a/untests/meta_tests.hpp +++ b/untests/meta_tests.hpp @@ -9,5 +9,6 @@ #include #include +#include #include #include From 495e149e57ee013cb18a37537c701348a58b811e Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 7 Jan 2022 19:56:35 +0700 Subject: [PATCH 151/233] remove std::tie comparing --- headers/meta.hpp/meta_types.hpp | 20 ++++++++++---------- untests/meta_utilities/value_tests.cpp | 10 +++++----- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/headers/meta.hpp/meta_types.hpp b/headers/meta.hpp/meta_types.hpp index 6f05a6f..3961fa0 100644 --- a/headers/meta.hpp/meta_types.hpp +++ b/headers/meta.hpp/meta_types.hpp @@ -601,11 +601,11 @@ namespace meta_hpp , name{std::move(name)} {} [[nodiscard]] friend bool operator<(const evalue_index& l, const evalue_index& r) noexcept { - return std::tie(l.type, l.name) < std::tie(r.type, r.name); + return (l.type < r.type) || (l.type == r.type && l.name < r.name); } [[nodiscard]] friend bool operator==(const evalue_index& l, const evalue_index& r) noexcept { - return std::tie(l.type, l.name) == std::tie(r.type, r.name); + return l.type == r.type && l.name == r.name; } }; @@ -618,11 +618,11 @@ namespace meta_hpp , name{std::move(name)} {} [[nodiscard]] friend bool operator<(const function_index& l, const function_index& r) noexcept { - return std::tie(l.type, l.name) < std::tie(r.type, r.name); + return (l.type < r.type) || (l.type == r.type && l.name < r.name); } [[nodiscard]] friend bool operator==(const function_index& l, const function_index& r) noexcept { - return std::tie(l.type, l.name) == std::tie(r.type, r.name); + return l.type == r.type && l.name == r.name; } }; @@ -635,11 +635,11 @@ namespace meta_hpp , name{std::move(name)} {} [[nodiscard]] friend bool operator<(const member_index& l, const member_index& r) noexcept { - return std::tie(l.type, l.name) < std::tie(r.type, r.name); + return (l.type < r.type) || (l.type == r.type && l.name < r.name); } [[nodiscard]] friend bool operator==(const member_index& l, const member_index& r) noexcept { - return std::tie(l.type, l.name) == std::tie(r.type, r.name); + return l.type == r.type && l.name == r.name; } }; @@ -652,11 +652,11 @@ namespace meta_hpp , name{std::move(name)} {} [[nodiscard]] friend bool operator<(const method_index& l, const method_index& r) noexcept { - return std::tie(l.type, l.name) < std::tie(r.type, r.name); + return (l.type < r.type) || (l.type == r.type && l.name < r.name); } [[nodiscard]] friend bool operator==(const method_index& l, const method_index& r) noexcept { - return std::tie(l.type, l.name) == std::tie(r.type, r.name); + return l.type == r.type && l.name == r.name; } }; @@ -684,11 +684,11 @@ namespace meta_hpp , name{std::move(name)} {} [[nodiscard]] friend bool operator<(const variable_index& l, const variable_index& r) noexcept { - return std::tie(l.type, l.name) < std::tie(r.type, r.name); + return (l.type < r.type) || (l.type == r.type && l.name < r.name); } [[nodiscard]] friend bool operator==(const variable_index& l, const variable_index& r) noexcept { - return std::tie(l.type, l.name) == std::tie(r.type, r.name); + return l.type == r.type && l.name == r.name; } }; } diff --git a/untests/meta_utilities/value_tests.cpp b/untests/meta_utilities/value_tests.cpp index 72f212c..296c520 100644 --- a/untests/meta_utilities/value_tests.cpp +++ b/untests/meta_utilities/value_tests.cpp @@ -40,12 +40,12 @@ namespace int ivec2::move_ctor_counter{0}; int ivec2::copy_ctor_counter{0}; - bool operator<(const ivec2& l, const ivec2& r) noexcept { - return std::tie(l.x, l.y) < std::tie(r.x, r.y); + [[maybe_unused]] bool operator<(const ivec2& l, const ivec2& r) noexcept { + return (l.x < r.x) || (l.x == r.x && l.y < r.y); } - bool operator==(const ivec2& l, const ivec2& r) noexcept { - return std::tie(l.x, l.y) == std::tie(r.x, r.y); + [[maybe_unused]] bool operator==(const ivec2& l, const ivec2& r) noexcept { + return l.x == r.x && l.y == r.y; } } @@ -303,7 +303,7 @@ TEST_CASE("meta/meta_utilities/value") { class empty_class1 {}; class empty_class2 {}; - CHECK(operator<(meta::value{empty_class1{}}, meta::value{empty_class2{}})); + CHECK((operator<(meta::value{empty_class1{}}, meta::value{empty_class2{}}) || operator<(meta::value{empty_class2{}}, meta::value{empty_class1{}}))); CHECK_THROWS(std::ignore = operator<(meta::value{empty_class1{}}, meta::value{empty_class1{}})); } } From 000304f7bfe395f034158f7d64611fccfc8f3118 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 7 Jan 2022 20:02:12 +0700 Subject: [PATCH 152/233] fix extra ';' --- CMakeLists.txt | 1 + headers/meta.hpp/meta_types.hpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9cf65da..cdc794d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,6 +37,7 @@ target_compile_options(${PROJECT_NAME} -Wno-shadow-field-in-constructor -Wno-unknown-warning-option -Wno-weak-vtables + -Wno-zero-as-null-pointer-constant >) if(BUILD_AS_STANDALONE) diff --git a/headers/meta.hpp/meta_types.hpp b/headers/meta.hpp/meta_types.hpp index 3961fa0..73da28f 100644 --- a/headers/meta.hpp/meta_types.hpp +++ b/headers/meta.hpp/meta_types.hpp @@ -709,7 +709,7 @@ namespace meta_hpp // NOLINTNEXTLINE(readability-named-parameter) [[nodiscard]] auto resolve_type(const T&) { return resolve_type>(); - }; + } } namespace meta_hpp From 3ffd824bb809f6052074c79d9353b62f84450372 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 7 Jan 2022 20:14:33 +0700 Subject: [PATCH 153/233] fix github-ci environments --- .github/workflows/coverage.yml | 2 +- .github/workflows/darwin.yml | 6 +++--- .github/workflows/linux.yml | 6 ------ .github/workflows/windows.yml | 2 -- README.md | 7 ++++--- 5 files changed, 8 insertions(+), 15 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 09e95e1..515f366 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -4,7 +4,7 @@ on: [push, pull_request] jobs: build: - runs-on: macos-10.15 + runs-on: macos-11 name: "coverage" steps: - uses: actions/checkout@v2 diff --git a/.github/workflows/darwin.yml b/.github/workflows/darwin.yml index 07e86ea..5d50da2 100644 --- a/.github/workflows/darwin.yml +++ b/.github/workflows/darwin.yml @@ -10,9 +10,9 @@ jobs: matrix: config: # https://github.com/actions/virtual-environments/tree/main/images/macos - - { os: "macos-10.15", xcode: "10.3" } - - { os: "macos-10.15", xcode: "11.7" } - - { os: "macos-10.15", xcode: "12.4" } + - { os: "macos-11", xcode: "13.0" } + - { os: "macos-11", xcode: "13.1" } + - { os: "macos-11", xcode: "13.2" } name: "xcode-${{matrix.config.xcode}}" steps: - uses: actions/checkout@v2 diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index c785bc7..b1296ea 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -10,13 +10,7 @@ jobs: matrix: config: # https://github.com/actions/virtual-environments/tree/main/images/linux - - { os: "ubuntu-20.04", cc: "gcc-7", cxx: "g++-7" } - - { os: "ubuntu-20.04", cc: "gcc-8", cxx: "g++-8" } - - { os: "ubuntu-20.04", cc: "gcc-9", cxx: "g++-9" } - { os: "ubuntu-20.04", cc: "gcc-10", cxx: "g++-10" } - - { os: "ubuntu-20.04", cc: "clang-7", cxx: "clang++-7" } - - { os: "ubuntu-20.04", cc: "clang-8", cxx: "clang++-8" } - - { os: "ubuntu-20.04", cc: "clang-9", cxx: "clang++-9" } - { os: "ubuntu-20.04", cc: "clang-10", cxx: "clang++-10" } name: "${{matrix.config.cxx}}" steps: diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 1486034..5bbc0b8 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -10,8 +10,6 @@ jobs: matrix: config: # https://github.com/actions/virtual-environments/tree/main/images/win - - { os: "windows-2016", vs: "Visual Studio 2017", arch: "x86" } - - { os: "windows-2016", vs: "Visual Studio 2017", arch: "x64" } - { os: "windows-2019", vs: "Visual Studio 2019", arch: "x86" } - { os: "windows-2019", vs: "Visual Studio 2019", arch: "x64" } name: "${{matrix.config.vs}} ${{matrix.config.arch}}" diff --git a/README.md b/README.md index fd3fd8a..5a61537 100644 --- a/README.md +++ b/README.md @@ -27,9 +27,10 @@ ## Requirements -- [gcc](https://www.gnu.org/software/gcc/) **>= 7** -- [clang](https://clang.llvm.org/) **>= 7** -- [msvc](https://visualstudio.microsoft.com/) **>= 2017** +- [clang](https://clang.llvm.org/) **>= 10** +- [gcc](https://www.gnu.org/software/gcc/) **>= 10** +- [msvc](https://visualstudio.microsoft.com/) **>= 2019** +- [xcode](https://developer.apple.com/xcode/) **>= 13.0** ## Installation From 02e7018473908bae2ecf6fa910814ea961bf6c35 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sat, 8 Jan 2022 05:53:42 +0700 Subject: [PATCH 154/233] add fmtlib for examples --- .gitmodules | 3 +++ CMakeLists.txt | 1 + untests/CMakeLists.txt | 2 +- vendors/fmtlib | 1 + 4 files changed, 6 insertions(+), 1 deletion(-) create mode 160000 vendors/fmtlib diff --git a/.gitmodules b/.gitmodules index 0e49f1a..2a54fa4 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "vendors/doctest"] path = vendors/doctest url = https://github.com/onqtam/doctest +[submodule "vendors/fmtlib"] + path = vendors/fmtlib + url = https://github.com/fmtlib/fmt diff --git a/CMakeLists.txt b/CMakeLists.txt index cdc794d..035b5df 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -45,6 +45,7 @@ if(BUILD_AS_STANDALONE) if(BUILD_WITH_UNTESTS) enable_testing() add_subdirectory(vendors/doctest) + add_subdirectory(vendors/fmtlib) add_subdirectory(untests) endif() endif() diff --git a/untests/CMakeLists.txt b/untests/CMakeLists.txt index 2fc86fc..3ec4640 100644 --- a/untests/CMakeLists.txt +++ b/untests/CMakeLists.txt @@ -18,7 +18,7 @@ endif() file(GLOB_RECURSE UNTESTS_SOURCES "*.cpp" "*.hpp") add_executable(${PROJECT_NAME} ${UNTESTS_SOURCES}) -target_link_libraries(${PROJECT_NAME} meta.hpp doctest_with_main) +target_link_libraries(${PROJECT_NAME} meta.hpp doctest_with_main fmt) target_compile_options(${PROJECT_NAME} PRIVATE diff --git a/vendors/fmtlib b/vendors/fmtlib new file mode 160000 index 0000000..b6f4cea --- /dev/null +++ b/vendors/fmtlib @@ -0,0 +1 @@ +Subproject commit b6f4ceaed0a0a24ccf575fab6c56dd50ccf6f1a9 From 84b6e202d288439c67e7d27217789c4ff5976ef6 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sat, 8 Jan 2022 06:01:00 +0700 Subject: [PATCH 155/233] add evalue::get_underlying_value --- headers/meta.hpp/meta_states.hpp | 4 +++- headers/meta.hpp/meta_states/evalue.hpp | 9 +++++++-- headers/meta.hpp/meta_utilities.hpp | 8 ++++++++ untests/meta_states/evalue_tests.cpp | 4 ++++ untests/meta_types/enum_type_tests.cpp | 2 ++ 5 files changed, 24 insertions(+), 3 deletions(-) diff --git a/headers/meta.hpp/meta_states.hpp b/headers/meta.hpp/meta_states.hpp index ef4bb2b..5b88b41 100644 --- a/headers/meta.hpp/meta_states.hpp +++ b/headers/meta.hpp/meta_states.hpp @@ -98,6 +98,7 @@ namespace meta_hpp [[nodiscard]] const std::string& get_name() const noexcept; [[nodiscard]] const value& get_value() const noexcept; + [[nodiscard]] const value& get_underlying_value() const noexcept; private: detail::evalue_state_ptr state_; }; @@ -248,7 +249,8 @@ namespace meta_hpp::detail struct evalue_state final { evalue_index index; - class value value; + value enum_value; + value underlying_value; template < enum_kind Enum > explicit evalue_state(evalue_index index, Enum value); diff --git a/headers/meta.hpp/meta_states/evalue.hpp b/headers/meta.hpp/meta_states/evalue.hpp index a27ba80..af2b6bd 100644 --- a/headers/meta.hpp/meta_states/evalue.hpp +++ b/headers/meta.hpp/meta_states/evalue.hpp @@ -16,7 +16,8 @@ namespace meta_hpp::detail template < enum_kind Enum > evalue_state::evalue_state(evalue_index index, Enum value) : index{std::move(index)} - , value{std::move(value)} {} + , enum_value{value} + , underlying_value{to_underlying(value)} {} template < enum_kind Enum > evalue_state_ptr evalue_state::make(std::string name, Enum value) { @@ -51,6 +52,10 @@ namespace meta_hpp } inline const value& evalue::get_value() const noexcept { - return state_->value; + return state_->enum_value; + } + + inline const value& evalue::get_underlying_value() const noexcept { + return state_->underlying_value; } } diff --git a/headers/meta.hpp/meta_utilities.hpp b/headers/meta.hpp/meta_utilities.hpp index ef2b588..2ae69d0 100644 --- a/headers/meta.hpp/meta_utilities.hpp +++ b/headers/meta.hpp/meta_utilities.hpp @@ -56,6 +56,14 @@ namespace meta_hpp::detail requires { static_cast(std::declval()); }; } +namespace meta_hpp::detail +{ + template < typename T > + [[nodiscard]] constexpr std::underlying_type_t to_underlying(T v) noexcept { + return static_cast>(v); + } +} + namespace meta_hpp::detail { template < typename T > diff --git a/untests/meta_states/evalue_tests.cpp b/untests/meta_states/evalue_tests.cpp index ef420a0..7ee8f1e 100644 --- a/untests/meta_states/evalue_tests.cpp +++ b/untests/meta_states/evalue_tests.cpp @@ -54,5 +54,9 @@ TEST_CASE("meta/meta_states/evalue") { CHECK(evalue.get_name() == "green"); CHECK(evalue.get_value() == color::green); + CHECK(evalue.get_value().get_type() == color_type); + + CHECK(evalue.get_underlying_value() == meta::detail::to_underlying(color::green)); + CHECK(evalue.get_underlying_value().get_type() == color_type.get_underlying_type()); } } diff --git a/untests/meta_types/enum_type_tests.cpp b/untests/meta_types/enum_type_tests.cpp index 5561bb2..52a7402 100644 --- a/untests/meta_types/enum_type_tests.cpp +++ b/untests/meta_types/enum_type_tests.cpp @@ -90,6 +90,7 @@ TEST_CASE("meta/meta_types/enum_type") { const meta::evalue green_value = color_type.get_evalue("green"); REQUIRE(green_value); CHECK(green_value.get_value() == color::green); + CHECK(green_value.get_underlying_value() == meta::detail::to_underlying(color::green)); } { @@ -106,6 +107,7 @@ TEST_CASE("meta/meta_types/enum_type") { const meta::evalue green_value = ecolor_type.get_evalue("green"); REQUIRE(green_value); CHECK(green_value.get_value() == ecolor_green); + CHECK(green_value.get_underlying_value() == meta::detail::to_underlying(ecolor_green)); } { From e7daccad06ce801ac7d2d2d86e1cb4e8d60fdf9e Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sat, 8 Jan 2022 06:06:18 +0700 Subject: [PATCH 156/233] more constness to meta states --- headers/meta.hpp/meta_states.hpp | 44 ++++++++++++++------------------ 1 file changed, 19 insertions(+), 25 deletions(-) diff --git a/headers/meta.hpp/meta_states.hpp b/headers/meta.hpp/meta_states.hpp index 5b88b41..ae96b16 100644 --- a/headers/meta.hpp/meta_states.hpp +++ b/headers/meta.hpp/meta_states.hpp @@ -234,10 +234,9 @@ namespace meta_hpp::detail using invoke_impl = std::function)>; using is_invocable_with_impl = std::function)>; - ctor_index index; - - invoke_impl invoke; - is_invocable_with_impl is_invocable_with; + const ctor_index index; + 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); @@ -247,10 +246,9 @@ namespace meta_hpp::detail }; struct evalue_state final { - evalue_index index; - - value enum_value; - value underlying_value; + const evalue_index index; + const value enum_value; + const value underlying_value; template < enum_kind Enum > explicit evalue_state(evalue_index index, Enum value); @@ -263,10 +261,9 @@ namespace meta_hpp::detail using invoke_impl = std::function(std::span)>; using is_invocable_with_impl = std::function)>; - function_index index; - - invoke_impl invoke; - is_invocable_with_impl is_invocable_with; + const function_index index; + const invoke_impl invoke; + const is_invocable_with_impl is_invocable_with; template < function_kind Function > explicit function_state(function_index index, Function function); @@ -279,10 +276,9 @@ namespace meta_hpp::detail using getter_impl = std::function; using setter_impl = std::function; - member_index index; - - getter_impl getter; - setter_impl setter; + const member_index index; + const getter_impl getter; + const setter_impl setter; template < member_kind Member > explicit member_state(member_index index, Member member); @@ -295,10 +291,9 @@ namespace meta_hpp::detail using invoke_impl = std::function(const inst&, std::span)>; using is_invocable_with_impl = std::function)>; - method_index index; - - invoke_impl invoke; - is_invocable_with_impl is_invocable_with; + const method_index index; + const invoke_impl invoke; + const is_invocable_with_impl is_invocable_with; template < method_kind Method > explicit method_state(method_index index, Method method); @@ -308,7 +303,7 @@ namespace meta_hpp::detail }; struct scope_state final { - scope_index index; + const scope_index index; class_map classes; enum_map enums; @@ -325,10 +320,9 @@ namespace meta_hpp::detail using getter_impl = std::function; using setter_impl = std::function; - variable_index index; - - getter_impl getter; - setter_impl setter; + const variable_index index; + const getter_impl getter; + const setter_impl setter; template < pointer_kind Pointer > explicit variable_state(variable_index index, Pointer pointer); From de77303c7aabdd4658939daf397d2c1bffb8ddb5 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sat, 8 Jan 2022 06:26:55 +0700 Subject: [PATCH 157/233] add member and variable call operators --- headers/meta.hpp/meta_states.hpp | 11 ++++ headers/meta.hpp/meta_states/member.hpp | 10 +++ headers/meta.hpp/meta_states/variable.hpp | 9 +++ untests/meta_states/member_tests.cpp | 78 ++++++++++++++++++----- untests/meta_states/variable_tests.cpp | 10 ++- 5 files changed, 101 insertions(+), 17 deletions(-) diff --git a/headers/meta.hpp/meta_states.hpp b/headers/meta.hpp/meta_states.hpp index ae96b16..d6484cc 100644 --- a/headers/meta.hpp/meta_states.hpp +++ b/headers/meta.hpp/meta_states.hpp @@ -147,6 +147,12 @@ namespace meta_hpp template < typename Instance, typename Value > void set(Instance&& instance, Value&& value) const; + + template < typename Instance > + [[nodiscard]] value operator()(Instance&& instance) const; + + template < typename Instance, typename Value > + void operator()(Instance&& instance, Value&& value) const; private: detail::member_state_ptr state_; }; @@ -223,6 +229,11 @@ namespace meta_hpp template < typename Value > void set(Value&& value) const; + + [[nodiscard]] value operator()() const; + + template < typename Value > + void operator()(Value&& value) const; private: detail::variable_state_ptr state_; }; diff --git a/headers/meta.hpp/meta_states/member.hpp b/headers/meta.hpp/meta_states/member.hpp index 8490c3f..b09824b 100644 --- a/headers/meta.hpp/meta_states/member.hpp +++ b/headers/meta.hpp/meta_states/member.hpp @@ -123,4 +123,14 @@ namespace meta_hpp using namespace detail; state_->setter(inst{std::forward(instance)}, arg{std::forward(value)}); } + + template < typename Instance > + value member::operator()(Instance&& instance) const { + return get(std::forward(instance)); + } + + template < typename Instance, typename Value > + void member::operator()(Instance&& instance, Value&& value) const { + set(std::forward(instance), std::forward(value)); + } } diff --git a/headers/meta.hpp/meta_states/variable.hpp b/headers/meta.hpp/meta_states/variable.hpp index 044fdf8..2b01ba7 100644 --- a/headers/meta.hpp/meta_states/variable.hpp +++ b/headers/meta.hpp/meta_states/variable.hpp @@ -103,4 +103,13 @@ namespace meta_hpp using namespace detail; state_->setter(arg{std::forward(value)}); } + + inline value variable::operator()() const { + return get(); + } + + template < typename Value > + void variable::operator()(Value&& value) const { + set(std::forward(value)); + } } diff --git a/untests/meta_states/member_tests.cpp b/untests/meta_states/member_tests.cpp index 2d771de..9fa978d 100644 --- a/untests/meta_states/member_tests.cpp +++ b/untests/meta_states/member_tests.cpp @@ -12,6 +12,8 @@ namespace int int_member = 1; const int const_int_member = 2; }; + + struct clazz_2 {}; } TEST_CASE("meta/meta_states/member") { @@ -47,16 +49,38 @@ TEST_CASE("meta/meta_states/member") { CHECK(vm.get_name() == "int_member"); clazz_1 v; + clazz_2 v2; - CHECK(vm.get(v) == 1); - CHECK(vm.get(std::as_const(v)) == 1); - CHECK(vm.get(std::move(v)) == 1); - CHECK(vm.get(std::move(std::as_const(v))) == 1); + { + CHECK(vm.get(v) == 1); + CHECK(vm.get(std::as_const(v)) == 1); + CHECK(vm.get(std::move(v)) == 1); + CHECK(vm.get(std::move(std::as_const(v))) == 1); - CHECK_NOTHROW(vm.set(v, 10)); CHECK(vm.get(v) == 10); - CHECK_THROWS(vm.set(std::as_const(v), 11)); CHECK(vm.get(v) == 10); - CHECK_NOTHROW(vm.set(std::move(v), 12)); CHECK(vm.get(v) == 12); - CHECK_THROWS(vm.set(std::move(std::as_const(v)), 13)); CHECK(vm.get(v) == 12); + CHECK(vm(v) == 1); + CHECK(vm(std::as_const(v)) == 1); + CHECK(vm(std::move(v)) == 1); + CHECK(vm(std::move(std::as_const(v))) == 1); + + CHECK_THROWS(std::ignore = vm.get(v2)); + CHECK_THROWS(std::ignore = vm(v2)); + } + + { + CHECK_NOTHROW(vm.set(v, 10)); CHECK(vm.get(v) == 10); + CHECK_THROWS(vm.set(std::as_const(v), 11)); CHECK(vm.get(v) == 10); + CHECK_NOTHROW(vm.set(std::move(v), 12)); CHECK(vm.get(v) == 12); + CHECK_THROWS(vm.set(std::move(std::as_const(v)), 13)); CHECK(vm.get(v) == 12); + + CHECK_NOTHROW(vm(v, 13)); CHECK(vm(v) == 13); + CHECK_THROWS(vm(std::as_const(v), 14)); CHECK(vm(v) == 13); + CHECK_NOTHROW(vm(std::move(v), 15)); CHECK(vm(v) == 15); + CHECK_THROWS(vm(std::move(std::as_const(v)), 16)); CHECK(vm(v) == 15); + + CHECK_THROWS(vm.set(v2, 17)); + CHECK_THROWS(vm(v2, 17)); + CHECK(vm(v) == 15); + } } SUBCASE("const int") { @@ -67,15 +91,37 @@ TEST_CASE("meta/meta_states/member") { CHECK(vm.get_name() == "const_int_member"); clazz_1 v; + clazz_2 v2; - CHECK(vm.get(v) == 2); - CHECK(vm.get(std::as_const(v)) == 2); - CHECK(vm.get(std::move(v)) == 2); - CHECK(vm.get(std::move(std::as_const(v))) == 2); + { + CHECK(vm.get(v) == 2); + CHECK(vm.get(std::as_const(v)) == 2); + CHECK(vm.get(std::move(v)) == 2); + CHECK(vm.get(std::move(std::as_const(v))) == 2); - CHECK_THROWS(vm.set(v, 10)); CHECK(vm.get(v) == 2); - CHECK_THROWS(vm.set(std::as_const(v), 11)); CHECK(vm.get(v) == 2); - CHECK_THROWS(vm.set(std::move(v), 12)); CHECK(vm.get(v) == 2); - CHECK_THROWS(vm.set(std::move(std::as_const(v)), 13)); CHECK(vm.get(v) == 2); + CHECK(vm(v) == 2); + CHECK(vm(std::as_const(v)) == 2); + CHECK(vm(std::move(v)) == 2); + CHECK(vm(std::move(std::as_const(v))) == 2); + + CHECK_THROWS(std::ignore = vm.get(v2)); + CHECK_THROWS(std::ignore = vm(v2)); + } + + { + CHECK_THROWS(vm.set(v, 10)); CHECK(vm.get(v) == 2); + CHECK_THROWS(vm.set(std::as_const(v), 11)); CHECK(vm.get(v) == 2); + CHECK_THROWS(vm.set(std::move(v), 12)); CHECK(vm.get(v) == 2); + CHECK_THROWS(vm.set(std::move(std::as_const(v)), 16)); CHECK(vm.get(v) == 2); + + CHECK_THROWS(vm(v, 13)); CHECK(vm(v) == 2); + CHECK_THROWS(vm(std::as_const(v), 14)); CHECK(vm(v) == 2); + CHECK_THROWS(vm(std::move(v), 15)); CHECK(vm(v) == 2); + CHECK_THROWS(vm(std::move(std::as_const(v)), 16)); CHECK(vm(v) == 2); + + CHECK_THROWS(vm.set(v2, 17)); + CHECK_THROWS(vm(v2, 17)); + CHECK(vm(v) == 2); + } } } diff --git a/untests/meta_states/variable_tests.cpp b/untests/meta_states/variable_tests.cpp index f15ff90..e38d85c 100644 --- a/untests/meta_states/variable_tests.cpp +++ b/untests/meta_states/variable_tests.cpp @@ -58,8 +58,10 @@ TEST_CASE("meta/meta_states/variable") { CHECK(vm.get_name() == "int_variable"); CHECK(vm.get() == 1); + CHECK(vm() == 1); CHECK_NOTHROW(vm.set(10)); CHECK(vm.get() == 10); + CHECK_NOTHROW(vm(11)); CHECK(vm() == 11); } SUBCASE("const int") { @@ -70,8 +72,10 @@ TEST_CASE("meta/meta_states/variable") { CHECK(vm.get_name() == "const_int_variable"); CHECK(vm.get() == 2); + CHECK(vm() == 2); CHECK_THROWS(vm.set(10)); CHECK(vm.get() == 2); + CHECK_THROWS(vm(10)); CHECK(vm() == 2); } SUBCASE("ref int") { @@ -81,9 +85,11 @@ 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() == 10); + CHECK(vm.get() == 11); + CHECK(vm() == 11); CHECK_NOTHROW(vm.set(20)); CHECK(vm.get() == 20); + CHECK_NOTHROW(vm(21)); CHECK(vm() == 21); } SUBCASE("const ref int") { @@ -94,7 +100,9 @@ TEST_CASE("meta/meta_states/variable") { CHECK(vm.get_name() == "const_ref_int_variable"); CHECK(vm.get() == 2); + CHECK(vm() == 2); CHECK_THROWS(vm.set(10)); CHECK(vm.get() == 2); + CHECK_THROWS(vm(11)); CHECK(vm() == 2); } } From a2708acbc7375cb925916af9e306b7a9112b743c Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sat, 8 Jan 2022 07:10:41 +0700 Subject: [PATCH 158/233] add is_gettable_with, is_settable_with for member and variable --- headers/meta.hpp/meta_states.hpp | 25 +++++++ headers/meta.hpp/meta_states/ctor.hpp | 18 ++--- headers/meta.hpp/meta_states/function.hpp | 18 ++--- headers/meta.hpp/meta_states/member.hpp | 70 ++++++++++++++++-- headers/meta.hpp/meta_states/method.hpp | 18 ++--- headers/meta.hpp/meta_states/variable.hpp | 36 ++++++++-- untests/meta_states/member_tests.cpp | 87 +++++++++++++++++++++++ untests/meta_states/variable_tests.cpp | 40 +++++++++++ 8 files changed, 277 insertions(+), 35 deletions(-) diff --git a/headers/meta.hpp/meta_states.hpp b/headers/meta.hpp/meta_states.hpp index d6484cc..ff4daea 100644 --- a/headers/meta.hpp/meta_states.hpp +++ b/headers/meta.hpp/meta_states.hpp @@ -153,6 +153,18 @@ namespace meta_hpp template < typename Instance, typename Value > void operator()(Instance&& instance, Value&& value) const; + + template < typename Instance > + [[nodiscard]] bool is_gettable_with() const noexcept; + + template < typename Instance > + [[nodiscard]] bool is_gettable_with(Instance&& instance) const noexcept; + + template < typename Instance, typename Value > + [[nodiscard]] bool is_settable_with() const noexcept; + + template < typename Instance, typename Value > + [[nodiscard]] bool is_settable_with(Instance&& instance, Value&& value) const noexcept; private: detail::member_state_ptr state_; }; @@ -234,6 +246,12 @@ namespace meta_hpp template < typename Value > void operator()(Value&& value) const; + + template < typename Value > + [[nodiscard]] bool is_settable_with() const noexcept; + + template < typename Value > + [[nodiscard]] bool is_settable_with(Value&& value) const noexcept; private: detail::variable_state_ptr state_; }; @@ -287,9 +305,14 @@ namespace meta_hpp::detail using getter_impl = std::function; using setter_impl = std::function; + using is_gettable_with_impl = std::function; + using is_settable_with_impl = std::function; + const member_index index; const getter_impl getter; const setter_impl setter; + 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); @@ -330,10 +353,12 @@ namespace meta_hpp::detail struct variable_state final { using getter_impl = std::function; using setter_impl = std::function; + using is_settable_with_impl = std::function; const variable_index index; const getter_impl getter; const setter_impl setter; + const is_settable_with_impl is_settable_with; template < pointer_kind Pointer > explicit variable_state(variable_index index, Pointer pointer); diff --git a/headers/meta.hpp/meta_states/ctor.hpp b/headers/meta.hpp/meta_states/ctor.hpp index 2175fe0..e501499 100644 --- a/headers/meta.hpp/meta_states/ctor.hpp +++ b/headers/meta.hpp/meta_states/ctor.hpp @@ -34,15 +34,6 @@ namespace meta_hpp::detail }, std::make_index_sequence()); } - template < class_kind Class, typename... Args > - ctor_state::invoke_impl make_ctor_invoke() { - using namespace std::placeholders; - return std::bind(&raw_ctor_invoke, _1); - } -} - -namespace meta_hpp::detail -{ template < class_kind Class, typename... Args > bool raw_ctor_is_invocable_with(std::span args) { using ct = ctor_traits; @@ -57,6 +48,15 @@ namespace meta_hpp::detail return (... && (args.data() + Is)->can_cast_to>()); }, std::make_index_sequence()); } +} + +namespace meta_hpp::detail +{ + template < class_kind Class, typename... Args > + ctor_state::invoke_impl make_ctor_invoke() { + using namespace std::placeholders; + return std::bind(&raw_ctor_invoke, _1); + } template < class_kind Class, typename... Args > ctor_state::is_invocable_with_impl make_ctor_is_invocable_with() { diff --git a/headers/meta.hpp/meta_states/function.hpp b/headers/meta.hpp/meta_states/function.hpp index f40c6f0..f1efd24 100644 --- a/headers/meta.hpp/meta_states/function.hpp +++ b/headers/meta.hpp/meta_states/function.hpp @@ -43,15 +43,6 @@ namespace meta_hpp::detail }, std::make_index_sequence()); } - template < function_kind Function > - function_state::invoke_impl make_function_invoke(Function function) { - using namespace std::placeholders; - return std::bind(&raw_function_invoke, function, _1); - } -} - -namespace meta_hpp::detail -{ template < function_kind Function > bool raw_function_is_invocable_with(std::span args) { using ft = function_traits; @@ -66,6 +57,15 @@ namespace meta_hpp::detail return (... && (args.data() + Is)->can_cast_to>()); }, std::make_index_sequence()); } +} + +namespace meta_hpp::detail +{ + template < function_kind Function > + function_state::invoke_impl make_function_invoke(Function function) { + using namespace std::placeholders; + return std::bind(&raw_function_invoke, function, _1); + } template < function_kind Function > function_state::is_invocable_with_impl make_function_is_invocable_with() { diff --git a/headers/meta.hpp/meta_states/member.hpp b/headers/meta.hpp/meta_states/member.hpp index b09824b..6a66ec1 100644 --- a/headers/meta.hpp/meta_states/member.hpp +++ b/headers/meta.hpp/meta_states/member.hpp @@ -37,7 +37,9 @@ namespace meta_hpp::detail using qualified_type = class_type; - if constexpr ( !std::is_const_v ) { + if constexpr ( std::is_const_v ) { + throw std::logic_error("an attempt to set a constant member"); + } else { if ( inst.is_const() ) { throw std::logic_error("an attempt to set a member with an const instance type"); } @@ -51,10 +53,32 @@ namespace meta_hpp::detail } std::invoke(member, inst.cast()) = arg.cast(); - } else { - throw std::logic_error("an attempt to set a constant member"); } } + + template < member_kind Member > + 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(); + } + + template < member_kind Member > + bool raw_member_is_settable_with(const inst_base& inst, const arg_base& arg) { + using mt = member_traits; + 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() + && arg.can_cast_to(); + } } namespace meta_hpp::detail @@ -70,6 +94,18 @@ namespace meta_hpp::detail using namespace std::placeholders; return std::bind(&raw_member_setter, member, _1, _2); } + + template < member_kind Member > + member_state::is_gettable_with_impl make_member_is_gettable_with() { + using namespace std::placeholders; + return std::bind(&raw_member_is_gettable_with, _1); + } + + template < member_kind Member > + member_state::is_settable_with_impl make_member_is_settable_with() { + using namespace std::placeholders; + return std::bind(&raw_member_is_settable_with, _1, _2); + } } namespace meta_hpp::detail @@ -78,7 +114,9 @@ namespace meta_hpp::detail member_state::member_state(member_index index, Member member) : index{std::move(index)} , getter{make_member_getter(member)} - , setter{make_member_setter(member)} {} + , setter{make_member_setter(member)} + , is_gettable_with{make_member_is_gettable_with()} + , is_settable_with{make_member_is_settable_with()} {} template < member_kind Member > member_state_ptr member_state::make(std::string name, Member member) { @@ -133,4 +171,28 @@ namespace meta_hpp void member::operator()(Instance&& instance, Value&& value) const { set(std::forward(instance), std::forward(value)); } + + template < typename Instance > + [[nodiscard]] bool member::is_gettable_with() const noexcept { + using namespace detail; + return state_->is_gettable_with(inst_base{type_list{}}); + } + + template < typename Instance > + [[nodiscard]] bool member::is_gettable_with(Instance&& instance) const noexcept { + using namespace detail; + return state_->is_gettable_with(inst{std::forward(instance)}); + } + + template < typename Instance, typename Value > + [[nodiscard]] bool member::is_settable_with() const noexcept { + using namespace detail; + return state_->is_settable_with(inst_base{type_list{}}, arg_base{type_list{}}); + } + + template < typename Instance, typename Value > + [[nodiscard]] bool member::is_settable_with(Instance&& instance, Value&& value) const noexcept { + using namespace detail; + return state_->is_settable_with(inst{std::forward(instance)}, arg{std::forward(value)}); + } } diff --git a/headers/meta.hpp/meta_states/method.hpp b/headers/meta.hpp/meta_states/method.hpp index 2d303bb..3719dfd 100644 --- a/headers/meta.hpp/meta_states/method.hpp +++ b/headers/meta.hpp/meta_states/method.hpp @@ -50,15 +50,6 @@ namespace meta_hpp::detail }, std::make_index_sequence()); } - template < method_kind Method > - method_state::invoke_impl make_method_invoke(Method method) { - using namespace std::placeholders; - return std::bind(&raw_method_invoke, method, _1, _2); - } -} - -namespace meta_hpp::detail -{ template < method_kind Method > bool raw_method_is_invocable_with(const inst_base& inst, std::span args) { using mt = method_traits; @@ -78,6 +69,15 @@ namespace meta_hpp::detail return (... && (args.data() + Is)->can_cast_to>()); }, std::make_index_sequence()); } +} + +namespace meta_hpp::detail +{ + template < method_kind Method > + method_state::invoke_impl make_method_invoke(Method method) { + using namespace std::placeholders; + return std::bind(&raw_method_invoke, method, _1, _2); + } template < method_kind Method > method_state::is_invocable_with_impl make_method_is_invocable_with() { diff --git a/headers/meta.hpp/meta_states/variable.hpp b/headers/meta.hpp/meta_states/variable.hpp index 2b01ba7..5db678e 100644 --- a/headers/meta.hpp/meta_states/variable.hpp +++ b/headers/meta.hpp/meta_states/variable.hpp @@ -27,16 +27,25 @@ namespace meta_hpp::detail using pt = pointer_traits; using data_type = typename pt::data_type; - if constexpr ( !std::is_const_v ) { + if constexpr ( std::is_const_v ) { + throw std::logic_error("an attempt to set a constant variable"); + } else { if ( !arg.can_cast_to() ) { throw std::logic_error("an attempt to set a variable with an incorrect argument type"); } *pointer = arg.cast(); - } else { - throw std::logic_error("an attempt to set a constant variable"); } } + + template < pointer_kind Pointer > + bool raw_variable_is_settable_with(const arg_base& arg) { + using pt = pointer_traits; + using data_type = typename pt::data_type; + + return !std::is_const_v + && arg.can_cast_to();; + } } namespace meta_hpp::detail @@ -52,6 +61,12 @@ namespace meta_hpp::detail using namespace std::placeholders; return std::bind(&raw_variable_setter, pointer, _1); } + + template < pointer_kind Pointer > + variable_state::is_settable_with_impl make_variable_is_settable_with() { + using namespace std::placeholders; + return std::bind(&raw_variable_is_settable_with, _1); + } } namespace meta_hpp::detail @@ -60,7 +75,8 @@ namespace meta_hpp::detail variable_state::variable_state(variable_index index, Pointer pointer) : index{std::move(index)} , getter{make_variable_getter(pointer)} - , setter{make_variable_setter(pointer)} {} + , setter{make_variable_setter(pointer)} + , is_settable_with{make_variable_is_settable_with()} {} template < pointer_kind Pointer > variable_state_ptr variable_state::make(std::string name, Pointer pointer) { @@ -112,4 +128,16 @@ namespace meta_hpp void variable::operator()(Value&& value) const { set(std::forward(value)); } + + template < typename Value > + bool variable::is_settable_with() const noexcept { + using namespace detail; + return state_->is_settable_with(arg_base{type_list{}}); + } + + template < typename Value > + bool variable::is_settable_with(Value&& value) const noexcept { + using namespace detail; + return state_->is_settable_with(arg{std::forward(value)}); + } } diff --git a/untests/meta_states/member_tests.cpp b/untests/meta_states/member_tests.cpp index 9fa978d..25c1362 100644 --- a/untests/meta_states/member_tests.cpp +++ b/untests/meta_states/member_tests.cpp @@ -51,6 +51,23 @@ TEST_CASE("meta/meta_states/member") { clazz_1 v; clazz_2 v2; + { + CHECK(vm.is_gettable_with()); + CHECK(vm.is_gettable_with()); + CHECK(vm.is_gettable_with()); + CHECK(vm.is_gettable_with()); + CHECK(vm.is_gettable_with()); + CHECK(vm.is_gettable_with()); + + CHECK(vm.is_gettable_with(v)); + CHECK(vm.is_gettable_with(std::as_const(v))); + CHECK(vm.is_gettable_with(std::move(v))); + CHECK(vm.is_gettable_with(std::move(std::as_const(v)))); + + CHECK_FALSE(vm.is_gettable_with()); + CHECK_FALSE(vm.is_gettable_with(v2)); + } + { CHECK(vm.get(v) == 1); CHECK(vm.get(std::as_const(v)) == 1); @@ -66,6 +83,34 @@ TEST_CASE("meta/meta_states/member") { CHECK_THROWS(std::ignore = vm(v2)); } + { + CHECK(vm.is_settable_with()); + CHECK(vm.is_settable_with()); + CHECK(vm.is_settable_with()); + + CHECK(vm.is_settable_with()); + CHECK(vm.is_settable_with()); + CHECK(vm.is_settable_with()); + + CHECK(vm.is_settable_with(v, 10)); + CHECK(vm.is_settable_with(std::move(v), 12)); + + CHECK_FALSE(vm.is_settable_with()); + CHECK_FALSE(vm.is_settable_with()); + CHECK_FALSE(vm.is_settable_with()); + + CHECK_FALSE(vm.is_settable_with()); + CHECK_FALSE(vm.is_settable_with()); + CHECK_FALSE(vm.is_settable_with()); + + CHECK_FALSE(vm.is_settable_with()); + + CHECK_FALSE(vm.is_settable_with(v2, 10)); + CHECK_FALSE(vm.is_settable_with(std::move(v2), 10)); + CHECK_FALSE(vm.is_settable_with(v, 10.0)); + CHECK_FALSE(vm.is_settable_with(std::move(v), 12.0)); + } + { CHECK_NOTHROW(vm.set(v, 10)); CHECK(vm.get(v) == 10); CHECK_THROWS(vm.set(std::as_const(v), 11)); CHECK(vm.get(v) == 10); @@ -93,6 +138,23 @@ TEST_CASE("meta/meta_states/member") { clazz_1 v; clazz_2 v2; + { + CHECK(vm.is_gettable_with()); + CHECK(vm.is_gettable_with()); + CHECK(vm.is_gettable_with()); + CHECK(vm.is_gettable_with()); + CHECK(vm.is_gettable_with()); + CHECK(vm.is_gettable_with()); + + CHECK(vm.is_gettable_with(v)); + CHECK(vm.is_gettable_with(std::as_const(v))); + CHECK(vm.is_gettable_with(std::move(v))); + CHECK(vm.is_gettable_with(std::move(std::as_const(v)))); + + CHECK_FALSE(vm.is_gettable_with()); + CHECK_FALSE(vm.is_gettable_with(v2)); + } + { CHECK(vm.get(v) == 2); CHECK(vm.get(std::as_const(v)) == 2); @@ -108,6 +170,31 @@ TEST_CASE("meta/meta_states/member") { CHECK_THROWS(std::ignore = vm(v2)); } + { + CHECK_FALSE(vm.is_settable_with()); + CHECK_FALSE(vm.is_settable_with()); + CHECK_FALSE(vm.is_settable_with()); + + CHECK_FALSE(vm.is_settable_with()); + CHECK_FALSE(vm.is_settable_with()); + CHECK_FALSE(vm.is_settable_with()); + + CHECK_FALSE(vm.is_settable_with()); + CHECK_FALSE(vm.is_settable_with()); + CHECK_FALSE(vm.is_settable_with()); + + CHECK_FALSE(vm.is_settable_with()); + CHECK_FALSE(vm.is_settable_with()); + CHECK_FALSE(vm.is_settable_with()); + + CHECK_FALSE(vm.is_settable_with(v, 10)); + CHECK_FALSE(vm.is_settable_with(std::move(v), 12)); + + CHECK_FALSE(vm.is_settable_with()); + CHECK_FALSE(vm.is_settable_with(v2, 10)); + CHECK_FALSE(vm.is_settable_with(std::move(v2), 12)); + } + { CHECK_THROWS(vm.set(v, 10)); CHECK(vm.get(v) == 2); CHECK_THROWS(vm.set(std::as_const(v), 11)); CHECK(vm.get(v) == 2); diff --git a/untests/meta_states/variable_tests.cpp b/untests/meta_states/variable_tests.cpp index e38d85c..17077b9 100644 --- a/untests/meta_states/variable_tests.cpp +++ b/untests/meta_states/variable_tests.cpp @@ -60,6 +60,16 @@ TEST_CASE("meta/meta_states/variable") { CHECK(vm.get() == 1); CHECK(vm() == 1); + CHECK(vm.is_settable_with()); + CHECK(vm.is_settable_with()); + CHECK(vm.is_settable_with()); + CHECK(vm.is_settable_with(1)); + + CHECK_FALSE(vm.is_settable_with()); + CHECK_FALSE(vm.is_settable_with()); + CHECK_FALSE(vm.is_settable_with()); + CHECK_FALSE(vm.is_settable_with(1.0)); + CHECK_NOTHROW(vm.set(10)); CHECK(vm.get() == 10); CHECK_NOTHROW(vm(11)); CHECK(vm() == 11); } @@ -74,6 +84,16 @@ TEST_CASE("meta/meta_states/variable") { CHECK(vm.get() == 2); CHECK(vm() == 2); + CHECK_FALSE(vm.is_settable_with()); + CHECK_FALSE(vm.is_settable_with()); + CHECK_FALSE(vm.is_settable_with()); + CHECK_FALSE(vm.is_settable_with(1)); + + CHECK_FALSE(vm.is_settable_with()); + CHECK_FALSE(vm.is_settable_with()); + CHECK_FALSE(vm.is_settable_with()); + CHECK_FALSE(vm.is_settable_with(1.0)); + CHECK_THROWS(vm.set(10)); CHECK(vm.get() == 2); CHECK_THROWS(vm(10)); CHECK(vm() == 2); } @@ -88,6 +108,16 @@ TEST_CASE("meta/meta_states/variable") { CHECK(vm.get() == 11); CHECK(vm() == 11); + CHECK(vm.is_settable_with()); + CHECK(vm.is_settable_with()); + CHECK(vm.is_settable_with()); + CHECK(vm.is_settable_with(1)); + + CHECK_FALSE(vm.is_settable_with()); + CHECK_FALSE(vm.is_settable_with()); + CHECK_FALSE(vm.is_settable_with()); + CHECK_FALSE(vm.is_settable_with(1.0)); + CHECK_NOTHROW(vm.set(20)); CHECK(vm.get() == 20); CHECK_NOTHROW(vm(21)); CHECK(vm() == 21); } @@ -102,6 +132,16 @@ TEST_CASE("meta/meta_states/variable") { CHECK(vm.get() == 2); CHECK(vm() == 2); + CHECK_FALSE(vm.is_settable_with()); + CHECK_FALSE(vm.is_settable_with()); + CHECK_FALSE(vm.is_settable_with()); + CHECK_FALSE(vm.is_settable_with(1)); + + CHECK_FALSE(vm.is_settable_with()); + CHECK_FALSE(vm.is_settable_with()); + CHECK_FALSE(vm.is_settable_with()); + CHECK_FALSE(vm.is_settable_with(1.0)); + CHECK_THROWS(vm.set(10)); CHECK(vm.get() == 2); CHECK_THROWS(vm(11)); CHECK(vm() == 2); } From a44bc0e11d6d7fc792520e376b35158f00bbbb80 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sat, 8 Jan 2022 07:14:16 +0700 Subject: [PATCH 159/233] examples cleanup --- README.md | 2 +- TODO.md | 9 +++--- untests/.clang-tidy | 1 + untests/examples/class_example.cpp | 20 +++++-------- untests/examples/complex_example.cpp | 44 ++++++++++++++-------------- untests/examples/enum_example.cpp | 24 +++++++++++---- untests/examples/member_example.cpp | 16 +++++----- untests/examples/method_example.cpp | 22 +++++++------- untests/examples/number_example.cpp | 2 -- untests/meta_tests.hpp | 1 + 10 files changed, 76 insertions(+), 65 deletions(-) diff --git a/README.md b/README.md index 5a61537..56c6f7c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # meta.hpp -> C++20 tiny reflection library +> C++20 tiny dynamic reflection library [![linux][badge.linux]][linux] [![darwin][badge.darwin]][darwin] diff --git a/TODO.md b/TODO.md index 0632421..a602e7c 100644 --- a/TODO.md +++ b/TODO.md @@ -1,6 +1,7 @@ # meta.hpp -- add debug type names -- add meta exception class -- add conversion of nullptr to any pointers -- add conversion of any pointers to void pointer ( identically cv-qualified ) +- add debug type names; +- add meta exception class; +- add conversion of nullptr to any pointers; +- add conversion of any pointers to void pointer ( identically cv-qualified ); +- add enum_type::create, number_type::create, and so on. diff --git a/untests/.clang-tidy b/untests/.clang-tidy index 76b1ec4..8762983 100644 --- a/untests/.clang-tidy +++ b/untests/.clang-tidy @@ -11,6 +11,7 @@ Checks: '-*, -cppcoreguidelines-special-member-functions, modernize-*, + -modernize-use-nodiscard, -modernize-use-trailing-return-type, portability-*, diff --git a/untests/examples/class_example.cpp b/untests/examples/class_example.cpp index f0cb81d..9a198e4 100644 --- a/untests/examples/class_example.cpp +++ b/untests/examples/class_example.cpp @@ -8,14 +8,12 @@ namespace { - constexpr double pi_v = 3.1415926536; - class shape { public: shape() = default; virtual ~shape() = default; - [[nodiscard]] virtual double area() const = 0; + virtual double area() const = 0; }; class circle : public shape { @@ -23,11 +21,11 @@ namespace explicit circle(double radius) : radius_{radius} {} - [[nodiscard]] double area() const override { - return pi_v * radius_ * radius_; + double area() const override { + return std::numbers::pi * radius_ * radius_; } - [[nodiscard]] double radius() const { + double radius() const { return radius_; } private: @@ -40,15 +38,15 @@ namespace : width_{width} , height_{height} {} - [[nodiscard]] double area() const override { + double area() const override { return width_ * height_; } - [[nodiscard]] double width() const { + double width() const { return width_; } - [[nodiscard]] double height() const { + double height() const { return height_; } private: @@ -84,7 +82,6 @@ TEST_CASE("meta/examples/class") { { const meta::class_type circle_type = geometry.get_class("circle"); - const meta::method radius_method = circle_type.get_method("radius"); const meta::value circle_v = circle_type.create(5.0).value(); @@ -98,11 +95,10 @@ TEST_CASE("meta/examples/class") { { const meta::class_type rectangle_type = geometry.get_class("rectangle"); - const meta::method width_method = rectangle_type.get_method("width"); const meta::method height_method = rectangle_type.get_method("height"); - const meta::value rectangle_v = rectangle_type(10.0, 20.0).value(); + const meta::value rectangle_v = rectangle_type.create(10.0, 20.0).value(); const meta::value rectangle_area_v = area_method(rectangle_v).value(); const meta::value rectangle_width_v = width_method(rectangle_v).value(); diff --git a/untests/examples/complex_example.cpp b/untests/examples/complex_example.cpp index 5bee1c3..e840873 100644 --- a/untests/examples/complex_example.cpp +++ b/untests/examples/complex_example.cpp @@ -16,15 +16,15 @@ namespace ivec2(int v) : x{v}, y{v} {} ivec2(int x, int y) : x{x}, y{y} {} - [[nodiscard]] int dot(const ivec2& other) const noexcept { + int dot(const ivec2& other) const { return x * other.x + y * other.y; } - [[nodiscard]] int length2() const noexcept { + int length2() const { return dot(*this); } - [[nodiscard]] friend bool operator==(const ivec2& l, const ivec2& r) noexcept { + friend bool operator==(const ivec2& l, const ivec2& r) { return l.x == r.x && l.y == r.y; } }; @@ -51,49 +51,49 @@ TEST_CASE("meta/examples/complex") { const meta::method ivec2_length2 = ivec2_type.get_method("length2"); { - const ivec2 v = ivec2_type.get_ctor_with<>().invoke().cast(); + const ivec2 v = ivec2_type()->cast(); CHECK(v == ivec2{}); - CHECK(ivec2_x.get(v) == 0); - CHECK(ivec2_y.get(v) == 0); + CHECK(ivec2_x(v) == 0); + CHECK(ivec2_y(v) == 0); } { - const ivec2 v = ivec2_type.get_ctor_with().invoke(3).cast(); + const ivec2 v = ivec2_type(3)->cast(); CHECK(v == ivec2{3}); - CHECK(ivec2_x.get(v) == 3); - CHECK(ivec2_y.get(v) == 3); + CHECK(ivec2_x(v) == 3); + CHECK(ivec2_y(v) == 3); } { - const meta::value v = ivec2_type.get_ctor_with().invoke(1, 2); + const meta::value v = ivec2_type(1, 2).value(); CHECK(v == ivec2{1, 2}); - CHECK(ivec2_x.get(v) == 1); - CHECK(ivec2_y.get(v) == 2); + CHECK(ivec2_x(v) == 1); + CHECK(ivec2_y(v) == 2); } { - meta::value v = ivec2_type.get_ctor_with().invoke(1, 2); + meta::value v = ivec2_type(1, 2).value(); - ivec2_x.set(v, 10); - ivec2_y.set(v, 20); + ivec2_x(v, 10); + ivec2_y(v, 20); - CHECK(ivec2_x.get(v) == 10); - CHECK(ivec2_y.get(v) == 20); + CHECK(ivec2_x(v) == 10); + CHECK(ivec2_y(v) == 20); } { - const meta::value v0 = ivec2_type.get_ctor_with().invoke(1, 2); - const meta::value v1 = ivec2_type.get_ctor_with().invoke(3, 4); + const meta::value v0 = ivec2_type(1, 2).value(); + const meta::value v1 = ivec2_type(3, 4).value(); - CHECK(ivec2_dot.invoke(v0, v1) == 1 * 3 + 2 * 4); + CHECK(ivec2_dot(v0, v1) == 1 * 3 + 2 * 4); } { - const meta::value v = ivec2_type.get_ctor_with().invoke(3, 4); + const meta::value v = ivec2_type(3, 4).value(); - CHECK(ivec2_length2.invoke(v) == 3 * 3 + 4 * 4); + CHECK(ivec2_length2(v) == 3 * 3 + 4 * 4); } } diff --git a/untests/examples/enum_example.cpp b/untests/examples/enum_example.cpp index 7402e25..653b322 100644 --- a/untests/examples/enum_example.cpp +++ b/untests/examples/enum_example.cpp @@ -26,11 +26,25 @@ TEST_CASE("meta/examples/enum") { .evalue_("white", color::white); meta::enum_type color_type = meta::resolve_type(); - REQUIRE(color_type); - CHECK(color_type.get_underlying_type() == meta::resolve_type()); + { + meta::number_type color_underlying_type = color_type.get_underlying_type(); - CHECK(color_type.get_evalue("green").get_index().name == "green"); - CHECK(color_type.get_evalue("green").get_value() == color::green); - CHECK_FALSE(color_type.get_evalue("yellow")); + CHECK(color_underlying_type.get_size() == 4); + CHECK(color_underlying_type.get_flags().has(meta::number_flags::is_unsigned)); + } + + { + meta::evalue green_evalue = color_type.get_evalue("green"); + + CHECK(green_evalue.get_name() == "green"); + CHECK(green_evalue.get_type() == color_type); + + CHECK(green_evalue.get_value() == color::green); + } + + { + CHECK(color_type.value_to_name(color::blue) == "blue"); + CHECK(color_type.name_to_value("white") == color::white); + } } diff --git a/untests/examples/member_example.cpp b/untests/examples/member_example.cpp index 7f239ee..f8c4f6a 100644 --- a/untests/examples/member_example.cpp +++ b/untests/examples/member_example.cpp @@ -8,7 +8,7 @@ namespace { - struct ivec2 final { + struct ivec2 { int x{}; int y{}; }; @@ -22,16 +22,16 @@ TEST_CASE("meta/examples/member") { .member_("y", &ivec2::y); const meta::class_type ivec2_type = meta::resolve_type(); - REQUIRE(ivec2_type); CHECK(ivec2_type.get_members().size() == 2); - const meta::member ivec2_x = ivec2_type.get_member("x"); - REQUIRE(ivec2_x); + { + const meta::member ivec2_x = ivec2_type.get_member("x"); - CHECK(ivec2_x.get_index().name == "x"); - CHECK(ivec2_x.get_type() == meta::resolve_type()); + CHECK(ivec2_x.get_name() == "x"); + CHECK(ivec2_x.get_type() == meta::resolve_type()); - CHECK(ivec2_x.get_type().get_owner_type() == meta::resolve_type()); - CHECK(ivec2_x.get_type().get_value_type() == meta::resolve_type()); + CHECK(ivec2_x.get_type().get_owner_type() == meta::resolve_type()); + CHECK(ivec2_x.get_type().get_value_type() == meta::resolve_type()); + } } diff --git a/untests/examples/method_example.cpp b/untests/examples/method_example.cpp index b51d70b..6153160 100644 --- a/untests/examples/method_example.cpp +++ b/untests/examples/method_example.cpp @@ -8,15 +8,15 @@ namespace { - struct ivec2 final { + struct ivec2 { int x{}; int y{}; - [[nodiscard]] int dot(const ivec2& other) const noexcept { + int dot(const ivec2& other) const { return x * other.x + y * other.y; } - [[nodiscard]] int length2() const noexcept { + int length2() const { return dot(*this); } }; @@ -32,17 +32,17 @@ TEST_CASE("meta/examples/method") { .method_("length2", &ivec2::length2); const meta::class_type ivec2_type = meta::resolve_type(); - REQUIRE(ivec2_type); CHECK(ivec2_type.get_methods().size() == 2); - const meta::method ivec2_dot = ivec2_type.get_method("dot"); - REQUIRE(ivec2_dot); + { + const meta::method ivec2_dot = ivec2_type.get_method("dot"); - CHECK(ivec2_dot.get_index().name == "dot"); - CHECK(ivec2_dot.get_type() == meta::resolve_type()); + CHECK(ivec2_dot.get_name() == "dot"); + CHECK(ivec2_dot.get_type() == meta::resolve_type()); - CHECK(ivec2_dot.get_type().get_arity() == 1); - CHECK(ivec2_dot.get_type().get_return_type() == meta::resolve_type()); - CHECK(ivec2_dot.get_type().get_argument_type(0) == meta::resolve_type()); + CHECK(ivec2_dot.get_type().get_arity() == 1); + CHECK(ivec2_dot.get_type().get_return_type() == meta::resolve_type()); + CHECK(ivec2_dot.get_type().get_argument_type(0) == meta::resolve_type()); + } } diff --git a/untests/examples/number_example.cpp b/untests/examples/number_example.cpp index 877dabc..f677b56 100644 --- a/untests/examples/number_example.cpp +++ b/untests/examples/number_example.cpp @@ -15,7 +15,6 @@ TEST_CASE("meta/examples/number") { { const meta::number_type int_type = meta::resolve_type(); - REQUIRE(int_type); CHECK(int_type.get_flags().has(meta::number_flags::is_signed)); CHECK(int_type.get_size() == sizeof(int)); @@ -23,7 +22,6 @@ TEST_CASE("meta/examples/number") { { const meta::number_type unsigned_type = meta::resolve_type(); - REQUIRE(unsigned_type); CHECK(unsigned_type.get_flags().has(meta::number_flags::is_unsigned)); CHECK(unsigned_type.get_size() == sizeof(unsigned)); diff --git a/untests/meta_tests.hpp b/untests/meta_tests.hpp index a4555fc..96ebd83 100644 --- a/untests/meta_tests.hpp +++ b/untests/meta_tests.hpp @@ -11,4 +11,5 @@ #include #include +#include #include From 86a2e3837926df79ade3be90b9f7d71ca6c7ceed Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sun, 9 Jan 2022 06:05:21 +0700 Subject: [PATCH 160/233] dummy manual sources --- CMakeLists.txt | 12 +- README.md | 2 +- TODO.md | 4 +- manuals/.clang-tidy | 19 +++ manuals/CMakeLists.txt | 38 ++++++ manuals/meta_examples/arrays_example.cpp | 15 +++ manuals/meta_examples/classes_example.cpp | 15 +++ manuals/meta_examples/enums_examples.cpp | 15 +++ manuals/meta_examples/functions_example.cpp | 15 +++ manuals/meta_examples/members_example.cpp | 15 +++ manuals/meta_examples/methods_example.cpp | 15 +++ manuals/meta_examples/numbers_example.cpp | 15 +++ manuals/meta_examples/pointers_example.cpp | 15 +++ manuals/meta_examples/references_example.cpp | 15 +++ manuals/meta_examples/variables_example.cpp | 15 +++ .../meta_manuals.hpp | 4 - untests/CMakeLists.txt | 6 +- untests/examples/class_example.cpp | 111 ------------------ untests/examples/complex_example.cpp | 99 ---------------- untests/examples/enum_example.cpp | 50 -------- untests/examples/member_example.cpp | 37 ------ untests/examples/method_example.cpp | 48 -------- untests/examples/number_example.cpp | 29 ----- untests/meta_features/diamond_tests.cpp | 4 +- untests/meta_states/evalue_tests.cpp | 2 +- untests/meta_states/function_tests.cpp | 2 +- untests/meta_states/member_tests.cpp | 2 +- untests/meta_states/method_tests.cpp | 2 +- untests/meta_states/scope_tests.cpp | 2 +- untests/meta_states/variable_tests.cpp | 2 +- untests/meta_types/array_type_tests.cpp | 2 +- untests/meta_types/class_type_tests.cpp | 2 +- untests/meta_types/enum_type_tests.cpp | 2 +- untests/meta_types/function_type_tests.cpp | 2 +- untests/meta_types/member_type_tests.cpp | 2 +- untests/meta_types/method_type_tests.cpp | 2 +- untests/meta_types/number_type_tests.cpp | 2 +- untests/meta_types/pointer_type_tests.cpp | 2 +- untests/meta_types/reference_type_tests.cpp | 2 +- untests/meta_types/void_type_tests.cpp | 2 +- untests/meta_untests.hpp | 11 ++ untests/meta_utilities/arg2_tests.cpp | 6 +- untests/meta_utilities/arg3_tests.cpp | 6 +- untests/meta_utilities/arg4_tests.cpp | 4 +- untests/meta_utilities/arg_tests.cpp | 12 +- untests/meta_utilities/detail_tests.cpp | 4 +- untests/meta_utilities/inst_tests.cpp | 8 +- untests/meta_utilities/value_tests.cpp | 18 +-- 48 files changed, 279 insertions(+), 435 deletions(-) create mode 100644 manuals/.clang-tidy create mode 100644 manuals/CMakeLists.txt create mode 100644 manuals/meta_examples/arrays_example.cpp create mode 100644 manuals/meta_examples/classes_example.cpp create mode 100644 manuals/meta_examples/enums_examples.cpp create mode 100644 manuals/meta_examples/functions_example.cpp create mode 100644 manuals/meta_examples/members_example.cpp create mode 100644 manuals/meta_examples/methods_example.cpp create mode 100644 manuals/meta_examples/numbers_example.cpp create mode 100644 manuals/meta_examples/pointers_example.cpp create mode 100644 manuals/meta_examples/references_example.cpp create mode 100644 manuals/meta_examples/variables_example.cpp rename untests/meta_tests.hpp => manuals/meta_manuals.hpp (90%) delete mode 100644 untests/examples/class_example.cpp delete mode 100644 untests/examples/complex_example.cpp delete mode 100644 untests/examples/enum_example.cpp delete mode 100644 untests/examples/member_example.cpp delete mode 100644 untests/examples/method_example.cpp delete mode 100644 untests/examples/number_example.cpp create mode 100644 untests/meta_untests.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 035b5df..ba9fe16 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,11 +41,9 @@ target_compile_options(${PROJECT_NAME} >) if(BUILD_AS_STANDALONE) - option(BUILD_WITH_UNTESTS "Build with unit tests" ON) - if(BUILD_WITH_UNTESTS) - enable_testing() - add_subdirectory(vendors/doctest) - add_subdirectory(vendors/fmtlib) - add_subdirectory(untests) - endif() + enable_testing() + add_subdirectory(vendors/doctest) + add_subdirectory(vendors/fmtlib) + add_subdirectory(manuals) + add_subdirectory(untests) endif() diff --git a/README.md b/README.md index 56c6f7c..4f33c3c 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ [meta.hpp][meta] is a header-only library. All you need to do is copy the headers files from `headers` directory into your project and include them: ```cpp -#include "meta.hpp/meta.hpp" +#include "meta.hpp/meta_all.hpp" ``` Also, you can add the root repository directory to your [cmake](https://cmake.org) project: diff --git a/TODO.md b/TODO.md index a602e7c..4a9ca8b 100644 --- a/TODO.md +++ b/TODO.md @@ -1,6 +1,8 @@ # meta.hpp -- add debug type names; +- add type names; +- add argument names +- add variable and member readonly flags - add meta exception class; - add conversion of nullptr to any pointers; - add conversion of any pointers to void pointer ( identically cv-qualified ); diff --git a/manuals/.clang-tidy b/manuals/.clang-tidy new file mode 100644 index 0000000..8762983 --- /dev/null +++ b/manuals/.clang-tidy @@ -0,0 +1,19 @@ +--- +Checks: '-*, + + clang-analyzer-*, + + concurrency-*, + + cppcoreguidelines-*, + -cppcoreguidelines-avoid-magic-numbers, + -cppcoreguidelines-avoid-non-const-global-variables, + -cppcoreguidelines-special-member-functions, + + modernize-*, + -modernize-use-nodiscard, + -modernize-use-trailing-return-type, + + portability-*, + ' +... diff --git a/manuals/CMakeLists.txt b/manuals/CMakeLists.txt new file mode 100644 index 0000000..cd2d17e --- /dev/null +++ b/manuals/CMakeLists.txt @@ -0,0 +1,38 @@ +project(meta.hpp.manuals) + +# +# coverage +# + +option(BUILD_WITH_COVERAGE "Build with coverage" OFF) +if(BUILD_WITH_COVERAGE AND (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")) + set(COVERAGE_FLAGS "--coverage") + set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${COVERAGE_FLAGS}") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${COVERAGE_FLAGS}") + set(CMAKE_LINKER_FLAGS_DEBUG "${CMAKE_LINKER_FLAGS_DEBUG} ${COVERAGE_FLAGS}") +endif() + +# +# executable +# + +file(GLOB_RECURSE MANUALS_SOURCES "*.cpp" "*.hpp") +add_executable(${PROJECT_NAME} ${MANUALS_SOURCES}) +target_link_libraries(${PROJECT_NAME} PRIVATE meta.hpp doctest_with_main fmt) + +target_compile_options(${PROJECT_NAME} + PRIVATE + $<$: + /WX /W4> + PRIVATE + $<$: + -Werror -Wall -Wextra -Wpedantic> + PRIVATE + $<$,$>: + -Werror -Weverything -Wconversion>) + +target_compile_definitions(${PROJECT_NAME} PRIVATE + DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS + DOCTEST_CONFIG_USE_STD_HEADERS) + +add_test(${PROJECT_NAME} ${PROJECT_NAME}) diff --git a/manuals/meta_examples/arrays_example.cpp b/manuals/meta_examples/arrays_example.cpp new file mode 100644 index 0000000..7c28b8b --- /dev/null +++ b/manuals/meta_examples/arrays_example.cpp @@ -0,0 +1,15 @@ +/******************************************************************************* + * 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_manuals.hpp" + +namespace +{ +} + +TEST_CASE("meta/meta_examples/arrays") { + namespace meta = meta_hpp; +} diff --git a/manuals/meta_examples/classes_example.cpp b/manuals/meta_examples/classes_example.cpp new file mode 100644 index 0000000..eae4b39 --- /dev/null +++ b/manuals/meta_examples/classes_example.cpp @@ -0,0 +1,15 @@ +/******************************************************************************* + * 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_manuals.hpp" + +namespace +{ +} + +TEST_CASE("meta/meta_examples/classes") { + namespace meta = meta_hpp; +} diff --git a/manuals/meta_examples/enums_examples.cpp b/manuals/meta_examples/enums_examples.cpp new file mode 100644 index 0000000..e1914b3 --- /dev/null +++ b/manuals/meta_examples/enums_examples.cpp @@ -0,0 +1,15 @@ +/******************************************************************************* + * 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_manuals.hpp" + +namespace +{ +} + +TEST_CASE("meta/meta_examples/enums") { + namespace meta = meta_hpp; +} diff --git a/manuals/meta_examples/functions_example.cpp b/manuals/meta_examples/functions_example.cpp new file mode 100644 index 0000000..e3bf2d0 --- /dev/null +++ b/manuals/meta_examples/functions_example.cpp @@ -0,0 +1,15 @@ +/******************************************************************************* + * 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_manuals.hpp" + +namespace +{ +} + +TEST_CASE("meta/meta_examples/functions") { + namespace meta = meta_hpp; +} diff --git a/manuals/meta_examples/members_example.cpp b/manuals/meta_examples/members_example.cpp new file mode 100644 index 0000000..40bae32 --- /dev/null +++ b/manuals/meta_examples/members_example.cpp @@ -0,0 +1,15 @@ +/******************************************************************************* + * 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_manuals.hpp" + +namespace +{ +} + +TEST_CASE("meta/meta_examples/members") { + namespace meta = meta_hpp; +} diff --git a/manuals/meta_examples/methods_example.cpp b/manuals/meta_examples/methods_example.cpp new file mode 100644 index 0000000..1a74e73 --- /dev/null +++ b/manuals/meta_examples/methods_example.cpp @@ -0,0 +1,15 @@ +/******************************************************************************* + * 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_manuals.hpp" + +namespace +{ +} + +TEST_CASE("meta/meta_examples/methods") { + namespace meta = meta_hpp; +} diff --git a/manuals/meta_examples/numbers_example.cpp b/manuals/meta_examples/numbers_example.cpp new file mode 100644 index 0000000..dc0c989 --- /dev/null +++ b/manuals/meta_examples/numbers_example.cpp @@ -0,0 +1,15 @@ +/******************************************************************************* + * 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_manuals.hpp" + +namespace +{ +} + +TEST_CASE("meta/meta_examples/numbers") { + namespace meta = meta_hpp; +} diff --git a/manuals/meta_examples/pointers_example.cpp b/manuals/meta_examples/pointers_example.cpp new file mode 100644 index 0000000..5729a42 --- /dev/null +++ b/manuals/meta_examples/pointers_example.cpp @@ -0,0 +1,15 @@ +/******************************************************************************* + * 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_manuals.hpp" + +namespace +{ +} + +TEST_CASE("meta/meta_examples/pointers") { + namespace meta = meta_hpp; +} diff --git a/manuals/meta_examples/references_example.cpp b/manuals/meta_examples/references_example.cpp new file mode 100644 index 0000000..1fef687 --- /dev/null +++ b/manuals/meta_examples/references_example.cpp @@ -0,0 +1,15 @@ +/******************************************************************************* + * 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_manuals.hpp" + +namespace +{ +} + +TEST_CASE("meta/meta_examples/references") { + namespace meta = meta_hpp; +} diff --git a/manuals/meta_examples/variables_example.cpp b/manuals/meta_examples/variables_example.cpp new file mode 100644 index 0000000..03d8c54 --- /dev/null +++ b/manuals/meta_examples/variables_example.cpp @@ -0,0 +1,15 @@ +/******************************************************************************* + * 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_manuals.hpp" + +namespace +{ +} + +TEST_CASE("meta/meta_examples/variables") { + namespace meta = meta_hpp; +} diff --git a/untests/meta_tests.hpp b/manuals/meta_manuals.hpp similarity index 90% rename from untests/meta_tests.hpp rename to manuals/meta_manuals.hpp index 96ebd83..03493c7 100644 --- a/untests/meta_tests.hpp +++ b/manuals/meta_manuals.hpp @@ -4,12 +4,8 @@ * Copyright (C) 2021, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ -#pragma once - #include #include -#include #include -#include #include diff --git a/untests/CMakeLists.txt b/untests/CMakeLists.txt index 3ec4640..d2c23e2 100644 --- a/untests/CMakeLists.txt +++ b/untests/CMakeLists.txt @@ -18,7 +18,7 @@ endif() file(GLOB_RECURSE UNTESTS_SOURCES "*.cpp" "*.hpp") add_executable(${PROJECT_NAME} ${UNTESTS_SOURCES}) -target_link_libraries(${PROJECT_NAME} meta.hpp doctest_with_main fmt) +target_link_libraries(${PROJECT_NAME} PRIVATE meta.hpp doctest_with_main fmt) target_compile_options(${PROJECT_NAME} PRIVATE @@ -31,4 +31,8 @@ target_compile_options(${PROJECT_NAME} $<$,$>: -Werror -Weverything -Wconversion>) +target_compile_definitions(${PROJECT_NAME} PRIVATE + DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS + DOCTEST_CONFIG_USE_STD_HEADERS) + add_test(${PROJECT_NAME} ${PROJECT_NAME}) diff --git a/untests/examples/class_example.cpp b/untests/examples/class_example.cpp deleted file mode 100644 index 9a198e4..0000000 --- a/untests/examples/class_example.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/******************************************************************************* - * 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_tests.hpp" - -namespace -{ - class shape { - public: - shape() = default; - virtual ~shape() = default; - - virtual double area() const = 0; - }; - - class circle : public shape { - public: - explicit circle(double radius) - : radius_{radius} {} - - double area() const override { - return std::numbers::pi * radius_ * radius_; - } - - double radius() const { - return radius_; - } - private: - double radius_{}; - }; - - class rectangle : public shape { - public: - explicit rectangle(double width, double height) - : width_{width} - , height_{height} {} - - double area() const override { - return width_ * height_; - } - - double width() const { - return width_; - } - - double height() const { - return height_; - } - private: - double width_{}; - double height_{}; - }; -} - -TEST_CASE("meta/examples/class") { - namespace meta = meta_hpp; - - meta::class_() - .method_("area", &shape::area); - - meta::class_() - .base_() - .ctor_() - .method_("radius", &circle::radius); - - meta::class_() - .base_() - .ctor_() - .method_("width", &rectangle::width) - .method_("height", &rectangle::height); - - const meta::scope geometry = meta::local_scope_("geometry") - .class_("shape") - .class_("circle") - .class_("rectangle"); - - const meta::class_type shape_type = geometry.get_class("shape"); - const meta::method area_method = shape_type.get_method("area"); - - { - const meta::class_type circle_type = geometry.get_class("circle"); - const meta::method radius_method = circle_type.get_method("radius"); - - const meta::value circle_v = circle_type.create(5.0).value(); - - const meta::value circle_area_v = area_method(circle_v).value(); - const meta::value circle_radius_v = radius_method(circle_v).value(); - - CHECK(circle_area_v.cast() == doctest::Approx(78.5).epsilon(0.1)); - CHECK(circle_radius_v == 5.0); - } - - { - const meta::class_type rectangle_type = geometry.get_class("rectangle"); - const meta::method width_method = rectangle_type.get_method("width"); - const meta::method height_method = rectangle_type.get_method("height"); - - const meta::value rectangle_v = rectangle_type.create(10.0, 20.0).value(); - - const meta::value rectangle_area_v = area_method(rectangle_v).value(); - const meta::value rectangle_width_v = width_method(rectangle_v).value(); - const meta::value rectangle_height_v = height_method(rectangle_v).value(); - - CHECK(rectangle_area_v.cast() == doctest::Approx(200.0).epsilon(0.1)); - CHECK(rectangle_width_v == 10.0); - CHECK(rectangle_height_v == 20.0); - } -} diff --git a/untests/examples/complex_example.cpp b/untests/examples/complex_example.cpp deleted file mode 100644 index e840873..0000000 --- a/untests/examples/complex_example.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/******************************************************************************* - * 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_tests.hpp" - -namespace -{ - struct ivec2 { - int x{}; - int y{}; - - ivec2() = default; - ivec2(int v) : x{v}, y{v} {} - ivec2(int x, int y) : x{x}, y{y} {} - - int dot(const ivec2& other) const { - return x * other.x + y * other.y; - } - - int length2() const { - return dot(*this); - } - - friend bool operator==(const ivec2& l, const ivec2& r) { - return l.x == r.x && l.y == r.y; - } - }; -} - -TEST_CASE("meta/examples/complex") { - namespace meta = meta_hpp; - - meta::class_() - .ctor_<>() - .ctor_() - .ctor_() - .member_("x", &ivec2::x) - .member_("y", &ivec2::y) - .method_("dot", &ivec2::dot) - .method_("length2", &ivec2::length2); - - const meta::class_type ivec2_type = meta::resolve_type(); - - const meta::member ivec2_x = ivec2_type.get_member("x"); - const meta::member ivec2_y = ivec2_type.get_member("y"); - - const meta::method ivec2_dot = ivec2_type.get_method("dot"); - const meta::method ivec2_length2 = ivec2_type.get_method("length2"); - - { - const ivec2 v = ivec2_type()->cast(); - CHECK(v == ivec2{}); - - CHECK(ivec2_x(v) == 0); - CHECK(ivec2_y(v) == 0); - } - - { - const ivec2 v = ivec2_type(3)->cast(); - CHECK(v == ivec2{3}); - - CHECK(ivec2_x(v) == 3); - CHECK(ivec2_y(v) == 3); - } - - { - const meta::value v = ivec2_type(1, 2).value(); - CHECK(v == ivec2{1, 2}); - - CHECK(ivec2_x(v) == 1); - CHECK(ivec2_y(v) == 2); - } - - { - meta::value v = ivec2_type(1, 2).value(); - - ivec2_x(v, 10); - ivec2_y(v, 20); - - CHECK(ivec2_x(v) == 10); - CHECK(ivec2_y(v) == 20); - } - - { - const meta::value v0 = ivec2_type(1, 2).value(); - const meta::value v1 = ivec2_type(3, 4).value(); - - CHECK(ivec2_dot(v0, v1) == 1 * 3 + 2 * 4); - } - - { - const meta::value v = ivec2_type(3, 4).value(); - - CHECK(ivec2_length2(v) == 3 * 3 + 4 * 4); - } -} diff --git a/untests/examples/enum_example.cpp b/untests/examples/enum_example.cpp deleted file mode 100644 index 653b322..0000000 --- a/untests/examples/enum_example.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/******************************************************************************* - * 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_tests.hpp" - -namespace -{ - enum class color : unsigned { - red = 0xFF0000, - green = 0x00FF00, - blue = 0x0000FF, - white = red | green | blue, - }; -} - -TEST_CASE("meta/examples/enum") { - namespace meta = meta_hpp; - - meta::enum_() - .evalue_("red", color::red) - .evalue_("green", color::green) - .evalue_("blue", color::blue) - .evalue_("white", color::white); - - meta::enum_type color_type = meta::resolve_type(); - - { - meta::number_type color_underlying_type = color_type.get_underlying_type(); - - CHECK(color_underlying_type.get_size() == 4); - CHECK(color_underlying_type.get_flags().has(meta::number_flags::is_unsigned)); - } - - { - meta::evalue green_evalue = color_type.get_evalue("green"); - - CHECK(green_evalue.get_name() == "green"); - CHECK(green_evalue.get_type() == color_type); - - CHECK(green_evalue.get_value() == color::green); - } - - { - CHECK(color_type.value_to_name(color::blue) == "blue"); - CHECK(color_type.name_to_value("white") == color::white); - } -} diff --git a/untests/examples/member_example.cpp b/untests/examples/member_example.cpp deleted file mode 100644 index f8c4f6a..0000000 --- a/untests/examples/member_example.cpp +++ /dev/null @@ -1,37 +0,0 @@ -/******************************************************************************* - * 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_tests.hpp" - -namespace -{ - struct ivec2 { - int x{}; - int y{}; - }; -} - -TEST_CASE("meta/examples/member") { - namespace meta = meta_hpp; - - meta::class_() - .member_("x", &ivec2::x) - .member_("y", &ivec2::y); - - const meta::class_type ivec2_type = meta::resolve_type(); - - CHECK(ivec2_type.get_members().size() == 2); - - { - const meta::member ivec2_x = ivec2_type.get_member("x"); - - CHECK(ivec2_x.get_name() == "x"); - CHECK(ivec2_x.get_type() == meta::resolve_type()); - - CHECK(ivec2_x.get_type().get_owner_type() == meta::resolve_type()); - CHECK(ivec2_x.get_type().get_value_type() == meta::resolve_type()); - } -} diff --git a/untests/examples/method_example.cpp b/untests/examples/method_example.cpp deleted file mode 100644 index 6153160..0000000 --- a/untests/examples/method_example.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/******************************************************************************* - * 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_tests.hpp" - -namespace -{ - struct ivec2 { - int x{}; - int y{}; - - int dot(const ivec2& other) const { - return x * other.x + y * other.y; - } - - int length2() const { - return dot(*this); - } - }; -} - -TEST_CASE("meta/examples/method") { - namespace meta = meta_hpp; - - meta::class_() - .member_("x", &ivec2::x) - .member_("y", &ivec2::y) - .method_("dot", &ivec2::dot) - .method_("length2", &ivec2::length2); - - const meta::class_type ivec2_type = meta::resolve_type(); - - CHECK(ivec2_type.get_methods().size() == 2); - - { - const meta::method ivec2_dot = ivec2_type.get_method("dot"); - - CHECK(ivec2_dot.get_name() == "dot"); - CHECK(ivec2_dot.get_type() == meta::resolve_type()); - - CHECK(ivec2_dot.get_type().get_arity() == 1); - CHECK(ivec2_dot.get_type().get_return_type() == meta::resolve_type()); - CHECK(ivec2_dot.get_type().get_argument_type(0) == meta::resolve_type()); - } -} diff --git a/untests/examples/number_example.cpp b/untests/examples/number_example.cpp deleted file mode 100644 index f677b56..0000000 --- a/untests/examples/number_example.cpp +++ /dev/null @@ -1,29 +0,0 @@ -/******************************************************************************* - * 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_tests.hpp" - -namespace -{ -} - -TEST_CASE("meta/examples/number") { - namespace meta = meta_hpp; - - { - const meta::number_type int_type = meta::resolve_type(); - - CHECK(int_type.get_flags().has(meta::number_flags::is_signed)); - CHECK(int_type.get_size() == sizeof(int)); - } - - { - const meta::number_type unsigned_type = meta::resolve_type(); - - CHECK(unsigned_type.get_flags().has(meta::number_flags::is_unsigned)); - CHECK(unsigned_type.get_size() == sizeof(unsigned)); - } -} diff --git a/untests/meta_features/diamond_tests.cpp b/untests/meta_features/diamond_tests.cpp index 008a5ca..8cc2da8 100644 --- a/untests/meta_features/diamond_tests.cpp +++ b/untests/meta_features/diamond_tests.cpp @@ -4,7 +4,7 @@ * Copyright (C) 2021, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ -#include "../meta_tests.hpp" +#include "../meta_untests.hpp" namespace { @@ -26,7 +26,7 @@ namespace struct E {}; } -TEST_CASE("features/features/diamond_inheritance") { +TEST_CASE("meta/meta_features/diamond") { namespace meta = meta_hpp; meta::class_(); diff --git a/untests/meta_states/evalue_tests.cpp b/untests/meta_states/evalue_tests.cpp index 7ee8f1e..93406af 100644 --- a/untests/meta_states/evalue_tests.cpp +++ b/untests/meta_states/evalue_tests.cpp @@ -4,7 +4,7 @@ * Copyright (C) 2021, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ -#include "../meta_tests.hpp" +#include "../meta_untests.hpp" namespace { diff --git a/untests/meta_states/function_tests.cpp b/untests/meta_states/function_tests.cpp index 6069fc9..aeb30ea 100644 --- a/untests/meta_states/function_tests.cpp +++ b/untests/meta_states/function_tests.cpp @@ -4,7 +4,7 @@ * Copyright (C) 2021, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ -#include "../meta_tests.hpp" +#include "../meta_untests.hpp" namespace { diff --git a/untests/meta_states/member_tests.cpp b/untests/meta_states/member_tests.cpp index 25c1362..78346e9 100644 --- a/untests/meta_states/member_tests.cpp +++ b/untests/meta_states/member_tests.cpp @@ -4,7 +4,7 @@ * Copyright (C) 2021, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ -#include "../meta_tests.hpp" +#include "../meta_untests.hpp" namespace { diff --git a/untests/meta_states/method_tests.cpp b/untests/meta_states/method_tests.cpp index ac67c8d..7ab50c6 100644 --- a/untests/meta_states/method_tests.cpp +++ b/untests/meta_states/method_tests.cpp @@ -4,7 +4,7 @@ * Copyright (C) 2021, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ -#include "../meta_tests.hpp" +#include "../meta_untests.hpp" namespace { diff --git a/untests/meta_states/scope_tests.cpp b/untests/meta_states/scope_tests.cpp index 32b3cdf..8128e2a 100644 --- a/untests/meta_states/scope_tests.cpp +++ b/untests/meta_states/scope_tests.cpp @@ -4,7 +4,7 @@ * Copyright (C) 2021, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ -#include "../meta_tests.hpp" +#include "../meta_untests.hpp" namespace { diff --git a/untests/meta_states/variable_tests.cpp b/untests/meta_states/variable_tests.cpp index 17077b9..6f7bc1e 100644 --- a/untests/meta_states/variable_tests.cpp +++ b/untests/meta_states/variable_tests.cpp @@ -4,7 +4,7 @@ * Copyright (C) 2021, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ -#include "../meta_tests.hpp" +#include "../meta_untests.hpp" namespace { diff --git a/untests/meta_types/array_type_tests.cpp b/untests/meta_types/array_type_tests.cpp index f4fe336..4c6301e 100644 --- a/untests/meta_types/array_type_tests.cpp +++ b/untests/meta_types/array_type_tests.cpp @@ -4,7 +4,7 @@ * Copyright (C) 2021, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ -#include "../meta_tests.hpp" +#include "../meta_untests.hpp" namespace { diff --git a/untests/meta_types/class_type_tests.cpp b/untests/meta_types/class_type_tests.cpp index cfbcbd6..a200cbb 100644 --- a/untests/meta_types/class_type_tests.cpp +++ b/untests/meta_types/class_type_tests.cpp @@ -4,7 +4,7 @@ * Copyright (C) 2021, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ -#include "../meta_tests.hpp" +#include "../meta_untests.hpp" namespace { diff --git a/untests/meta_types/enum_type_tests.cpp b/untests/meta_types/enum_type_tests.cpp index 52a7402..139703f 100644 --- a/untests/meta_types/enum_type_tests.cpp +++ b/untests/meta_types/enum_type_tests.cpp @@ -4,7 +4,7 @@ * Copyright (C) 2021, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ -#include "../meta_tests.hpp" +#include "../meta_untests.hpp" namespace { diff --git a/untests/meta_types/function_type_tests.cpp b/untests/meta_types/function_type_tests.cpp index 5bbad1d..71562fb 100644 --- a/untests/meta_types/function_type_tests.cpp +++ b/untests/meta_types/function_type_tests.cpp @@ -4,7 +4,7 @@ * Copyright (C) 2021, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ -#include "../meta_tests.hpp" +#include "../meta_untests.hpp" namespace { diff --git a/untests/meta_types/member_type_tests.cpp b/untests/meta_types/member_type_tests.cpp index 3998ca2..6fe3a4c 100644 --- a/untests/meta_types/member_type_tests.cpp +++ b/untests/meta_types/member_type_tests.cpp @@ -4,7 +4,7 @@ * Copyright (C) 2021, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ -#include "../meta_tests.hpp" +#include "../meta_untests.hpp" namespace { diff --git a/untests/meta_types/method_type_tests.cpp b/untests/meta_types/method_type_tests.cpp index cbc96a6..5d73a90 100644 --- a/untests/meta_types/method_type_tests.cpp +++ b/untests/meta_types/method_type_tests.cpp @@ -4,7 +4,7 @@ * Copyright (C) 2021, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ -#include "../meta_tests.hpp" +#include "../meta_untests.hpp" namespace { diff --git a/untests/meta_types/number_type_tests.cpp b/untests/meta_types/number_type_tests.cpp index 38c6605..ccd6545 100644 --- a/untests/meta_types/number_type_tests.cpp +++ b/untests/meta_types/number_type_tests.cpp @@ -4,7 +4,7 @@ * Copyright (C) 2021, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ -#include "../meta_tests.hpp" +#include "../meta_untests.hpp" namespace { diff --git a/untests/meta_types/pointer_type_tests.cpp b/untests/meta_types/pointer_type_tests.cpp index 7d4c3a2..df26406 100644 --- a/untests/meta_types/pointer_type_tests.cpp +++ b/untests/meta_types/pointer_type_tests.cpp @@ -4,7 +4,7 @@ * Copyright (C) 2021, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ -#include "../meta_tests.hpp" +#include "../meta_untests.hpp" namespace { diff --git a/untests/meta_types/reference_type_tests.cpp b/untests/meta_types/reference_type_tests.cpp index 2f948c9..68a1580 100644 --- a/untests/meta_types/reference_type_tests.cpp +++ b/untests/meta_types/reference_type_tests.cpp @@ -4,7 +4,7 @@ * Copyright (C) 2021, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ -#include "../meta_tests.hpp" +#include "../meta_untests.hpp" namespace { diff --git a/untests/meta_types/void_type_tests.cpp b/untests/meta_types/void_type_tests.cpp index 3593cdf..b34697c 100644 --- a/untests/meta_types/void_type_tests.cpp +++ b/untests/meta_types/void_type_tests.cpp @@ -4,7 +4,7 @@ * Copyright (C) 2021, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ -#include "../meta_tests.hpp" +#include "../meta_untests.hpp" namespace { diff --git a/untests/meta_untests.hpp b/untests/meta_untests.hpp new file mode 100644 index 0000000..03493c7 --- /dev/null +++ b/untests/meta_untests.hpp @@ -0,0 +1,11 @@ +/******************************************************************************* + * 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 +#include + +#include +#include diff --git a/untests/meta_utilities/arg2_tests.cpp b/untests/meta_utilities/arg2_tests.cpp index 74e6289..01a86bb 100644 --- a/untests/meta_utilities/arg2_tests.cpp +++ b/untests/meta_utilities/arg2_tests.cpp @@ -4,7 +4,7 @@ * Copyright (C) 2021, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ -#include "../meta_tests.hpp" +#include "../meta_untests.hpp" namespace { @@ -44,7 +44,7 @@ namespace }; } -TEST_CASE("features/meta_utilities/arg2") { +TEST_CASE("meta/meta_utilities/arg2") { namespace meta = meta_hpp; // * <- B <- * @@ -57,7 +57,7 @@ TEST_CASE("features/meta_utilities/arg2") { meta::class_().base_().base_(); } -TEST_CASE("features/meta_utilities/arg2/cast") { +TEST_CASE("meta/meta_utilities/arg2/cast") { namespace meta = meta_hpp; using meta::detail::arg; diff --git a/untests/meta_utilities/arg3_tests.cpp b/untests/meta_utilities/arg3_tests.cpp index 0506a36..f0647cc 100644 --- a/untests/meta_utilities/arg3_tests.cpp +++ b/untests/meta_utilities/arg3_tests.cpp @@ -4,7 +4,7 @@ * Copyright (C) 2021, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ -#include "../meta_tests.hpp" +#include "../meta_untests.hpp" namespace { @@ -37,7 +37,7 @@ namespace }; } -TEST_CASE("features/meta_utilities/arg3") { +TEST_CASE("meta/meta_utilities/arg3") { namespace meta = meta_hpp; // * <- B <- * @@ -50,7 +50,7 @@ TEST_CASE("features/meta_utilities/arg3") { meta::class_().base_().base_(); } -TEST_CASE("features/meta_utilities/arg3/cast") { +TEST_CASE("meta/meta_utilities/arg3/cast") { namespace meta = meta_hpp; using meta::detail::arg; diff --git a/untests/meta_utilities/arg4_tests.cpp b/untests/meta_utilities/arg4_tests.cpp index 51ea113..549c8a4 100644 --- a/untests/meta_utilities/arg4_tests.cpp +++ b/untests/meta_utilities/arg4_tests.cpp @@ -4,9 +4,9 @@ * Copyright (C) 2021, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ -#include "../meta_tests.hpp" +#include "../meta_untests.hpp" -TEST_CASE("features/meta_utilities/arg4/cast") { +TEST_CASE("meta/meta_utilities/arg4/cast") { namespace meta = meta_hpp; using meta::detail::arg; diff --git a/untests/meta_utilities/arg_tests.cpp b/untests/meta_utilities/arg_tests.cpp index 6fd0222..f69ae43 100644 --- a/untests/meta_utilities/arg_tests.cpp +++ b/untests/meta_utilities/arg_tests.cpp @@ -4,7 +4,7 @@ * Copyright (C) 2021, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ -#include "../meta_tests.hpp" +#include "../meta_untests.hpp" namespace { @@ -107,7 +107,7 @@ namespace }\ } -TEST_CASE("features/meta_utilities/arg") { +TEST_CASE("meta/meta_utilities/arg") { namespace meta = meta_hpp; meta::class_(); @@ -115,7 +115,7 @@ TEST_CASE("features/meta_utilities/arg") { meta::class_().base_().base_(); } -TEST_CASE("features/meta_utilities/arg/refs") { +TEST_CASE("meta/meta_utilities/arg/refs") { namespace meta = meta_hpp; { @@ -303,7 +303,7 @@ TEST_CASE("features/meta_utilities/arg/refs") { } } -TEST_CASE("features/meta_utilities/arg/ptrs") { +TEST_CASE("meta/meta_utilities/arg/ptrs") { namespace meta = meta_hpp; { @@ -837,7 +837,7 @@ TEST_CASE("features/meta_utilities/arg/ptrs") { } } -TEST_CASE("features/meta_utilities/arg/values") { +TEST_CASE("meta/meta_utilities/arg/values") { namespace meta = meta_hpp; { @@ -1027,7 +1027,7 @@ TEST_CASE("features/meta_utilities/arg/values") { } } -TEST_CASE("features/meta_utilities/arg/ptr_values") { +TEST_CASE("meta/meta_utilities/arg/ptr_values") { namespace meta = meta_hpp; { diff --git a/untests/meta_utilities/detail_tests.cpp b/untests/meta_utilities/detail_tests.cpp index 9e2dd61..079ace8 100644 --- a/untests/meta_utilities/detail_tests.cpp +++ b/untests/meta_utilities/detail_tests.cpp @@ -4,9 +4,9 @@ * Copyright (C) 2021, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ -#include "../meta_tests.hpp" +#include "../meta_untests.hpp" -TEST_CASE("features/meta_utilities/detail") { +TEST_CASE("meta/meta_utilities/detail") { namespace meta = meta_hpp; SUBCASE("cvref_traits") { diff --git a/untests/meta_utilities/inst_tests.cpp b/untests/meta_utilities/inst_tests.cpp index 969240a..5bfe24f 100644 --- a/untests/meta_utilities/inst_tests.cpp +++ b/untests/meta_utilities/inst_tests.cpp @@ -4,7 +4,7 @@ * Copyright (C) 2021, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ -#include "../meta_tests.hpp" +#include "../meta_untests.hpp" namespace { @@ -67,7 +67,7 @@ namespace }\ } -TEST_CASE("features/meta_utilities/inst2") { +TEST_CASE("meta/meta_utilities/inst2") { namespace meta = meta_hpp; meta::class_(); @@ -75,7 +75,7 @@ TEST_CASE("features/meta_utilities/inst2") { meta::class_().base_().base_(); } -TEST_CASE("features/meta_utilities/inst2/refs") { +TEST_CASE("meta/meta_utilities/inst2/refs") { namespace meta = meta_hpp; { @@ -235,7 +235,7 @@ TEST_CASE("features/meta_utilities/inst2/refs") { } } -TEST_CASE("features/meta_utilities/inst2/values") { +TEST_CASE("meta/meta_utilities/inst2/values") { namespace meta = meta_hpp; { diff --git a/untests/meta_utilities/value_tests.cpp b/untests/meta_utilities/value_tests.cpp index 296c520..602c13b 100644 --- a/untests/meta_utilities/value_tests.cpp +++ b/untests/meta_utilities/value_tests.cpp @@ -4,7 +4,7 @@ * Copyright (C) 2021, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ -#include "../meta_tests.hpp" +#include "../meta_untests.hpp" namespace { @@ -90,10 +90,10 @@ TEST_CASE("meta/meta_utilities/value") { CHECK(val.get_type() == meta::resolve_type()); - CHECK(!std::memcmp(val.data(), &vr, sizeof(ivec2))); - CHECK(!std::memcmp(val.cdata(), &vr, sizeof(ivec2))); - CHECK(!std::memcmp(std::as_const(val).data(), &vr, sizeof(ivec2))); - CHECK(!std::memcmp(std::as_const(val).cdata(), &vr, sizeof(ivec2))); + CHECK(*static_cast(val.data()) == vr); + CHECK(*static_cast(val.cdata()) == vr); + CHECK(*static_cast(std::as_const(val).data()) == vr); + CHECK(*static_cast(std::as_const(val).cdata()) == vr); CHECK(val == ivec2{1,2}); CHECK(val == meta::value{ivec2{1,2}}); @@ -115,10 +115,10 @@ TEST_CASE("meta/meta_utilities/value") { CHECK(val.get_type() == meta::resolve_type()); - CHECK(!std::memcmp(val.data(), &vr, sizeof(ivec2))); - CHECK(!std::memcmp(val.cdata(), &vr, sizeof(ivec2))); - CHECK(!std::memcmp(std::as_const(val).data(), &vr, sizeof(ivec2))); - CHECK(!std::memcmp(std::as_const(val).cdata(), &vr, sizeof(ivec2))); + CHECK(*static_cast(val.data()) == vr); + CHECK(*static_cast(val.cdata()) == vr); + CHECK(*static_cast(std::as_const(val).data()) == vr); + CHECK(*static_cast(std::as_const(val).cdata()) == vr); CHECK(val == ivec2{1,2}); CHECK(val == meta::value{ivec2{1,2}}); From d27b2ca12eec1873b67700b004f46427894e6b0f Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sun, 9 Jan 2022 06:05:42 +0700 Subject: [PATCH 161/233] update doctest to 2.4.7 version --- vendors/doctest | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendors/doctest b/vendors/doctest index 4d8716f..a384864 160000 --- a/vendors/doctest +++ b/vendors/doctest @@ -1 +1 @@ -Subproject commit 4d8716f1efc1d14aa736ef52ee727bd4204f4c40 +Subproject commit a384864346f48c7ff5608051c176e7bd505712ae From 25736b2cec02a01d433cb604b5f99c8020240f57 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sun, 9 Jan 2022 08:04:08 +0700 Subject: [PATCH 162/233] fix missing any_type::as_ctor impl --- headers/meta.hpp/meta_types/any_type.hpp | 6 + manuals/.clang-tidy | 2 + untests/.clang-tidy | 2 + untests/meta_types/any_type_tests.cpp | 240 +++++++++++++++++++++++ 4 files changed, 250 insertions(+) create mode 100644 untests/meta_types/any_type_tests.cpp diff --git a/headers/meta.hpp/meta_types/any_type.hpp b/headers/meta.hpp/meta_types/any_type.hpp index d5ff2ff..81716a9 100644 --- a/headers/meta.hpp/meta_types/any_type.hpp +++ b/headers/meta.hpp/meta_types/any_type.hpp @@ -119,6 +119,12 @@ namespace meta_hpp : class_type{}; } + inline ctor_type any_type::as_ctor() const noexcept { + return is_ctor() + ? ctor_type{std::static_pointer_cast(data_)} + : ctor_type{}; + } + inline enum_type any_type::as_enum() const noexcept { return is_enum() ? enum_type{std::static_pointer_cast(data_)} diff --git a/manuals/.clang-tidy b/manuals/.clang-tidy index 8762983..13fda4f 100644 --- a/manuals/.clang-tidy +++ b/manuals/.clang-tidy @@ -6,11 +6,13 @@ Checks: '-*, concurrency-*, cppcoreguidelines-*, + -cppcoreguidelines-avoid-c-arrays, -cppcoreguidelines-avoid-magic-numbers, -cppcoreguidelines-avoid-non-const-global-variables, -cppcoreguidelines-special-member-functions, modernize-*, + -modernize-avoid-c-arrays, -modernize-use-nodiscard, -modernize-use-trailing-return-type, diff --git a/untests/.clang-tidy b/untests/.clang-tidy index 8762983..13fda4f 100644 --- a/untests/.clang-tidy +++ b/untests/.clang-tidy @@ -6,11 +6,13 @@ Checks: '-*, concurrency-*, cppcoreguidelines-*, + -cppcoreguidelines-avoid-c-arrays, -cppcoreguidelines-avoid-magic-numbers, -cppcoreguidelines-avoid-non-const-global-variables, -cppcoreguidelines-special-member-functions, modernize-*, + -modernize-avoid-c-arrays, -modernize-use-nodiscard, -modernize-use-trailing-return-type, diff --git a/untests/meta_types/any_type_tests.cpp b/untests/meta_types/any_type_tests.cpp new file mode 100644 index 0000000..c9ab8f7 --- /dev/null +++ b/untests/meta_types/any_type_tests.cpp @@ -0,0 +1,240 @@ +/******************************************************************************* + * 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 class_t { + class_t() = default; + class_t(int i): member_v{i} {} + + int member_v{}; + void method_v() {} + }; + + enum class enum_t { + evalue_v, + }; + + int array_v[42]; + const class_t class_v; + const enum_t enum_v{enum_t::evalue_v}; + void function_v() {} + const int number_v{42}; + const int* pointer_v{&number_v}; +} + +TEST_CASE("meta/meta_types/any_type") { + namespace meta = meta_hpp; + + meta::class_() + .ctor_<>() + .ctor_(); + + SUBCASE("") { + const meta::any_type type{}; + CHECK_FALSE(type); + CHECK_FALSE(type.is_valid()); + + CHECK_FALSE(type.is_array()); + CHECK_FALSE(type.as_array()); + } + + SUBCASE("array") { + const meta::any_type& type = meta::resolve_type(array_v); + + REQUIRE(type); + REQUIRE(type == meta::resolve_type()); + REQUIRE(type.get_id() == meta::resolve_type().get_id()); + + CHECK(type.is_array()); + CHECK(type.get_kind() == meta::type_kind::array_); + + CHECK_FALSE(type.is_class()); + CHECK_FALSE(type.as_class()); + + const meta::array_type& specific_type = type.as_array(); + REQUIRE(specific_type); + CHECK(specific_type.get_id() == type.get_id()); + } + + SUBCASE("class") { + const meta::any_type& type = meta::resolve_type(class_v); + + REQUIRE(type); + REQUIRE(type == meta::resolve_type()); + REQUIRE(type.get_id() == meta::resolve_type().get_id()); + + CHECK(type.is_class()); + CHECK(type.get_kind() == meta::type_kind::class_); + + CHECK_FALSE(type.is_ctor()); + CHECK_FALSE(type.as_ctor()); + + const meta::class_type& specific_type = type.as_class(); + REQUIRE(specific_type); + CHECK(specific_type.get_id() == type.get_id()); + } + + SUBCASE("ctor") { + const meta::any_type& type = meta::resolve_type() + .get_ctor_with<>() + .get_type(); + + REQUIRE(type); + + CHECK(type.is_ctor()); + CHECK(type.get_kind() == meta::type_kind::ctor_); + + CHECK_FALSE(type.is_enum()); + CHECK_FALSE(type.as_enum()); + + const meta::ctor_type& specific_type = type.as_ctor(); + REQUIRE(specific_type); + CHECK(specific_type.get_id() == type.get_id()); + } + + SUBCASE("enum") { + const meta::any_type& type = meta::resolve_type(enum_v); + + REQUIRE(type); + REQUIRE(type == meta::resolve_type()); + REQUIRE(type.get_id() == meta::resolve_type().get_id()); + + CHECK(type.is_enum()); + CHECK(type.get_kind() == meta::type_kind::enum_); + + CHECK_FALSE(type.is_function()); + CHECK_FALSE(type.as_function()); + + const meta::enum_type& specific_type = type.as_enum(); + REQUIRE(specific_type); + CHECK(specific_type.get_id() == type.get_id()); + } + + SUBCASE("function") { + const meta::any_type& type = meta::resolve_type(&function_v); + + REQUIRE(type); + REQUIRE(type == meta::resolve_type()); + REQUIRE(type.get_id() == meta::resolve_type().get_id()); + + CHECK(type.is_function()); + CHECK(type.get_kind() == meta::type_kind::function_); + + CHECK_FALSE(type.is_member()); + CHECK_FALSE(type.as_member()); + + const meta::function_type& specific_type = type.as_function(); + REQUIRE(specific_type); + CHECK(specific_type.get_id() == type.get_id()); + } + + SUBCASE("member") { + const meta::any_type& type = meta::resolve_type(&class_t::member_v); + + REQUIRE(type); + REQUIRE(type == meta::resolve_type()); + REQUIRE(type.get_id() == meta::resolve_type().get_id()); + + CHECK(type.is_member()); + CHECK(type.get_kind() == meta::type_kind::member_); + + CHECK_FALSE(type.is_method()); + CHECK_FALSE(type.as_method()); + + const meta::member_type& specific_type = type.as_member(); + REQUIRE(specific_type); + CHECK(specific_type.get_id() == type.get_id()); + } + + SUBCASE("method") { + const meta::any_type& type = meta::resolve_type(&class_t::method_v); + + REQUIRE(type); + REQUIRE(type == meta::resolve_type()); + REQUIRE(type.get_id() == meta::resolve_type().get_id()); + + CHECK(type.is_method()); + CHECK(type.get_kind() == meta::type_kind::method_); + + CHECK_FALSE(type.is_number()); + CHECK_FALSE(type.as_number()); + + const meta::method_type& specific_type = type.as_method(); + REQUIRE(specific_type); + CHECK(specific_type.get_id() == type.get_id()); + } + + SUBCASE("number") { + const meta::any_type& type = meta::resolve_type(number_v); + + REQUIRE(type); + REQUIRE(type == meta::resolve_type()); + REQUIRE(type.get_id() == meta::resolve_type().get_id()); + + CHECK(type.is_number()); + CHECK(type.get_kind() == meta::type_kind::number_); + + CHECK_FALSE(type.is_pointer()); + CHECK_FALSE(type.as_pointer()); + + const meta::number_type& specific_type = type.as_number(); + REQUIRE(specific_type); + CHECK(specific_type.get_id() == type.get_id()); + } + + SUBCASE("pointer") { + const meta::any_type& type = meta::resolve_type(pointer_v); + + REQUIRE(type); + REQUIRE(type == meta::resolve_type()); + REQUIRE(type.get_id() == meta::resolve_type().get_id()); + + CHECK(type.is_pointer()); + CHECK(type.get_kind() == meta::type_kind::pointer_); + + CHECK_FALSE(type.is_reference()); + CHECK_FALSE(type.as_reference()); + + const meta::pointer_type& specific_type = type.as_pointer(); + REQUIRE(specific_type); + CHECK(specific_type.get_id() == type.get_id()); + } + + SUBCASE("reference") { + const meta::any_type& type = meta::resolve_type(); + + REQUIRE(type); + + CHECK(type.is_reference()); + CHECK(type.get_kind() == meta::type_kind::reference_); + + CHECK_FALSE(type.is_void()); + CHECK_FALSE(type.as_void()); + + const meta::reference_type& specific_type = type.as_reference(); + REQUIRE(specific_type); + CHECK(specific_type.get_id() == type.get_id()); + } + + SUBCASE("void") { + const meta::any_type& type = meta::resolve_type(); + + REQUIRE(type); + + CHECK(type.is_void()); + CHECK(type.get_kind() == meta::type_kind::void_); + + CHECK_FALSE(type.is_array()); + CHECK_FALSE(type.as_array()); + + const meta::void_type& specific_type = type.as_void(); + REQUIRE(specific_type); + CHECK(specific_type.get_id() == type.get_id()); + } +} From 6ea935071ce7f48d9da0b554520502f8bb61dd02 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sun, 9 Jan 2022 15:34:08 +0700 Subject: [PATCH 163/233] add member_flags::is_readonly --- headers/meta.hpp/meta_traits.hpp | 1 + headers/meta.hpp/meta_traits/member_traits.hpp | 8 +++++++- untests/meta_types/member_type_tests.cpp | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/headers/meta.hpp/meta_traits.hpp b/headers/meta.hpp/meta_traits.hpp index 7e3888f..18f55ae 100644 --- a/headers/meta.hpp/meta_traits.hpp +++ b/headers/meta.hpp/meta_traits.hpp @@ -73,6 +73,7 @@ namespace meta_hpp }; enum class member_flags : std::uint32_t { + is_readonly = 1 << 0, }; enum class method_flags : std::uint32_t { diff --git a/headers/meta.hpp/meta_traits/member_traits.hpp b/headers/meta.hpp/meta_traits/member_traits.hpp index 78cee42..8bf227a 100644 --- a/headers/meta.hpp/meta_traits/member_traits.hpp +++ b/headers/meta.hpp/meta_traits/member_traits.hpp @@ -20,7 +20,13 @@ namespace meta_hpp::detail using value_type = V; [[nodiscard]] static constexpr bitflags make_flags() noexcept { - return {}; + bitflags flags; + + if constexpr ( std::is_const_v ) { + flags.set(member_flags::is_readonly); + } + + return flags; } }; } diff --git a/untests/meta_types/member_type_tests.cpp b/untests/meta_types/member_type_tests.cpp index 6fe3a4c..77be0e7 100644 --- a/untests/meta_types/member_type_tests.cpp +++ b/untests/meta_types/member_type_tests.cpp @@ -39,7 +39,7 @@ TEST_CASE("meta/meta_types/member_type") { REQUIRE(type); CHECK(type.get_id() == meta::resolve_type(&clazz_1::const_int_member).get_id()); - CHECK(type.get_flags() == meta::member_flags{}); + CHECK(type.get_flags() == meta::member_flags::is_readonly); CHECK(type.get_owner_type() == meta::resolve_type()); CHECK(type.get_value_type() == meta::resolve_type()); From 900feef75459fbbe2f42c032ebf8a7dfcde5577a Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sun, 9 Jan 2022 15:49:47 +0700 Subject: [PATCH 164/233] remove void_flags --- headers/meta.hpp/meta_all.hpp | 1 - headers/meta.hpp/meta_traits.hpp | 4 ---- headers/meta.hpp/meta_traits/void_traits.hpp | 20 -------------------- headers/meta.hpp/meta_types.hpp | 3 --- headers/meta.hpp/meta_types/void_type.hpp | 9 +-------- untests/meta_types/pointer_type_tests.cpp | 12 ++++++++---- untests/meta_types/reference_type_tests.cpp | 16 ++++++---------- untests/meta_types/void_type_tests.cpp | 17 ++++++++++++++++- 8 files changed, 31 insertions(+), 51 deletions(-) delete mode 100644 headers/meta.hpp/meta_traits/void_traits.hpp diff --git a/headers/meta.hpp/meta_all.hpp b/headers/meta.hpp/meta_all.hpp index 242dcb4..cf67b10 100644 --- a/headers/meta.hpp/meta_all.hpp +++ b/headers/meta.hpp/meta_all.hpp @@ -35,7 +35,6 @@ #include "meta_traits/number_traits.hpp" #include "meta_traits/pointer_traits.hpp" #include "meta_traits/reference_traits.hpp" -#include "meta_traits/void_traits.hpp" #include "meta_types.hpp" #include "meta_types/any_type.hpp" diff --git a/headers/meta.hpp/meta_traits.hpp b/headers/meta.hpp/meta_traits.hpp index 18f55ae..d2cd0db 100644 --- a/headers/meta.hpp/meta_traits.hpp +++ b/headers/meta.hpp/meta_traits.hpp @@ -100,9 +100,6 @@ namespace meta_hpp is_rvalue = 1 << 2, }; - enum class void_flags : std::uint32_t { - }; - ENUM_HPP_OPERATORS_DECL(array_flags) ENUM_HPP_OPERATORS_DECL(class_flags) ENUM_HPP_OPERATORS_DECL(ctor_flags) @@ -113,5 +110,4 @@ namespace meta_hpp ENUM_HPP_OPERATORS_DECL(number_flags) ENUM_HPP_OPERATORS_DECL(pointer_flags) ENUM_HPP_OPERATORS_DECL(reference_flags) - ENUM_HPP_OPERATORS_DECL(void_flags) } diff --git a/headers/meta.hpp/meta_traits/void_traits.hpp b/headers/meta.hpp/meta_traits/void_traits.hpp deleted file mode 100644 index f1e4f4f..0000000 --- a/headers/meta.hpp/meta_traits/void_traits.hpp +++ /dev/null @@ -1,20 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "../meta_base.hpp" -#include "../meta_traits.hpp" - -namespace meta_hpp::detail -{ - template < void_kind Void > - struct void_traits { - [[nodiscard]] static constexpr bitflags make_flags() noexcept { - return {}; - } - }; -} diff --git a/headers/meta.hpp/meta_types.hpp b/headers/meta.hpp/meta_types.hpp index 73da28f..22fcf3a 100644 --- a/headers/meta.hpp/meta_types.hpp +++ b/headers/meta.hpp/meta_types.hpp @@ -412,7 +412,6 @@ namespace meta_hpp [[nodiscard]] explicit operator bool() const noexcept; [[nodiscard]] type_id get_id() const noexcept; - [[nodiscard]] bitflags get_flags() const noexcept; private: detail::void_type_data_ptr data_; friend auto detail::data_access(const void_type&); @@ -565,8 +564,6 @@ namespace meta_hpp::detail }; struct void_type_data final : type_data_base { - const bitflags flags; - template < void_kind Void > explicit void_type_data(type_list); diff --git a/headers/meta.hpp/meta_types/void_type.hpp b/headers/meta.hpp/meta_types/void_type.hpp index 0ca40e9..a314920 100644 --- a/headers/meta.hpp/meta_types/void_type.hpp +++ b/headers/meta.hpp/meta_types/void_type.hpp @@ -9,8 +9,6 @@ #include "../meta_base.hpp" #include "../meta_types.hpp" -#include "../meta_traits/void_traits.hpp" - namespace meta_hpp::detail { template < void_kind Void > @@ -19,8 +17,7 @@ namespace meta_hpp::detail template < void_kind Void > // NOLINTNEXTLINE(readability-named-parameter) void_type_data::void_type_data(type_list) - : type_data_base{type_id{type_list>{}}, type_kind::void_} - , flags{void_traits::make_flags()} {} + : type_data_base{type_id{type_list>{}}, type_kind::void_} {} template < void_kind Void > void_type_data_ptr void_type_data::get_static() { @@ -45,8 +42,4 @@ namespace meta_hpp inline type_id void_type::get_id() const noexcept { return data_->id; } - - inline bitflags void_type::get_flags() const noexcept { - return data_->flags; - } } diff --git a/untests/meta_types/pointer_type_tests.cpp b/untests/meta_types/pointer_type_tests.cpp index df26406..2469905 100644 --- a/untests/meta_types/pointer_type_tests.cpp +++ b/untests/meta_types/pointer_type_tests.cpp @@ -24,6 +24,7 @@ TEST_CASE("meta/meta_types/pointer_type") { REQUIRE(type); CHECK(type.get_id() == meta::resolve_type().get_id()); + CHECK(type.get_flags() == meta::pointer_flags{}); CHECK(type.get_data_type() == meta::resolve_type()); } @@ -32,7 +33,8 @@ TEST_CASE("meta/meta_types/pointer_type") { REQUIRE(type); CHECK(type.get_id() == meta::resolve_type().get_id()); - CHECK(type.get_data_type() == meta::resolve_type()); + CHECK(type.get_flags() == meta::pointer_flags::is_readonly); + CHECK(type.get_data_type() == meta::resolve_type()); } SUBCASE("int**") { @@ -40,14 +42,16 @@ TEST_CASE("meta/meta_types/pointer_type") { REQUIRE(type); CHECK(type.get_id() == meta::resolve_type().get_id()); + CHECK(type.get_flags() == meta::pointer_flags{}); CHECK(type.get_data_type() == meta::resolve_type()); } - SUBCASE("const int** const") { - const meta::pointer_type type = meta::resolve_type(); + SUBCASE("const int* const*") { + const meta::pointer_type type = meta::resolve_type(); REQUIRE(type); - CHECK(type.get_id() == meta::resolve_type().get_id()); + CHECK(type.get_id() == meta::resolve_type().get_id()); + CHECK(type.get_flags() == meta::pointer_flags::is_readonly); CHECK(type.get_data_type() == meta::resolve_type()); } } diff --git a/untests/meta_types/reference_type_tests.cpp b/untests/meta_types/reference_type_tests.cpp index 68a1580..68a15ec 100644 --- a/untests/meta_types/reference_type_tests.cpp +++ b/untests/meta_types/reference_type_tests.cpp @@ -23,9 +23,8 @@ TEST_CASE("meta/meta_types/reference_type") { const meta::reference_type type = meta::resolve_type(); REQUIRE(type); - CHECK(type.get_flags() == (meta::reference_flags::is_lvalue)); - CHECK(type.get_id() == meta::resolve_type().get_id()); + CHECK(type.get_flags() == (meta::reference_flags::is_lvalue)); CHECK(type.get_data_type() == meta::resolve_type()); } @@ -33,19 +32,17 @@ TEST_CASE("meta/meta_types/reference_type") { const meta::reference_type type = meta::resolve_type(); REQUIRE(type); - CHECK(type.get_flags() == (meta::reference_flags::is_readonly | meta::reference_flags::is_lvalue)); - CHECK(type.get_id() == meta::resolve_type().get_id()); - CHECK(type.get_data_type() == meta::resolve_type()); + CHECK(type.get_flags() == (meta::reference_flags::is_readonly | meta::reference_flags::is_lvalue)); + CHECK(type.get_data_type() == meta::resolve_type()); } SUBCASE("int&&") { const meta::reference_type type = meta::resolve_type(); REQUIRE(type); - CHECK(type.get_flags() == (meta::reference_flags::is_rvalue)); - CHECK(type.get_id() == meta::resolve_type().get_id()); + CHECK(type.get_flags() == (meta::reference_flags::is_rvalue)); CHECK(type.get_data_type() == meta::resolve_type()); } @@ -53,9 +50,8 @@ TEST_CASE("meta/meta_types/reference_type") { const meta::reference_type type = meta::resolve_type(); REQUIRE(type); - CHECK(type.get_flags() == (meta::reference_flags::is_readonly | meta::reference_flags::is_rvalue)); - CHECK(type.get_id() == meta::resolve_type().get_id()); - CHECK(type.get_data_type() == meta::resolve_type()); + CHECK(type.get_flags() == (meta::reference_flags::is_readonly | meta::reference_flags::is_rvalue)); + CHECK(type.get_data_type() == meta::resolve_type()); } } diff --git a/untests/meta_types/void_type_tests.cpp b/untests/meta_types/void_type_tests.cpp index b34697c..8fb4104 100644 --- a/untests/meta_types/void_type_tests.cpp +++ b/untests/meta_types/void_type_tests.cpp @@ -24,6 +24,21 @@ TEST_CASE("meta/meta_types/void_type") { REQUIRE(type); CHECK(type.get_id() == meta::resolve_type().get_id()); - CHECK(type.get_flags() == meta::void_flags{}); + } + + SUBCASE("void*") { + void* ptr{}; + const meta::pointer_type ptr_type = meta::resolve_type(ptr); + CHECK(ptr_type == meta::resolve_type()); + CHECK_FALSE(ptr_type.get_flags().has(meta::pointer_flags::is_readonly)); + CHECK(ptr_type.get_data_type() == meta::resolve_type()); + } + + SUBCASE("const void*") { + const void* ptr{}; + const meta::pointer_type ptr_type = meta::resolve_type(ptr); + CHECK(ptr_type == meta::resolve_type()); + CHECK(ptr_type.get_flags().has(meta::pointer_flags::is_readonly)); + CHECK(ptr_type.get_data_type() == meta::resolve_type()); } } From c68c7a87796fa3d10895076602ba7ce497c4fa4b Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sun, 9 Jan 2022 16:28:30 +0700 Subject: [PATCH 165/233] update enum.hpp --- vendors/enum.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendors/enum.hpp b/vendors/enum.hpp index 9e9dc26..2917a83 160000 --- a/vendors/enum.hpp +++ b/vendors/enum.hpp @@ -1 +1 @@ -Subproject commit 9e9dc269238e4f43254282042bc0367b8b5e7aeb +Subproject commit 2917a832dbaf83eb9e3898b066bbd15099664e07 From bdf1462da1e3c291d6e4260dec09f10694425110 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sun, 9 Jan 2022 16:47:23 +0700 Subject: [PATCH 166/233] function and member examples --- manuals/meta_examples/functions_example.cpp | 59 ++++++++++++++++++++- manuals/meta_examples/members_example.cpp | 56 ++++++++++++++++++- 2 files changed, 113 insertions(+), 2 deletions(-) diff --git a/manuals/meta_examples/functions_example.cpp b/manuals/meta_examples/functions_example.cpp index e3bf2d0..4857b39 100644 --- a/manuals/meta_examples/functions_example.cpp +++ b/manuals/meta_examples/functions_example.cpp @@ -8,8 +8,65 @@ namespace { + int add(int a, int b) { + return a + b; + } + + int sub(int a, int b) { + return a - b; + } } -TEST_CASE("meta/meta_examples/functions") { +TEST_CASE("meta/meta_examples/functions/type") { namespace meta = meta_hpp; + + // resolves a function type by pointer + const meta::function_type add_function_type = meta::resolve_type(&add); + + // also, it can be resolved by static function type declaration + CHECK(add_function_type == meta::resolve_type()); + + // checks a return value type + CHECK(add_function_type.get_return_type() == meta::resolve_type()); + + // allows to know an argument count + CHECK(add_function_type.get_arity() == 2); + + // ... and their types + CHECK(add_function_type.get_argument_type(0) == meta::resolve_type()); + CHECK(add_function_type.get_argument_type(1) == meta::resolve_type()); +} + +TEST_CASE("meta/meta_examples/functions/usage") { + namespace meta = meta_hpp; + + // 'math' local scope declaration + const meta::scope math_scope = meta::local_scope_("math") + .function_("add", &add) + .function_("sub", &sub); + + // finds the function by name 'sub' + const meta::function sub_function = math_scope.get_function("sub"); + + // also, we can find it with argument types (for overloaded functions) + CHECK(sub_function == math_scope.get_function_with("sub")); + + // checks a type of the founded function + CHECK(sub_function.get_type() == meta::resolve_type()); + + // checks the ability to call the function with specific parameters + CHECK(sub_function.is_invocable_with(60, 18)); + CHECK(sub_function.is_invocable_with()); + + // calls the function and retrieves a returned value + const meta::value sub_result_value = sub_function.invoke(60, 18).value(); + + // checks the type of the returned value + CHECK(sub_result_value.get_type() == meta::resolve_type()); + + // casts the dynamic returned value to the typed value + const int sub_function_typed_result = sub_result_value.cast(); + + // here is our typed result + CHECK(sub_function_typed_result == 42); } diff --git a/manuals/meta_examples/members_example.cpp b/manuals/meta_examples/members_example.cpp index 40bae32..350a0e3 100644 --- a/manuals/meta_examples/members_example.cpp +++ b/manuals/meta_examples/members_example.cpp @@ -8,8 +8,62 @@ namespace { + struct ivec2 { + int x{}; + int y{}; + }; } -TEST_CASE("meta/meta_examples/members") { +TEST_CASE("meta/meta_examples/members/type") { namespace meta = meta_hpp; + + // 'ivec2' class type registration + meta::class_() + .member_("x", &ivec2::x) + .member_("y", &ivec2::y); + + // resolves a member type by pointer + const meta::member_type x_member_type = meta::resolve_type(&ivec2::x); + + // also, it can be resolved by static member type + CHECK(x_member_type == meta::resolve_type()); + + // allows to know the owner class type + CHECK(x_member_type.get_owner_type() == meta::resolve_type()); + + // ... and the value type of the member + CHECK(x_member_type.get_value_type() == meta::resolve_type()); +} + +TEST_CASE("meta/meta_examples/members/usage") { + namespace meta = meta_hpp; + + ivec2 v{42, 21}; + + // resolves a class type by instance 'v' + const meta::class_type ivec2_type = meta::resolve_type(v); + + // finds the member 'x' by name + const meta::member ivec2_x = ivec2_type.get_member("x"); + + // checks the type of the member 'x' + CHECK(ivec2_x.get_type() == meta::resolve_type()); + + // retrieves a member value of the class instance 'v' + const meta::value ivec2_x_value = ivec2_x.get(v); + + // checks the type of the retrieved value + CHECK(ivec2_x_value.get_type() == meta::resolve_type()); + + // casts the dynamic value to the typed value + const int ivec2_x_typed_value = ivec2_x_value.cast(); + + // here is our member typed value + CHECK(ivec2_x_typed_value == 42); + + // also, we can change the member value, of course + ivec2_x.set(v, 11); + + // checks the result of our manipulations + CHECK(v.x == 11); } From 7f1d512716e07a78d53d301ca238f773a9e28f4a Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sun, 9 Jan 2022 18:03:51 +0700 Subject: [PATCH 167/233] add method example --- TODO.md | 2 + manuals/meta_examples/methods_example.cpp | 67 ++++++++++++++++++++++- 2 files changed, 68 insertions(+), 1 deletion(-) diff --git a/TODO.md b/TODO.md index 4a9ca8b..ebcd278 100644 --- a/TODO.md +++ b/TODO.md @@ -7,3 +7,5 @@ - add conversion of nullptr to any pointers; - add conversion of any pointers to void pointer ( identically cv-qualified ); - add enum_type::create, number_type::create, and so on. +- add return value policy +- add is_invocable_with by dynamic types diff --git a/manuals/meta_examples/methods_example.cpp b/manuals/meta_examples/methods_example.cpp index 1a74e73..ddd4a48 100644 --- a/manuals/meta_examples/methods_example.cpp +++ b/manuals/meta_examples/methods_example.cpp @@ -8,8 +8,73 @@ namespace { + struct ivec2 { + int x{}; + int y{}; + + ivec2& add(const ivec2& other) { + x += other.x; + y += other.y; + return *this; + } + + friend bool operator==(const ivec2& l, const ivec2& r) { + return l.x == r.x && l.y == r.y; + } + }; } -TEST_CASE("meta/meta_examples/methods") { +TEST_CASE("meta/meta_examples/methods/type") { namespace meta = meta_hpp; + + // 'ivec2' class type registration + meta::class_() + .method_("add", &ivec2::add); + + // resolves a method type by pointer + const meta::method_type add_method_type = meta::resolve_type(&ivec2::add); + + // also, it can be resolved by static method type + CHECK(add_method_type == meta::resolve_type()); + + // allows to know the owner class type + CHECK(add_method_type.get_owner_type() == meta::resolve_type()); + + // checks a return value type + CHECK(add_method_type.get_return_type() == meta::resolve_type()); + + // allows to know an argument count + CHECK(add_method_type.get_arity() == 1); + + // ... and their types + CHECK(add_method_type.get_argument_type(0) == meta::resolve_type()); +} + +TEST_CASE("meta/meta_examples/methods/usage") { + namespace meta = meta_hpp; + + ivec2 v{20, 10}; + + // resolves a class type by instance 'v' + const meta::class_type ivec2_type = meta::resolve_type(v); + + // finds the method 'add' by name + const meta::method ivec2_add = ivec2_type.get_method("add"); + + // checks the type of the method 'add' + CHECK(ivec2_add.get_type() == meta::resolve_type()); + + // checks the ability to call the method with specific parameters + CHECK(ivec2_add.is_invocable_with(v, ivec2{22, 11})); + CHECK(ivec2_add.is_invocable_with()); + + // calls the method and retrieves a returned value + const meta::value ivec2_add_result_value = ivec2_add.invoke(v, ivec2{22, 11}).value(); + + // checks the type and value of the result + CHECK(ivec2_add_result_value.get_type() == meta::resolve_type()); + CHECK(ivec2_add_result_value == ivec2{42, 21}); + + // checks the result of our manipulations + CHECK(v == ivec2{42, 21}); } From a09481d9f8ccf98e59bdcf9594bc8f72129ad3cc Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sun, 9 Jan 2022 20:57:36 +0700 Subject: [PATCH 168/233] add enum example --- TODO.md | 1 + manuals/meta_examples/enums_examples.cpp | 46 +++++++++++++++++++++++- manuals/meta_manuals.hpp | 15 ++++++++ 3 files changed, 61 insertions(+), 1 deletion(-) diff --git a/TODO.md b/TODO.md index ebcd278..80cc916 100644 --- a/TODO.md +++ b/TODO.md @@ -9,3 +9,4 @@ - add enum_type::create, number_type::create, and so on. - add return value policy - add is_invocable_with by dynamic types +- add metadata to every type and state diff --git a/manuals/meta_examples/enums_examples.cpp b/manuals/meta_examples/enums_examples.cpp index e1914b3..4885c7b 100644 --- a/manuals/meta_examples/enums_examples.cpp +++ b/manuals/meta_examples/enums_examples.cpp @@ -8,8 +8,52 @@ namespace { + enum class align { + left, + right, + center, + }; } -TEST_CASE("meta/meta_examples/enums") { +TEST_CASE("meta/meta_examples/enums/type") { namespace meta = meta_hpp; + + // 'align' enumeration type registration + meta::enum_() + .evalue_("left", align::left) + .evalue_("right", align::right) + .evalue_("center", align::center); + + // resolves a enumeration type by enumerator + const meta::enum_type align_type = meta::resolve_type(align::left); + + // also, it can be resolved by static enumeration type + CHECK(align_type == meta::resolve_type()); + + // allows to know the underlying type + CHECK(align_type.get_underlying_type() == meta::resolve_type()); + + // prints all enumerators + fmt::print("* align:\n"); + for ( auto&& [index, evalue] : align_type.get_evalues() ) { + fmt::print(" - {} = {}\n", index.name, evalue.get_underlying_value()); + } +} + +TEST_CASE("meta/meta_examples/enums/usage") { + namespace meta = meta_hpp; + + const align e = align::center; + + // resolves a enumeration type by enumerator instance 'e' + const meta::enum_type align_type = meta::resolve_type(e); + + // converts the enumerator to its name + CHECK(align_type.value_to_name(e).value() == "center"); + + // also, it works with dynamic value types + CHECK(align_type.value_to_name(meta::value{e}).value() == "center"); + + // ... and back again + CHECK(align_type.name_to_value("center").value() == e); } diff --git a/manuals/meta_manuals.hpp b/manuals/meta_manuals.hpp index 03493c7..cd7bd26 100644 --- a/manuals/meta_manuals.hpp +++ b/manuals/meta_manuals.hpp @@ -7,5 +7,20 @@ #include #include +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdocumentation-unknown-command" +#pragma clang diagnostic ignored "-Wsigned-enum-bitfield" +#pragma clang diagnostic ignored "-Wswitch-enum" +#pragma clang diagnostic ignored "-Wundefined-func-template" +#endif + +#include +#include + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + #include #include From 11fa954aef8f223f1dcddd3c2deefc3be2aaa138 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sun, 9 Jan 2022 21:27:41 +0700 Subject: [PATCH 169/233] add variable example --- manuals/meta_examples/enums_examples.cpp | 2 +- manuals/meta_examples/functions_example.cpp | 6 ++++ manuals/meta_examples/variables_example.cpp | 34 ++++++++++++++++++++- 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/manuals/meta_examples/enums_examples.cpp b/manuals/meta_examples/enums_examples.cpp index 4885c7b..f5970dc 100644 --- a/manuals/meta_examples/enums_examples.cpp +++ b/manuals/meta_examples/enums_examples.cpp @@ -36,7 +36,7 @@ TEST_CASE("meta/meta_examples/enums/type") { // prints all enumerators fmt::print("* align:\n"); for ( auto&& [index, evalue] : align_type.get_evalues() ) { - fmt::print(" - {} = {}\n", index.name, evalue.get_underlying_value()); + fmt::print(" - {}:{}\n", index.name, evalue.get_underlying_value()); } } diff --git a/manuals/meta_examples/functions_example.cpp b/manuals/meta_examples/functions_example.cpp index 4857b39..b2b08c4 100644 --- a/manuals/meta_examples/functions_example.cpp +++ b/manuals/meta_examples/functions_example.cpp @@ -69,4 +69,10 @@ TEST_CASE("meta/meta_examples/functions/usage") { // here is our typed result CHECK(sub_function_typed_result == 42); + + // prints all functions in the scope + fmt::print("* {}:\n", math_scope.get_name()); + for ( auto&& [index, function] : math_scope.get_functions() ) { + fmt::print(" + {}/{}\n", index.name, function.get_type().get_arity()); + } } diff --git a/manuals/meta_examples/variables_example.cpp b/manuals/meta_examples/variables_example.cpp index 03d8c54..54da4d7 100644 --- a/manuals/meta_examples/variables_example.cpp +++ b/manuals/meta_examples/variables_example.cpp @@ -8,8 +8,40 @@ namespace { + const double pi_v = 3.1415926536; + const double sqrt2_v = 1.4142135624; } -TEST_CASE("meta/meta_examples/variables") { +TEST_CASE("meta/meta_examples/variables/usage") { namespace meta = meta_hpp; + + // 'constants' local scope declaration + const meta::scope constants_scope = meta::local_scope_("constants") + .variable_("pi_v", &pi_v) + .variable_("sqrt2_v", &sqrt2_v); + + // finds the variable by name 'pi_v' + const meta::variable pi_variable = constants_scope.get_variable("pi_v"); + + // checks the type and data type of the founded variable + CHECK(pi_variable.get_type() == meta::resolve_type()); + CHECK(pi_variable.get_type().get_data_type() == meta::resolve_type()); + + // retrieves a variable value + const meta::value pi_variable_value = pi_variable.get(); + + // checks the type of the retrieved value + CHECK(pi_variable_value.get_type() == meta::resolve_type()); + + // checks the typed variable value + CHECK(pi_variable_value.cast() == doctest::Approx(3.14).epsilon(0.01)); + + // we can change variable values, but only non-const + CHECK_THROWS(pi_variable.set(6.0)); + + // prints all variables in the scope + fmt::print("* {}:\n", constants_scope.get_name()); + for ( auto&& [index, variable] : constants_scope.get_variables() ) { + fmt::print(" - {}:{}\n", index.name, variable.get()); + } } From 8125e4cdafe7d84d91b74f15412178037bfaabf7 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Mon, 10 Jan 2022 14:51:18 +0700 Subject: [PATCH 170/233] add value with function pointer tests --- manuals/meta_examples/variables_example.cpp | 4 +- untests/meta_utilities/value_tests.cpp | 47 ++++++++++++++++++--- 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/manuals/meta_examples/variables_example.cpp b/manuals/meta_examples/variables_example.cpp index 54da4d7..87578cf 100644 --- a/manuals/meta_examples/variables_example.cpp +++ b/manuals/meta_examples/variables_example.cpp @@ -8,8 +8,8 @@ namespace { - const double pi_v = 3.1415926536; - const double sqrt2_v = 1.4142135624; + const double pi_v{3.1415926536}; + const double sqrt2_v{1.4142135624}; } TEST_CASE("meta/meta_examples/variables/usage") { diff --git a/untests/meta_utilities/value_tests.cpp b/untests/meta_utilities/value_tests.cpp index 602c13b..3a6b09d 100644 --- a/untests/meta_utilities/value_tests.cpp +++ b/untests/meta_utilities/value_tests.cpp @@ -12,9 +12,9 @@ namespace int x{}; int y{}; - [[maybe_unused]] ivec2() = default; - [[maybe_unused]] explicit ivec2(int v): x{v}, y{v} {} - [[maybe_unused]] ivec2(int x, int y): x{x}, y{y} {} + ivec2() = default; + explicit ivec2(int v): x{v}, y{v} {} + ivec2(int x, int y): x{x}, y{y} {} ivec2(ivec2&& other) noexcept : x{other.x} @@ -40,15 +40,32 @@ namespace int ivec2::move_ctor_counter{0}; int ivec2::copy_ctor_counter{0}; - [[maybe_unused]] bool operator<(const ivec2& l, const ivec2& r) noexcept { + ivec2 iadd2(ivec2 l, ivec2 r) { + return {l.x + r.x, l.y + r.y}; + } + + bool operator<(const ivec2& l, const ivec2& r) noexcept { return (l.x < r.x) || (l.x == r.x && l.y < r.y); } - [[maybe_unused]] bool operator==(const ivec2& l, const ivec2& r) noexcept { + bool operator==(const ivec2& l, const ivec2& r) noexcept { return l.x == r.x && l.y == r.y; } } +TEST_CASE("meta/meta_utilities/value/ivec2") { + namespace meta = meta_hpp; + + meta::class_() + .ctor_<>() + .ctor_() + .ctor_() + .ctor_() + .ctor_() + .member_("x", &ivec2::x) + .member_("y", &ivec2::y); +} + TEST_CASE("meta/meta_utilities/value") { namespace meta = meta_hpp; using namespace std::string_literals; @@ -303,7 +320,8 @@ TEST_CASE("meta/meta_utilities/value") { class empty_class1 {}; class empty_class2 {}; - CHECK((operator<(meta::value{empty_class1{}}, meta::value{empty_class2{}}) || operator<(meta::value{empty_class2{}}, meta::value{empty_class1{}}))); + CHECK((operator<(meta::value{empty_class1{}}, meta::value{empty_class2{}}) + || operator<(meta::value{empty_class2{}}, meta::value{empty_class1{}}))); CHECK_THROWS(std::ignore = operator<(meta::value{empty_class1{}}, meta::value{empty_class1{}})); } } @@ -327,3 +345,20 @@ TEST_CASE("meta/meta_utilities/value") { } } } + +TEST_CASE("meta/meta_utilities/value/functions") { + namespace meta = meta_hpp; + + SUBCASE("iadd2") { + { + const meta::value v{iadd2}; + CHECK(v.get_type() == meta::resolve_type()); + CHECK(v.cast()(ivec2{1,2}, ivec2{3,4}) == ivec2{4,6}); + } + { + const meta::value v{&iadd2}; + CHECK(v.get_type() == meta::resolve_type()); + CHECK(v.cast()(ivec2{1,2}, ivec2{3,4}) == ivec2{4,6}); + } + } +} From 7cfce057d76bc1a30828aea13ec44a5ffe2cbd3a Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Wed, 12 Jan 2022 21:26:07 +0700 Subject: [PATCH 171/233] traits enums fixes --- TODO.md | 2 ++ headers/meta.hpp/meta_traits.hpp | 22 +++++++++++----------- manuals/.clang-tidy | 2 ++ untests/.clang-tidy | 2 ++ 4 files changed, 17 insertions(+), 11 deletions(-) diff --git a/TODO.md b/TODO.md index 80cc916..8e27475 100644 --- a/TODO.md +++ b/TODO.md @@ -10,3 +10,5 @@ - add return value policy - add is_invocable_with by dynamic types - add metadata to every type and state +- add integral implicit conversions +- add meta::invoke function diff --git a/headers/meta.hpp/meta_traits.hpp b/headers/meta.hpp/meta_traits.hpp index d2cd0db..41db8dc 100644 --- a/headers/meta.hpp/meta_traits.hpp +++ b/headers/meta.hpp/meta_traits.hpp @@ -53,11 +53,11 @@ namespace meta_hpp }; enum class class_flags : std::uint32_t { - is_empty = 1 << 1, - is_final = 1 << 2, - is_abstract = 1 << 3, - is_polymorphic = 1 << 4, - is_template_instantiation = 1 << 5, + is_empty = 1 << 0, + is_final = 1 << 1, + is_abstract = 1 << 2, + is_polymorphic = 1 << 3, + is_template_instantiation = 1 << 4, }; enum class ctor_flags : std::uint32_t { @@ -79,15 +79,15 @@ namespace meta_hpp enum class method_flags : std::uint32_t { is_const = 1 << 0, is_noexcept = 1 << 1, - is_lvalue_qualified = 1 << 3, - is_rvalue_qualified = 1 << 4, + is_lvalue_qualified = 1 << 2, + is_rvalue_qualified = 1 << 3, }; enum class number_flags : std::uint32_t { - is_signed = 1 << 1, - is_unsigned = 1 << 2, - is_integral = 1 << 3, - is_floating_point = 1 << 4, + is_signed = 1 << 0, + is_unsigned = 1 << 1, + is_integral = 1 << 2, + is_floating_point = 1 << 3, }; enum class pointer_flags : std::uint32_t { diff --git a/manuals/.clang-tidy b/manuals/.clang-tidy index 13fda4f..7f0ca8e 100644 --- a/manuals/.clang-tidy +++ b/manuals/.clang-tidy @@ -9,6 +9,8 @@ Checks: '-*, -cppcoreguidelines-avoid-c-arrays, -cppcoreguidelines-avoid-magic-numbers, -cppcoreguidelines-avoid-non-const-global-variables, + -cppcoreguidelines-pro-bounds-array-to-pointer-decay, + -cppcoreguidelines-pro-bounds-pointer-arithmetic, -cppcoreguidelines-special-member-functions, modernize-*, diff --git a/untests/.clang-tidy b/untests/.clang-tidy index 13fda4f..7f0ca8e 100644 --- a/untests/.clang-tidy +++ b/untests/.clang-tidy @@ -9,6 +9,8 @@ Checks: '-*, -cppcoreguidelines-avoid-c-arrays, -cppcoreguidelines-avoid-magic-numbers, -cppcoreguidelines-avoid-non-const-global-variables, + -cppcoreguidelines-pro-bounds-array-to-pointer-decay, + -cppcoreguidelines-pro-bounds-pointer-arithmetic, -cppcoreguidelines-special-member-functions, modernize-*, From c277dbfc1c4ac6a334e0721ecc4deba321a853f8 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 14 Jan 2022 07:14:28 +0700 Subject: [PATCH 172/233] array arg support --- headers/meta.hpp/meta_utilities/arg.hpp | 36 +++ manuals/meta_examples/arrays_example.cpp | 15 -- manuals/meta_examples/numbers_example.cpp | 15 -- untests/meta_states/function_tests.cpp | 127 ++++++++++- untests/meta_types/function_type_tests.cpp | 53 +++++ untests/meta_utilities/arg5_tests.cpp | 254 +++++++++++++++++++++ 6 files changed, 469 insertions(+), 31 deletions(-) delete mode 100644 manuals/meta_examples/arrays_example.cpp delete mode 100644 manuals/meta_examples/numbers_example.cpp create mode 100644 untests/meta_utilities/arg5_tests.cpp diff --git a/headers/meta.hpp/meta_utilities/arg.hpp b/headers/meta.hpp/meta_utilities/arg.hpp index b987134..9e30664 100644 --- a/headers/meta.hpp/meta_utilities/arg.hpp +++ b/headers/meta.hpp/meta_utilities/arg.hpp @@ -87,6 +87,21 @@ namespace meta_hpp::detail }; if constexpr ( std::is_pointer_v ) { + if ( to_type.is_pointer() && from_type.is_array() ) { + const pointer_type& to_type_ptr = to_type.as_pointer(); + const bool to_type_ptr_readonly = to_type_ptr.get_flags().has(pointer_flags::is_readonly); + + const array_type& from_type_array = from_type.as_array(); + const bool from_type_array_readonly = is_const(); + + const any_type& to_data_type = to_type_ptr.get_data_type(); + const any_type& from_data_type = from_type_array.get_data_type(); + + if ( is_a(to_data_type, from_data_type) && to_type_ptr_readonly >= from_type_array_readonly ) { + return true; + } + } + if ( to_type.is_pointer() && from_type.is_pointer() ) { const pointer_type& to_type_ptr = to_type.as_pointer(); const bool to_type_ptr_readonly = to_type_ptr.get_flags().has(pointer_flags::is_readonly); @@ -177,6 +192,27 @@ namespace meta_hpp::detail const any_type& to_type = resolve_type(); if constexpr ( std::is_pointer_v ) { + if ( to_type.is_pointer() && from_type.is_array() ) { + const pointer_type& to_type_ptr = to_type.as_pointer(); + const array_type& from_type_array = from_type.as_array(); + + const any_type& to_data_type = to_type_ptr.get_data_type(); + const any_type& from_data_type = from_type_array.get_data_type(); + + if ( to_data_type == from_data_type ) { + void* to_ptr = static_cast(data_); + return static_cast(to_ptr); + } + + if ( to_data_type.is_class() && from_data_type.is_class() ) { + const class_type& to_data_class = to_data_type.as_class(); + const class_type& from_data_class = from_data_type.as_class(); + + void* to_ptr = detail::pointer_upcast(data_, from_data_class, to_data_class); + return static_cast(to_ptr); + } + } + if ( to_type.is_pointer() && from_type.is_pointer() ) { const pointer_type& to_type_ptr = to_type.as_pointer(); const pointer_type& from_type_ptr = from_type.as_pointer(); diff --git a/manuals/meta_examples/arrays_example.cpp b/manuals/meta_examples/arrays_example.cpp deleted file mode 100644 index 7c28b8b..0000000 --- a/manuals/meta_examples/arrays_example.cpp +++ /dev/null @@ -1,15 +0,0 @@ -/******************************************************************************* - * 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_manuals.hpp" - -namespace -{ -} - -TEST_CASE("meta/meta_examples/arrays") { - namespace meta = meta_hpp; -} diff --git a/manuals/meta_examples/numbers_example.cpp b/manuals/meta_examples/numbers_example.cpp deleted file mode 100644 index dc0c989..0000000 --- a/manuals/meta_examples/numbers_example.cpp +++ /dev/null @@ -1,15 +0,0 @@ -/******************************************************************************* - * 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_manuals.hpp" - -namespace -{ -} - -TEST_CASE("meta/meta_examples/numbers") { - namespace meta = meta_hpp; -} diff --git a/untests/meta_states/function_tests.cpp b/untests/meta_states/function_tests.cpp index aeb30ea..449e1d8 100644 --- a/untests/meta_states/function_tests.cpp +++ b/untests/meta_states/function_tests.cpp @@ -19,6 +19,11 @@ namespace static int ilength2(const ivec2& v) noexcept { return v.x * v.x + v.y * v.y; } + + static int arg_bounded_arr(ivec2 vs[2]) { return vs[0].x + vs[0].y + vs[1].x + vs[1].y; } + static int arg_unbounded_arr(ivec2 vs[]) { return vs[0].x + vs[0].y + vs[1].x + vs[1].y; } + static int arg_bounded_const_arr(const ivec2 vs[2]) { return vs[0].x + vs[0].y + vs[1].x + vs[1].y; } + static int arg_unbounded_const_arr(const ivec2 vs[]) { return vs[0].x + vs[0].y + vs[1].x + vs[1].y; } }; bool operator==(const ivec2& l, const ivec2& r) noexcept { @@ -31,7 +36,11 @@ TEST_CASE("meta/meta_states/function") { meta::class_() .function_("iadd", &ivec2::iadd) - .function_("ilength2", &ivec2::ilength2); + .function_("ilength2", &ivec2::ilength2) + .function_("arg_bounded_arr", &ivec2::arg_bounded_arr) + .function_("arg_unbounded_arr", &ivec2::arg_unbounded_arr) + .function_("arg_bounded_const_arr", &ivec2::arg_bounded_const_arr) + .function_("arg_unbounded_const_arr", &ivec2::arg_unbounded_const_arr); const meta::class_type ivec2_type = meta::resolve_type(); REQUIRE(ivec2_type); @@ -104,4 +113,120 @@ TEST_CASE("meta/meta_states/function") { CHECK(func.invoke(ivec2{2,3})); CHECK(func.invoke(ivec2{2,3}).value() == 13); } + + SUBCASE("arg_arr") { + ivec2 bounded_arr[2]{{1,2},{3,4}}; + ivec2* unbounded_arr = bounded_arr; + + const ivec2 bounded_const_arr[2]{{1,2},{3,4}}; + const ivec2* unbounded_const_arr = bounded_const_arr; + + { + const meta::function func1 = ivec2_type.get_function("arg_bounded_arr"); + REQUIRE(func1); + + CHECK(func1.is_invocable_with()); + CHECK(func1.is_invocable_with()); + CHECK_FALSE(func1.is_invocable_with()); + CHECK_FALSE(func1.is_invocable_with()); + + CHECK(func1.invoke(bounded_arr) == 10); + CHECK(func1.invoke(unbounded_arr) == 10); + CHECK_THROWS(func1.invoke(bounded_const_arr)); + CHECK_THROWS(func1.invoke(unbounded_const_arr)); + + CHECK(func1.invoke(meta::value{bounded_arr}) == 10); + CHECK(func1.invoke(meta::value{unbounded_arr}) == 10); + CHECK_THROWS(func1.invoke(meta::value{bounded_const_arr})); + CHECK_THROWS(func1.invoke(meta::value{unbounded_const_arr})); + + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); + } + + { + const meta::function func2 = ivec2_type.get_function("arg_unbounded_arr"); + REQUIRE(func2); + + CHECK(func2.is_invocable_with()); + CHECK(func2.is_invocable_with()); + CHECK_FALSE(func2.is_invocable_with()); + CHECK_FALSE(func2.is_invocable_with()); + + CHECK(func2.invoke(bounded_arr) == 10); + CHECK(func2.invoke(unbounded_arr) == 10); + CHECK_THROWS(func2.invoke(bounded_const_arr)); + CHECK_THROWS(func2.invoke(unbounded_const_arr)); + + CHECK(func2.invoke(meta::value{bounded_arr}) == 10); + CHECK(func2.invoke(meta::value{unbounded_arr}) == 10); + CHECK_THROWS(func2.invoke(meta::value{bounded_const_arr})); + CHECK_THROWS(func2.invoke(meta::value{unbounded_const_arr})); + + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); + } + } + + SUBCASE("arg_const_arr") { + ivec2 bounded_arr[2]{{1,2},{3,4}}; + ivec2* unbounded_arr = bounded_arr; + + const ivec2 bounded_const_arr[2]{{1,2},{3,4}}; + const ivec2* unbounded_const_arr = bounded_const_arr; + + { + const meta::function func1 = ivec2_type.get_function("arg_bounded_const_arr"); + REQUIRE(func1); + + CHECK(func1.is_invocable_with()); + CHECK(func1.is_invocable_with()); + CHECK(func1.is_invocable_with()); + CHECK(func1.is_invocable_with()); + + CHECK(func1.invoke(bounded_arr) == 10); + CHECK(func1.invoke(unbounded_arr) == 10); + CHECK(func1.invoke(bounded_const_arr) == 10); + CHECK(func1.invoke(unbounded_const_arr) == 10); + + CHECK(func1.invoke(meta::value{bounded_arr}) == 10); + CHECK(func1.invoke(meta::value{unbounded_arr}) == 10); + CHECK(func1.invoke(meta::value{bounded_const_arr}) == 10); + CHECK(func1.invoke(meta::value{unbounded_const_arr}) == 10); + + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + } + + { + const meta::function func2 = ivec2_type.get_function("arg_unbounded_const_arr"); + REQUIRE(func2); + + CHECK(func2.is_invocable_with()); + CHECK(func2.is_invocable_with()); + CHECK(func2.is_invocable_with()); + CHECK(func2.is_invocable_with()); + + CHECK(func2.invoke(bounded_arr) == 10); + CHECK(func2.invoke(unbounded_arr) == 10); + CHECK(func2.invoke(bounded_const_arr) == 10); + CHECK(func2.invoke(unbounded_const_arr) == 10); + + CHECK(func2.invoke(meta::value{bounded_arr}) == 10); + CHECK(func2.invoke(meta::value{unbounded_arr}) == 10); + CHECK(func2.invoke(meta::value{bounded_const_arr}) == 10); + CHECK(func2.invoke(meta::value{unbounded_const_arr}) == 10); + + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + } + } } diff --git a/untests/meta_types/function_type_tests.cpp b/untests/meta_types/function_type_tests.cpp index 71562fb..9d02c58 100644 --- a/untests/meta_types/function_type_tests.cpp +++ b/untests/meta_types/function_type_tests.cpp @@ -16,6 +16,11 @@ namespace void arg_copy(ivec2) {} void arg_ref_noexcept(ivec2&) noexcept {} void arg_cref_noexcept(const ivec2&) noexcept {} + + void arg_bounded_arr(ivec2[2]) {} + void arg_unbounded_arr(ivec2[]) {} + void arg_bounded_const_arr(const ivec2[2]) {} + void arg_unbounded_const_arr(const ivec2[]) {} } TEST_CASE("meta/meta_types/function_type") { @@ -65,4 +70,52 @@ TEST_CASE("meta/meta_types/function_type") { CHECK(type.get_argument_type(0) == meta::resolve_type()); CHECK_FALSE(type.get_argument_type(1)); } + + SUBCASE("arg_bounded_arr") { + const meta::function_type type = meta::resolve_type(&arg_bounded_arr); + REQUIRE(type); + + CHECK(type.get_id() == meta::resolve_type(&arg_bounded_arr).get_id()); + CHECK(type.get_flags() == meta::function_flags{}); + CHECK(type.get_argument_types() == std::vector{meta::resolve_type()}); + + CHECK(type.get_argument_type(0) == meta::resolve_type()); + CHECK_FALSE(type.get_argument_type(1)); + } + + SUBCASE("arg_unbounded_arr") { + const meta::function_type type = meta::resolve_type(&arg_unbounded_arr); + REQUIRE(type); + + CHECK(type.get_id() == meta::resolve_type(&arg_unbounded_arr).get_id()); + CHECK(type.get_flags() == meta::function_flags{}); + CHECK(type.get_argument_types() == std::vector{meta::resolve_type()}); + + CHECK(type.get_argument_type(0) == meta::resolve_type()); + CHECK_FALSE(type.get_argument_type(1)); + } + + SUBCASE("arg_bounded_const_arr") { + const meta::function_type type = meta::resolve_type(&arg_bounded_const_arr); + REQUIRE(type); + + CHECK(type.get_id() == meta::resolve_type(&arg_bounded_const_arr).get_id()); + CHECK(type.get_flags() == meta::function_flags{}); + CHECK(type.get_argument_types() == std::vector{meta::resolve_type()}); + + CHECK(type.get_argument_type(0) == meta::resolve_type()); + CHECK_FALSE(type.get_argument_type(1)); + } + + SUBCASE("arg_unbounded_const_arr") { + const meta::function_type type = meta::resolve_type(&arg_unbounded_const_arr); + REQUIRE(type); + + CHECK(type.get_id() == meta::resolve_type(&arg_unbounded_const_arr).get_id()); + CHECK(type.get_flags() == meta::function_flags{}); + CHECK(type.get_argument_types() == std::vector{meta::resolve_type()}); + + CHECK(type.get_argument_type(0) == meta::resolve_type()); + CHECK_FALSE(type.get_argument_type(1)); + } } diff --git a/untests/meta_utilities/arg5_tests.cpp b/untests/meta_utilities/arg5_tests.cpp new file mode 100644 index 0000000..3275e88 --- /dev/null +++ b/untests/meta_utilities/arg5_tests.cpp @@ -0,0 +1,254 @@ +/******************************************************************************* + * 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 A { + A() = default; + virtual ~A() = default; + + A(A&&) = delete; + A(const A&) = delete; + A& operator=(A&&) = delete; + A& operator=(const A&) = delete; + + int i = 1; + }; + + struct B : virtual A { + int i = 2; + }; + + struct C : virtual A { + int i = 3; + }; + + struct D : B, C { + int i = 4; + }; +} + +TEST_CASE("meta/meta_utilities/arg5") { + namespace meta = meta_hpp; + + // * <- B <- * + // A D + // * <- C <- * + + meta::class_(); + meta::class_().base_(); + meta::class_().base_(); + meta::class_().base_().base_(); +} + +TEST_CASE("meta/meta_utilities/arg5/cast") { + namespace meta = meta_hpp; + using meta::detail::arg; + + SUBCASE("int[2]") { + int arr[2]{1,2}; + CHECK(arg(arr).get_raw_type() == meta::resolve_type(arr)); + + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + + CHECK(arg(arr).can_cast_to()); + CHECK(arg(arr).can_cast_to()); + CHECK(arg(arr).can_cast_to()); + CHECK(arg(arr).can_cast_to()); + + CHECK(arg(arr).cast() == static_cast(arr)); + CHECK(arg(arr).cast() == static_cast(arr)); + CHECK(arg(arr).cast() == static_cast(arr)); + CHECK(arg(arr).cast() == static_cast(arr)); + } + + SUBCASE("const int[2]") { + const int arr[2]{1,2}; + CHECK(arg(arr).get_raw_type() == meta::resolve_type(arr)); + + static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); + + CHECK_FALSE(arg(arr).can_cast_to()); + CHECK(arg(arr).can_cast_to()); + CHECK_FALSE(arg(arr).can_cast_to()); + CHECK(arg(arr).can_cast_to()); + + CHECK_THROWS(std::ignore = arg(arr).cast()); + CHECK(arg(arr).cast() == static_cast(arr)); + CHECK_THROWS(std::ignore = arg(arr).cast()); + CHECK(arg(arr).cast() == static_cast(arr)); + } + + SUBCASE("D[2]") { + D arr[2]; + CHECK(arg(arr).get_raw_type() == meta::resolve_type(arr)); + + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + + CHECK(arg(arr).can_cast_to()); + CHECK(arg(arr).can_cast_to()); + CHECK(arg(arr).can_cast_to()); + CHECK(arg(arr).can_cast_to()); + + CHECK(arg(arr).cast() == static_cast(arr)); + CHECK(arg(arr).cast() == static_cast(arr)); + CHECK(arg(arr).cast() == static_cast(arr)); + CHECK(arg(arr).cast() == static_cast(arr)); + } + + SUBCASE("const D[2]") { + const D arr[2]; + CHECK(arg(arr).get_raw_type() == meta::resolve_type(arr)); + + static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); + + CHECK_FALSE(arg(arr).can_cast_to()); + CHECK(arg(arr).can_cast_to()); + CHECK_FALSE(arg(arr).can_cast_to()); + CHECK(arg(arr).can_cast_to()); + + CHECK_THROWS(std::ignore = arg(arr).cast()); + CHECK(arg(arr).cast() == static_cast(arr)); + CHECK_THROWS(std::ignore = arg(arr).cast()); + CHECK(arg(arr).cast() == static_cast(arr)); + } + + SUBCASE("&") { + using T = D[2]; + static T src{}; + + { + auto LV = []() -> T& { return src; }; + CHECK(arg{LV()}.get_raw_type() == meta::resolve_type()); + + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + + CHECK_NOTHROW([](A*){}(LV())); + CHECK_NOTHROW([](const A*){}(LV())); + CHECK_NOTHROW([](A* const){}(LV())); + CHECK_NOTHROW([](const A* const){}(LV())); + + CHECK(arg(LV()).cast() == static_cast(src)); + CHECK(arg(LV()).cast() == static_cast(src)); + CHECK(arg(LV()).cast() == static_cast(src)); + CHECK(arg(LV()).cast() == static_cast(src)); + } + + { + auto CLV = []() -> const T& { return src; }; + CHECK(arg{CLV()}.get_raw_type() == meta::resolve_type()); + + static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); + + CHECK_THROWS(std::ignore = arg(CLV()).cast()); + CHECK(arg(CLV()).cast() == static_cast(src)); + CHECK_THROWS(std::ignore = arg(CLV()).cast()); + CHECK(arg(CLV()).cast() == static_cast(src)); + } + + { + auto XV = []() -> T&& { return std::move(src); }; + CHECK(arg{XV()}.get_raw_type() == meta::resolve_type()); + + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + + CHECK(arg(XV()).cast() == static_cast(src)); + CHECK(arg(XV()).cast() == static_cast(src)); + CHECK(arg(XV()).cast() == static_cast(src)); + CHECK(arg(XV()).cast() == static_cast(src)); + } + + { + auto CXV = []() -> const T&& { return std::move(src); }; + CHECK(arg{CXV()}.get_raw_type() == meta::resolve_type()); + + static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); + + CHECK_THROWS(std::ignore = arg(CXV()).cast()); + CHECK(arg(CXV()).cast() == static_cast(src)); + CHECK_THROWS(std::ignore = arg(CXV()).cast()); + CHECK(arg(CXV()).cast() == static_cast(src)); + } + } + + SUBCASE("*") { + { + static D arr[2]{}; + + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + + CHECK(arg{arr}.can_cast_to()); + CHECK(arg{arr}.can_cast_to()); + CHECK(arg{&arr}.can_cast_to()); + CHECK(arg{&arr}.can_cast_to()); + CHECK(arg{&arr}.can_cast_to()); + CHECK(arg{&arr}.can_cast_to()); + + CHECK(&arg{arr}.cast() == &arr); + CHECK(&arg{arr}.cast() == &arr); + CHECK(arg{&arr}.cast() == &arr); + CHECK(arg{&arr}.cast() == &arr); + CHECK(arg{&arr}.cast() == &arr); + CHECK(arg{&arr}.cast() == &arr); + } + + { + static const D arr[2]{}; + + static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); + + CHECK_FALSE(arg{arr}.can_cast_to()); + CHECK(arg{arr}.can_cast_to()); + CHECK_FALSE(arg{&arr}.can_cast_to()); + CHECK(arg{&arr}.can_cast_to()); + CHECK_FALSE(arg{&arr}.can_cast_to()); + CHECK(arg{&arr}.can_cast_to()); + + CHECK_THROWS(std::ignore = &arg{arr}.cast()); + CHECK(&arg{arr}.cast() == &arr); + CHECK_THROWS(std::ignore = arg{&arr}.cast()); + CHECK(arg{&arr}.cast() == &arr); + CHECK_THROWS(std::ignore = arg{&arr}.cast()); + CHECK(arg{&arr}.cast() == &arr); + } + } +} From 0a1303e2151e1f2f892a9aa313dea015f40a943f Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 14 Jan 2022 10:44:57 +0700 Subject: [PATCH 173/233] check class member pointers arg --- headers/meta.hpp/meta_utilities/arg.hpp | 16 +++--- untests/meta_states/method_tests.cpp | 48 +++++++++++++++-- untests/meta_utilities/arg6_tests.cpp | 72 +++++++++++++++++++++++++ 3 files changed, 122 insertions(+), 14 deletions(-) create mode 100644 untests/meta_utilities/arg6_tests.cpp diff --git a/headers/meta.hpp/meta_utilities/arg.hpp b/headers/meta.hpp/meta_utilities/arg.hpp index 9e30664..529c24e 100644 --- a/headers/meta.hpp/meta_utilities/arg.hpp +++ b/headers/meta.hpp/meta_utilities/arg.hpp @@ -200,8 +200,7 @@ namespace meta_hpp::detail const any_type& from_data_type = from_type_array.get_data_type(); if ( to_data_type == from_data_type ) { - void* to_ptr = static_cast(data_); - return static_cast(to_ptr); + return static_cast(data_); } if ( to_data_type.is_class() && from_data_type.is_class() ) { @@ -223,30 +222,27 @@ namespace meta_hpp::detail void** from_data_ptr = static_cast(data_); if ( to_data_type == from_data_type ) { - void* to_data_ptr = *from_data_ptr; - return static_cast(to_data_ptr); + return static_cast(*from_data_ptr); } if ( to_data_type.is_class() && from_data_type.is_class() ) { const class_type& to_data_class = to_data_type.as_class(); const class_type& from_data_class = from_data_type.as_class(); - void* to_data_ptr = detail::pointer_upcast(*from_data_ptr, from_data_class, to_data_class); - return static_cast(to_data_ptr); + void* to_ptr = detail::pointer_upcast(*from_data_ptr, from_data_class, to_data_class); + return static_cast(to_ptr); } } } if constexpr ( std::is_reference_v ) { if ( to_type == from_type ) { - void* to_ptr = static_cast(data_); - if constexpr ( std::is_lvalue_reference_v ) { - return *static_cast(to_ptr); + return *static_cast(data_); } if constexpr ( std::is_rvalue_reference_v ) { - return std::move(*static_cast(to_ptr)); + return std::move(*static_cast(data_)); } } diff --git a/untests/meta_states/method_tests.cpp b/untests/meta_states/method_tests.cpp index 7ab50c6..884a049 100644 --- a/untests/meta_states/method_tests.cpp +++ b/untests/meta_states/method_tests.cpp @@ -8,7 +8,12 @@ namespace { - struct clazz { + struct base { + virtual ~base() = default; + virtual int pure_virtual_method() = 0; + }; + + struct clazz : base { clazz() = default; clazz(clazz&&) = delete; @@ -36,10 +41,14 @@ namespace int const_method_rref() const && { return 11; } int const_method_noexcept_rref() const && noexcept { return 12; } + + // + + int pure_virtual_method() override { return -1; } }; struct derived_clazz : clazz { - [[maybe_unused]] derived_clazz() = default; + int pure_virtual_method() override { return -2; } }; struct clazz2 {}; @@ -48,10 +57,12 @@ namespace TEST_CASE("meta/meta_states/method") { namespace meta = meta_hpp; - meta::class_() - .base_(); + meta::class_() + .method_("pure_virtual_method", &base::pure_virtual_method); meta::class_() + .base_() + .method_("non_const_method", &clazz::non_const_method) .method_("non_const_method_noexcept", &clazz::non_const_method_noexcept) @@ -70,6 +81,9 @@ TEST_CASE("meta/meta_states/method") { .method_("const_method_rref", &clazz::const_method_rref) .method_("const_method_noexcept_rref", &clazz::const_method_noexcept_rref); + meta::class_() + .base_(); + const meta::class_type ct = meta::resolve_type(); REQUIRE(ct); @@ -627,4 +641,30 @@ TEST_CASE("meta/meta_states/method") { static_assert(std::is_invocable_v); static_assert(std::is_invocable_v); } + + SUBCASE("pure_virtual_method") { + const meta::method mi = ct.get_method("pure_virtual_method"); + REQUIRE(mi); + + CHECK(mi.get_name() == "pure_virtual_method"); + + { + CHECK(mi.get_type().get_arity() == 0); + CHECK(mi.get_type().get_owner_type() == meta::resolve_type()); + CHECK(mi.get_type().get_return_type() == meta::resolve_type()); + CHECK(mi.get_type().get_flags() == meta::method_flags{}); + } + + { + clazz cl; + CHECK(mi.is_invocable_with()); + CHECK(mi.invoke(cl) == -1); + } + + { + derived_clazz dcl; + CHECK(mi.is_invocable_with()); + CHECK(mi.invoke(dcl) == -2); + } + } } diff --git a/untests/meta_utilities/arg6_tests.cpp b/untests/meta_utilities/arg6_tests.cpp new file mode 100644 index 0000000..25ea23f --- /dev/null +++ b/untests/meta_utilities/arg6_tests.cpp @@ -0,0 +1,72 @@ +/******************************************************************************* + * 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 base { + virtual ~base() = default; + virtual int int_method() const = 0; + }; + + struct clazz : base { + int int_member{42}; + int int_method() const override { return int_member; } + }; + + using int_member_t = int clazz::*; + using int_method_t = int (clazz::*)() const; + + int func_with_member(const clazz& cl, int_member_t m) { + return std::invoke(m, cl); + } + + int func_with_method(const clazz& cl, int_method_t m) { + return std::invoke(m, cl); + } +} + +TEST_CASE("meta/meta_utilities/arg6") { + namespace meta = meta_hpp; + using meta::detail::arg; + + const meta::scope scope = meta::local_scope_("scope") + .function_("func_with_member", &func_with_member) + .function_("func_with_method", &func_with_method); + + SUBCASE("int_member") { + static_assert(sizeof(int_member_t) == 8); + + const meta::function f = scope.get_function("func_with_member"); + REQUIRE(f); + + clazz cl; + CHECK(f.is_invocable_with()); + + CHECK(f.is_invocable_with(cl, &clazz::int_member)); + CHECK(f.invoke(cl, &clazz::int_member) == 42); + + CHECK(f.is_invocable_with(meta::value{cl}, meta::value{&clazz::int_member})); + CHECK(f.invoke(meta::value{cl}, meta::value{&clazz::int_member}) == 42); + } + + SUBCASE("int_method") { + static_assert(sizeof(int_method_t) == 16); + + const meta::function f = scope.get_function("func_with_method"); + REQUIRE(f); + + clazz cl; + CHECK(f.is_invocable_with()); + + CHECK(f.is_invocable_with(cl, &clazz::int_method)); + CHECK(f.invoke(cl, &clazz::int_method) == 42); + + CHECK(f.is_invocable_with(meta::value{cl}, meta::value{&clazz::int_method})); + CHECK(f.invoke(meta::value{cl}, meta::value{&clazz::int_method}) == 42); + } +} From ef5b04add062722c33d16aada2df03ff0238a272 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 14 Jan 2022 17:28:33 +0700 Subject: [PATCH 174/233] universal meta::invoke --- headers/meta.hpp/meta_all.hpp | 1 + headers/meta.hpp/meta_states.hpp | 12 +- headers/meta.hpp/meta_states/ctor.hpp | 20 +-- headers/meta.hpp/meta_states/function.hpp | 24 +-- headers/meta.hpp/meta_states/member.hpp | 70 ++++---- headers/meta.hpp/meta_states/method.hpp | 33 ++-- headers/meta.hpp/meta_states/variable.hpp | 9 +- headers/meta.hpp/meta_utilities.hpp | 12 ++ headers/meta.hpp/meta_utilities/arg.hpp | 12 +- headers/meta.hpp/meta_utilities/inst.hpp | 12 +- headers/meta.hpp/meta_utilities/vinvoke.hpp | 170 ++++++++++++++++++++ untests/meta_utilities/arg6_tests.cpp | 4 - untests/meta_utilities/invoke_tests.cpp | 85 ++++++++++ 13 files changed, 383 insertions(+), 81 deletions(-) create mode 100644 headers/meta.hpp/meta_utilities/vinvoke.hpp create mode 100644 untests/meta_utilities/invoke_tests.cpp diff --git a/headers/meta.hpp/meta_all.hpp b/headers/meta.hpp/meta_all.hpp index cf67b10..5fca320 100644 --- a/headers/meta.hpp/meta_all.hpp +++ b/headers/meta.hpp/meta_all.hpp @@ -54,3 +54,4 @@ #include "meta_utilities/arg.hpp" #include "meta_utilities/inst.hpp" #include "meta_utilities/value.hpp" +#include "meta_utilities/vinvoke.hpp" diff --git a/headers/meta.hpp/meta_states.hpp b/headers/meta.hpp/meta_states.hpp index ff4daea..8af4685 100644 --- a/headers/meta.hpp/meta_states.hpp +++ b/headers/meta.hpp/meta_states.hpp @@ -260,8 +260,8 @@ namespace meta_hpp namespace meta_hpp::detail { struct ctor_state final { - using invoke_impl = std::function)>; - using is_invocable_with_impl = std::function)>; + using invoke_impl = std::function)>; + using is_invocable_with_impl = std::function)>; const ctor_index index; const invoke_impl invoke; @@ -287,8 +287,8 @@ namespace meta_hpp::detail }; struct function_state final { - using invoke_impl = std::function(std::span)>; - using is_invocable_with_impl = std::function)>; + using invoke_impl = std::function(std::span)>; + using is_invocable_with_impl = std::function)>; const function_index index; const invoke_impl invoke; @@ -322,8 +322,8 @@ namespace meta_hpp::detail }; struct method_state final { - using invoke_impl = std::function(const inst&, std::span)>; - using is_invocable_with_impl = std::function)>; + using invoke_impl = std::function(const inst&, std::span)>; + using is_invocable_with_impl = std::function)>; const method_index index; const invoke_impl invoke; diff --git a/headers/meta.hpp/meta_states/ctor.hpp b/headers/meta.hpp/meta_states/ctor.hpp index e501499..203695c 100644 --- a/headers/meta.hpp/meta_states/ctor.hpp +++ b/headers/meta.hpp/meta_states/ctor.hpp @@ -14,7 +14,7 @@ namespace meta_hpp::detail { template < class_kind Class, typename... Args > - value raw_ctor_invoke(std::span args) { + value vargs_invoke(std::span args) { using ct = ctor_traits; using class_type = typename ct::class_type; using argument_types = typename ct::argument_types; @@ -35,7 +35,7 @@ namespace meta_hpp::detail } template < class_kind Class, typename... Args > - bool raw_ctor_is_invocable_with(std::span args) { + bool vargs_is_invocable_with(std::span args) { using ct = ctor_traits; using argument_types = typename ct::argument_types; @@ -55,13 +55,13 @@ namespace meta_hpp::detail template < class_kind Class, typename... Args > ctor_state::invoke_impl make_ctor_invoke() { using namespace std::placeholders; - return std::bind(&raw_ctor_invoke, _1); + return std::bind(&vargs_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(&raw_ctor_is_invocable_with, _1); + return std::bind(&vargs_is_invocable_with, _1); } } @@ -104,9 +104,9 @@ namespace meta_hpp template < typename... Args > value ctor::invoke(Args&&... args) const { - using namespace detail; if constexpr ( sizeof...(Args) > 0 ) { - std::array vargs{arg{std::forward(args)}...}; + using namespace detail; + const std::array vargs{arg{std::forward(args)}...}; return state_->invoke(vargs); } else { return state_->invoke({}); @@ -120,9 +120,9 @@ namespace meta_hpp template < typename... Args > bool ctor::is_invocable_with() const noexcept { - using namespace detail; if constexpr ( sizeof...(Args) > 0 ) { - std::array vargs{arg_base{type_list{}}...}; + using namespace detail; + const std::array vargs{arg_base{type_list{}}...}; return state_->is_invocable_with(vargs); } else { return state_->is_invocable_with({}); @@ -131,9 +131,9 @@ namespace meta_hpp template < typename... Args > bool ctor::is_invocable_with(Args&&... args) const noexcept { - using namespace detail; if constexpr ( sizeof...(Args) > 0 ) { - std::array vargs{arg{std::forward(args)}...}; + using namespace detail; + const std::array vargs{arg_base{std::forward(args)}...}; return state_->is_invocable_with(vargs); } else { return state_->is_invocable_with({}); diff --git a/headers/meta.hpp/meta_states/function.hpp b/headers/meta.hpp/meta_states/function.hpp index f1efd24..02447a8 100644 --- a/headers/meta.hpp/meta_states/function.hpp +++ b/headers/meta.hpp/meta_states/function.hpp @@ -14,7 +14,7 @@ namespace meta_hpp::detail { template < function_kind Function > - std::optional raw_function_invoke(Function function, std::span args) { + std::optional vargs_invoke(Function function, std::span args) { using ft = function_traits; using return_type = typename ft::return_type; using argument_types = typename ft::argument_types; @@ -24,7 +24,7 @@ namespace meta_hpp::detail } // NOLINTNEXTLINE(readability-named-parameter) - return std::invoke([&function, &args](std::index_sequence){ + return std::invoke([function = std::move(function), &args](std::index_sequence){ if ( !(... && (args.data() + Is)->can_cast_to>()) ) { throw std::logic_error("an attempt to call a function with incorrect argument types"); } @@ -44,7 +44,7 @@ namespace meta_hpp::detail } template < function_kind Function > - bool raw_function_is_invocable_with(std::span args) { + bool vargs_is_invocable_with(std::span args) { using ft = function_traits; using argument_types = typename ft::argument_types; @@ -64,13 +64,13 @@ namespace meta_hpp::detail template < function_kind Function > function_state::invoke_impl make_function_invoke(Function function) { using namespace std::placeholders; - return std::bind(&raw_function_invoke, function, _1); + return std::bind(&vargs_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(&raw_function_is_invocable_with, _1); + return std::bind(&vargs_is_invocable_with, _1); } } @@ -79,7 +79,7 @@ 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(function)} + , invoke{make_function_invoke(std::move(function))} , is_invocable_with{make_function_is_invocable_with()} {} template < function_kind Function > @@ -116,9 +116,9 @@ namespace meta_hpp template < typename... Args > std::optional function::invoke(Args&&... args) const { - using namespace detail; if constexpr ( sizeof...(Args) > 0 ) { - std::array vargs{arg{std::forward(args)}...}; + using namespace detail; + const std::array vargs{arg{std::forward(args)}...}; return state_->invoke(vargs); } else { return state_->invoke({}); @@ -132,9 +132,9 @@ namespace meta_hpp template < typename... Args > bool function::is_invocable_with() const noexcept { - using namespace detail; if constexpr ( sizeof...(Args) > 0 ) { - std::array vargs{arg_base{type_list{}}...}; + using namespace detail; + const std::array vargs{arg_base{type_list{}}...}; return state_->is_invocable_with(vargs); } else { return state_->is_invocable_with({}); @@ -143,9 +143,9 @@ namespace meta_hpp template < typename... Args > bool function::is_invocable_with(Args&&... args) const noexcept { - using namespace detail; if constexpr ( sizeof...(Args) > 0 ) { - std::array vargs{arg{std::forward(args)}...}; + using namespace detail; + const std::array vargs{arg_base{std::forward(args)}...}; return state_->is_invocable_with(vargs); } else { return state_->is_invocable_with({}); diff --git a/headers/meta.hpp/meta_states/member.hpp b/headers/meta.hpp/meta_states/member.hpp index 6a66ec1..73243b3 100644 --- a/headers/meta.hpp/meta_states/member.hpp +++ b/headers/meta.hpp/meta_states/member.hpp @@ -14,7 +14,7 @@ namespace meta_hpp::detail { template < member_kind Member > - value raw_member_getter(Member member, const inst& inst) { + value vargs_invoke(Member member, const inst& inst) { using mt = member_traits; using class_type = typename mt::class_type; using value_type = typename mt::value_type; @@ -25,10 +25,23 @@ namespace meta_hpp::detail throw std::logic_error("an attempt to get a member with an incorrect instance type"); } - value_type return_value{std::invoke(member, inst.cast())}; + value_type return_value{std::invoke(std::move(member), inst.cast())}; return value{std::forward(return_value)}; } + template < member_kind Member > + bool vargs_is_invocable_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(); + } +} + +namespace meta_hpp::detail +{ template < member_kind Member > void raw_member_setter([[maybe_unused]] Member member, const inst& inst, const arg& arg) { using mt = member_traits; @@ -52,20 +65,10 @@ namespace meta_hpp::detail throw std::logic_error("an attempt to set a member with an incorrect argument type"); } - std::invoke(member, inst.cast()) = arg.cast(); + std::invoke(std::move(member), inst.cast()) = arg.cast(); } } - template < member_kind Member > - 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(); - } - template < member_kind Member > bool raw_member_is_settable_with(const inst_base& inst, const arg_base& arg) { using mt = member_traits; @@ -86,19 +89,19 @@ namespace meta_hpp::detail template < member_kind Member > member_state::getter_impl make_member_getter(Member member) { using namespace std::placeholders; - return std::bind(&raw_member_getter, member, _1); - } - - template < member_kind Member > - member_state::setter_impl make_member_setter(Member member) { - using namespace std::placeholders; - return std::bind(&raw_member_setter, member, _1, _2); + return std::bind(&vargs_invoke, 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(&raw_member_is_gettable_with, _1); + return std::bind(&vargs_is_invocable_with, _1); + } + + template < member_kind Member > + member_state::setter_impl make_member_setter(Member member) { + using namespace std::placeholders; + return std::bind(&raw_member_setter, std::move(member), _1, _2); } template < member_kind Member > @@ -113,8 +116,8 @@ 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(member)} - , setter{make_member_setter(member)} + , 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()} {} @@ -153,13 +156,16 @@ namespace meta_hpp template < typename Instance > value member::get(Instance&& instance) const { using namespace detail; - return state_->getter(inst{std::forward(instance)}); + const inst vinst{std::forward(instance)}; + return state_->getter(vinst); } template < typename Instance, typename Value > void member::set(Instance&& instance, Value&& value) const { using namespace detail; - state_->setter(inst{std::forward(instance)}, arg{std::forward(value)}); + const inst vinst{std::forward(instance)}; + const arg vvalue{std::forward(value)}; + state_->setter(vinst, vvalue); } template < typename Instance > @@ -175,24 +181,30 @@ namespace meta_hpp template < typename Instance > [[nodiscard]] bool member::is_gettable_with() const noexcept { using namespace detail; - return state_->is_gettable_with(inst_base{type_list{}}); + const inst_base vinst{type_list{}}; + return state_->is_gettable_with(vinst); } template < typename Instance > [[nodiscard]] bool member::is_gettable_with(Instance&& instance) const noexcept { using namespace detail; - return state_->is_gettable_with(inst{std::forward(instance)}); + const inst_base vinst{std::forward(instance)}; + return state_->is_gettable_with(vinst); } template < typename Instance, typename Value > [[nodiscard]] bool member::is_settable_with() const noexcept { using namespace detail; - return state_->is_settable_with(inst_base{type_list{}}, arg_base{type_list{}}); + const inst_base vinst{type_list{}}; + const arg_base vvalue{type_list{}}; + return state_->is_settable_with(vinst, vvalue); } template < typename Instance, typename Value > [[nodiscard]] bool member::is_settable_with(Instance&& instance, Value&& value) const noexcept { using namespace detail; - return state_->is_settable_with(inst{std::forward(instance)}, arg{std::forward(value)}); + const inst_base vinst{std::forward(instance)}; + const arg_base vvalue{std::forward(value)}; + return state_->is_settable_with(vinst, vvalue); } } diff --git a/headers/meta.hpp/meta_states/method.hpp b/headers/meta.hpp/meta_states/method.hpp index 3719dfd..0ea9b00 100644 --- a/headers/meta.hpp/meta_states/method.hpp +++ b/headers/meta.hpp/meta_states/method.hpp @@ -14,7 +14,7 @@ namespace meta_hpp::detail { template < method_kind Method > - std::optional raw_method_invoke(Method method, const inst& inst, std::span args) { + std::optional vargs_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; @@ -29,7 +29,7 @@ namespace meta_hpp::detail } // NOLINTNEXTLINE(readability-named-parameter) - return std::invoke([&method, &inst, &args](std::index_sequence){ + return std::invoke([method = std::move(method), &inst, &args](std::index_sequence){ if ( !(... && (args.data() + Is)->can_cast_to>()) ) { throw std::logic_error("an attempt to call a method with incorrect argument types"); } @@ -51,7 +51,7 @@ namespace meta_hpp::detail } template < method_kind Method > - bool raw_method_is_invocable_with(const inst_base& inst, std::span args) { + bool vargs_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; @@ -76,13 +76,13 @@ namespace meta_hpp::detail template < method_kind Method > method_state::invoke_impl make_method_invoke(Method method) { using namespace std::placeholders; - return std::bind(&raw_method_invoke, method, _1, _2); + return std::bind(&vargs_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(&raw_method_is_invocable_with, _1, _2); + return std::bind(&vargs_is_invocable_with, _1, _2); } } @@ -91,7 +91,7 @@ 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(method)} + , invoke{make_method_invoke(std::move(method))} , is_invocable_with{make_method_is_invocable_with()} {} template < method_kind Method > @@ -129,11 +129,12 @@ namespace meta_hpp template < typename Instance, typename... Args > std::optional method::invoke(Instance&& instance, Args&&... args) const { using namespace detail; + const inst vinst{std::forward(instance)}; if constexpr ( sizeof...(Args) > 0 ) { - std::array vargs{arg{std::forward(args)}...}; - return state_->invoke(inst{std::forward(instance)}, vargs); + const std::array vargs{arg{std::forward(args)}...}; + return state_->invoke(vinst, vargs); } else { - return state_->invoke(inst{std::forward(instance)}, {}); + return state_->invoke(vinst, {}); } } @@ -145,22 +146,24 @@ namespace meta_hpp template < typename Instance, typename... Args > bool method::is_invocable_with() const noexcept { using namespace detail; + const inst_base vinst{type_list{}}; if constexpr ( sizeof...(Args) > 0 ) { - std::array vargs{arg_base{type_list{}}...}; - return state_->is_invocable_with(inst_base{type_list{}}, vargs); + const std::array vargs{arg_base{type_list{}}...}; + return state_->is_invocable_with(vinst, vargs); } else { - return state_->is_invocable_with(inst_base{type_list{}}, {}); + return state_->is_invocable_with(vinst, {}); } } template < typename Instance, typename... Args > bool method::is_invocable_with(Instance&& instance, Args&&... args) const noexcept { using namespace detail; + const inst_base vinst{std::forward(instance)}; if constexpr ( sizeof...(Args) > 0 ) { - std::array vargs{arg{std::forward(args)}...}; - return state_->is_invocable_with(inst{std::forward(instance)}, vargs); + const std::array vargs{arg_base{std::forward(args)}...}; + return state_->is_invocable_with(vinst, vargs); } else { - return state_->is_invocable_with(inst{std::forward(instance)}, {}); + return state_->is_invocable_with(vinst, {}); } } } diff --git a/headers/meta.hpp/meta_states/variable.hpp b/headers/meta.hpp/meta_states/variable.hpp index 5db678e..0bb8b3c 100644 --- a/headers/meta.hpp/meta_states/variable.hpp +++ b/headers/meta.hpp/meta_states/variable.hpp @@ -117,7 +117,8 @@ namespace meta_hpp template < typename Value > void variable::set(Value&& value) const { using namespace detail; - state_->setter(arg{std::forward(value)}); + const arg vvalue{std::forward(value)}; + state_->setter(vvalue); } inline value variable::operator()() const { @@ -132,12 +133,14 @@ namespace meta_hpp template < typename Value > bool variable::is_settable_with() const noexcept { using namespace detail; - return state_->is_settable_with(arg_base{type_list{}}); + const arg_base vvalue{type_list{}}; + return state_->is_settable_with(vvalue); } template < typename Value > bool variable::is_settable_with(Value&& value) const noexcept { using namespace detail; - return state_->is_settable_with(arg{std::forward(value)}); + const arg vvalue{std::forward(value)}; + return state_->is_settable_with(vvalue); } } diff --git a/headers/meta.hpp/meta_utilities.hpp b/headers/meta.hpp/meta_utilities.hpp index 2ae69d0..27315b2 100644 --- a/headers/meta.hpp/meta_utilities.hpp +++ b/headers/meta.hpp/meta_utilities.hpp @@ -236,6 +236,12 @@ namespace meta_hpp::detail virtual ~arg_base() = default; + template < decay_value_kind T > + explicit arg_base(T&& v); + + template < decay_non_uvalue_kind T > + explicit arg_base(T&& v); + template < arg_lvalue_ref_kind T > requires decay_non_uvalue_kind explicit arg_base(type_list); @@ -313,6 +319,12 @@ namespace meta_hpp::detail virtual ~inst_base() = default; + template < decay_value_kind T > + explicit inst_base(T&& v); + + template < decay_non_uvalue_kind T > + explicit inst_base(T&& v); + template < inst_class_lvalue_ref_kind T > explicit inst_base(type_list); diff --git a/headers/meta.hpp/meta_utilities/arg.hpp b/headers/meta.hpp/meta_utilities/arg.hpp index 529c24e..259bb42 100644 --- a/headers/meta.hpp/meta_utilities/arg.hpp +++ b/headers/meta.hpp/meta_utilities/arg.hpp @@ -11,6 +11,16 @@ namespace meta_hpp::detail { + template < decay_value_kind T > + // NOLINTNEXTLINE(readability-named-parameter) + arg_base::arg_base(T&&) + : arg_base{type_list{}} {} + + template < decay_non_uvalue_kind T > + // NOLINTNEXTLINE(readability-named-parameter) + arg_base::arg_base(T&&) + : arg_base{type_list{}} {} + template < arg_lvalue_ref_kind T > requires decay_non_uvalue_kind // NOLINTNEXTLINE(readability-named-parameter) @@ -174,7 +184,7 @@ namespace meta_hpp::detail template < decay_non_uvalue_kind T > arg::arg(T&& v) - : arg_base{type_list{}} + : arg_base{std::forward(v)} // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast) , data_{const_cast*>(std::addressof(v))} {} diff --git a/headers/meta.hpp/meta_utilities/inst.hpp b/headers/meta.hpp/meta_utilities/inst.hpp index c52868a..9c34939 100644 --- a/headers/meta.hpp/meta_utilities/inst.hpp +++ b/headers/meta.hpp/meta_utilities/inst.hpp @@ -62,6 +62,16 @@ namespace meta_hpp::detail namespace meta_hpp::detail { + template < decay_value_kind T > + // NOLINTNEXTLINE(readability-named-parameter) + inst_base::inst_base(T&&) + : inst_base{type_list{}} {} + + template < decay_non_uvalue_kind T > + // NOLINTNEXTLINE(readability-named-parameter) + inst_base::inst_base(T&&) + : inst_base{type_list{}} {} + template < inst_class_lvalue_ref_kind T > // NOLINTNEXTLINE(readability-named-parameter) inst_base::inst_base(type_list) @@ -174,7 +184,7 @@ namespace meta_hpp::detail template < decay_non_uvalue_kind T > inst::inst(T&& v) - : inst_base{type_list{}} + : inst_base{std::forward(v)} // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast) , data_{const_cast*>(std::addressof(v))} {} diff --git a/headers/meta.hpp/meta_utilities/vinvoke.hpp b/headers/meta.hpp/meta_utilities/vinvoke.hpp new file mode 100644 index 0000000..65c49c1 --- /dev/null +++ b/headers/meta.hpp/meta_utilities/vinvoke.hpp @@ -0,0 +1,170 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_states.hpp" +#include "../meta_utilities.hpp" + +namespace meta_hpp +{ + template < typename... Args > + std::optional invoke(const function& function, Args&&... args) { + return function.invoke(std::forward(args)...); + } + + template < detail::function_kind Function, typename... Args > + std::optional invoke(Function&& function, Args&&... args) { + using namespace detail; + if constexpr ( sizeof...(Args) > 0 ) { + const std::array vargs{arg{std::forward(args)}...}; + return vargs_invoke(std::forward(function), vargs); + } else { + return vargs_invoke(std::forward(function), {}); + } + } +} + +namespace meta_hpp +{ + template < typename Instance > + std::optional invoke(const member& member, Instance&& instance) { + return member.get(std::forward(instance)); + } + + template < detail::member_kind Member, typename Instance > + std::optional invoke(Member&& member, Instance&& instance) { + using namespace detail; + const inst vinst{std::forward(instance)}; + return vargs_invoke(std::forward(member), vinst); + } +} + +namespace meta_hpp +{ + template < typename Instance, typename... Args > + std::optional invoke(const method& method, Instance&& instance, Args&&... args) { + return method.invoke(std::forward(instance), std::forward(args)...); + } + + template < detail::method_kind Method, typename Instance, typename... Args > + std::optional invoke(Method&& method, Instance&& instance, Args&&... args) { + using namespace detail; + 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); + } else { + return vargs_invoke(std::forward(method), vinst, {}); + } + } +} + +namespace meta_hpp +{ + template < typename... Args > + bool is_invocable_with(const function& function) { + return function.is_invocable_with(); + } + + template < typename... Args > + bool is_invocable_with(const function& function, Args&&... args) { + return function.is_invocable_with(std::forward(args)...); + } + + template < detail::function_kind Function, typename... Args > + bool is_invocable_with() { + if constexpr ( sizeof...(Args) > 0 ) { + using namespace detail; + const std::array vargs{arg_base{type_list{}}...}; + return vargs_is_invocable_with(vargs); + } else { + return vargs_is_invocable_with({}); + } + } + + template < detail::function_kind Function, typename... Args > + bool is_invocable_with(Args&&... args) { + if constexpr ( sizeof...(Args) > 0 ) { + using namespace detail; + const std::array vargs{arg_base{std::forward(args)}...}; + return vargs_is_invocable_with(vargs); + } else { + return vargs_is_invocable_with({}); + } + } +} + +namespace meta_hpp +{ + template < typename Instance > + bool is_invocable_with(const member& member) { + return member.is_gettable_with(); + } + + template < typename Instance > + bool is_invocable_with(const member& member, Instance&& instance) { + return member.is_gettable_with(std::forward(instance)); + } +} + +namespace meta_hpp +{ + template < typename Instance, typename... Args > + bool is_invocable_with(const method& method) { + return method.is_invocable_with(); + } + + template < typename Instance, typename... Args > + bool is_invocable_with(const method& method, Instance&& instance, Args&&... args) { + return method.is_invocable_with(std::forward(instance), std::forward(args)...); + } +} + +namespace meta_hpp +{ + template < detail::member_kind Member, typename Instance > + bool is_invocable_with() { + using namespace detail; + const inst_base vinst{type_list{}}; + return vargs_is_invocable_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); + } +} + +namespace meta_hpp +{ + template < detail::method_kind Method, typename Instance, typename... Args > + bool is_invocable_with() { + using namespace detail; + 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); + } else { + return vargs_is_invocable_with(vinst, {}); + } + } + + template < detail::method_kind Method, typename Instance, typename... Args > + bool is_invocable_with(Instance&& instance, Args&&... args) { + using namespace detail; + 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); + } else { + return vargs_is_invocable_with(vinst, {}); + } + } +} diff --git a/untests/meta_utilities/arg6_tests.cpp b/untests/meta_utilities/arg6_tests.cpp index 25ea23f..67c09da 100644 --- a/untests/meta_utilities/arg6_tests.cpp +++ b/untests/meta_utilities/arg6_tests.cpp @@ -39,8 +39,6 @@ TEST_CASE("meta/meta_utilities/arg6") { .function_("func_with_method", &func_with_method); SUBCASE("int_member") { - static_assert(sizeof(int_member_t) == 8); - const meta::function f = scope.get_function("func_with_member"); REQUIRE(f); @@ -55,8 +53,6 @@ TEST_CASE("meta/meta_utilities/arg6") { } SUBCASE("int_method") { - static_assert(sizeof(int_method_t) == 16); - const meta::function f = scope.get_function("func_with_method"); REQUIRE(f); diff --git a/untests/meta_utilities/invoke_tests.cpp b/untests/meta_utilities/invoke_tests.cpp new file mode 100644 index 0000000..f13e07b --- /dev/null +++ b/untests/meta_utilities/invoke_tests.cpp @@ -0,0 +1,85 @@ +/******************************************************************************* + * 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 { + int member{1}; + int method(int i) const { return i; } + static int function(int i) { return i; } + }; +} + +TEST_CASE("meta/meta_utilities/invoke") { + namespace meta = meta_hpp; + + meta::class_() + .member_("member", &clazz::member) + .method_("method", &clazz::method) + .function_("function", &clazz::function); + + const meta::class_type& clazz_type = meta::resolve_type(); + REQUIRE(clazz_type); + + const meta::member& clazz_member = clazz_type.get_member("member"); + const meta::method& clazz_method = clazz_type.get_method("method"); + const meta::function& clazz_function = clazz_type.get_function("function"); + REQUIRE((clazz_member && clazz_method && clazz_function)); + + { + CHECK(meta::invoke(&clazz::function, 3) == 3); + CHECK(meta::invoke(&clazz::function, meta::value(3)) == 3); + CHECK(meta::invoke(clazz_function, 3) == 3); + CHECK(meta::invoke(clazz_function, meta::value(3)) == 3); + + CHECK(meta::is_invocable_with(clazz_function, 3)); + CHECK(meta::is_invocable_with(clazz_function, meta::value(3))); + CHECK(meta::is_invocable_with(clazz_function)); + + using function_t = decltype(&clazz::function); + CHECK(meta::is_invocable_with(3)); + CHECK(meta::is_invocable_with(meta::value(3))); + CHECK(meta::is_invocable_with()); + } + + { + clazz cl; + + CHECK(meta::invoke(&clazz::member, cl) == 1); + CHECK(meta::invoke(&clazz::member, meta::value{cl}) == 1); + CHECK(meta::invoke(clazz_member, cl) == 1); + CHECK(meta::invoke(clazz_member, meta::value{cl}) == 1); + + CHECK(meta::is_invocable_with(clazz_member, cl)); + CHECK(meta::is_invocable_with(clazz_member, meta::value{cl})); + CHECK(meta::is_invocable_with(clazz_member)); + + using member_t = decltype(&clazz::member); + CHECK(meta::is_invocable_with(cl)); + CHECK(meta::is_invocable_with(meta::value{cl})); + CHECK(meta::is_invocable_with()); + } + + { + clazz cl; + + CHECK(meta::invoke(&clazz::method, cl, 2) == 2); + CHECK(meta::invoke(&clazz::method, meta::value{cl}, meta::value(2)) == 2); + CHECK(meta::invoke(clazz_method, cl, 2) == 2); + CHECK(meta::invoke(clazz_method, meta::value{cl}, meta::value(2)) == 2); + + CHECK(meta::is_invocable_with(clazz_method, cl, 2)); + CHECK(meta::is_invocable_with(clazz_method, meta::value{cl}, meta::value(2))); + CHECK(meta::is_invocable_with(clazz_method)); + + using method_t = decltype(&clazz::method); + CHECK(meta::is_invocable_with(cl, 2)); + CHECK(meta::is_invocable_with(meta::value{cl}, meta::value(2))); + CHECK(meta::is_invocable_with()); + } +} From fb604ba61ed7a08a6473835d788336a0a12c38b3 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sat, 15 Jan 2022 07:48:22 +0700 Subject: [PATCH 175/233] add value deref function --- TODO.md | 20 +++--- headers/meta.hpp/meta_utilities.hpp | 9 +++ headers/meta.hpp/meta_utilities/value.hpp | 34 +++++++++++ untests/meta_utilities/value_tests.cpp | 74 ++++++++++++++++++++++- 4 files changed, 126 insertions(+), 11 deletions(-) diff --git a/TODO.md b/TODO.md index 8e27475..c002f02 100644 --- a/TODO.md +++ b/TODO.md @@ -1,14 +1,16 @@ # meta.hpp -- add type names; -- add argument names -- add variable and member readonly flags +- add array value access +- add return value policy - add meta exception class; - add conversion of nullptr to any pointers; - add conversion of any pointers to void pointer ( identically cv-qualified ); -- add enum_type::create, number_type::create, and so on. -- add return value policy -- add is_invocable_with by dynamic types -- add metadata to every type and state -- add integral implicit conversions -- add meta::invoke function + +* argument names +* argument defaults +* type conversions +* states and types metadata + +? add type names; +? add enum_type::create, number_type::create, and so on. +? add invoke and is_invocable_with by dynamic types diff --git a/headers/meta.hpp/meta_utilities.hpp b/headers/meta.hpp/meta_utilities.hpp index 27315b2..8cf7683 100644 --- a/headers/meta.hpp/meta_utilities.hpp +++ b/headers/meta.hpp/meta_utilities.hpp @@ -116,6 +116,11 @@ namespace meta_hpp::detail namespace meta_hpp::detail { + template < typename T > + concept has_deref_op_kind = requires(const T& v) { + { *v } -> convertible_to>; + }; + template < typename T > concept has_less_op_kind = requires(const T& v) { { v < v } -> convertible_to; @@ -182,6 +187,10 @@ namespace meta_hpp [[nodiscard]] const void* data() const noexcept; [[nodiscard]] const void* cdata() const noexcept; + [[nodiscard]] value deref(); + [[nodiscard]] value deref() const; + [[nodiscard]] value cderef() const; + template < typename T, typename Tp = std::decay_t > [[nodiscard]] Tp& cast() &; diff --git a/headers/meta.hpp/meta_utilities/value.hpp b/headers/meta.hpp/meta_utilities/value.hpp index 7be7bad..3e64be2 100644 --- a/headers/meta.hpp/meta_utilities/value.hpp +++ b/headers/meta.hpp/meta_utilities/value.hpp @@ -17,6 +17,9 @@ namespace meta_hpp void* (*const data)(value&) noexcept; const void* (*const cdata)(const value&) noexcept; + value (*const deref)(value&); + value (*const cderef)(const value&); + bool (*const less)(const value&, const value&); bool (*const equals)(const value&, const value&); @@ -32,6 +35,8 @@ namespace meta_hpp template < typename T > const value::traits* value::traits::get() noexcept { + static_assert(std::is_same_v>); + static const traits traits{ .type = resolve_type(), @@ -43,6 +48,22 @@ namespace meta_hpp return v.try_cast(); }, + .deref = +[]([[maybe_unused]] value& v) -> value { + if constexpr ( detail::has_deref_op_kind ) { + return value{*v.cast()}; + } else { + throw std::logic_error("value type doesn't have deref operator"); + } + }, + + .cderef = +[]([[maybe_unused]] const value& v) -> value { + if constexpr ( detail::has_deref_op_kind ) { + return value{*v.cast()}; + } else { + throw std::logic_error("value type doesn't have deref operator"); + } + }, + .less = +[]([[maybe_unused]] const value& l, [[maybe_unused]] const value& r) -> bool { if constexpr ( detail::has_less_op_kind ) { return l.cast() < r.cast(); @@ -91,6 +112,7 @@ namespace meta_hpp } }, }; + return &traits; } } @@ -159,6 +181,18 @@ namespace meta_hpp return traits_->cdata(*this); } + inline value value::deref() { + return traits_->deref(*this); + } + + inline value value::deref() const { + return traits_->cderef(*this); + } + + inline value value::cderef() const { + return traits_->cderef(*this); + } + template < typename T, typename Tp > Tp& value::cast() & { if ( get_type() != resolve_type() ) { diff --git a/untests/meta_utilities/value_tests.cpp b/untests/meta_utilities/value_tests.cpp index 3a6b09d..46838c3 100644 --- a/untests/meta_utilities/value_tests.cpp +++ b/untests/meta_utilities/value_tests.cpp @@ -30,6 +30,12 @@ namespace ++copy_ctor_counter; } + ivec2& add(const ivec2& other) { + x += other.x; + y += other.y; + return *this; + } + ivec2& operator=(ivec2&& other) = delete; ivec2& operator=(const ivec2& other) = delete; public: @@ -344,21 +350,85 @@ TEST_CASE("meta/meta_utilities/value") { CHECK_THROWS(std::ignore = operator==(meta::value{empty_class1{}}, meta::value{empty_class1{}})); } } + + SUBCASE("deref") { + { + int i{42}; + const meta::value v{meta::value{&i}.deref()}; + CHECK(v.get_type() == meta::resolve_type()); + CHECK(v.data() != &i); + } + { + const char i{42}; + const meta::value v{meta::value{&i}.deref()}; + CHECK(v.get_type() == meta::resolve_type()); + CHECK(v.data() != &i); + } + { + const int i{42}; + const int* const pi = &i; + const meta::value v{meta::value{&pi}.deref()}; + CHECK(v.get_type() == meta::resolve_type() ); + CHECK(v.cast() == pi); + } + { + int i{42}; + + void* p1 = &i; + const void* p2 = &i; + void* const& p3 = &i; + const void* const& p4 = &i; + + CHECK_THROWS(std::ignore = meta::value(p1).deref()); + CHECK_THROWS(std::ignore = meta::value(p2).deref()); + CHECK_THROWS(std::ignore = meta::value(p3).deref()); + CHECK_THROWS(std::ignore = meta::value(p4).deref()); + } + { + ivec2 v{1,2}; + meta::value vp{&v}; + CHECK(ivec2::move_ctor_counter == 0); + CHECK(ivec2::copy_ctor_counter == 0); + + meta::value vv1{vp.deref()}; + CHECK(ivec2::move_ctor_counter == 0); + CHECK(ivec2::copy_ctor_counter == 1); + + meta::value vv2{std::move(vp).deref()}; + CHECK(ivec2::move_ctor_counter == 0); + CHECK(ivec2::copy_ctor_counter == 2); + + meta::value vv3{vp.cderef()}; + CHECK(ivec2::move_ctor_counter == 0); + CHECK(ivec2::copy_ctor_counter == 3); + } + } } TEST_CASE("meta/meta_utilities/value/functions") { namespace meta = meta_hpp; + SUBCASE("add") { + { + const meta::value v{&ivec2::add}; + CHECK(v.get_type() == meta::resolve_type()); + CHECK(std::invoke(v.cast(), ivec2{1,2}, ivec2{3,4}) == ivec2{4,6}); + CHECK(std::invoke(*v.try_cast(), ivec2{1,2}, ivec2{3,4}) == ivec2{4,6}); + } + } + SUBCASE("iadd2") { { const meta::value v{iadd2}; CHECK(v.get_type() == meta::resolve_type()); - CHECK(v.cast()(ivec2{1,2}, ivec2{3,4}) == ivec2{4,6}); + CHECK(std::invoke(v.cast(), ivec2{1,2}, ivec2{3,4}) == ivec2{4,6}); + CHECK(std::invoke(*v.try_cast(), ivec2{1,2}, ivec2{3,4}) == ivec2{4,6}); } { const meta::value v{&iadd2}; CHECK(v.get_type() == meta::resolve_type()); - CHECK(v.cast()(ivec2{1,2}, ivec2{3,4}) == ivec2{4,6}); + CHECK(std::invoke(v.cast(), ivec2{1,2}, ivec2{3,4}) == ivec2{4,6}); + CHECK(std::invoke(*v.try_cast(), ivec2{1,2}, ivec2{3,4}) == ivec2{4,6}); } } } From f942f8ffa01385adcb76318072f189c87f57ba3b Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sun, 16 Jan 2022 09:42:51 +0700 Subject: [PATCH 176/233] value index operator --- TODO.md | 2 + headers/meta.hpp/meta_base.hpp | 47 +++++++++++ headers/meta.hpp/meta_registry/class_bind.hpp | 4 +- headers/meta.hpp/meta_states/evalue.hpp | 2 +- headers/meta.hpp/meta_utilities.hpp | 63 +-------------- headers/meta.hpp/meta_utilities/value.hpp | 59 +++++++------- .../value_traits/deref_traits.hpp | 52 ++++++++++++ .../value_traits/equals_traits.hpp | 33 ++++++++ .../value_traits/index_traits.hpp | 66 ++++++++++++++++ .../value_traits/istream_traits.hpp | 33 ++++++++ .../value_traits/less_traits.hpp | 33 ++++++++ .../value_traits/ostream_traits.hpp | 33 ++++++++ manuals/meta_examples/references_example.cpp | 15 ---- ...ointers_example.cpp => values_example.cpp} | 2 +- untests/meta_states/evalue_tests.cpp | 2 +- untests/meta_types/enum_type_tests.cpp | 4 +- untests/meta_utilities/value_tests.cpp | 79 ++++++++++++++++--- 17 files changed, 408 insertions(+), 121 deletions(-) create mode 100644 headers/meta.hpp/meta_utilities/value_traits/deref_traits.hpp create mode 100644 headers/meta.hpp/meta_utilities/value_traits/equals_traits.hpp create mode 100644 headers/meta.hpp/meta_utilities/value_traits/index_traits.hpp create mode 100644 headers/meta.hpp/meta_utilities/value_traits/istream_traits.hpp create mode 100644 headers/meta.hpp/meta_utilities/value_traits/less_traits.hpp create mode 100644 headers/meta.hpp/meta_utilities/value_traits/ostream_traits.hpp delete mode 100644 manuals/meta_examples/references_example.cpp rename manuals/meta_examples/{pointers_example.cpp => values_example.cpp} (91%) diff --git a/TODO.md b/TODO.md index c002f02..a7dfaf4 100644 --- a/TODO.md +++ b/TODO.md @@ -5,6 +5,8 @@ - add meta exception class; - add conversion of nullptr to any pointers; - add conversion of any pointers to void pointer ( identically cv-qualified ); +- void value? +- all string to hash? * argument names * argument defaults diff --git a/headers/meta.hpp/meta_base.hpp b/headers/meta.hpp/meta_base.hpp index 1ae7f8f..7c6f43c 100644 --- a/headers/meta.hpp/meta_base.hpp +++ b/headers/meta.hpp/meta_base.hpp @@ -182,3 +182,50 @@ namespace meta_hpp using scope_map = std::map>; using variable_map = std::map>; } + +namespace meta_hpp::detail::stdex +{ + template < typename T > + [[nodiscard]] constexpr std::underlying_type_t to_underlying(T v) noexcept { + return static_cast>(v); + } +} + +namespace meta_hpp::detail::stdex +{ + template < typename T, typename U > + concept same_as = + std::is_same_v && + std::is_same_v; + + template < typename Derived, typename Base > + concept derived_from = + std::is_base_of_v && + std::is_convertible_v; + + template < typename From, typename To > + concept convertible_to = + std::is_convertible_v && + requires { static_cast(std::declval()); }; + + template < typename T > + concept destructible = + std::is_nothrow_destructible_v; + + template < typename T, typename... Args > + concept constructible_from = + destructible && + std::is_constructible_v; + + template < typename T > + concept move_constructible = + constructible_from && + convertible_to; + + template + concept copy_constructible = + move_constructible && + constructible_from && convertible_to && + constructible_from && convertible_to && + constructible_from && convertible_to; +} diff --git a/headers/meta.hpp/meta_registry/class_bind.hpp b/headers/meta.hpp/meta_registry/class_bind.hpp index 36ba7cc..81dce45 100644 --- a/headers/meta.hpp/meta_registry/class_bind.hpp +++ b/headers/meta.hpp/meta_registry/class_bind.hpp @@ -23,7 +23,7 @@ namespace meta_hpp template < detail::class_kind Class > template < typename... Args > class_bind& class_bind::ctor_() { - static_assert(detail::constructible_from); + static_assert(detail::stdex::constructible_from); auto ctor_state = detail::ctor_state::make(); data_->ctors.emplace(ctor_state->index, std::move(ctor_state)); return *this; @@ -32,7 +32,7 @@ namespace meta_hpp template < detail::class_kind Class > template < detail::class_kind Base > class_bind& class_bind::base_() { - static_assert(detail::derived_from); + static_assert(detail::stdex::derived_from); data_->bases.emplace(resolve_type()); data_->bases_info.emplace(resolve_type(), detail::class_type_data::base_info{ .upcast = +[](void* derived) -> void* { diff --git a/headers/meta.hpp/meta_states/evalue.hpp b/headers/meta.hpp/meta_states/evalue.hpp index af2b6bd..df4328d 100644 --- a/headers/meta.hpp/meta_states/evalue.hpp +++ b/headers/meta.hpp/meta_states/evalue.hpp @@ -17,7 +17,7 @@ namespace meta_hpp::detail evalue_state::evalue_state(evalue_index index, Enum value) : index{std::move(index)} , enum_value{value} - , underlying_value{to_underlying(value)} {} + , underlying_value{stdex::to_underlying(value)} {} template < enum_kind Enum > evalue_state_ptr evalue_state::make(std::string name, Enum value) { diff --git a/headers/meta.hpp/meta_utilities.hpp b/headers/meta.hpp/meta_utilities.hpp index 8cf7683..8d4eac5 100644 --- a/headers/meta.hpp/meta_utilities.hpp +++ b/headers/meta.hpp/meta_utilities.hpp @@ -34,36 +34,6 @@ namespace meta_hpp::detail using copy_cvref_t = typename cvref_traits::template copy_to; } -namespace meta_hpp::detail -{ - template < typename T > - concept destructible = - std::is_nothrow_destructible_v; - - template < typename T, typename... Args > - concept constructible_from = - destructible && - std::is_constructible_v; - - template < typename Derived, typename Base > - concept derived_from = - std::is_base_of_v && - std::is_convertible_v; - - template < typename From, typename To > - concept convertible_to = - std::is_convertible_v && - requires { static_cast(std::declval()); }; -} - -namespace meta_hpp::detail -{ - template < typename T > - [[nodiscard]] constexpr std::underlying_type_t to_underlying(T v) noexcept { - return static_cast>(v); - } -} - namespace meta_hpp::detail { template < typename T > @@ -114,34 +84,6 @@ namespace meta_hpp::detail (std::is_rvalue_reference_v && std::is_class_v>); } -namespace meta_hpp::detail -{ - template < typename T > - concept has_deref_op_kind = requires(const T& v) { - { *v } -> convertible_to>; - }; - - template < typename T > - concept has_less_op_kind = requires(const T& v) { - { v < v } -> convertible_to; - }; - - template < typename T > - concept has_equals_op_kind = requires(const T& v) { - { v == v } -> convertible_to; - }; - - template < typename T > - concept has_istream_op_kind = requires(std::istream& is, T& v) { - { is >> v } -> convertible_to; - }; - - template < typename T > - concept has_ostream_op_kind = requires(std::ostream& os, const T& v) { - { os << v } -> convertible_to; - }; -} - namespace meta_hpp::detail { class noncopyable { @@ -187,9 +129,8 @@ namespace meta_hpp [[nodiscard]] const void* data() const noexcept; [[nodiscard]] const void* cdata() const noexcept; - [[nodiscard]] value deref(); - [[nodiscard]] value deref() const; - [[nodiscard]] value cderef() const; + [[nodiscard]] value operator*() const; + [[nodiscard]] value operator[](std::size_t index) const; template < typename T, typename Tp = std::decay_t > [[nodiscard]] Tp& cast() &; diff --git a/headers/meta.hpp/meta_utilities/value.hpp b/headers/meta.hpp/meta_utilities/value.hpp index 3e64be2..24c6e82 100644 --- a/headers/meta.hpp/meta_utilities/value.hpp +++ b/headers/meta.hpp/meta_utilities/value.hpp @@ -9,6 +9,13 @@ #include "../meta_base.hpp" #include "../meta_utilities.hpp" +#include "value_traits/deref_traits.hpp" +#include "value_traits/equals_traits.hpp" +#include "value_traits/index_traits.hpp" +#include "value_traits/istream_traits.hpp" +#include "value_traits/less_traits.hpp" +#include "value_traits/ostream_traits.hpp" + namespace meta_hpp { struct value::traits final { @@ -17,8 +24,8 @@ namespace meta_hpp void* (*const data)(value&) noexcept; const void* (*const cdata)(const value&) noexcept; - value (*const deref)(value&); - value (*const cderef)(const value&); + value (*const deref)(const value&); + value (*const index)(const value&, std::size_t); bool (*const less)(const value&, const value&); bool (*const equals)(const value&, const value&); @@ -48,35 +55,35 @@ namespace meta_hpp return v.try_cast(); }, - .deref = +[]([[maybe_unused]] value& v) -> value { - if constexpr ( detail::has_deref_op_kind ) { + .deref = +[]([[maybe_unused]] const value& v) -> value { + if constexpr ( detail::has_value_deref_traits ) { return value{*v.cast()}; } else { - throw std::logic_error("value type doesn't have deref operator"); + throw std::logic_error("value type doesn't have value deref traits"); } }, - .cderef = +[]([[maybe_unused]] const value& v) -> value { - if constexpr ( detail::has_deref_op_kind ) { - return value{*v.cast()}; + .index = +[]([[maybe_unused]] const value& v, [[maybe_unused]] std::size_t index) -> value { + if constexpr ( detail::has_value_index_traits ) { + return detail::value_index_traits{}(v.cast(), index); } else { - throw std::logic_error("value type doesn't have deref operator"); + throw std::logic_error("value type doesn't have value index traits"); } }, .less = +[]([[maybe_unused]] const value& l, [[maybe_unused]] const value& r) -> bool { - if constexpr ( detail::has_less_op_kind ) { - return l.cast() < r.cast(); + if constexpr ( detail::has_value_less_traits ) { + return detail::value_less_traits{}(l.cast(), r.cast()); } else { - throw std::logic_error("value type doesn't have less operator"); + throw std::logic_error("value type doesn't have value less traits"); } }, .equals = +[]([[maybe_unused]] const value& l, [[maybe_unused]] const value& r) -> bool { - if constexpr ( detail::has_equals_op_kind ) { - return l.cast() == r.cast(); + if constexpr ( detail::has_value_equals_traits ) { + return detail::value_equals_traits{}(l.cast(), r.cast()); } else { - throw std::logic_error("value type doesn't have equality operator"); + throw std::logic_error("value type doesn't have value equals traits"); } }, @@ -97,18 +104,18 @@ namespace meta_hpp }, .istream = +[]([[maybe_unused]] std::istream& is, [[maybe_unused]] value& v) -> std::istream& { - if constexpr ( detail::has_istream_op_kind ) { - return is >> v.cast(); + if constexpr ( detail::has_value_istream_traits ) { + return detail::value_istream_traits{}(is, v.cast()); } else { - throw std::logic_error("value type doesn't have istream operator"); + throw std::logic_error("value type doesn't have value istream traits"); } }, .ostream = +[]([[maybe_unused]] std::ostream& os, [[maybe_unused]] const value& v) -> std::ostream& { - if constexpr ( detail::has_ostream_op_kind ) { - return os << v.cast(); + if constexpr ( detail::has_value_ostream_traits ) { + return detail::value_ostream_traits{}(os, v.cast()); } else { - throw std::logic_error("value type doesn't have ostream operator"); + throw std::logic_error("value type doesn't have value ostream traits"); } }, }; @@ -181,16 +188,12 @@ namespace meta_hpp return traits_->cdata(*this); } - inline value value::deref() { + inline value value::operator*() const { return traits_->deref(*this); } - inline value value::deref() const { - return traits_->cderef(*this); - } - - inline value value::cderef() const { - return traits_->cderef(*this); + inline value value::operator[](std::size_t index) const { + return traits_->index(*this, index); } template < typename T, typename Tp > diff --git a/headers/meta.hpp/meta_utilities/value_traits/deref_traits.hpp b/headers/meta.hpp/meta_utilities/value_traits/deref_traits.hpp new file mode 100644 index 0000000..6ac5ad0 --- /dev/null +++ b/headers/meta.hpp/meta_utilities/value_traits/deref_traits.hpp @@ -0,0 +1,52 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../../meta_base.hpp" +#include "../../meta_utilities.hpp" + +namespace meta_hpp::detail +{ + template < typename T > + struct value_deref_traits; + + template < typename T > + concept has_value_deref_traits = requires(const T& v) { + { value_deref_traits{}(v) } -> stdex::convertible_to; + }; +} + +namespace meta_hpp::detail +{ + template < stdex::copy_constructible T > + struct value_deref_traits { + value operator()(T* v) const { + return value{*v}; + } + }; + + template < stdex::copy_constructible T > + struct value_deref_traits { + value operator()(const T* v) const { + return value{*v}; + } + }; + + template < stdex::copy_constructible T > + struct value_deref_traits> { + value operator()(const std::shared_ptr& v) const { + return value{*v}; + } + }; + + template < stdex::copy_constructible T > + struct value_deref_traits> { + value operator()(const std::unique_ptr& v) const { + return value{*v}; + } + }; +} diff --git a/headers/meta.hpp/meta_utilities/value_traits/equals_traits.hpp b/headers/meta.hpp/meta_utilities/value_traits/equals_traits.hpp new file mode 100644 index 0000000..6441c16 --- /dev/null +++ b/headers/meta.hpp/meta_utilities/value_traits/equals_traits.hpp @@ -0,0 +1,33 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../../meta_base.hpp" + +namespace meta_hpp::detail +{ + template < typename T > + struct value_equals_traits; + + template < typename T > + concept has_value_equals_traits = requires(const T& v) { + { value_equals_traits{}(v, v) } -> stdex::convertible_to; + }; +} + +namespace meta_hpp::detail +{ + template < typename T > + requires requires(const T& v) { + { v == v } -> stdex::convertible_to; + } + struct value_equals_traits { + bool operator()(const T& l, const T& r) const { + return l == r; + } + }; +} diff --git a/headers/meta.hpp/meta_utilities/value_traits/index_traits.hpp b/headers/meta.hpp/meta_utilities/value_traits/index_traits.hpp new file mode 100644 index 0000000..2382f84 --- /dev/null +++ b/headers/meta.hpp/meta_utilities/value_traits/index_traits.hpp @@ -0,0 +1,66 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../../meta_base.hpp" +#include "../../meta_utilities.hpp" + +namespace meta_hpp::detail +{ + template < typename T > + struct value_index_traits; + + template < typename T > + concept has_value_index_traits = requires(const T& v, std::size_t i) { + { value_index_traits{}(v, i) } -> stdex::convertible_to; + }; +} + +namespace meta_hpp::detail +{ + template < stdex::copy_constructible T > + struct value_index_traits { + value operator()(T* v, std::size_t i) const { + return value{*(v + i)}; + } + }; + + template < stdex::copy_constructible T > + struct value_index_traits { + value operator()(const T* v, std::size_t i) const { + return value{*(v + i)}; + } + }; + + template < stdex::copy_constructible T, std::size_t Size > + struct value_index_traits> { + value operator()(const std::array& v, std::size_t i) const { + return value{v[i]}; + } + }; + + template < stdex::copy_constructible T, std::size_t Extent > + struct value_index_traits> { + value operator()(const std::span& v, std::size_t i) const { + return value{v[i]}; + } + }; + + template < stdex::copy_constructible T, typename Traits, typename Allocator > + struct value_index_traits> { + value operator()(const std::basic_string& v, std::size_t i) const { + return value{v[i]}; + } + }; + + template < stdex::copy_constructible T, typename Allocator > + struct value_index_traits> { + value operator()(const std::vector& v, std::size_t i) { + return value{v[i]}; + } + }; +} diff --git a/headers/meta.hpp/meta_utilities/value_traits/istream_traits.hpp b/headers/meta.hpp/meta_utilities/value_traits/istream_traits.hpp new file mode 100644 index 0000000..8bb1fe9 --- /dev/null +++ b/headers/meta.hpp/meta_utilities/value_traits/istream_traits.hpp @@ -0,0 +1,33 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../../meta_base.hpp" + +namespace meta_hpp::detail +{ + template < typename T > + struct value_istream_traits; + + template < typename T > + concept has_value_istream_traits = requires(std::istream& is, T& v) { + { value_istream_traits{}(is, v) } -> stdex::convertible_to; + }; +} + +namespace meta_hpp::detail +{ + template < typename T > + requires requires(std::istream& is, T& v) { + { is >> v } -> stdex::convertible_to; + } + struct value_istream_traits { + std::istream& operator()(std::istream& is, T& v) const { + return is >> v; + } + }; +} diff --git a/headers/meta.hpp/meta_utilities/value_traits/less_traits.hpp b/headers/meta.hpp/meta_utilities/value_traits/less_traits.hpp new file mode 100644 index 0000000..ca2498b --- /dev/null +++ b/headers/meta.hpp/meta_utilities/value_traits/less_traits.hpp @@ -0,0 +1,33 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../../meta_base.hpp" + +namespace meta_hpp::detail +{ + template < typename T > + struct value_less_traits; + + template < typename T > + concept has_value_less_traits = requires(const T& v) { + { value_less_traits{}(v, v) } -> stdex::convertible_to; + }; +} + +namespace meta_hpp::detail +{ + template < typename T > + requires requires(const T& v) { + { v < v } -> stdex::convertible_to; + } + struct value_less_traits { + bool operator()(const T& l, const T& r) const { + return l < r; + } + }; +} diff --git a/headers/meta.hpp/meta_utilities/value_traits/ostream_traits.hpp b/headers/meta.hpp/meta_utilities/value_traits/ostream_traits.hpp new file mode 100644 index 0000000..e2f5ed9 --- /dev/null +++ b/headers/meta.hpp/meta_utilities/value_traits/ostream_traits.hpp @@ -0,0 +1,33 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../../meta_base.hpp" + +namespace meta_hpp::detail +{ + template < typename T > + struct value_ostream_traits; + + template < typename T > + concept has_value_ostream_traits = requires(std::ostream& is, const T& v) { + { value_ostream_traits{}(is, v) } -> stdex::convertible_to; + }; +} + +namespace meta_hpp::detail +{ + template < typename T > + requires requires(std::ostream& os, const T& v) { + { os << v } -> stdex::convertible_to; + } + struct value_ostream_traits { + std::ostream& operator()(std::ostream& is, const T& v) const { + return is << v; + } + }; +} diff --git a/manuals/meta_examples/references_example.cpp b/manuals/meta_examples/references_example.cpp deleted file mode 100644 index 1fef687..0000000 --- a/manuals/meta_examples/references_example.cpp +++ /dev/null @@ -1,15 +0,0 @@ -/******************************************************************************* - * 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_manuals.hpp" - -namespace -{ -} - -TEST_CASE("meta/meta_examples/references") { - namespace meta = meta_hpp; -} diff --git a/manuals/meta_examples/pointers_example.cpp b/manuals/meta_examples/values_example.cpp similarity index 91% rename from manuals/meta_examples/pointers_example.cpp rename to manuals/meta_examples/values_example.cpp index 5729a42..c0940df 100644 --- a/manuals/meta_examples/pointers_example.cpp +++ b/manuals/meta_examples/values_example.cpp @@ -10,6 +10,6 @@ namespace { } -TEST_CASE("meta/meta_examples/pointers") { +TEST_CASE("meta/meta_examples/values") { namespace meta = meta_hpp; } diff --git a/untests/meta_states/evalue_tests.cpp b/untests/meta_states/evalue_tests.cpp index 93406af..ea3e1c6 100644 --- a/untests/meta_states/evalue_tests.cpp +++ b/untests/meta_states/evalue_tests.cpp @@ -56,7 +56,7 @@ TEST_CASE("meta/meta_states/evalue") { CHECK(evalue.get_value() == color::green); CHECK(evalue.get_value().get_type() == color_type); - CHECK(evalue.get_underlying_value() == meta::detail::to_underlying(color::green)); + CHECK(evalue.get_underlying_value() == meta::detail::stdex::to_underlying(color::green)); CHECK(evalue.get_underlying_value().get_type() == color_type.get_underlying_type()); } } diff --git a/untests/meta_types/enum_type_tests.cpp b/untests/meta_types/enum_type_tests.cpp index 139703f..b18cd0b 100644 --- a/untests/meta_types/enum_type_tests.cpp +++ b/untests/meta_types/enum_type_tests.cpp @@ -90,7 +90,7 @@ TEST_CASE("meta/meta_types/enum_type") { const meta::evalue green_value = color_type.get_evalue("green"); REQUIRE(green_value); CHECK(green_value.get_value() == color::green); - CHECK(green_value.get_underlying_value() == meta::detail::to_underlying(color::green)); + CHECK(green_value.get_underlying_value() == meta::detail::stdex::to_underlying(color::green)); } { @@ -107,7 +107,7 @@ TEST_CASE("meta/meta_types/enum_type") { const meta::evalue green_value = ecolor_type.get_evalue("green"); REQUIRE(green_value); CHECK(green_value.get_value() == ecolor_green); - CHECK(green_value.get_underlying_value() == meta::detail::to_underlying(ecolor_green)); + CHECK(green_value.get_underlying_value() == meta::detail::stdex::to_underlying(ecolor_green)); } { diff --git a/untests/meta_utilities/value_tests.cpp b/untests/meta_utilities/value_tests.cpp index 46838c3..7a3199b 100644 --- a/untests/meta_utilities/value_tests.cpp +++ b/untests/meta_utilities/value_tests.cpp @@ -354,20 +354,20 @@ TEST_CASE("meta/meta_utilities/value") { SUBCASE("deref") { { int i{42}; - const meta::value v{meta::value{&i}.deref()}; + const meta::value v{*meta::value{&i}}; CHECK(v.get_type() == meta::resolve_type()); CHECK(v.data() != &i); } { const char i{42}; - const meta::value v{meta::value{&i}.deref()}; + const meta::value v{*meta::value{&i}}; CHECK(v.get_type() == meta::resolve_type()); CHECK(v.data() != &i); } { const int i{42}; const int* const pi = &i; - const meta::value v{meta::value{&pi}.deref()}; + const meta::value v{*meta::value{&pi}}; CHECK(v.get_type() == meta::resolve_type() ); CHECK(v.cast() == pi); } @@ -379,10 +379,10 @@ TEST_CASE("meta/meta_utilities/value") { void* const& p3 = &i; const void* const& p4 = &i; - CHECK_THROWS(std::ignore = meta::value(p1).deref()); - CHECK_THROWS(std::ignore = meta::value(p2).deref()); - CHECK_THROWS(std::ignore = meta::value(p3).deref()); - CHECK_THROWS(std::ignore = meta::value(p4).deref()); + CHECK_THROWS(std::ignore = *meta::value(p1)); + CHECK_THROWS(std::ignore = *meta::value(p2)); + CHECK_THROWS(std::ignore = *meta::value(p3)); + CHECK_THROWS(std::ignore = *meta::value(p4)); } { ivec2 v{1,2}; @@ -390,18 +390,77 @@ TEST_CASE("meta/meta_utilities/value") { CHECK(ivec2::move_ctor_counter == 0); CHECK(ivec2::copy_ctor_counter == 0); - meta::value vv1{vp.deref()}; + meta::value vv1{*vp}; CHECK(ivec2::move_ctor_counter == 0); CHECK(ivec2::copy_ctor_counter == 1); - meta::value vv2{std::move(vp).deref()}; + meta::value vv2{*std::move(vp)}; CHECK(ivec2::move_ctor_counter == 0); CHECK(ivec2::copy_ctor_counter == 2); - meta::value vv3{vp.cderef()}; + meta::value vv3{*std::as_const(vp)}; CHECK(ivec2::move_ctor_counter == 0); CHECK(ivec2::copy_ctor_counter == 3); } + { + meta::value v{std::make_shared(42)}; + CHECK(*v == 42); + } + } +} + +TEST_CASE("meta/meta_utilities/value/arrays") { + namespace meta = meta_hpp; + + SUBCASE("int[3]") { + int arr[3]{1,2,3}; + meta::value v{arr}; + CHECK(v.get_type() == meta::resolve_type()); + CHECK(v[0] == 1); + CHECK(v[1] == 2); + CHECK(v[2] == 3); + } + + SUBCASE("const int[3]") { + const int arr[3]{1,2,3}; + meta::value v{arr}; + CHECK(v.get_type() == meta::resolve_type()); + CHECK(v[0] == 1); + CHECK(v[1] == 2); + CHECK(v[2] == 3); + } + + SUBCASE("std::array") { + meta::value v{std::array{1,2,3}}; + CHECK(v.get_type() == meta::resolve_type>()); + CHECK(v[0] == 1); + CHECK(v[1] == 2); + CHECK(v[2] == 3); + } + + SUBCASE("std::string") { + meta::value v{std::string{"hi!"}}; + CHECK(v.get_type() == meta::resolve_type()); + CHECK(v[0] == 'h'); + CHECK(v[1] == 'i'); + CHECK(v[2] == '!'); + } + + SUBCASE("std::span") { + std::vector arr{1,2,3}; + meta::value v{std::span{arr}}; + CHECK(v.get_type() == meta::resolve_type>()); + CHECK(v[0] == 1); + CHECK(v[1] == 2); + CHECK(v[2] == 3); + } + + SUBCASE("std::vector") { + const meta::value v{std::vector{1,2,3}}; + CHECK(v.get_type() == meta::resolve_type>()); + CHECK(v[0] == 1); + CHECK(v[1] == 2); + CHECK(v[2] == 3); } } From dffad68627bf0c6532603fa69e4f45363446c752 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sun, 16 Jan 2022 10:07:13 +0700 Subject: [PATCH 177/233] add conversion of any pointers to void pointer --- TODO.md | 1 - headers/meta.hpp/meta_utilities/arg.hpp | 16 +-- untests/meta_utilities/arg7_tests.cpp | 124 ++++++++++++++++++++++++ 3 files changed, 134 insertions(+), 7 deletions(-) create mode 100644 untests/meta_utilities/arg7_tests.cpp diff --git a/TODO.md b/TODO.md index a7dfaf4..7bad6d4 100644 --- a/TODO.md +++ b/TODO.md @@ -4,7 +4,6 @@ - add return value policy - add meta exception class; - add conversion of nullptr to any pointers; -- add conversion of any pointers to void pointer ( identically cv-qualified ); - void value? - all string to hash? diff --git a/headers/meta.hpp/meta_utilities/arg.hpp b/headers/meta.hpp/meta_utilities/arg.hpp index 259bb42..f081759 100644 --- a/headers/meta.hpp/meta_utilities/arg.hpp +++ b/headers/meta.hpp/meta_utilities/arg.hpp @@ -107,8 +107,10 @@ namespace meta_hpp::detail const any_type& to_data_type = to_type_ptr.get_data_type(); const any_type& from_data_type = from_type_array.get_data_type(); - if ( is_a(to_data_type, from_data_type) && to_type_ptr_readonly >= from_type_array_readonly ) { - return true; + if ( to_type_ptr_readonly >= from_type_array_readonly ) { + if ( to_data_type.is_void() || is_a(to_data_type, from_data_type) ) { + return true; + } } } @@ -122,8 +124,10 @@ namespace meta_hpp::detail const any_type& to_data_type = to_type_ptr.get_data_type(); const any_type& from_data_type = from_type_ptr.get_data_type(); - if ( is_a(to_data_type, from_data_type) && to_type_ptr_readonly >= from_type_ptr_readonly ) { - return true; + if ( to_type_ptr_readonly >= from_type_ptr_readonly ) { + if ( to_data_type.is_void() || is_a(to_data_type, from_data_type) ) { + return true; + } } } } @@ -209,7 +213,7 @@ namespace meta_hpp::detail const any_type& to_data_type = to_type_ptr.get_data_type(); const any_type& from_data_type = from_type_array.get_data_type(); - if ( to_data_type == from_data_type ) { + if ( to_data_type.is_void() || to_data_type == from_data_type ) { return static_cast(data_); } @@ -231,7 +235,7 @@ namespace meta_hpp::detail void** from_data_ptr = static_cast(data_); - if ( to_data_type == from_data_type ) { + if ( to_data_type.is_void() || to_data_type == from_data_type ) { return static_cast(*from_data_ptr); } diff --git a/untests/meta_utilities/arg7_tests.cpp b/untests/meta_utilities/arg7_tests.cpp new file mode 100644 index 0000000..4ffe3da --- /dev/null +++ b/untests/meta_utilities/arg7_tests.cpp @@ -0,0 +1,124 @@ +/******************************************************************************* + * 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 A { + A() = default; + virtual ~A() = default; + + A(A&&) = delete; + A(const A&) = delete; + A& operator=(A&&) = delete; + A& operator=(const A&) = delete; + + int i = 1; + }; + + struct B : virtual A { + int i = 2; + }; + + struct C : virtual A { + int i = 3; + }; + + struct D : B, C { + int i = 4; + }; +} + +TEST_CASE("meta/meta_utilities/arg7") { + namespace meta = meta_hpp; + + // * <- B <- * + // A D + // * <- C <- * + + meta::class_(); + meta::class_().base_(); + meta::class_().base_(); + meta::class_().base_().base_(); +} + +TEST_CASE("meta/meta_utilities/arg7/cast") { + namespace meta = meta_hpp; + using meta::detail::arg; + + SUBCASE("int*") { + int i{42}; + + CHECK(arg{&i}.can_cast_to()); + CHECK(arg{&i}.can_cast_to()); + + CHECK(arg{&i}.cast() == &i); + CHECK(arg{&i}.cast() == &i); + } + + SUBCASE("const int*") { + const int i{42}; + + CHECK_FALSE(arg{&i}.can_cast_to()); + CHECK(arg{&i}.can_cast_to()); + + CHECK_THROWS(std::ignore = arg{&i}.cast()); + CHECK(arg{&i}.cast() == &i); + } + + SUBCASE("D*") { + D d; + + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + + CHECK(arg{&d}.can_cast_to()); + CHECK(arg{&d}.can_cast_to()); + + CHECK(arg{&d}.cast() == &d); + CHECK(arg{&d}.cast() == &d); + } + + SUBCASE("const D*") { + const D d; + + static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); + + CHECK_FALSE(arg{&d}.can_cast_to()); + CHECK(arg{&d}.can_cast_to()); + + CHECK_THROWS(std::ignore = arg{&d}.cast()); + CHECK(arg{&d}.cast() == &d); + } + + SUBCASE("D[2]") { + D arr[2]; + + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + + CHECK(arg{arr}.can_cast_to()); + CHECK(arg{arr}.can_cast_to()); + + CHECK(arg{arr}.cast() == &arr); + CHECK(arg{arr}.cast() == &arr); + } + + SUBCASE("const D[2]") { + const D arr[2]; + + static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); + + CHECK_FALSE(arg{arr}.can_cast_to()); + CHECK(arg{arr}.can_cast_to()); + + CHECK_THROWS(std::ignore = arg{arr}.cast()); + CHECK(arg{arr}.cast() == &arr); + } +} From 0564b1055725883dfe73f6f05ffd621b5d490f4a Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sun, 16 Jan 2022 10:54:01 +0700 Subject: [PATCH 178/233] nullptr type --- TODO.md | 1 - headers/meta.hpp/meta_all.hpp | 1 + headers/meta.hpp/meta_base.hpp | 3 + headers/meta.hpp/meta_kinds.hpp | 11 +++ headers/meta.hpp/meta_traits.hpp | 3 - headers/meta.hpp/meta_types.hpp | 26 ++++++ headers/meta.hpp/meta_types/any_type.hpp | 13 +++ headers/meta.hpp/meta_types/nullptr_type.hpp | 45 ++++++++++ headers/meta.hpp/meta_utilities/arg.hpp | 8 ++ untests/meta_states/function_tests.cpp | 15 ++++ untests/meta_types/any_type_tests.cpp | 20 ++++- untests/meta_utilities/arg7_tests.cpp | 86 ++++++++++++++++++-- 12 files changed, 220 insertions(+), 12 deletions(-) create mode 100644 headers/meta.hpp/meta_types/nullptr_type.hpp diff --git a/TODO.md b/TODO.md index 7bad6d4..af4fed2 100644 --- a/TODO.md +++ b/TODO.md @@ -3,7 +3,6 @@ - add array value access - add return value policy - add meta exception class; -- add conversion of nullptr to any pointers; - void value? - all string to hash? diff --git a/headers/meta.hpp/meta_all.hpp b/headers/meta.hpp/meta_all.hpp index 5fca320..3befe92 100644 --- a/headers/meta.hpp/meta_all.hpp +++ b/headers/meta.hpp/meta_all.hpp @@ -45,6 +45,7 @@ #include "meta_types/function_type.hpp" #include "meta_types/member_type.hpp" #include "meta_types/method_type.hpp" +#include "meta_types/nullptr_type.hpp" #include "meta_types/number_type.hpp" #include "meta_types/pointer_type.hpp" #include "meta_types/reference_type.hpp" diff --git a/headers/meta.hpp/meta_base.hpp b/headers/meta.hpp/meta_base.hpp index 7c6f43c..45ab91a 100644 --- a/headers/meta.hpp/meta_base.hpp +++ b/headers/meta.hpp/meta_base.hpp @@ -123,6 +123,7 @@ namespace meta_hpp class function_type; class member_type; class method_type; + class nullptr_type; class number_type; class pointer_type; class reference_type; @@ -138,6 +139,7 @@ namespace meta_hpp struct function_type_data; struct member_type_data; struct method_type_data; + struct nullptr_type_data; struct number_type_data; struct pointer_type_data; struct reference_type_data; @@ -151,6 +153,7 @@ namespace meta_hpp using function_type_data_ptr = std::shared_ptr; using member_type_data_ptr = std::shared_ptr; using method_type_data_ptr = std::shared_ptr; + using nullptr_type_data_ptr = std::shared_ptr; using number_type_data_ptr = std::shared_ptr; using pointer_type_data_ptr = std::shared_ptr; using reference_type_data_ptr = std::shared_ptr; diff --git a/headers/meta.hpp/meta_kinds.hpp b/headers/meta.hpp/meta_kinds.hpp index c524c13..9ff3d00 100644 --- a/headers/meta.hpp/meta_kinds.hpp +++ b/headers/meta.hpp/meta_kinds.hpp @@ -18,6 +18,7 @@ namespace meta_hpp function_, member_, method_, + nullptr_, number_, pointer_, reference_, @@ -45,6 +46,9 @@ namespace meta_hpp::detail template < typename T > concept method_kind = std::is_member_function_pointer_v; + template < typename T > + concept nullptr_kind = std::is_null_pointer_v; + template < typename T > concept number_kind = std::is_arithmetic_v; @@ -65,6 +69,7 @@ namespace meta_hpp::detail if constexpr ( function_kind ) { return type_kind::function_; } if constexpr ( member_kind ) { return type_kind::member_; } if constexpr ( method_kind ) { return type_kind::method_; } + if constexpr ( nullptr_kind ) { return type_kind::nullptr_; } if constexpr ( number_kind ) { return type_kind::number_; } if constexpr ( pointer_kind ) { return type_kind::pointer_; } if constexpr ( reference_kind ) { return type_kind::reference_; } @@ -119,6 +124,12 @@ namespace meta_hpp::detail using kind_type_data = method_type_data; }; + template <> + struct type_kind_traits { + using kind_type = nullptr_type; + using kind_type_data = nullptr_type_data; + }; + template <> struct type_kind_traits { using kind_type = number_type; diff --git a/headers/meta.hpp/meta_traits.hpp b/headers/meta.hpp/meta_traits.hpp index 41db8dc..cde2cd0 100644 --- a/headers/meta.hpp/meta_traits.hpp +++ b/headers/meta.hpp/meta_traits.hpp @@ -40,9 +40,6 @@ namespace meta_hpp::detail template < reference_kind Reference > struct reference_traits; - - template < void_kind Void > - struct void_traits; } namespace meta_hpp diff --git a/headers/meta.hpp/meta_types.hpp b/headers/meta.hpp/meta_types.hpp index 22fcf3a..ebf8a7e 100644 --- a/headers/meta.hpp/meta_types.hpp +++ b/headers/meta.hpp/meta_types.hpp @@ -72,6 +72,7 @@ namespace meta_hpp std::is_same_v || std::is_same_v || std::is_same_v || + std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v || @@ -135,6 +136,7 @@ namespace meta_hpp any_type(const function_type& other) noexcept; any_type(const member_type& other) noexcept; any_type(const method_type& other) noexcept; + any_type(const nullptr_type& other) noexcept; any_type(const number_type& other) noexcept; any_type(const pointer_type& other) noexcept; any_type(const reference_type& other) noexcept; @@ -147,6 +149,7 @@ namespace meta_hpp [[nodiscard]] bool is_function() const noexcept; [[nodiscard]] bool is_member() const noexcept; [[nodiscard]] bool is_method() const noexcept; + [[nodiscard]] bool is_nullptr() const noexcept; [[nodiscard]] bool is_number() const noexcept; [[nodiscard]] bool is_pointer() const noexcept; [[nodiscard]] bool is_reference() const noexcept; @@ -159,6 +162,7 @@ namespace meta_hpp [[nodiscard]] function_type as_function() const noexcept; [[nodiscard]] member_type as_member() const noexcept; [[nodiscard]] method_type as_method() const noexcept; + [[nodiscard]] nullptr_type as_nullptr() const noexcept; [[nodiscard]] number_type as_number() const noexcept; [[nodiscard]] pointer_type as_pointer() const noexcept; [[nodiscard]] reference_type as_reference() const noexcept; @@ -352,6 +356,20 @@ namespace meta_hpp friend auto detail::data_access(const method_type&); }; + class nullptr_type final { + public: + nullptr_type() = default; + nullptr_type(detail::nullptr_type_data_ptr data); + + [[nodiscard]] bool is_valid() const noexcept; + [[nodiscard]] explicit operator bool() const noexcept; + + [[nodiscard]] type_id get_id() const noexcept; + private: + detail::nullptr_type_data_ptr data_; + friend auto detail::data_access(const nullptr_type&); + }; + class number_type final { public: number_type() = default; @@ -530,6 +548,14 @@ namespace meta_hpp::detail [[nodiscard]] static method_type_data_ptr get_static(); }; + struct nullptr_type_data final : type_data_base { + template < nullptr_kind Nullptr > + explicit nullptr_type_data(type_list); + + template < nullptr_kind Nullptr > + [[nodiscard]] static nullptr_type_data_ptr get_static(); + }; + struct number_type_data final : type_data_base { const bitflags flags; const std::size_t size; diff --git a/headers/meta.hpp/meta_types/any_type.hpp b/headers/meta.hpp/meta_types/any_type.hpp index 81716a9..2a4884c 100644 --- a/headers/meta.hpp/meta_types/any_type.hpp +++ b/headers/meta.hpp/meta_types/any_type.hpp @@ -51,6 +51,9 @@ namespace meta_hpp inline any_type::any_type(const method_type& other) noexcept : data_{detail::data_access(other)} {} + inline any_type::any_type(const nullptr_type& other) noexcept + : data_{detail::data_access(other)} {} + inline any_type::any_type(const number_type& other) noexcept : data_{detail::data_access(other)} {} @@ -91,6 +94,10 @@ namespace meta_hpp return data_ && data_->kind == type_kind::method_; } + inline bool any_type::is_nullptr() const noexcept { + return data_ && data_->kind == type_kind::nullptr_; + } + inline bool any_type::is_number() const noexcept { return data_ && data_->kind == type_kind::number_; } @@ -149,6 +156,12 @@ namespace meta_hpp : method_type{}; } + inline nullptr_type any_type::as_nullptr() const noexcept { + return is_nullptr() + ? nullptr_type{std::static_pointer_cast(data_)} + : nullptr_type{}; + } + inline number_type any_type::as_number() const noexcept { return is_number() ? number_type{std::static_pointer_cast(data_)} diff --git a/headers/meta.hpp/meta_types/nullptr_type.hpp b/headers/meta.hpp/meta_types/nullptr_type.hpp new file mode 100644 index 0000000..c566a9b --- /dev/null +++ b/headers/meta.hpp/meta_types/nullptr_type.hpp @@ -0,0 +1,45 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_types.hpp" + +namespace meta_hpp::detail +{ + template < nullptr_kind Nullptr > + struct nullptr_tag {}; + + template < nullptr_kind Nullptr > + // NOLINTNEXTLINE(readability-named-parameter) + nullptr_type_data::nullptr_type_data(type_list) + : type_data_base{type_id{type_list>{}}, type_kind::nullptr_} {} + + template < nullptr_kind Nullptr > + nullptr_type_data_ptr nullptr_type_data::get_static() { + static nullptr_type_data_ptr data = std::make_shared(type_list{}); + return data; + } +} + +namespace meta_hpp +{ + inline nullptr_type::nullptr_type(detail::nullptr_type_data_ptr data) + : data_{std::move(data)} {} + + inline bool nullptr_type::is_valid() const noexcept { + return !!data_; + } + + inline nullptr_type::operator bool() const noexcept { + return is_valid(); + } + + inline type_id nullptr_type::get_id() const noexcept { + return data_->id; + } +} diff --git a/headers/meta.hpp/meta_utilities/arg.hpp b/headers/meta.hpp/meta_utilities/arg.hpp index f081759..c71de18 100644 --- a/headers/meta.hpp/meta_utilities/arg.hpp +++ b/headers/meta.hpp/meta_utilities/arg.hpp @@ -97,6 +97,10 @@ namespace meta_hpp::detail }; if constexpr ( std::is_pointer_v ) { + if ( to_type.is_pointer() && from_type.is_nullptr() ) { + return true; + } + if ( to_type.is_pointer() && from_type.is_array() ) { const pointer_type& to_type_ptr = to_type.as_pointer(); const bool to_type_ptr_readonly = to_type_ptr.get_flags().has(pointer_flags::is_readonly); @@ -206,6 +210,10 @@ namespace meta_hpp::detail const any_type& to_type = resolve_type(); if constexpr ( std::is_pointer_v ) { + if ( to_type.is_pointer() && from_type.is_nullptr() ) { + return static_cast(nullptr); + } + if ( to_type.is_pointer() && from_type.is_array() ) { const pointer_type& to_type_ptr = to_type.as_pointer(); const array_type& from_type_array = from_type.as_array(); diff --git a/untests/meta_states/function_tests.cpp b/untests/meta_states/function_tests.cpp index 449e1d8..a5b24bc 100644 --- a/untests/meta_states/function_tests.cpp +++ b/untests/meta_states/function_tests.cpp @@ -20,6 +20,7 @@ namespace return v.x * v.x + v.y * v.y; } + static bool arg_nullptr(const void* ptr) { return ptr == nullptr; } static int arg_bounded_arr(ivec2 vs[2]) { return vs[0].x + vs[0].y + vs[1].x + vs[1].y; } static int arg_unbounded_arr(ivec2 vs[]) { return vs[0].x + vs[0].y + vs[1].x + vs[1].y; } static int arg_bounded_const_arr(const ivec2 vs[2]) { return vs[0].x + vs[0].y + vs[1].x + vs[1].y; } @@ -37,6 +38,7 @@ TEST_CASE("meta/meta_states/function") { meta::class_() .function_("iadd", &ivec2::iadd) .function_("ilength2", &ivec2::ilength2) + .function_("arg_nullptr", &ivec2::arg_nullptr) .function_("arg_bounded_arr", &ivec2::arg_bounded_arr) .function_("arg_unbounded_arr", &ivec2::arg_unbounded_arr) .function_("arg_bounded_const_arr", &ivec2::arg_bounded_const_arr) @@ -114,6 +116,19 @@ TEST_CASE("meta/meta_states/function") { CHECK(func.invoke(ivec2{2,3}).value() == 13); } + SUBCASE("arg_null") { + const meta::function func = ivec2_type.get_function("arg_nullptr"); + REQUIRE(func); + + CHECK(func.is_invocable_with()); + CHECK(func.is_invocable_with()); + CHECK(func.is_invocable_with()); + + int i{42}; + CHECK(func.invoke(&i) == false); + CHECK(func.invoke(nullptr) == true); + } + SUBCASE("arg_arr") { ivec2 bounded_arr[2]{{1,2},{3,4}}; ivec2* unbounded_arr = bounded_arr; diff --git a/untests/meta_types/any_type_tests.cpp b/untests/meta_types/any_type_tests.cpp index c9ab8f7..bf04fa7 100644 --- a/untests/meta_types/any_type_tests.cpp +++ b/untests/meta_types/any_type_tests.cpp @@ -162,10 +162,28 @@ TEST_CASE("meta/meta_types/any_type") { CHECK(type.is_method()); CHECK(type.get_kind() == meta::type_kind::method_); + CHECK_FALSE(type.is_nullptr()); + CHECK_FALSE(type.as_nullptr()); + + const meta::method_type& specific_type = type.as_method(); + REQUIRE(specific_type); + CHECK(specific_type.get_id() == type.get_id()); + } + + SUBCASE("nullptr") { + const meta::any_type& type = meta::resolve_type(nullptr); + + REQUIRE(type); + REQUIRE(type == meta::resolve_type()); + REQUIRE(type.get_id() == meta::resolve_type().get_id()); + + CHECK(type.is_nullptr()); + CHECK(type.get_kind() == meta::type_kind::nullptr_); + CHECK_FALSE(type.is_number()); CHECK_FALSE(type.as_number()); - const meta::method_type& specific_type = type.as_method(); + const meta::nullptr_type& specific_type = type.as_nullptr(); REQUIRE(specific_type); CHECK(specific_type.get_id() == type.get_id()); } diff --git a/untests/meta_utilities/arg7_tests.cpp b/untests/meta_utilities/arg7_tests.cpp index 4ffe3da..2fed809 100644 --- a/untests/meta_utilities/arg7_tests.cpp +++ b/untests/meta_utilities/arg7_tests.cpp @@ -46,13 +46,16 @@ TEST_CASE("meta/meta_utilities/arg7") { meta::class_().base_().base_(); } -TEST_CASE("meta/meta_utilities/arg7/cast") { +TEST_CASE("meta/meta_utilities/arg7/cast/to_void") { namespace meta = meta_hpp; using meta::detail::arg; - SUBCASE("int*") { + SUBCASE("int* -> void*") { int i{42}; + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + CHECK(arg{&i}.can_cast_to()); CHECK(arg{&i}.can_cast_to()); @@ -60,9 +63,12 @@ TEST_CASE("meta/meta_utilities/arg7/cast") { CHECK(arg{&i}.cast() == &i); } - SUBCASE("const int*") { + SUBCASE("const int* -> void*") { const int i{42}; + static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); + CHECK_FALSE(arg{&i}.can_cast_to()); CHECK(arg{&i}.can_cast_to()); @@ -70,7 +76,7 @@ TEST_CASE("meta/meta_utilities/arg7/cast") { CHECK(arg{&i}.cast() == &i); } - SUBCASE("D*") { + SUBCASE("D* -> void*") { D d; static_assert(std::is_invocable_v); @@ -83,7 +89,7 @@ TEST_CASE("meta/meta_utilities/arg7/cast") { CHECK(arg{&d}.cast() == &d); } - SUBCASE("const D*") { + SUBCASE("const D* -> void*") { const D d; static_assert(!std::is_invocable_v); @@ -96,7 +102,7 @@ TEST_CASE("meta/meta_utilities/arg7/cast") { CHECK(arg{&d}.cast() == &d); } - SUBCASE("D[2]") { + SUBCASE("D[2] -> void*") { D arr[2]; static_assert(std::is_invocable_v); @@ -109,7 +115,7 @@ TEST_CASE("meta/meta_utilities/arg7/cast") { CHECK(arg{arr}.cast() == &arr); } - SUBCASE("const D[2]") { + SUBCASE("const D[2] -> void*") { const D arr[2]; static_assert(!std::is_invocable_v); @@ -122,3 +128,69 @@ TEST_CASE("meta/meta_utilities/arg7/cast") { CHECK(arg{arr}.cast() == &arr); } } + +TEST_CASE("meta/meta_utilities/arg7/cast/from_nullptr") { + namespace meta = meta_hpp; + using meta::detail::arg; + + SUBCASE("nullptr -> *") { + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + + nullptr_t n1{nullptr}; + const nullptr_t n2{nullptr}; + + CHECK(arg{n1}.can_cast_to()); + CHECK(arg{std::move(n1)}.can_cast_to()); + CHECK(arg{n2}.can_cast_to()); + CHECK(arg{std::move(n2)}.can_cast_to()); + + CHECK(arg{n1}.can_cast_to()); + CHECK(arg{std::move(n1)}.can_cast_to()); + CHECK(arg{n2}.can_cast_to()); + CHECK(arg{std::move(n2)}.can_cast_to()); + + CHECK(arg{n1}.can_cast_to()); + CHECK(arg{std::move(n1)}.can_cast_to()); + CHECK(arg{n2}.can_cast_to()); + CHECK(arg{std::move(n2)}.can_cast_to()); + + CHECK(arg{n1}.can_cast_to()); + CHECK(arg{std::move(n1)}.can_cast_to()); + CHECK(arg{n2}.can_cast_to()); + CHECK(arg{std::move(n2)}.can_cast_to()); + + // + + CHECK(arg{n1}.cast() == nullptr); + CHECK(arg{std::move(n1)}.cast() == nullptr); + CHECK(arg{n2}.cast() == nullptr); + CHECK(arg{std::move(n2)}.cast() == nullptr); + + CHECK(arg{n1}.cast() == nullptr); + CHECK(arg{std::move(n1)}.cast() == nullptr); + CHECK(arg{n2}.cast() == nullptr); + CHECK(arg{std::move(n2)}.cast() == nullptr); + + CHECK(arg{n1}.cast() == nullptr); + CHECK(arg{std::move(n1)}.cast() == nullptr); + CHECK(arg{n2}.cast() == nullptr); + CHECK(arg{std::move(n2)}.cast() == nullptr); + + CHECK(arg{n1}.cast() == nullptr); + CHECK(arg{std::move(n1)}.cast() == nullptr); + CHECK(arg{n2}.cast() == nullptr); + CHECK(arg{std::move(n2)}.cast() == nullptr); + } +} From 4bfdc9d69b3107dc0add29542080e39b627f252f Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sun, 16 Jan 2022 14:50:11 +0700 Subject: [PATCH 179/233] class bind concepts instead static assets --- headers/meta.hpp/meta_base.hpp | 2 +- headers/meta.hpp/meta_registry.hpp | 37 +++++++++++++++++++ headers/meta.hpp/meta_registry/class_bind.hpp | 10 +++-- untests/meta_states/function_tests.cpp | 2 +- untests/meta_types/any_type_tests.cpp | 4 +- untests/meta_utilities/arg7_tests.cpp | 28 +++++++------- 6 files changed, 61 insertions(+), 22 deletions(-) diff --git a/headers/meta.hpp/meta_base.hpp b/headers/meta.hpp/meta_base.hpp index 45ab91a..7068549 100644 --- a/headers/meta.hpp/meta_base.hpp +++ b/headers/meta.hpp/meta_base.hpp @@ -47,7 +47,7 @@ namespace meta_hpp } template < typename Signature, typename Class > - constexpr auto select(Signature Class::*func) -> decltype(func) { + constexpr auto select(Signature Class::*func) noexcept -> Signature Class::* { return func; } diff --git a/headers/meta.hpp/meta_registry.hpp b/headers/meta.hpp/meta_registry.hpp index a5b8448..47efb89 100644 --- a/headers/meta.hpp/meta_registry.hpp +++ b/headers/meta.hpp/meta_registry.hpp @@ -9,6 +9,37 @@ #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 { template < detail::class_kind Class > @@ -18,21 +49,27 @@ namespace meta_hpp operator class_type() const noexcept; template < typename... Args > + requires detail::class_bind_ctor_kind class_bind& ctor_(); template < detail::class_kind Base > + requires detail::class_bind_base_kind class_bind& base_(); template < detail::function_kind Function > + requires detail::class_bind_function_kind class_bind& function_(std::string name, Function function); template < detail::member_kind Member > + requires detail::class_bind_member_kind class_bind& member_(std::string name, Member member); template < detail::method_kind Method > + requires detail::class_bind_method_kind class_bind& method_(std::string name, Method method); template < detail::pointer_kind Pointer > + requires detail::class_bind_variable_kind class_bind& variable_(std::string name, Pointer pointer); private: detail::class_type_data_ptr data_; diff --git a/headers/meta.hpp/meta_registry/class_bind.hpp b/headers/meta.hpp/meta_registry/class_bind.hpp index 81dce45..9dc1554 100644 --- a/headers/meta.hpp/meta_registry/class_bind.hpp +++ b/headers/meta.hpp/meta_registry/class_bind.hpp @@ -22,8 +22,8 @@ namespace meta_hpp template < detail::class_kind Class > template < typename... Args > + requires detail::class_bind_ctor_kind class_bind& class_bind::ctor_() { - static_assert(detail::stdex::constructible_from); auto ctor_state = detail::ctor_state::make(); data_->ctors.emplace(ctor_state->index, std::move(ctor_state)); return *this; @@ -31,8 +31,8 @@ namespace meta_hpp template < detail::class_kind Class > template < detail::class_kind Base > + requires detail::class_bind_base_kind class_bind& class_bind::base_() { - static_assert(detail::stdex::derived_from); data_->bases.emplace(resolve_type()); data_->bases_info.emplace(resolve_type(), detail::class_type_data::base_info{ .upcast = +[](void* derived) -> void* { @@ -44,6 +44,7 @@ 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)); data_->functions.emplace(function_state->index, std::move(function_state)); @@ -52,8 +53,8 @@ namespace meta_hpp template < detail::class_kind Class > template < detail::member_kind Member > + requires detail::class_bind_member_kind class_bind& class_bind::member_(std::string name, Member member) { - static_assert(std::is_same_v::class_type>); 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; @@ -61,8 +62,8 @@ namespace meta_hpp template < detail::class_kind Class > template < detail::method_kind Method > + requires detail::class_bind_method_kind class_bind& class_bind::method_(std::string name, Method method) { - static_assert(std::is_same_v::class_type>); 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; @@ -70,6 +71,7 @@ namespace meta_hpp 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)); data_->variables.emplace(variable_state->index, std::move(variable_state)); diff --git a/untests/meta_states/function_tests.cpp b/untests/meta_states/function_tests.cpp index a5b24bc..f58b630 100644 --- a/untests/meta_states/function_tests.cpp +++ b/untests/meta_states/function_tests.cpp @@ -122,7 +122,7 @@ TEST_CASE("meta/meta_states/function") { CHECK(func.is_invocable_with()); CHECK(func.is_invocable_with()); - CHECK(func.is_invocable_with()); + CHECK(func.is_invocable_with()); int i{42}; CHECK(func.invoke(&i) == false); diff --git a/untests/meta_types/any_type_tests.cpp b/untests/meta_types/any_type_tests.cpp index bf04fa7..2bf6c88 100644 --- a/untests/meta_types/any_type_tests.cpp +++ b/untests/meta_types/any_type_tests.cpp @@ -174,8 +174,8 @@ TEST_CASE("meta/meta_types/any_type") { const meta::any_type& type = meta::resolve_type(nullptr); REQUIRE(type); - REQUIRE(type == meta::resolve_type()); - REQUIRE(type.get_id() == meta::resolve_type().get_id()); + REQUIRE(type == meta::resolve_type()); + REQUIRE(type.get_id() == meta::resolve_type().get_id()); CHECK(type.is_nullptr()); CHECK(type.get_kind() == meta::type_kind::nullptr_); diff --git a/untests/meta_utilities/arg7_tests.cpp b/untests/meta_utilities/arg7_tests.cpp index 2fed809..bd515b9 100644 --- a/untests/meta_utilities/arg7_tests.cpp +++ b/untests/meta_utilities/arg7_tests.cpp @@ -134,22 +134,22 @@ TEST_CASE("meta/meta_utilities/arg7/cast/from_nullptr") { using meta::detail::arg; SUBCASE("nullptr -> *") { - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); - static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v); - nullptr_t n1{nullptr}; - const nullptr_t n2{nullptr}; + std::nullptr_t n1{nullptr}; + const std::nullptr_t n2{nullptr}; CHECK(arg{n1}.can_cast_to()); CHECK(arg{std::move(n1)}.can_cast_to()); From f510ba8ca43d7b6ab7253668b2c8ecb5d1a8a966 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sun, 16 Jan 2022 15:10:22 +0700 Subject: [PATCH 180/233] add classes example --- manuals/meta_examples/classes_example.cpp | 65 ++++++++++++++++++++++- manuals/meta_examples/scopes_example.cpp | 15 ++++++ 2 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 manuals/meta_examples/scopes_example.cpp diff --git a/manuals/meta_examples/classes_example.cpp b/manuals/meta_examples/classes_example.cpp index eae4b39..ea6b6aa 100644 --- a/manuals/meta_examples/classes_example.cpp +++ b/manuals/meta_examples/classes_example.cpp @@ -8,8 +8,71 @@ namespace { + class shape { + public: + virtual ~shape() = default; + virtual int get_area() const = 0; + }; + + class rectangle : public shape { + public: + explicit rectangle(int width, int height) + : width_{width} + , height_{height} {} + + int get_width() const { + return width_; + } + + int get_height() const { + return height_; + } + + int get_area() const override { + return width_ * height_; + } + private: + int width_{}; + int height_{}; + }; } -TEST_CASE("meta/meta_examples/classes") { +TEST_CASE("meta/meta_examples/classes/type") { namespace meta = meta_hpp; + + // 'shape' class type registration + meta::class_() + .method_("get_area", &shape::get_area); + + // 'rectangle' class type registration + meta::class_() + .base_() + .ctor_() + .method_("get_width", &rectangle::get_width) + .method_("get_height", &rectangle::get_height); + + // resolves a class type by static class type + const meta::class_type rectangle_type = meta::resolve_type(); + + // prints all class methods + fmt::print("* rectangle:\n"); + for ( auto&& [index, method] : rectangle_type.get_methods() ) { + fmt::print(" + {}/{}\n", index.name, index.type.get_arity()); + } +} + +TEST_CASE("meta/meta_examples/classes/usage") { + namespace meta = meta_hpp; + + // resolves a class type by static class type + const meta::class_type rectangle_type = meta::resolve_type(); + + // finds the method 'get_area' by name + const meta::method rectangle_area = rectangle_type.get_method("get_area"); + + // creates a rectangle instance by the registered constructor(int, int) + const meta::value rectangle_v = rectangle_type.create(10, 20).value(); + + // calls the method with the dynamic rectangle instance 'rectangle_v' + CHECK(rectangle_area.invoke(rectangle_v) == 200); } diff --git a/manuals/meta_examples/scopes_example.cpp b/manuals/meta_examples/scopes_example.cpp new file mode 100644 index 0000000..8f948ee --- /dev/null +++ b/manuals/meta_examples/scopes_example.cpp @@ -0,0 +1,15 @@ +/******************************************************************************* + * 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_manuals.hpp" + +namespace +{ +} + +TEST_CASE("meta/meta_examples/scopes") { + namespace meta = meta_hpp; +} From 79b26bef0956138dd1aa38bfe5927b0cde0b6c49 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Mon, 17 Jan 2022 04:10:55 +0700 Subject: [PATCH 181/233] add value ctor copy constraints --- headers/meta.hpp/meta_utilities.hpp | 7 ++++--- headers/meta.hpp/meta_utilities/value.hpp | 14 ++++++++------ 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/headers/meta.hpp/meta_utilities.hpp b/headers/meta.hpp/meta_utilities.hpp index 8d4eac5..522233d 100644 --- a/headers/meta.hpp/meta_utilities.hpp +++ b/headers/meta.hpp/meta_utilities.hpp @@ -93,7 +93,6 @@ namespace meta_hpp::detail public: noncopyable(noncopyable&&) = delete; noncopyable(const noncopyable&) = delete; - noncopyable& operator=(noncopyable&&) = delete; noncopyable& operator=(const noncopyable&) = delete; }; @@ -115,10 +114,12 @@ namespace meta_hpp ~value() = default; - template < detail::decay_non_uvalue_kind T > + template < detail::decay_non_uvalue_kind T, typename Tp = std::decay_t > + requires detail::stdex::copy_constructible explicit value(T&& val); - template < detail::decay_non_uvalue_kind T > + template < detail::decay_non_uvalue_kind T, typename Tp = std::decay_t > + requires detail::stdex::copy_constructible value& operator=(T&& val); void swap(value& other) noexcept; diff --git a/headers/meta.hpp/meta_utilities/value.hpp b/headers/meta.hpp/meta_utilities/value.hpp index 24c6e82..571a61f 100644 --- a/headers/meta.hpp/meta_utilities/value.hpp +++ b/headers/meta.hpp/meta_utilities/value.hpp @@ -154,12 +154,14 @@ namespace meta_hpp return *this; } - template < detail::decay_non_uvalue_kind T > + template < detail::decay_non_uvalue_kind T, typename Tp > + requires detail::stdex::copy_constructible value::value(T&& val) : raw_{std::forward(val)} , traits_{traits::get>()} {} - template < detail::decay_non_uvalue_kind T > + template < detail::decay_non_uvalue_kind T, typename Tp > + requires detail::stdex::copy_constructible value& value::operator=(T&& val) { value temp{std::forward(val)}; swap(temp); @@ -241,14 +243,14 @@ namespace meta_hpp namespace meta_hpp { - template < typename T > + template < detail::has_value_less_traits T > [[nodiscard]] bool operator<(const value& l, const T& r) { const any_type& r_type = resolve_type(); return (l.get_type() < r_type) || (l.get_type() == r_type && std::less<>{}(l.cast(), r)); } - template < typename T > + template < detail::has_value_less_traits T > [[nodiscard]] bool operator<(const T& l, const value& r) { const any_type& l_type = resolve_type(); return (l_type < r.get_type()) @@ -263,13 +265,13 @@ namespace meta_hpp namespace meta_hpp { - template < typename T > + template < detail::has_value_equals_traits T > [[nodiscard]] bool operator==(const value& l, const T& r) { return l.get_type() == resolve_type() && std::equal_to<>{}(l.cast(), r); } - template < typename T > + template < detail::has_value_equals_traits T > [[nodiscard]] bool operator==(const T& l, const value& r) { return resolve_type() == r.get_type() && std::equal_to<>{}(l, r.cast()); From b414e71d8f709277147b56ac2a7419dbf16421da Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 21 Jan 2022 22:01:57 +0700 Subject: [PATCH 182/233] 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());\ From a0a24ea94ef90f6f310e4a859d88122a99377f3a Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sat, 22 Jan 2022 05:58:04 +0700 Subject: [PATCH 183/233] simple dtors --- headers/meta.hpp/meta_all.hpp | 3 + headers/meta.hpp/meta_base.hpp | 8 + headers/meta.hpp/meta_kinds.hpp | 7 + headers/meta.hpp/meta_registry.hpp | 8 + headers/meta.hpp/meta_registry/class_bind.hpp | 9 ++ headers/meta.hpp/meta_states.hpp | 39 +++++ headers/meta.hpp/meta_states/dtor.hpp | 114 ++++++++++++++ headers/meta.hpp/meta_traits.hpp | 8 + headers/meta.hpp/meta_traits/dtor_traits.hpp | 28 ++++ headers/meta.hpp/meta_types.hpp | 52 +++++++ headers/meta.hpp/meta_types/any_type.hpp | 13 ++ headers/meta.hpp/meta_types/class_type.hpp | 15 ++ headers/meta.hpp/meta_types/dtor_type.hpp | 57 +++++++ headers/meta.hpp/meta_utilities.hpp | 16 +- headers/meta.hpp/meta_utilities/arg.hpp | 2 - headers/meta.hpp/meta_utilities/inst.hpp | 66 ++++---- untests/meta_states/ctor_tests.cpp | 141 ++++++++++++++---- 17 files changed, 507 insertions(+), 79 deletions(-) create mode 100644 headers/meta.hpp/meta_states/dtor.hpp create mode 100644 headers/meta.hpp/meta_traits/dtor_traits.hpp create mode 100644 headers/meta.hpp/meta_types/dtor_type.hpp diff --git a/headers/meta.hpp/meta_all.hpp b/headers/meta.hpp/meta_all.hpp index 3befe92..432a9f8 100644 --- a/headers/meta.hpp/meta_all.hpp +++ b/headers/meta.hpp/meta_all.hpp @@ -17,6 +17,7 @@ #include "meta_states.hpp" #include "meta_states/ctor.hpp" +#include "meta_states/dtor.hpp" #include "meta_states/evalue.hpp" #include "meta_states/function.hpp" #include "meta_states/member.hpp" @@ -28,6 +29,7 @@ #include "meta_traits/array_traits.hpp" #include "meta_traits/class_traits.hpp" #include "meta_traits/ctor_traits.hpp" +#include "meta_traits/dtor_traits.hpp" #include "meta_traits/enum_traits.hpp" #include "meta_traits/function_traits.hpp" #include "meta_traits/member_traits.hpp" @@ -41,6 +43,7 @@ #include "meta_types/array_type.hpp" #include "meta_types/class_type.hpp" #include "meta_types/ctor_type.hpp" +#include "meta_types/dtor_type.hpp" #include "meta_types/enum_type.hpp" #include "meta_types/function_type.hpp" #include "meta_types/member_type.hpp" diff --git a/headers/meta.hpp/meta_base.hpp b/headers/meta.hpp/meta_base.hpp index 7068549..5f08db5 100644 --- a/headers/meta.hpp/meta_base.hpp +++ b/headers/meta.hpp/meta_base.hpp @@ -86,6 +86,7 @@ namespace meta_hpp namespace meta_hpp { class ctor; + class dtor; class evalue; class function; class member; @@ -96,6 +97,7 @@ namespace meta_hpp namespace detail { struct ctor_state; + struct dtor_state; struct evalue_state; struct function_state; struct member_state; @@ -104,6 +106,7 @@ namespace meta_hpp struct variable_state; using ctor_state_ptr = std::shared_ptr; + using dtor_state_ptr = std::shared_ptr; using evalue_state_ptr = std::shared_ptr; using function_state_ptr = std::shared_ptr; using member_state_ptr = std::shared_ptr; @@ -119,6 +122,7 @@ namespace meta_hpp class array_type; class class_type; class ctor_type; + class dtor_type; class enum_type; class function_type; class member_type; @@ -135,6 +139,7 @@ namespace meta_hpp struct array_type_data; struct class_type_data; struct ctor_type_data; + struct dtor_type_data; struct enum_type_data; struct function_type_data; struct member_type_data; @@ -149,6 +154,7 @@ namespace meta_hpp using array_type_data_ptr = std::shared_ptr; using class_type_data_ptr = std::shared_ptr; using ctor_type_data_ptr = std::shared_ptr; + using dtor_type_data_ptr = std::shared_ptr; using enum_type_data_ptr = std::shared_ptr; using function_type_data_ptr = std::shared_ptr; using member_type_data_ptr = std::shared_ptr; @@ -164,6 +170,7 @@ namespace meta_hpp namespace meta_hpp { struct ctor_index; + struct dtor_index; struct evalue_index; struct function_index; struct member_index; @@ -178,6 +185,7 @@ namespace meta_hpp using enum_map = std::map>; using ctor_map = std::map>; + using dtor_map = std::map>; using evalue_map = std::map>; using function_map = std::map>; using member_map = std::map>; diff --git a/headers/meta.hpp/meta_kinds.hpp b/headers/meta.hpp/meta_kinds.hpp index 9ff3d00..72691a6 100644 --- a/headers/meta.hpp/meta_kinds.hpp +++ b/headers/meta.hpp/meta_kinds.hpp @@ -14,6 +14,7 @@ namespace meta_hpp array_, class_, ctor_, + dtor_, enum_, function_, member_, @@ -100,6 +101,12 @@ namespace meta_hpp::detail using kind_type_data = ctor_type_data; }; + template <> + struct type_kind_traits { + using kind_type = dtor_type; + using kind_type_data = dtor_type_data; + }; + template <> struct type_kind_traits { using kind_type = enum_type; diff --git a/headers/meta.hpp/meta_registry.hpp b/headers/meta.hpp/meta_registry.hpp index 52b365a..958013b 100644 --- a/headers/meta.hpp/meta_registry.hpp +++ b/headers/meta.hpp/meta_registry.hpp @@ -18,6 +18,11 @@ namespace meta_hpp class_kind && requires(Args&&... args) { { Class{std::forward(args)...} }; }; + template < typename Class > + concept class_bind_dtor_kind = + class_kind && + requires(Class&& inst) { { inst.~Class() }; }; + template < typename Class, typename Base > concept class_bind_base_kind = class_kind && class_kind && @@ -45,6 +50,9 @@ namespace meta_hpp class_bind& ctor_(Policy = Policy{}) requires detail::class_bind_ctor_kind; + class_bind& dtor_() + requires detail::class_bind_dtor_kind; + template < detail::class_kind Base > class_bind& base_() requires detail::class_bind_base_kind; diff --git a/headers/meta.hpp/meta_registry/class_bind.hpp b/headers/meta.hpp/meta_registry/class_bind.hpp index 5f5b811..c2388f8 100644 --- a/headers/meta.hpp/meta_registry/class_bind.hpp +++ b/headers/meta.hpp/meta_registry/class_bind.hpp @@ -31,6 +31,15 @@ namespace meta_hpp return *this; } + template < detail::class_kind Class > + class_bind& class_bind::dtor_() + requires detail::class_bind_dtor_kind + { + auto dtor_state = detail::dtor_state::make(); + data_->dtors.emplace(dtor_state->index, std::move(dtor_state)); + return *this; + } + template < detail::class_kind Class > template < detail::class_kind Base > class_bind& class_bind::base_() diff --git a/headers/meta.hpp/meta_states.hpp b/headers/meta.hpp/meta_states.hpp index c8f5bc7..9115cd4 100644 --- a/headers/meta.hpp/meta_states.hpp +++ b/headers/meta.hpp/meta_states.hpp @@ -17,6 +17,7 @@ namespace meta_hpp template < typename T > concept state_family = std::is_same_v || + std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v || @@ -153,6 +154,32 @@ namespace meta_hpp detail::ctor_state_ptr state_; }; + class dtor final { + public: + explicit dtor() = default; + explicit dtor(detail::dtor_state_ptr state); + + [[nodiscard]] bool is_valid() const noexcept; + [[nodiscard]] explicit operator bool() const noexcept; + + [[nodiscard]] const dtor_index& get_index() const noexcept; + [[nodiscard]] const dtor_type& get_type() const noexcept; + + template < typename Arg > + void invoke(Arg&& ptr) const; + + template < typename Arg > + void operator()(Arg&& ptr) const; + + template < typename Arg > + [[nodiscard]] bool is_invocable_with() const noexcept; + + template < typename Arg > + [[nodiscard]] bool is_invocable_with(Arg&& ptr) const noexcept; + private: + detail::dtor_state_ptr state_; + }; + class evalue final { public: explicit evalue() = default; @@ -339,6 +366,18 @@ namespace meta_hpp::detail [[nodiscard]] static ctor_state_ptr make(); }; + struct dtor_state final { + using invoke_impl = std::function; + using is_invocable_with_impl = std::function; + + const dtor_index index; + const invoke_impl invoke; + const is_invocable_with_impl is_invocable_with; + + template < class_kind Class > + [[nodiscard]] static dtor_state_ptr make(); + }; + struct evalue_state final { const evalue_index index; const value enum_value; diff --git a/headers/meta.hpp/meta_states/dtor.hpp b/headers/meta.hpp/meta_states/dtor.hpp new file mode 100644 index 0000000..fdee5bd --- /dev/null +++ b/headers/meta.hpp/meta_states/dtor.hpp @@ -0,0 +1,114 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_states.hpp" + +#include "../meta_types/dtor_type.hpp" + +namespace meta_hpp::detail +{ + template < class_kind Class > + void raw_dtor_invoke(const arg& ptr) { + using dt = dtor_traits; + using class_type = typename dt::class_type; + + if ( !ptr.can_cast_to() ) { + throw std::logic_error("an attempt to call a destructor with an incorrect argument type"); + } + + class_type* raw_ptr = ptr.cast(); + if ( raw_ptr ) { + raw_ptr->~Class(); + } + } + + template < class_kind Class > + bool raw_dtor_is_invocable_with(const arg_base& ptr) { + using dt = dtor_traits; + using class_type = typename dt::class_type; + + return ptr.can_cast_to(); + } +} + +namespace meta_hpp::detail +{ + template < class_kind Class > + dtor_state::invoke_impl make_dtor_invoke() { + using namespace std::placeholders; + return std::bind(&raw_dtor_invoke, _1); + } + + template < class_kind Class > + dtor_state::is_invocable_with_impl make_dtor_is_invocable_with() { + using namespace std::placeholders; + return std::bind(&raw_dtor_is_invocable_with, _1); + } +} + +namespace meta_hpp::detail +{ + template < class_kind Class > + dtor_state_ptr dtor_state::make() { + dtor_index index{dtor_type_data::get_static()}; + return std::make_shared(dtor_state{ + .index{std::move(index)}, + .invoke{make_dtor_invoke()}, + .is_invocable_with{make_dtor_is_invocable_with()}, + }); + } +} + +namespace meta_hpp +{ + inline dtor::dtor(detail::dtor_state_ptr state) + : state_{std::move(state)} {} + + inline bool dtor::is_valid() const noexcept { + return !!state_; + } + + inline dtor::operator bool() const noexcept { + return is_valid(); + } + + inline const dtor_index& dtor::get_index() const noexcept { + return state_->index; + } + + inline const dtor_type& dtor::get_type() const noexcept { + return state_->index.type; + } + + template < typename Arg > + void dtor::invoke(Arg&& ptr) const { + using namespace detail; + const arg varg{std::forward(ptr)}; + state_->invoke(varg); + } + + template < typename Arg > + void dtor::operator()(Arg&& ptr) const { + invoke(std::forward(ptr)); + } + + template < typename Arg > + bool dtor::is_invocable_with() const noexcept { + using namespace detail; + const arg_base varg{type_list{}}; + return state_->is_invocable_with(varg); + } + + template < typename Arg > + bool dtor::is_invocable_with(Arg&& ptr) const noexcept { + using namespace detail; + const arg_base varg{std::forward(ptr)}; + return state_->is_invocable_with(varg); + } +} diff --git a/headers/meta.hpp/meta_traits.hpp b/headers/meta.hpp/meta_traits.hpp index cde2cd0..5ce4006 100644 --- a/headers/meta.hpp/meta_traits.hpp +++ b/headers/meta.hpp/meta_traits.hpp @@ -20,6 +20,9 @@ namespace meta_hpp::detail template < class_kind Class, typename... Args > struct ctor_traits; + template < class_kind Class > + struct dtor_traits; + template < enum_kind Enum > struct enum_traits; @@ -61,6 +64,10 @@ namespace meta_hpp is_noexcept = 1 << 0, }; + enum class dtor_flags : std::uint32_t { + is_noexcept = 1 << 0, + }; + enum class enum_flags : std::uint32_t { is_scoped = 1 << 0, }; @@ -100,6 +107,7 @@ namespace meta_hpp ENUM_HPP_OPERATORS_DECL(array_flags) ENUM_HPP_OPERATORS_DECL(class_flags) ENUM_HPP_OPERATORS_DECL(ctor_flags) + ENUM_HPP_OPERATORS_DECL(dtor_flags) ENUM_HPP_OPERATORS_DECL(enum_flags) ENUM_HPP_OPERATORS_DECL(function_flags) ENUM_HPP_OPERATORS_DECL(member_flags) diff --git a/headers/meta.hpp/meta_traits/dtor_traits.hpp b/headers/meta.hpp/meta_traits/dtor_traits.hpp new file mode 100644 index 0000000..1838343 --- /dev/null +++ b/headers/meta.hpp/meta_traits/dtor_traits.hpp @@ -0,0 +1,28 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_traits.hpp" + +namespace meta_hpp::detail +{ + template < class_kind Class > + struct dtor_traits { + using class_type = Class; + + [[nodiscard]] static constexpr bitflags make_flags() noexcept { + bitflags flags; + + if constexpr ( std::is_nothrow_destructible_v ) { + flags.set(dtor_flags::is_noexcept); + } + + return flags; + } + }; +} diff --git a/headers/meta.hpp/meta_types.hpp b/headers/meta.hpp/meta_types.hpp index ebf8a7e..d0a6d90 100644 --- a/headers/meta.hpp/meta_types.hpp +++ b/headers/meta.hpp/meta_types.hpp @@ -68,6 +68,7 @@ namespace meta_hpp std::is_same_v || std::is_same_v || std::is_same_v || + std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v || @@ -132,6 +133,7 @@ namespace meta_hpp any_type(const array_type& other) noexcept; any_type(const class_type& other) noexcept; any_type(const ctor_type& other) noexcept; + any_type(const dtor_type& other) noexcept; any_type(const enum_type& other) noexcept; any_type(const function_type& other) noexcept; any_type(const member_type& other) noexcept; @@ -145,6 +147,7 @@ namespace meta_hpp [[nodiscard]] bool is_array() const noexcept; [[nodiscard]] bool is_class() const noexcept; [[nodiscard]] bool is_ctor() const noexcept; + [[nodiscard]] bool is_dtor() const noexcept; [[nodiscard]] bool is_enum() const noexcept; [[nodiscard]] bool is_function() const noexcept; [[nodiscard]] bool is_member() const noexcept; @@ -158,6 +161,7 @@ namespace meta_hpp [[nodiscard]] array_type as_array() const noexcept; [[nodiscard]] class_type as_class() const noexcept; [[nodiscard]] ctor_type as_ctor() const noexcept; + [[nodiscard]] dtor_type as_dtor() const noexcept; [[nodiscard]] enum_type as_enum() const noexcept; [[nodiscard]] function_type as_function() const noexcept; [[nodiscard]] member_type as_member() const noexcept; @@ -208,6 +212,7 @@ namespace meta_hpp [[nodiscard]] const std::vector& get_argument_types() const noexcept; [[nodiscard]] const ctor_map& get_ctors() const noexcept; + [[nodiscard]] const dtor_map& get_dtors() const noexcept; [[nodiscard]] const class_set& get_bases() const noexcept; [[nodiscard]] const function_map& get_functions() const noexcept; [[nodiscard]] const member_map& get_members() const noexcept; @@ -220,6 +225,9 @@ namespace meta_hpp template < typename... Args > [[nodiscard]] std::optional operator()(Args&&... args) const; + template < typename Arg > + bool destroy(Arg&& ptr) const; + template < detail::class_kind Derived > [[nodiscard]] bool is_base_of() const noexcept; [[nodiscard]] bool is_base_of(const class_type& derived) const noexcept; @@ -272,6 +280,23 @@ namespace meta_hpp friend auto detail::data_access(const ctor_type&); }; + class dtor_type final { + public: + dtor_type() = default; + dtor_type(detail::dtor_type_data_ptr data); + + [[nodiscard]] bool is_valid() const noexcept; + [[nodiscard]] explicit operator bool() const noexcept; + + [[nodiscard]] type_id get_id() const noexcept; + [[nodiscard]] bitflags get_flags() const noexcept; + + [[nodiscard]] any_type get_class_type() const noexcept; + private: + detail::dtor_type_data_ptr data_; + friend auto detail::data_access(const dtor_type&); + }; + class enum_type final { public: enum_type() = default; @@ -465,6 +490,7 @@ namespace meta_hpp::detail const std::vector argument_types; ctor_map ctors; + dtor_map dtors; class_set bases; function_map functions; member_map members; @@ -498,6 +524,17 @@ namespace meta_hpp::detail [[nodiscard]] static ctor_type_data_ptr get_static(); }; + struct dtor_type_data final : type_data_base { + const bitflags flags; + const any_type class_type; + + template < class_kind Class > + explicit dtor_type_data(type_list); + + template < class_kind Class > + [[nodiscard]] static dtor_type_data_ptr get_static(); + }; + struct enum_type_data final : type_data_base { const bitflags flags; const number_type underlying_type; @@ -615,6 +652,21 @@ namespace meta_hpp } }; + struct dtor_index final { + const dtor_type type; + + explicit dtor_index(dtor_type type) + : type{std::move(type)} {} + + [[nodiscard]] friend bool operator<(const dtor_index& l, const dtor_index& r) noexcept { + return l.type < r.type; + } + + [[nodiscard]] friend bool operator==(const dtor_index& l, const dtor_index& r) noexcept { + return l.type == r.type; + } + }; + struct evalue_index final { const enum_type type; const std::string name; diff --git a/headers/meta.hpp/meta_types/any_type.hpp b/headers/meta.hpp/meta_types/any_type.hpp index 2a4884c..a545ee5 100644 --- a/headers/meta.hpp/meta_types/any_type.hpp +++ b/headers/meta.hpp/meta_types/any_type.hpp @@ -39,6 +39,9 @@ namespace meta_hpp inline any_type::any_type(const ctor_type& other) noexcept : data_{detail::data_access(other)} {} + inline any_type::any_type(const dtor_type& other) noexcept + : data_{detail::data_access(other)} {} + inline any_type::any_type(const enum_type& other) noexcept : data_{detail::data_access(other)} {} @@ -78,6 +81,10 @@ namespace meta_hpp return data_ && data_->kind == type_kind::ctor_; } + inline bool any_type::is_dtor() const noexcept { + return data_ && data_->kind == type_kind::dtor_; + } + inline bool any_type::is_enum() const noexcept { return data_ && data_->kind == type_kind::enum_; } @@ -132,6 +139,12 @@ namespace meta_hpp : ctor_type{}; } + inline dtor_type any_type::as_dtor() const noexcept { + return is_dtor() + ? dtor_type{std::static_pointer_cast(data_)} + : dtor_type{}; + } + inline enum_type any_type::as_enum() const noexcept { return is_enum() ? enum_type{std::static_pointer_cast(data_)} diff --git a/headers/meta.hpp/meta_types/class_type.hpp b/headers/meta.hpp/meta_types/class_type.hpp index d2bb6bf..4925fda 100644 --- a/headers/meta.hpp/meta_types/class_type.hpp +++ b/headers/meta.hpp/meta_types/class_type.hpp @@ -78,6 +78,10 @@ namespace meta_hpp return data_->ctors; } + inline const dtor_map& class_type::get_dtors() const noexcept { + return data_->dtors; + } + inline const class_set& class_type::get_bases() const noexcept { return data_->bases; } @@ -113,6 +117,17 @@ namespace meta_hpp return create(std::forward(args)...); } + template < typename Arg > + bool class_type::destroy(Arg&& ptr) const { + for ( auto&& dtor : data_->dtors ) { + if ( dtor.second.is_invocable_with(std::forward(ptr)) ) { + dtor.second.invoke(std::forward(ptr)); + return true; + } + } + return false; + } + template < detail::class_kind Derived > bool class_type::is_base_of() const noexcept { return is_base_of(resolve_type()); diff --git a/headers/meta.hpp/meta_types/dtor_type.hpp b/headers/meta.hpp/meta_types/dtor_type.hpp new file mode 100644 index 0000000..5e2c3da --- /dev/null +++ b/headers/meta.hpp/meta_types/dtor_type.hpp @@ -0,0 +1,57 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_types.hpp" + +#include "../meta_traits/dtor_traits.hpp" + +namespace meta_hpp::detail +{ + template < class_kind Class > + struct dtor_tag {}; + + template < class_kind Class > + // NOLINTNEXTLINE(readability-named-parameter) + dtor_type_data::dtor_type_data(type_list) + : type_data_base{type_id{type_list>{}}, type_kind::dtor_} + , flags{dtor_traits::make_flags()} + , class_type{resolve_type::class_type>()} {} + + template < class_kind Class > + dtor_type_data_ptr dtor_type_data::get_static() { + static dtor_type_data_ptr data = std::make_shared(type_list{}); + return data; + } +} + +namespace meta_hpp +{ + inline dtor_type::dtor_type(detail::dtor_type_data_ptr data) + : data_{std::move(data)} {} + + inline bool dtor_type::is_valid() const noexcept { + return !!data_; + } + + inline dtor_type::operator bool() const noexcept { + return is_valid(); + } + + inline type_id dtor_type::get_id() const noexcept { + return data_->id; + } + + inline bitflags dtor_type::get_flags() const noexcept { + return data_->flags; + } + + inline any_type dtor_type::get_class_type() const noexcept { + return data_->class_type; + } +} diff --git a/headers/meta.hpp/meta_utilities.hpp b/headers/meta.hpp/meta_utilities.hpp index 522233d..e97eb99 100644 --- a/headers/meta.hpp/meta_utilities.hpp +++ b/headers/meta.hpp/meta_utilities.hpp @@ -62,12 +62,13 @@ namespace meta_hpp::detail template < typename T > concept arg_lvalue_ref_kind = + (decay_non_uvalue_kind) && (std::is_lvalue_reference_v); template < typename T > concept arg_rvalue_ref_kind = - (!std::is_reference_v) || - (std::is_rvalue_reference_v); + (decay_non_uvalue_kind) && + (!std::is_reference_v || std::is_rvalue_reference_v); template < typename T > concept inst_class_ref_kind = @@ -76,12 +77,13 @@ namespace meta_hpp::detail template < typename T > concept inst_class_lvalue_ref_kind = + (decay_non_uvalue_kind) && (std::is_lvalue_reference_v && std::is_class_v>); template < typename T > concept inst_class_rvalue_ref_kind = - (std::is_class_v) || - (std::is_rvalue_reference_v && std::is_class_v>); + (decay_non_uvalue_kind) && + (std::is_class_v || (std::is_rvalue_reference_v && std::is_class_v>)); } namespace meta_hpp::detail @@ -194,11 +196,9 @@ namespace meta_hpp::detail explicit arg_base(T&& v); template < arg_lvalue_ref_kind T > - requires decay_non_uvalue_kind explicit arg_base(type_list); template < arg_rvalue_ref_kind T > - requires decay_non_uvalue_kind explicit arg_base(type_list); explicit arg_base(value& v); @@ -293,13 +293,13 @@ namespace meta_hpp::detail [[nodiscard]] bool is_rvalue() const noexcept; [[nodiscard]] ref_types get_ref_type() const noexcept; - [[nodiscard]] const class_type& get_raw_type() const noexcept; + [[nodiscard]] const any_type& get_raw_type() const noexcept; template < inst_class_ref_kind Q > [[nodiscard]] bool can_cast_to() const noexcept; private: ref_types ref_type_{}; - class_type raw_type_{}; + any_type raw_type_{}; }; } diff --git a/headers/meta.hpp/meta_utilities/arg.hpp b/headers/meta.hpp/meta_utilities/arg.hpp index c71de18..9181066 100644 --- a/headers/meta.hpp/meta_utilities/arg.hpp +++ b/headers/meta.hpp/meta_utilities/arg.hpp @@ -22,7 +22,6 @@ namespace meta_hpp::detail : arg_base{type_list{}} {} template < arg_lvalue_ref_kind T > - requires decay_non_uvalue_kind // NOLINTNEXTLINE(readability-named-parameter) arg_base::arg_base(type_list) : ref_type_{std::is_const_v> @@ -31,7 +30,6 @@ namespace meta_hpp::detail , raw_type_{resolve_type>()} {} template < arg_rvalue_ref_kind T > - requires decay_non_uvalue_kind // NOLINTNEXTLINE(readability-named-parameter) arg_base::arg_base(type_list) : ref_type_{std::is_const_v> diff --git a/headers/meta.hpp/meta_utilities/inst.hpp b/headers/meta.hpp/meta_utilities/inst.hpp index 9c34939..b49c9f5 100644 --- a/headers/meta.hpp/meta_utilities/inst.hpp +++ b/headers/meta.hpp/meta_utilities/inst.hpp @@ -90,35 +90,19 @@ namespace meta_hpp::detail inline inst_base::inst_base(value& v) : ref_type_{ref_types::lvalue} - , raw_type_{v.get_type().as_class()} { - if ( !v.get_type().is_class() ) { - throw std::logic_error("an attempt to create an instance with a non-class value type"); - } - } + , raw_type_{v.get_type()} {} inline inst_base::inst_base(const value& v) : ref_type_{ref_types::const_lvalue} - , raw_type_{v.get_type().as_class()} { - if ( !v.get_type().is_class() ) { - throw std::logic_error("an attempt to create an instance with a non-class value type"); - } - } + , raw_type_{v.get_type()} {} inline inst_base::inst_base(value&& v) : ref_type_{ref_types::rvalue} - , raw_type_{v.get_type().as_class()} { - if ( !v.get_type().is_class() ) { - throw std::logic_error("an attempt to create an instance with a non-class value type"); - } - } + , raw_type_{v.get_type()} {} inline inst_base::inst_base(const value&& v) : ref_type_{ref_types::const_rvalue} - , raw_type_{v.get_type().as_class()} { - if ( !v.get_type().is_class() ) { - throw std::logic_error("an attempt to create an instance with a non-class value type"); - } - } + , raw_type_{v.get_type()} {} inline bool inst_base::is_const() const noexcept { return ref_type_ == ref_types::const_lvalue @@ -139,7 +123,7 @@ namespace meta_hpp::detail return ref_type_; } - inline const class_type& inst_base::get_raw_type() const noexcept { + inline const any_type& inst_base::get_raw_type() const noexcept { return raw_type_; } @@ -148,11 +132,12 @@ namespace meta_hpp::detail using inst_class = typename inst_traits::class_type; using inst_method = typename inst_traits::method_type; - const class_type& from_type = get_raw_type(); - const class_type& to_type = resolve_type(); + const any_type& from_type = get_raw_type(); + const any_type& to_type = resolve_type(); - const auto is_a = [](const class_type& base, const class_type& derived){ - return base == derived || base.is_base_of(derived); + const auto is_a = [](const any_type& base, const any_type& derived){ + return (base == derived) + || (base.is_class() && derived.is_class() && base.as_class().is_base_of(derived.as_class())); }; const auto is_invocable = [this](){ @@ -197,21 +182,28 @@ namespace meta_hpp::detail using inst_class_cv = std::remove_reference_t; using inst_class = std::remove_cv_t; - const class_type& from_type = get_raw_type(); - const class_type& to_type = resolve_type(); + const any_type& from_type = get_raw_type(); + const any_type& to_type = resolve_type(); - void* to_ptr = detail::pointer_upcast(data_, from_type, to_type); + if ( from_type.is_class() && to_type.is_class() ) { + const class_type& from_class = from_type.as_class(); + const class_type& to_class = to_type.as_class(); - if constexpr ( !std::is_reference_v ) { - return *static_cast(to_ptr); + void* to_ptr = detail::pointer_upcast(data_, from_class, to_class); + + if constexpr ( !std::is_reference_v ) { + return *static_cast(to_ptr); + } + + if constexpr ( std::is_lvalue_reference_v ) { + return *static_cast(to_ptr); + } + + if constexpr ( std::is_rvalue_reference_v ) { + return std::move(*static_cast(to_ptr)); + } } - if constexpr ( std::is_lvalue_reference_v ) { - return *static_cast(to_ptr); - } - - if constexpr ( std::is_rvalue_reference_v ) { - return std::move(*static_cast(to_ptr)); - } + throw std::logic_error("bad instance cast"); } } diff --git a/untests/meta_states/ctor_tests.cpp b/untests/meta_states/ctor_tests.cpp index 3318d39..5b5b4f2 100644 --- a/untests/meta_states/ctor_tests.cpp +++ b/untests/meta_states/ctor_tests.cpp @@ -8,60 +8,137 @@ namespace { - struct clazz_1 { + template < std::size_t N > + struct clazz { int i{}; - clazz_1(int i) : i{i} {} + + clazz(int i) + : i{i} { + ++ctor_counter; + } + + clazz(clazz&& other) + : i{other.i} { + other.i = 0; + ++move_ctor_counter; + } + + clazz(const clazz& other) + : i{other.i} { + ++copy_ctor_counter; + } + + clazz& operator=(clazz&& other) = delete; + clazz& operator=(const clazz& other) = delete; + + ~clazz() { + ++dtor_counter; + } + public: + static int ctor_counter; + static int dtor_counter; + static int move_ctor_counter; + static int copy_ctor_counter; }; - struct clazz_2 { - int i{}; - clazz_2(int i) : i{i} {} - }; + template < std::size_t N > + int clazz::ctor_counter{0}; - struct clazz_3 { - int i{}; - clazz_3(int i) : i{i} {} - }; + template < std::size_t N > + int clazz::dtor_counter{0}; + + template < std::size_t N > + int clazz::move_ctor_counter{0}; + + template < std::size_t N > + int clazz::copy_ctor_counter{0}; } 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_object{}) + .dtor_(); - meta::class_() - .ctor_(meta::ctor_policy::as_raw_pointer{}); + meta::class_>() + .ctor_(meta::ctor_policy::as_raw_pointer{}) + .dtor_(); - meta::class_() - .ctor_(meta::ctor_policy::as_shared_pointer{}); + meta::class_>() + .ctor_(meta::ctor_policy::as_shared_pointer{}) + .dtor_(); - SUBCASE("clazz_1") { - const meta::class_type clazz_type = meta::resolve_type(); + clazz<1>::ctor_counter = 0; + clazz<1>::dtor_counter = 0; + clazz<1>::move_ctor_counter = 0; + clazz<1>::copy_ctor_counter = 0; + + clazz<2>::ctor_counter = 0; + clazz<2>::dtor_counter = 0; + clazz<2>::move_ctor_counter = 0; + clazz<2>::copy_ctor_counter = 0; + + clazz<3>::ctor_counter = 0; + clazz<3>::dtor_counter = 0; + clazz<3>::move_ctor_counter = 0; + clazz<3>::copy_ctor_counter = 0; + + 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); + { + const meta::value v = clazz_type.create(10).value(); + CHECK(v.get_type() == meta::resolve_type>()); + CHECK(v.cast>().i == 10); + + CHECK(clazz_type.destroy(nullptr)); + CHECK(clazz_type.destroy(meta::value{nullptr})); + } + + CHECK(clazz<1>::ctor_counter == 1); + CHECK(clazz<1>::dtor_counter == 4); + CHECK(clazz<1>::move_ctor_counter == 3); + CHECK(clazz<1>::copy_ctor_counter == 0); } - SUBCASE("clazz_2") { - const meta::class_type clazz_type = meta::resolve_type(); + 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); + { + const meta::value v = clazz_type.create(20).value(); + CHECK(v.get_type() == meta::resolve_type*>()); + CHECK(v.cast*>()->i == 20); + CHECK(clazz_type.destroy(v)); - //TODO: dtor!!! + CHECK(clazz_type.destroy(nullptr)); + CHECK(clazz_type.destroy(meta::value{nullptr})); + } + + CHECK(clazz<2>::ctor_counter == 1); + CHECK(clazz<2>::dtor_counter == 1); + CHECK(clazz<2>::move_ctor_counter == 0); + CHECK(clazz<2>::copy_ctor_counter == 0); } - SUBCASE("clazz_3") { - const meta::class_type clazz_type = meta::resolve_type(); + 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); + { + const meta::value v = clazz_type.create(30).value(); + CHECK(v.get_type() == meta::resolve_type>>()); + CHECK(v.cast>>()->i == 30); + + CHECK(clazz_type.destroy(nullptr)); + CHECK(clazz_type.destroy(meta::value{nullptr})); + } + + CHECK(clazz<3>::ctor_counter == 1); + CHECK(clazz<3>::dtor_counter == 1); + CHECK(clazz<3>::move_ctor_counter == 0); + CHECK(clazz<3>::copy_ctor_counter == 0); } } From 15235534e7c083d423ef1df0e4f0e296b971cf84 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sat, 22 Jan 2022 15:26:45 +0700 Subject: [PATCH 184/233] fix warnings --- CMakeLists.txt | 1 + headers/meta.hpp/meta_states.hpp | 16 ++++++++-------- headers/meta.hpp/meta_states/evalue.hpp | 6 +++--- headers/meta.hpp/meta_utilities/value.hpp | 8 ++++---- 4 files changed, 16 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f69d397..3756690 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,6 +32,7 @@ target_compile_options(${PROJECT_NAME} -Wno-extra-semi-stmt -Wno-float-equal -Wno-global-constructors + -Wno-ordered-compare-function-pointers -Wno-padded -Wno-reserved-identifier -Wno-shadow-field diff --git a/headers/meta.hpp/meta_states.hpp b/headers/meta.hpp/meta_states.hpp index 9115cd4..43287bf 100644 --- a/headers/meta.hpp/meta_states.hpp +++ b/headers/meta.hpp/meta_states.hpp @@ -79,21 +79,21 @@ namespace meta_hpp 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 = @@ -384,7 +384,7 @@ namespace meta_hpp::detail const value underlying_value; template < enum_kind Enum > - [[nodiscard]] static evalue_state_ptr make(std::string name, Enum value); + [[nodiscard]] static evalue_state_ptr make(std::string name, Enum evalue); }; struct function_state final { @@ -431,10 +431,10 @@ namespace meta_hpp::detail struct scope_state final { const scope_index index; - class_map classes; - enum_map enums; - function_map functions; - variable_map variables; + class_map classes{}; + enum_map enums{}; + function_map functions{}; + variable_map variables{}; [[nodiscard]] static scope_state_ptr make(std::string name); [[nodiscard]] static scope_state_ptr get_static(std::string_view name); diff --git a/headers/meta.hpp/meta_states/evalue.hpp b/headers/meta.hpp/meta_states/evalue.hpp index 73c4a41..26e6f6e 100644 --- a/headers/meta.hpp/meta_states/evalue.hpp +++ b/headers/meta.hpp/meta_states/evalue.hpp @@ -14,12 +14,12 @@ namespace meta_hpp::detail { template < enum_kind Enum > - evalue_state_ptr evalue_state::make(std::string name, Enum value) { + evalue_state_ptr evalue_state::make(std::string name, Enum evalue) { evalue_index index{enum_type_data::get_static(), std::move(name)}; return std::make_shared(evalue_state{ .index{std::move(index)}, - .enum_value{value}, - .underlying_value{stdex::to_underlying(value)}, + .enum_value{value{evalue}}, + .underlying_value{value{stdex::to_underlying(evalue)}}, }); } } diff --git a/headers/meta.hpp/meta_utilities/value.hpp b/headers/meta.hpp/meta_utilities/value.hpp index 571a61f..8be8b74 100644 --- a/headers/meta.hpp/meta_utilities/value.hpp +++ b/headers/meta.hpp/meta_utilities/value.hpp @@ -243,14 +243,14 @@ namespace meta_hpp namespace meta_hpp { - template < detail::has_value_less_traits T > + template < typename T > [[nodiscard]] bool operator<(const value& l, const T& r) { const any_type& r_type = resolve_type(); return (l.get_type() < r_type) || (l.get_type() == r_type && std::less<>{}(l.cast(), r)); } - template < detail::has_value_less_traits T > + template < typename T > [[nodiscard]] bool operator<(const T& l, const value& r) { const any_type& l_type = resolve_type(); return (l_type < r.get_type()) @@ -265,13 +265,13 @@ namespace meta_hpp namespace meta_hpp { - template < detail::has_value_equals_traits T > + template < typename T > [[nodiscard]] bool operator==(const value& l, const T& r) { return l.get_type() == resolve_type() && std::equal_to<>{}(l.cast(), r); } - template < detail::has_value_equals_traits T > + template < typename T > [[nodiscard]] bool operator==(const T& l, const value& r) { return resolve_type() == r.get_type() && std::equal_to<>{}(l, r.cast()); From f49dd09eca1808ceac7fc87cea5626deeafb653e Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sat, 22 Jan 2022 18:38:33 +0700 Subject: [PATCH 185/233] update todo --- TODO.md | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/TODO.md b/TODO.md index 51d0971..65809e2 100644 --- a/TODO.md +++ b/TODO.md @@ -1,15 +1,11 @@ # meta.hpp -- add dtors -- add meta exception class; -- void value? -- all string to hash? - * argument names -* argument defaults -* type conversions +* exception class +* move-only value type support * states and types metadata +* type conversions -? add type names; -? add enum_type::create, number_type::create, and so on. -? add invoke and is_invocable_with by dynamic types +- (?) type names +- (?) argument defaults +- (?) enum_type::create, number_type::create, and so on From d54194d52eba95402f2a82fefb3114516a62e3d6 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sun, 23 Jan 2022 22:34:25 +0700 Subject: [PATCH 186/233] fix value deref --- headers/meta.hpp/meta_utilities/value.hpp | 2 +- .../meta_utilities/value_traits/equals_traits.hpp | 9 +++++---- .../meta_utilities/value_traits/istream_traits.hpp | 1 + .../meta_utilities/value_traits/less_traits.hpp | 9 +++++---- .../meta_utilities/value_traits/ostream_traits.hpp | 9 +++++---- untests/meta_utilities/value_tests.cpp | 10 +++++----- 6 files changed, 22 insertions(+), 18 deletions(-) diff --git a/headers/meta.hpp/meta_utilities/value.hpp b/headers/meta.hpp/meta_utilities/value.hpp index 8be8b74..b9acae1 100644 --- a/headers/meta.hpp/meta_utilities/value.hpp +++ b/headers/meta.hpp/meta_utilities/value.hpp @@ -57,7 +57,7 @@ namespace meta_hpp .deref = +[]([[maybe_unused]] const value& v) -> value { if constexpr ( detail::has_value_deref_traits ) { - return value{*v.cast()}; + return detail::value_deref_traits{}(v.cast()); } else { throw std::logic_error("value type doesn't have value deref traits"); } diff --git a/headers/meta.hpp/meta_utilities/value_traits/equals_traits.hpp b/headers/meta.hpp/meta_utilities/value_traits/equals_traits.hpp index 6441c16..23ce64b 100644 --- a/headers/meta.hpp/meta_utilities/value_traits/equals_traits.hpp +++ b/headers/meta.hpp/meta_utilities/value_traits/equals_traits.hpp @@ -7,6 +7,7 @@ #pragma once #include "../../meta_base.hpp" +#include "../../meta_utilities.hpp" namespace meta_hpp::detail { @@ -14,16 +15,16 @@ namespace meta_hpp::detail struct value_equals_traits; template < typename T > - concept has_value_equals_traits = requires(const T& v) { - { value_equals_traits{}(v, v) } -> stdex::convertible_to; + concept has_value_equals_traits = requires(const T& l, const T& r) { + { value_equals_traits{}(l, r) } -> stdex::convertible_to; }; } namespace meta_hpp::detail { template < typename T > - requires requires(const T& v) { - { v == v } -> stdex::convertible_to; + requires requires(const T& l, const T& r) { + { l == r } -> stdex::convertible_to; } struct value_equals_traits { bool operator()(const T& l, const T& r) const { diff --git a/headers/meta.hpp/meta_utilities/value_traits/istream_traits.hpp b/headers/meta.hpp/meta_utilities/value_traits/istream_traits.hpp index 8bb1fe9..9d0f333 100644 --- a/headers/meta.hpp/meta_utilities/value_traits/istream_traits.hpp +++ b/headers/meta.hpp/meta_utilities/value_traits/istream_traits.hpp @@ -7,6 +7,7 @@ #pragma once #include "../../meta_base.hpp" +#include "../../meta_utilities.hpp" namespace meta_hpp::detail { diff --git a/headers/meta.hpp/meta_utilities/value_traits/less_traits.hpp b/headers/meta.hpp/meta_utilities/value_traits/less_traits.hpp index ca2498b..e79e1b2 100644 --- a/headers/meta.hpp/meta_utilities/value_traits/less_traits.hpp +++ b/headers/meta.hpp/meta_utilities/value_traits/less_traits.hpp @@ -7,6 +7,7 @@ #pragma once #include "../../meta_base.hpp" +#include "../../meta_utilities.hpp" namespace meta_hpp::detail { @@ -14,16 +15,16 @@ namespace meta_hpp::detail struct value_less_traits; template < typename T > - concept has_value_less_traits = requires(const T& v) { - { value_less_traits{}(v, v) } -> stdex::convertible_to; + concept has_value_less_traits = requires(const T& l, const T& r) { + { value_less_traits{}(l, r) } -> stdex::convertible_to; }; } namespace meta_hpp::detail { template < typename T > - requires requires(const T& v) { - { v < v } -> stdex::convertible_to; + requires requires(const T& l, const T& r) { + { l < r } -> stdex::convertible_to; } struct value_less_traits { bool operator()(const T& l, const T& r) const { diff --git a/headers/meta.hpp/meta_utilities/value_traits/ostream_traits.hpp b/headers/meta.hpp/meta_utilities/value_traits/ostream_traits.hpp index e2f5ed9..95f8601 100644 --- a/headers/meta.hpp/meta_utilities/value_traits/ostream_traits.hpp +++ b/headers/meta.hpp/meta_utilities/value_traits/ostream_traits.hpp @@ -7,6 +7,7 @@ #pragma once #include "../../meta_base.hpp" +#include "../../meta_utilities.hpp" namespace meta_hpp::detail { @@ -14,8 +15,8 @@ namespace meta_hpp::detail struct value_ostream_traits; template < typename T > - concept has_value_ostream_traits = requires(std::ostream& is, const T& v) { - { value_ostream_traits{}(is, v) } -> stdex::convertible_to; + concept has_value_ostream_traits = requires(std::ostream& os, const T& v) { + { value_ostream_traits{}(os, v) } -> stdex::convertible_to; }; } @@ -26,8 +27,8 @@ namespace meta_hpp::detail { os << v } -> stdex::convertible_to; } struct value_ostream_traits { - std::ostream& operator()(std::ostream& is, const T& v) const { - return is << v; + std::ostream& operator()(std::ostream& os, const T& v) const { + return os << v; } }; } diff --git a/untests/meta_utilities/value_tests.cpp b/untests/meta_utilities/value_tests.cpp index 7a3199b..6be5630 100644 --- a/untests/meta_utilities/value_tests.cpp +++ b/untests/meta_utilities/value_tests.cpp @@ -50,11 +50,11 @@ namespace return {l.x + r.x, l.y + r.y}; } - bool operator<(const ivec2& l, const ivec2& r) noexcept { + [[maybe_unused]] bool operator<(const ivec2& l, const ivec2& r) noexcept { return (l.x < r.x) || (l.x == r.x && l.y < r.y); } - bool operator==(const ivec2& l, const ivec2& r) noexcept { + [[maybe_unused]] bool operator==(const ivec2& l, const ivec2& r) noexcept { return l.x == r.x && l.y == r.y; } } @@ -390,15 +390,15 @@ TEST_CASE("meta/meta_utilities/value") { CHECK(ivec2::move_ctor_counter == 0); CHECK(ivec2::copy_ctor_counter == 0); - meta::value vv1{*vp}; + [[maybe_unused]] meta::value vv1{*vp}; CHECK(ivec2::move_ctor_counter == 0); CHECK(ivec2::copy_ctor_counter == 1); - meta::value vv2{*std::move(vp)}; + [[maybe_unused]] meta::value vv2{*std::move(vp)}; CHECK(ivec2::move_ctor_counter == 0); CHECK(ivec2::copy_ctor_counter == 2); - meta::value vv3{*std::as_const(vp)}; + [[maybe_unused]] meta::value vv3{*std::as_const(vp)}; CHECK(ivec2::move_ctor_counter == 0); CHECK(ivec2::copy_ctor_counter == 3); } From 6e127b41da5728229b8130d0c977be6cdb838c10 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sun, 23 Jan 2022 23:50:00 +0700 Subject: [PATCH 187/233] little value fixes --- headers/meta.hpp/meta_utilities.hpp | 40 +++++----- headers/meta.hpp/meta_utilities/value.hpp | 91 +++++++---------------- untests/meta_states/ctor_tests.cpp | 4 +- untests/meta_utilities/value_tests.cpp | 72 +++++++++++++++--- 4 files changed, 111 insertions(+), 96 deletions(-) diff --git a/headers/meta.hpp/meta_utilities.hpp b/headers/meta.hpp/meta_utilities.hpp index e97eb99..5e9701c 100644 --- a/headers/meta.hpp/meta_utilities.hpp +++ b/headers/meta.hpp/meta_utilities.hpp @@ -106,22 +106,20 @@ namespace meta_hpp public: value() = delete; - // NOLINTNEXTLINE(performance-noexcept-move-constructor) - value(value&& other); - value(const value& other); + value(value&& other) noexcept = default; + value(const value& other) = default; - // NOLINTNEXTLINE(performance-noexcept-move-constructor) - value& operator=(value&& other); + value& operator=(value&& other) noexcept; value& operator=(const value& other); ~value() = default; - template < detail::decay_non_uvalue_kind T, typename Tp = std::decay_t > - requires detail::stdex::copy_constructible + template < detail::decay_non_uvalue_kind T > + requires detail::stdex::copy_constructible> explicit value(T&& val); - template < detail::decay_non_uvalue_kind T, typename Tp = std::decay_t > - requires detail::stdex::copy_constructible + template < detail::decay_non_uvalue_kind T > + requires detail::stdex::copy_constructible> value& operator=(T&& val); void swap(value& other) noexcept; @@ -135,23 +133,23 @@ namespace meta_hpp [[nodiscard]] value operator*() const; [[nodiscard]] value operator[](std::size_t index) const; - template < typename T, typename Tp = std::decay_t > - [[nodiscard]] Tp& cast() &; + template < typename T > + [[nodiscard]] std::decay_t& cast() &; - template < typename T, typename Tp = std::decay_t > - [[nodiscard]] Tp&& cast() &&; + template < typename T > + [[nodiscard]] std::decay_t&& cast() &&; - template < typename T, typename Tp = std::decay_t > - [[nodiscard]] const Tp& cast() const &; + template < typename T > + [[nodiscard]] const std::decay_t& cast() const &; - template < typename T, typename Tp = std::decay_t > - [[nodiscard]] const Tp&& cast() const &&; + template < typename T > + [[nodiscard]] const std::decay_t&& cast() const &&; - template < typename T, typename Tp = std::decay_t > - [[nodiscard]] Tp* try_cast() noexcept; + template < typename T > + [[nodiscard]] std::decay_t* try_cast() noexcept; - template < typename T, typename Tp = std::decay_t > - [[nodiscard]] const Tp* try_cast() const noexcept; + template < typename T > + [[nodiscard]] const std::decay_t* try_cast() const noexcept; friend bool operator<(const value& l, const value& r); friend bool operator==(const value& l, const value& r); diff --git a/headers/meta.hpp/meta_utilities/value.hpp b/headers/meta.hpp/meta_utilities/value.hpp index b9acae1..753ff6f 100644 --- a/headers/meta.hpp/meta_utilities/value.hpp +++ b/headers/meta.hpp/meta_utilities/value.hpp @@ -30,9 +30,6 @@ namespace meta_hpp bool (*const less)(const value&, const value&); bool (*const equals)(const value&, const value&); - void (*const move_ctor)(std::any&, value&&); - void (*const copy_ctor)(std::any&, const value&); - std::istream& (*const istream)(std::istream&, value&); std::ostream& (*const ostream)(std::ostream&, const value&); @@ -87,22 +84,6 @@ namespace meta_hpp } }, - .move_ctor = +[]([[maybe_unused]] std::any& dst, [[maybe_unused]] value&& src) { - if constexpr ( std::is_move_constructible_v ) { - dst.emplace(std::move(src).cast()); - } else { - throw std::logic_error("value type is not move constructible"); - } - }, - - .copy_ctor = +[]([[maybe_unused]] std::any& dst, [[maybe_unused]] const value& src) { - if constexpr ( std::is_copy_constructible_v ) { - dst.emplace(src.cast()); - } else { - throw std::logic_error("value type is not copy constructible"); - } - }, - .istream = +[]([[maybe_unused]] std::istream& is, [[maybe_unused]] value& v) -> std::istream& { if constexpr ( detail::has_value_istream_traits ) { return detail::value_istream_traits{}(is, v.cast()); @@ -126,42 +107,30 @@ namespace meta_hpp namespace meta_hpp { - // NOLINTNEXTLINE(performance-noexcept-move-constructor) - inline value::value(value&& other) - : traits_{other.traits_} { - traits_->move_ctor(raw_, std::move(other)); - } - - inline value::value(const value& other) - : traits_{other.traits_} { - traits_->copy_ctor(raw_, other); - } - - // NOLINTNEXTLINE(performance-noexcept-move-constructor) - inline value& value::operator=(value&& other) { + inline value& value::operator=(value&& other) noexcept { if ( this != &other ) { - traits_ = other.traits_; - traits_->move_ctor(raw_, std::move(other)); + value temp{std::move(other)}; + swap(temp); } return *this; } inline value& value::operator=(const value& other) { if ( this != &other ) { - traits_ = other.traits_; - traits_->copy_ctor(raw_, other); + value temp{other}; + swap(temp); } return *this; } - template < detail::decay_non_uvalue_kind T, typename Tp > - requires detail::stdex::copy_constructible + template < detail::decay_non_uvalue_kind T > + requires detail::stdex::copy_constructible> value::value(T&& val) : raw_{std::forward(val)} , traits_{traits::get>()} {} - template < detail::decay_non_uvalue_kind T, typename Tp > - requires detail::stdex::copy_constructible + template < detail::decay_non_uvalue_kind T > + requires detail::stdex::copy_constructible> value& value::operator=(T&& val) { value temp{std::forward(val)}; swap(temp); @@ -198,45 +167,39 @@ namespace meta_hpp return traits_->index(*this, index); } - template < typename T, typename Tp > - Tp& value::cast() & { - if ( get_type() != resolve_type() ) { - throw std::logic_error("bad value cast"); - } + template < typename T > + std::decay_t& value::cast() & { + using Tp = std::decay_t; return std::any_cast(raw_); } - template < typename T, typename Tp > - Tp&& value::cast() && { - if ( get_type() != resolve_type() ) { - throw std::logic_error("bad value cast"); - } + template < typename T > + std::decay_t&& value::cast() && { + using Tp = std::decay_t; return std::move(std::any_cast(raw_)); } - template < typename T, typename Tp > - const Tp& value::cast() const & { - if ( get_type() != resolve_type() ) { - throw std::logic_error("bad value cast"); - } + template < typename T > + const std::decay_t& value::cast() const & { + using Tp = std::decay_t; return std::any_cast(raw_); } - template < typename T, typename Tp > - const Tp&& value::cast() const && { - if ( get_type() != resolve_type() ) { - throw std::logic_error("bad value cast"); - } + template < typename T > + const std::decay_t&& value::cast() const && { + using Tp = std::decay_t; return std::move(std::any_cast(raw_)); } - template < typename T, typename Tp > - Tp* value::try_cast() noexcept { + template < typename T > + std::decay_t* value::try_cast() noexcept { + using Tp = std::decay_t; return std::any_cast(&raw_); } - template < typename T, typename Tp > - const Tp* value::try_cast() const noexcept { + template < typename T > + const std::decay_t* value::try_cast() const noexcept { + using Tp = std::decay_t; return std::any_cast(&raw_); } } diff --git a/untests/meta_states/ctor_tests.cpp b/untests/meta_states/ctor_tests.cpp index 5b5b4f2..ac5f36c 100644 --- a/untests/meta_states/ctor_tests.cpp +++ b/untests/meta_states/ctor_tests.cpp @@ -98,8 +98,8 @@ TEST_CASE("meta/meta_states/ctor") { } CHECK(clazz<1>::ctor_counter == 1); - CHECK(clazz<1>::dtor_counter == 4); - CHECK(clazz<1>::move_ctor_counter == 3); + CHECK(clazz<1>::dtor_counter == 2); + CHECK(clazz<1>::move_ctor_counter == 1); CHECK(clazz<1>::copy_ctor_counter == 0); } diff --git a/untests/meta_utilities/value_tests.cpp b/untests/meta_utilities/value_tests.cpp index 6be5630..38b2e44 100644 --- a/untests/meta_utilities/value_tests.cpp +++ b/untests/meta_utilities/value_tests.cpp @@ -43,6 +43,16 @@ namespace static int copy_ctor_counter; }; + struct ivec3 { + int x{}; + int y{}; + int z{}; + + ivec3() = default; + explicit ivec3(int v): x{v}, y{v}, z{v} {} + ivec3(int x, int y, int z): x{x}, y{y}, z{z} {} + }; + int ivec2::move_ctor_counter{0}; int ivec2::copy_ctor_counter{0}; @@ -72,6 +82,20 @@ TEST_CASE("meta/meta_utilities/value/ivec2") { .member_("y", &ivec2::y); } +TEST_CASE("meta/meta_utilities/value/ivec3") { + namespace meta = meta_hpp; + + meta::class_() + .ctor_<>() + .ctor_() + .ctor_() + .ctor_() + .ctor_() + .member_("x", &ivec3::x) + .member_("y", &ivec3::y) + .member_("z", &ivec3::z); +} + TEST_CASE("meta/meta_utilities/value") { namespace meta = meta_hpp; using namespace std::string_literals; @@ -123,9 +147,18 @@ TEST_CASE("meta/meta_utilities/value") { CHECK(val.cast() == ivec2{1,2}); CHECK(std::as_const(val).cast() == ivec2{1,2}); + CHECK(std::move(val).cast() == ivec2{1,2}); + CHECK(std::move(std::as_const(val)).cast() == ivec2{1,2}); + + CHECK_THROWS(std::ignore = val.cast()); + CHECK_THROWS(std::ignore = std::as_const(val).cast()); + CHECK_THROWS(std::ignore = std::move(val).cast()); + CHECK_THROWS(std::ignore = std::move(std::as_const(val)).cast()); CHECK(*val.try_cast() == ivec2{1,2}); CHECK(*std::as_const(val).try_cast() == ivec2{1,2}); + CHECK(val.try_cast() == nullptr); + CHECK(std::as_const(val).try_cast() == nullptr); } SUBCASE("const ivec2&") { @@ -148,9 +181,18 @@ TEST_CASE("meta/meta_utilities/value") { CHECK(val.cast() == ivec2{1,2}); CHECK(std::as_const(val).cast() == ivec2{1,2}); + CHECK(std::move(val).cast() == ivec2{1,2}); + CHECK(std::move(std::as_const(val)).cast() == ivec2{1,2}); + + CHECK_THROWS(std::ignore = val.cast()); + CHECK_THROWS(std::ignore = std::as_const(val).cast()); + CHECK_THROWS(std::ignore = std::move(val).cast()); + CHECK_THROWS(std::ignore = std::move(std::as_const(val)).cast()); CHECK(*val.try_cast() == ivec2{1,2}); CHECK(*std::as_const(val).try_cast() == ivec2{1,2}); + CHECK(val.try_cast() == nullptr); + CHECK(std::as_const(val).try_cast() == nullptr); } SUBCASE("ivec2&&") { @@ -167,9 +209,18 @@ TEST_CASE("meta/meta_utilities/value") { CHECK(val.cast() == ivec2{1,2}); CHECK(std::as_const(val).cast() == ivec2{1,2}); + CHECK(std::move(val).cast() == ivec2{1,2}); + CHECK(std::move(std::as_const(val)).cast() == ivec2{1,2}); + + CHECK_THROWS(std::ignore = val.cast()); + CHECK_THROWS(std::ignore = std::as_const(val).cast()); + CHECK_THROWS(std::ignore = std::move(val).cast()); + CHECK_THROWS(std::ignore = std::move(std::as_const(val)).cast()); CHECK(*val.try_cast() == ivec2{1,2}); CHECK(*std::as_const(val).try_cast() == ivec2{1,2}); + CHECK(val.try_cast() == nullptr); + CHECK(std::as_const(val).try_cast() == nullptr); } SUBCASE("const ivec2&&") { @@ -186,9 +237,18 @@ TEST_CASE("meta/meta_utilities/value") { CHECK(val.cast() == ivec2{1,2}); CHECK(std::as_const(val).cast() == ivec2{1,2}); + CHECK(std::move(val).cast() == ivec2{1,2}); + CHECK(std::move(std::as_const(val)).cast() == ivec2{1,2}); + + CHECK_THROWS(std::ignore = val.cast()); + CHECK_THROWS(std::ignore = std::as_const(val).cast()); + CHECK_THROWS(std::ignore = std::move(val).cast()); + CHECK_THROWS(std::ignore = std::move(std::as_const(val)).cast()); CHECK(*val.try_cast() == ivec2{1,2}); CHECK(*std::as_const(val).try_cast() == ivec2{1,2}); + CHECK(val.try_cast() == nullptr); + CHECK(std::as_const(val).try_cast() == nullptr); } SUBCASE("value(value&&)") { @@ -201,9 +261,6 @@ TEST_CASE("meta/meta_utilities/value") { CHECK(val_dst == ivec2{1,2}); CHECK(ivec2::move_ctor_counter == 2); CHECK(ivec2::copy_ctor_counter == 0); - - CHECK(val_src == ivec2{0,0}); - CHECK(val_src.data() != val_dst.data()); } SUBCASE("value(const meta::value&)") { @@ -246,11 +303,8 @@ TEST_CASE("meta/meta_utilities/value") { val_dst = std::move(val_src2); CHECK(val_dst == ivec2{1,2}); - CHECK(ivec2::move_ctor_counter == 2); + CHECK(ivec2::move_ctor_counter == 4); CHECK(ivec2::copy_ctor_counter == 0); - - CHECK(val_src2 == ivec2{0,0}); - CHECK(val_src2.data() != val_dst.data()); } SUBCASE("value& operator=(const meta::value&)") { @@ -268,7 +322,7 @@ TEST_CASE("meta/meta_utilities/value") { val_dst = val_src2; CHECK(val_dst == ivec2{1,2}); - CHECK(ivec2::move_ctor_counter == 1); + CHECK(ivec2::move_ctor_counter == 3); CHECK(ivec2::copy_ctor_counter == 1); CHECK(val_src2 == ivec2{1,2}); @@ -284,7 +338,7 @@ TEST_CASE("meta/meta_utilities/value") { val1.swap(val2); CHECK(val1 == ivec2{1,2}); CHECK(val2 == "world"s); - CHECK((ivec2::move_ctor_counter == 2 || ivec2::move_ctor_counter == 3)); + CHECK(ivec2::move_ctor_counter == 3); CHECK(ivec2::copy_ctor_counter == 0); swap(val1, val2); From fc69b71779721e9ba92fc8e46d461cf46b1a1ae8 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Mon, 24 Jan 2022 04:13:20 +0700 Subject: [PATCH 188/233] nullable value type --- headers/meta.hpp/meta_utilities.hpp | 7 ++- headers/meta.hpp/meta_utilities/value.hpp | 56 ++++++++++++++++++--- untests/meta_utilities/value_tests.cpp | 59 +++++++++++++++++++++++ 3 files changed, 113 insertions(+), 9 deletions(-) diff --git a/headers/meta.hpp/meta_utilities.hpp b/headers/meta.hpp/meta_utilities.hpp index 5e9701c..c4ec2bb 100644 --- a/headers/meta.hpp/meta_utilities.hpp +++ b/headers/meta.hpp/meta_utilities.hpp @@ -104,7 +104,7 @@ namespace meta_hpp { class value final { public: - value() = delete; + value() = default; value(value&& other) noexcept = default; value(const value& other) = default; @@ -122,9 +122,12 @@ namespace meta_hpp requires detail::stdex::copy_constructible> value& operator=(T&& val); + [[nodiscard]] bool is_valid() const noexcept; + [[nodiscard]] explicit operator bool() const noexcept; + void swap(value& other) noexcept; - [[nodiscard]] const any_type& get_type() const noexcept; + [[nodiscard]] any_type get_type() const noexcept; [[nodiscard]] void* data() noexcept; [[nodiscard]] const void* data() const noexcept; diff --git a/headers/meta.hpp/meta_utilities/value.hpp b/headers/meta.hpp/meta_utilities/value.hpp index 753ff6f..9364fb0 100644 --- a/headers/meta.hpp/meta_utilities/value.hpp +++ b/headers/meta.hpp/meta_utilities/value.hpp @@ -137,34 +137,44 @@ namespace meta_hpp return *this; } + inline bool value::is_valid() const noexcept { + return raw_.has_value(); + } + + inline value::operator bool() const noexcept { + return is_valid(); + } + inline void value::swap(value& other) noexcept { using std::swap; swap(raw_, other.raw_); swap(traits_, other.traits_); } - inline const any_type& value::get_type() const noexcept { - return traits_->type; + inline any_type value::get_type() const noexcept { + return traits_ != nullptr + ? traits_->type + : resolve_type(); } inline void* value::data() noexcept { - return traits_->data(*this); + return traits_ != nullptr ? traits_->data(*this) : nullptr; } inline const void* value::data() const noexcept { - return traits_->cdata(*this); + return traits_ != nullptr ? traits_->cdata(*this) : nullptr; } inline const void* value::cdata() const noexcept { - return traits_->cdata(*this); + return traits_ != nullptr ? traits_->cdata(*this) : nullptr; } inline value value::operator*() const { - return traits_->deref(*this); + return traits_ != nullptr ? traits_->deref(*this) : value{}; } inline value value::operator[](std::size_t index) const { - return traits_->index(*this, index); + return traits_ != nullptr ? traits_->index(*this, index) : value{}; } template < typename T > @@ -208,6 +218,10 @@ namespace meta_hpp { template < typename T > [[nodiscard]] bool operator<(const value& l, const T& r) { + if ( !static_cast(l) ) { + return true; + } + const any_type& r_type = resolve_type(); return (l.get_type() < r_type) || (l.get_type() == r_type && std::less<>{}(l.cast(), r)); @@ -215,12 +229,24 @@ namespace meta_hpp template < typename T > [[nodiscard]] bool operator<(const T& l, const value& r) { + if ( !static_cast(r) ) { + return false; + } + const any_type& l_type = resolve_type(); return (l_type < r.get_type()) || (l_type == r.get_type() && std::less<>{}(l, r.cast())); } [[nodiscard]] inline bool operator<(const value& l, const value& r) { + if ( !static_cast(r) ) { + return false; + } + + if ( !static_cast(l) ) { + return true; + } + return (l.get_type() < r.get_type()) || (l.get_type() == r.get_type() && l.traits_->less(l, r)); } @@ -230,17 +256,33 @@ namespace meta_hpp { template < typename T > [[nodiscard]] bool operator==(const value& l, const T& r) { + if ( !static_cast(l) ) { + return false; + } + return l.get_type() == resolve_type() && std::equal_to<>{}(l.cast(), r); } template < typename T > [[nodiscard]] bool operator==(const T& l, const value& r) { + if ( !static_cast(r) ) { + return false; + } + return resolve_type() == r.get_type() && std::equal_to<>{}(l, r.cast()); } [[nodiscard]] inline bool operator==(const value& l, const value& r) { + if ( static_cast(l) != static_cast(r) ) { + return false; + } + + if ( !static_cast(l) ) { + return true; + } + return l.get_type() == r.get_type() && l.traits_->equals(l, r); } diff --git a/untests/meta_utilities/value_tests.cpp b/untests/meta_utilities/value_tests.cpp index 38b2e44..4f97bd6 100644 --- a/untests/meta_utilities/value_tests.cpp +++ b/untests/meta_utilities/value_tests.cpp @@ -127,6 +127,65 @@ TEST_CASE("meta/meta_utilities/value") { const ivec2*>); } + SUBCASE("ivec2{}") { + { + meta::value val{}; + + CHECK(!val); + CHECK_FALSE(val); + + CHECK_FALSE(val.is_valid()); + CHECK(val.data() == nullptr); + CHECK(std::as_const(val).data() == nullptr); + CHECK(std::as_const(val).cdata() == nullptr); + + CHECK_FALSE(*val); + CHECK_FALSE(val[0]); + + CHECK(val.try_cast() == nullptr); + CHECK(std::as_const(val).try_cast() == nullptr); + + CHECK_THROWS(std::ignore = val.cast()); + CHECK_THROWS(std::ignore = std::as_const(val).cast()); + CHECK_THROWS(std::ignore = std::move(val).cast()); + CHECK_THROWS(std::ignore = std::move(std::as_const(val)).cast()); + } + + { + CHECK_FALSE(meta::value{1} < meta::value{}); + CHECK(meta::value{} < meta::value{1}); + CHECK_FALSE(meta::value{} < meta::value{}); + + CHECK_FALSE(1 < meta::value{}); + CHECK(meta::value{} < 1); + CHECK_FALSE(meta::value{} < meta::value{}); + } + + { + CHECK_FALSE(meta::value{1} == meta::value{}); + CHECK_FALSE(meta::value{} == meta::value{1}); + CHECK(meta::value{} == meta::value{}); + + CHECK_FALSE(1 == meta::value{}); + CHECK_FALSE(meta::value{} == 1); + CHECK(meta::value{} == meta::value{}); + } + + { + CHECK(meta::value{1} != meta::value{}); + CHECK(meta::value{} != meta::value{1}); + CHECK_FALSE(meta::value{} != meta::value{}); + + CHECK(1 != meta::value{}); + CHECK(meta::value{} != 1); + CHECK_FALSE(meta::value{} != meta::value{}); + } + + CHECK_FALSE(meta::value{} == 0); + CHECK_FALSE(meta::value{} == nullptr); + CHECK(meta::value{}.get_type() == meta::resolve_type()); + } + SUBCASE("ivec2&") { ivec2 v{1,2}; ivec2& vr = v; From 193e8eddd1cd1013083ca4e36951a77ba9b621cf Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Mon, 24 Jan 2022 04:20:27 +0700 Subject: [PATCH 189/233] empty value instead std::optional --- headers/meta.hpp/meta_base.hpp | 1 - headers/meta.hpp/meta_states.hpp | 12 +++--- headers/meta.hpp/meta_states/function.hpp | 10 ++--- headers/meta.hpp/meta_states/method.hpp | 10 ++--- headers/meta.hpp/meta_types.hpp | 8 ++-- headers/meta.hpp/meta_types/class_type.hpp | 6 +-- headers/meta.hpp/meta_types/enum_type.hpp | 11 ++--- headers/meta.hpp/meta_utilities/vinvoke.hpp | 12 +++--- untests/meta_states/ctor_tests.cpp | 9 ++-- untests/meta_states/function_tests.cpp | 4 +- untests/meta_states/method_tests.cpp | 48 ++++++++++----------- untests/meta_types/enum_type_tests.cpp | 38 ++++------------ 12 files changed, 75 insertions(+), 94 deletions(-) diff --git a/headers/meta.hpp/meta_base.hpp b/headers/meta.hpp/meta_base.hpp index 5f08db5..0ec657c 100644 --- a/headers/meta.hpp/meta_base.hpp +++ b/headers/meta.hpp/meta_base.hpp @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include diff --git a/headers/meta.hpp/meta_states.hpp b/headers/meta.hpp/meta_states.hpp index 43287bf..578024f 100644 --- a/headers/meta.hpp/meta_states.hpp +++ b/headers/meta.hpp/meta_states.hpp @@ -211,10 +211,10 @@ namespace meta_hpp [[nodiscard]] const std::string& get_name() const noexcept; template < typename... Args > - std::optional invoke(Args&&... args) const; + value invoke(Args&&... args) const; template < typename... Args > - std::optional operator()(Args&&... args) const; + value operator()(Args&&... args) const; template < typename... Args > [[nodiscard]] bool is_invocable_with() const noexcept; @@ -277,10 +277,10 @@ namespace meta_hpp [[nodiscard]] const std::string& get_name() const noexcept; template < typename Instance, typename... Args > - std::optional invoke(Instance&& instance, Args&&... args) const; + value invoke(Instance&& instance, Args&&... args) const; template < typename Instance, typename... Args > - std::optional operator()(Instance&& instance, Args&&... args) const; + value operator()(Instance&& instance, Args&&... args) const; template < typename Instance, typename... Args > [[nodiscard]] bool is_invocable_with() const noexcept; @@ -388,7 +388,7 @@ namespace meta_hpp::detail }; struct function_state final { - using invoke_impl = std::function(std::span)>; + using invoke_impl = std::function)>; using is_invocable_with_impl = std::function)>; const function_index index; @@ -417,7 +417,7 @@ namespace meta_hpp::detail }; struct method_state final { - using invoke_impl = std::function(const inst&, std::span)>; + using invoke_impl = std::function)>; using is_invocable_with_impl = std::function)>; const method_index index; diff --git a/headers/meta.hpp/meta_states/function.hpp b/headers/meta.hpp/meta_states/function.hpp index 3f5154b..1d8a25c 100644 --- a/headers/meta.hpp/meta_states/function.hpp +++ b/headers/meta.hpp/meta_states/function.hpp @@ -14,7 +14,7 @@ namespace meta_hpp::detail { template < function_policy_kind Policy, function_kind Function > - std::optional raw_function_invoke(Function function, std::span args) { + value 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; @@ -40,7 +40,7 @@ namespace meta_hpp::detail return std::invoke([ args, function = std::move(function) // NOLINTNEXTLINE(readability-named-parameter) - ](std::index_sequence) -> std::optional { + ](std::index_sequence) -> value { if ( !(... && (args.data() + Is)->can_cast_to>()) ) { throw std::logic_error("an attempt to call a function with incorrect argument types"); } @@ -49,7 +49,7 @@ namespace meta_hpp::detail std::ignore = std::invoke( std::move(function), (args.data() + Is)->cast>()...); - return std::nullopt; + return {}; } else { return_type&& return_value = std::invoke( std::move(function), @@ -134,7 +134,7 @@ namespace meta_hpp } template < typename... Args > - std::optional function::invoke(Args&&... args) const { + value function::invoke(Args&&... args) const { if constexpr ( sizeof...(Args) > 0 ) { using namespace detail; const std::array vargs{arg{std::forward(args)}...}; @@ -145,7 +145,7 @@ namespace meta_hpp } template < typename... Args > - std::optional function::operator()(Args&&... args) const { + value function::operator()(Args&&... args) const { return invoke(std::forward(args)...); } diff --git a/headers/meta.hpp/meta_states/method.hpp b/headers/meta.hpp/meta_states/method.hpp index 1f2c1f8..762b0d4 100644 --- a/headers/meta.hpp/meta_states/method.hpp +++ b/headers/meta.hpp/meta_states/method.hpp @@ -14,7 +14,7 @@ namespace meta_hpp::detail { template < method_policy_kind Policy, method_kind Method > - std::optional raw_method_invoke(Method method, const inst& inst, std::span args) { + value 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; @@ -46,7 +46,7 @@ namespace meta_hpp::detail &inst, &args, method = std::move(method) // NOLINTNEXTLINE(readability-named-parameter) - ](std::index_sequence) -> std::optional { + ](std::index_sequence) -> value { if ( !(... && (args.data() + Is)->can_cast_to>()) ) { throw std::logic_error("an attempt to call a method with incorrect argument types"); } @@ -56,7 +56,7 @@ namespace meta_hpp::detail std::move(method), inst.cast(), (args.data() + Is)->cast>()...); - return std::nullopt; + return {}; } else { return_type&& return_value = std::invoke( std::move(method), @@ -147,7 +147,7 @@ namespace meta_hpp } template < typename Instance, typename... Args > - std::optional method::invoke(Instance&& instance, Args&&... args) const { + value method::invoke(Instance&& instance, Args&&... args) const { using namespace detail; const inst vinst{std::forward(instance)}; if constexpr ( sizeof...(Args) > 0 ) { @@ -159,7 +159,7 @@ namespace meta_hpp } template < typename Instance, typename... Args > - std::optional method::operator()(Instance&& instance, Args&&... args) const { + value method::operator()(Instance&& instance, Args&&... args) const { return invoke(std::forward(instance), std::forward(args)...); } diff --git a/headers/meta.hpp/meta_types.hpp b/headers/meta.hpp/meta_types.hpp index d0a6d90..dd7b014 100644 --- a/headers/meta.hpp/meta_types.hpp +++ b/headers/meta.hpp/meta_types.hpp @@ -220,10 +220,10 @@ namespace meta_hpp [[nodiscard]] const variable_map& get_variables() const noexcept; template < typename... Args > - [[nodiscard]] std::optional create(Args&&... args) const; + [[nodiscard]] value create(Args&&... args) const; template < typename... Args > - [[nodiscard]] std::optional operator()(Args&&... args) const; + [[nodiscard]] value operator()(Args&&... args) const; template < typename Arg > bool destroy(Arg&& ptr) const; @@ -315,8 +315,8 @@ namespace meta_hpp [[nodiscard]] evalue get_evalue(std::string_view name) const noexcept; template < typename Value > - [[nodiscard]] std::optional value_to_name(Value&& value) const noexcept; - [[nodiscard]] std::optional name_to_value(std::string_view name) const noexcept; + [[nodiscard]] std::string_view value_to_name(Value&& value) const noexcept; + [[nodiscard]] value name_to_value(std::string_view name) const noexcept; private: detail::enum_type_data_ptr data_; friend auto detail::data_access(const enum_type&); diff --git a/headers/meta.hpp/meta_types/class_type.hpp b/headers/meta.hpp/meta_types/class_type.hpp index 4925fda..de4aebc 100644 --- a/headers/meta.hpp/meta_types/class_type.hpp +++ b/headers/meta.hpp/meta_types/class_type.hpp @@ -103,17 +103,17 @@ namespace meta_hpp } template < typename... Args > - std::optional class_type::create(Args&&... args) const { + value class_type::create(Args&&... args) const { for ( auto&& ctor : data_->ctors ) { if ( ctor.second.is_invocable_with(std::forward(args)...) ) { return ctor.second.invoke(std::forward(args)...); } } - return std::nullopt; + return {}; } template < typename... Args > - std::optional class_type::operator()(Args&&... args) const { + value class_type::operator()(Args&&... args) const { return create(std::forward(args)...); } diff --git a/headers/meta.hpp/meta_types/enum_type.hpp b/headers/meta.hpp/meta_types/enum_type.hpp index f2088a5..1b84bb1 100644 --- a/headers/meta.hpp/meta_types/enum_type.hpp +++ b/headers/meta.hpp/meta_types/enum_type.hpp @@ -71,11 +71,11 @@ namespace meta_hpp } template < typename Value > - std::optional enum_type::value_to_name(Value&& value) const noexcept { + std::string_view enum_type::value_to_name(Value&& value) const noexcept { const detail::arg value_arg{std::forward(value)}; if ( value_arg.get_raw_type() != *this ) { - return std::nullopt; + return std::string_view{}; } for ( auto&& evalue : data_->evalues ) { @@ -84,13 +84,14 @@ namespace meta_hpp } } - return std::nullopt; + return std::string_view{}; } - inline std::optional enum_type::name_to_value(std::string_view name) const noexcept { + inline value enum_type::name_to_value(std::string_view name) const noexcept { if ( const evalue value = get_evalue(name); value ) { return value.get_value(); } - return std::nullopt; + + return value{}; } } diff --git a/headers/meta.hpp/meta_utilities/vinvoke.hpp b/headers/meta.hpp/meta_utilities/vinvoke.hpp index 66cb0ef..5c786e8 100644 --- a/headers/meta.hpp/meta_utilities/vinvoke.hpp +++ b/headers/meta.hpp/meta_utilities/vinvoke.hpp @@ -13,12 +13,12 @@ namespace meta_hpp { template < typename... Args > - std::optional invoke(const function& function, Args&&... args) { + value invoke(const function& function, Args&&... args) { return function.invoke(std::forward(args)...); } template < detail::function_kind Function, typename... Args > - std::optional invoke(Function&& function, Args&&... args) { + value invoke(Function&& function, Args&&... args) { using namespace detail; if constexpr ( sizeof...(Args) > 0 ) { const std::array vargs{arg{std::forward(args)}...}; @@ -32,12 +32,12 @@ namespace meta_hpp namespace meta_hpp { template < typename Instance > - std::optional invoke(const member& member, Instance&& instance) { + value invoke(const member& member, Instance&& instance) { return member.get(std::forward(instance)); } template < detail::member_kind Member, typename Instance > - std::optional invoke(Member&& member, Instance&& instance) { + value invoke(Member&& member, Instance&& instance) { using namespace detail; const inst vinst{std::forward(instance)}; return raw_member_getter(std::forward(member), vinst); @@ -47,12 +47,12 @@ namespace meta_hpp namespace meta_hpp { template < typename Instance, typename... Args > - std::optional invoke(const method& method, Instance&& instance, Args&&... args) { + value invoke(const method& method, Instance&& instance, Args&&... args) { return method.invoke(std::forward(instance), std::forward(args)...); } template < detail::method_kind Method, typename Instance, typename... Args > - std::optional invoke(Method&& method, Instance&& instance, Args&&... args) { + value invoke(Method&& method, Instance&& instance, Args&&... args) { using namespace detail; const inst vinst{std::forward(instance)}; if constexpr ( sizeof...(Args) > 0 ) { diff --git a/untests/meta_states/ctor_tests.cpp b/untests/meta_states/ctor_tests.cpp index ac5f36c..60d1267 100644 --- a/untests/meta_states/ctor_tests.cpp +++ b/untests/meta_states/ctor_tests.cpp @@ -89,7 +89,8 @@ TEST_CASE("meta/meta_states/ctor") { REQUIRE(clazz_type); { - const meta::value v = clazz_type.create(10).value(); + CHECK_FALSE(clazz_type.create(10, 20)); + const meta::value v = clazz_type.create(10); CHECK(v.get_type() == meta::resolve_type>()); CHECK(v.cast>().i == 10); @@ -108,7 +109,8 @@ TEST_CASE("meta/meta_states/ctor") { REQUIRE(clazz_type); { - const meta::value v = clazz_type.create(20).value(); + CHECK_FALSE(clazz_type.create(10, 20)); + const meta::value v = clazz_type.create(20); CHECK(v.get_type() == meta::resolve_type*>()); CHECK(v.cast*>()->i == 20); CHECK(clazz_type.destroy(v)); @@ -128,7 +130,8 @@ TEST_CASE("meta/meta_states/ctor") { REQUIRE(clazz_type); { - const meta::value v = clazz_type.create(30).value(); + CHECK_FALSE(clazz_type.create(10, 20)); + const meta::value v = clazz_type.create(30); CHECK(v.get_type() == meta::resolve_type>>()); CHECK(v.cast>>()->i == 30); diff --git a/untests/meta_states/function_tests.cpp b/untests/meta_states/function_tests.cpp index f58b630..c7bdd78 100644 --- a/untests/meta_states/function_tests.cpp +++ b/untests/meta_states/function_tests.cpp @@ -88,7 +88,7 @@ TEST_CASE("meta/meta_states/function") { CHECK_THROWS(func.invoke(ivec2{}, ivec2{}, 42)); CHECK(func.invoke(ivec2{1,2}, ivec2{3,4})); - CHECK(func.invoke(ivec2{1,2}, ivec2{3,4}).value() == ivec2{4,6}); + CHECK(func.invoke(ivec2{1,2}, ivec2{3,4}) == ivec2{4,6}); } SUBCASE("ilength2") { @@ -113,7 +113,7 @@ TEST_CASE("meta/meta_states/function") { CHECK_THROWS(func.invoke(ivec2{}, 42)); CHECK(func.invoke(ivec2{2,3})); - CHECK(func.invoke(ivec2{2,3}).value() == 13); + CHECK(func.invoke(ivec2{2,3}) == 13); } SUBCASE("arg_null") { diff --git a/untests/meta_states/method_tests.cpp b/untests/meta_states/method_tests.cpp index 884a049..fac12d3 100644 --- a/untests/meta_states/method_tests.cpp +++ b/untests/meta_states/method_tests.cpp @@ -130,9 +130,9 @@ TEST_CASE("meta/meta_states/method") { { clazz cl; - CHECK(mi.invoke(cl).value() == 1); + CHECK(mi.invoke(cl) == 1); CHECK_THROWS(mi.invoke(std::as_const(cl))); - CHECK(mi.invoke(std::move(cl)).value() == 1); + CHECK(mi.invoke(std::move(cl)) == 1); CHECK_THROWS(mi.invoke(std::move(std::as_const(cl)))); } @@ -175,9 +175,9 @@ TEST_CASE("meta/meta_states/method") { { clazz cl; - CHECK(mi.invoke(cl).value() == 2); + CHECK(mi.invoke(cl) == 2); CHECK_THROWS(mi.invoke(std::as_const(cl))); - CHECK(mi.invoke(std::move(cl)).value() == 2); + CHECK(mi.invoke(std::move(cl)) == 2); CHECK_THROWS(mi.invoke(std::move(std::as_const(cl)))); } @@ -220,10 +220,10 @@ TEST_CASE("meta/meta_states/method") { { clazz cl; - CHECK(mi.invoke(cl).value() == 3); - CHECK(mi.invoke(std::as_const(cl)).value() == 3); - CHECK(mi.invoke(std::move(cl)).value() == 3); - CHECK(mi.invoke(std::move(std::as_const(cl))).value() == 3); + CHECK(mi.invoke(cl) == 3); + CHECK(mi.invoke(std::as_const(cl)) == 3); + CHECK(mi.invoke(std::move(cl)) == 3); + CHECK(mi.invoke(std::move(std::as_const(cl))) == 3); } static_assert(std::is_invocable_v); @@ -265,10 +265,10 @@ TEST_CASE("meta/meta_states/method") { { clazz cl; - CHECK(mi.invoke(cl).value() == 4); - CHECK(mi.invoke(std::as_const(cl)).value() == 4); - CHECK(mi.invoke(std::move(cl)).value() == 4); - CHECK(mi.invoke(std::move(std::as_const(cl))).value() == 4); + CHECK(mi.invoke(cl) == 4); + CHECK(mi.invoke(std::as_const(cl)) == 4); + CHECK(mi.invoke(std::move(cl)) == 4); + CHECK(mi.invoke(std::move(std::as_const(cl))) == 4); } static_assert(std::is_invocable_v); @@ -310,7 +310,7 @@ TEST_CASE("meta/meta_states/method") { { clazz cl; - CHECK(mi.invoke(cl).value() == 5); + CHECK(mi.invoke(cl) == 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)))); @@ -355,7 +355,7 @@ TEST_CASE("meta/meta_states/method") { { clazz cl; - CHECK(mi.invoke(cl).value() == 6); + CHECK(mi.invoke(cl) == 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)))); @@ -400,8 +400,8 @@ TEST_CASE("meta/meta_states/method") { { clazz cl; - CHECK(mi.invoke(cl).value() == 7); - CHECK(mi.invoke(std::as_const(cl)).value() == 7); + CHECK(mi.invoke(cl) == 7); + CHECK(mi.invoke(std::as_const(cl)) == 7); CHECK(mi.invoke(std::move(cl)) == 7); CHECK(mi.invoke(std::move(std::as_const(cl))) == 7); } @@ -445,8 +445,8 @@ TEST_CASE("meta/meta_states/method") { { clazz cl; - CHECK(mi.invoke(cl).value() == 8); - CHECK(mi.invoke(std::as_const(cl)).value() == 8); + CHECK(mi.invoke(cl) == 8); + CHECK(mi.invoke(std::as_const(cl)) == 8); CHECK(mi.invoke(std::move(cl)) == 8); CHECK(mi.invoke(std::move(std::as_const(cl))) == 8); } @@ -492,7 +492,7 @@ TEST_CASE("meta/meta_states/method") { CHECK_THROWS(mi.invoke(cl)); CHECK_THROWS(mi.invoke(std::as_const(cl))); - CHECK(mi.invoke(std::move(cl)).value() == 9); + CHECK(mi.invoke(std::move(cl)) == 9); CHECK_THROWS(mi.invoke(std::move(std::as_const(cl)))); } @@ -537,7 +537,7 @@ TEST_CASE("meta/meta_states/method") { CHECK_THROWS(mi.invoke(cl)); CHECK_THROWS(mi.invoke(std::as_const(cl))); - CHECK(mi.invoke(std::move(cl)).value() == 10); + CHECK(mi.invoke(std::move(cl)) == 10); CHECK_THROWS(mi.invoke(std::move(std::as_const(cl)))); } @@ -582,8 +582,8 @@ TEST_CASE("meta/meta_states/method") { CHECK_THROWS(mi.invoke(cl)); CHECK_THROWS(mi.invoke(std::as_const(cl))); - CHECK(mi.invoke(std::move(cl)).value() == 11); - CHECK(mi.invoke(std::move(std::as_const(cl))).value() == 11); + CHECK(mi.invoke(std::move(cl)) == 11); + CHECK(mi.invoke(std::move(std::as_const(cl))) == 11); } static_assert(!std::is_invocable_v); @@ -627,8 +627,8 @@ TEST_CASE("meta/meta_states/method") { CHECK_THROWS(mi.invoke(cl)); CHECK_THROWS(mi.invoke(std::as_const(cl))); - CHECK(mi.invoke(std::move(cl)).value() == 12); - CHECK(mi.invoke(std::move(std::as_const(cl))).value() == 12); + CHECK(mi.invoke(std::move(cl)) == 12); + CHECK(mi.invoke(std::move(std::as_const(cl))) == 12); } static_assert(!std::is_invocable_v); diff --git a/untests/meta_types/enum_type_tests.cpp b/untests/meta_types/enum_type_tests.cpp index b18cd0b..c50d603 100644 --- a/untests/meta_types/enum_type_tests.cpp +++ b/untests/meta_types/enum_type_tests.cpp @@ -120,42 +120,20 @@ TEST_CASE("meta/meta_types/enum_type") { const meta::enum_type color_type = meta::resolve_type(); REQUIRE(color_type); - { - REQUIRE(color_type.value_to_name(color::red)); - CHECK(color_type.value_to_name(color::red) == "red"); - } - - { - - REQUIRE(color_type.value_to_name(meta::value{color::blue})); - CHECK(color_type.value_to_name(color::blue) == "blue"); - } - - { - REQUIRE_FALSE(color_type.value_to_name(100500)); - REQUIRE_FALSE(color_type.value_to_name(color{100500})); - } + CHECK(color_type.value_to_name(color::red) == "red"); + CHECK(color_type.value_to_name(color::blue) == "blue"); + CHECK(color_type.value_to_name(100500).empty()); + CHECK(color_type.value_to_name(color{100500}).empty()); } SUBCASE("ecolor/value_to_name") { const meta::enum_type ecolor_type = meta::resolve_type(); REQUIRE(ecolor_type); - { - REQUIRE(ecolor_type.value_to_name(ecolor_red)); - CHECK(ecolor_type.value_to_name(ecolor_red) == "red"); - } - - { - - REQUIRE(ecolor_type.value_to_name(meta::value{ecolor_blue})); - CHECK(ecolor_type.value_to_name(ecolor_blue) == "blue"); - } - - { - REQUIRE_FALSE(ecolor_type.value_to_name(100500)); - REQUIRE_FALSE(ecolor_type.value_to_name(ecolor{100500})); - } + CHECK(ecolor_type.value_to_name(ecolor_red) == "red"); + CHECK(ecolor_type.value_to_name(meta::value{ecolor_blue}) == "blue"); + CHECK(ecolor_type.value_to_name(100500).empty()); + CHECK(ecolor_type.value_to_name(ecolor{100500}).empty()); } SUBCASE("color/name_to_value") { From 5c0dc2350f00bb41bcd062b09cc970c0715e5c78 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Mon, 24 Jan 2022 04:44:28 +0700 Subject: [PATCH 190/233] fix examples --- headers/meta.hpp/meta_states/function.hpp | 2 +- headers/meta.hpp/meta_states/method.hpp | 2 +- headers/meta.hpp/meta_types/class_type.hpp | 2 +- manuals/meta_examples/classes_example.cpp | 2 +- manuals/meta_examples/enums_examples.cpp | 6 +++--- manuals/meta_examples/functions_example.cpp | 2 +- manuals/meta_examples/methods_example.cpp | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/headers/meta.hpp/meta_states/function.hpp b/headers/meta.hpp/meta_states/function.hpp index 1d8a25c..3f7299f 100644 --- a/headers/meta.hpp/meta_states/function.hpp +++ b/headers/meta.hpp/meta_states/function.hpp @@ -49,7 +49,7 @@ namespace meta_hpp::detail std::ignore = std::invoke( std::move(function), (args.data() + Is)->cast>()...); - return {}; + return value{}; } else { return_type&& return_value = std::invoke( std::move(function), diff --git a/headers/meta.hpp/meta_states/method.hpp b/headers/meta.hpp/meta_states/method.hpp index 762b0d4..deb11a6 100644 --- a/headers/meta.hpp/meta_states/method.hpp +++ b/headers/meta.hpp/meta_states/method.hpp @@ -56,7 +56,7 @@ namespace meta_hpp::detail std::move(method), inst.cast(), (args.data() + Is)->cast>()...); - return {}; + return value{}; } else { return_type&& return_value = std::invoke( std::move(method), diff --git a/headers/meta.hpp/meta_types/class_type.hpp b/headers/meta.hpp/meta_types/class_type.hpp index de4aebc..09d2459 100644 --- a/headers/meta.hpp/meta_types/class_type.hpp +++ b/headers/meta.hpp/meta_types/class_type.hpp @@ -109,7 +109,7 @@ namespace meta_hpp return ctor.second.invoke(std::forward(args)...); } } - return {}; + return value{}; } template < typename... Args > diff --git a/manuals/meta_examples/classes_example.cpp b/manuals/meta_examples/classes_example.cpp index ea6b6aa..ad71d88 100644 --- a/manuals/meta_examples/classes_example.cpp +++ b/manuals/meta_examples/classes_example.cpp @@ -71,7 +71,7 @@ TEST_CASE("meta/meta_examples/classes/usage") { const meta::method rectangle_area = rectangle_type.get_method("get_area"); // creates a rectangle instance by the registered constructor(int, int) - const meta::value rectangle_v = rectangle_type.create(10, 20).value(); + const meta::value rectangle_v = rectangle_type.create(10, 20); // calls the method with the dynamic rectangle instance 'rectangle_v' CHECK(rectangle_area.invoke(rectangle_v) == 200); diff --git a/manuals/meta_examples/enums_examples.cpp b/manuals/meta_examples/enums_examples.cpp index f5970dc..123444e 100644 --- a/manuals/meta_examples/enums_examples.cpp +++ b/manuals/meta_examples/enums_examples.cpp @@ -49,11 +49,11 @@ TEST_CASE("meta/meta_examples/enums/usage") { const meta::enum_type align_type = meta::resolve_type(e); // converts the enumerator to its name - CHECK(align_type.value_to_name(e).value() == "center"); + CHECK(align_type.value_to_name(e) == "center"); // also, it works with dynamic value types - CHECK(align_type.value_to_name(meta::value{e}).value() == "center"); + CHECK(align_type.value_to_name(meta::value{e}) == "center"); // ... and back again - CHECK(align_type.name_to_value("center").value() == e); + CHECK(align_type.name_to_value("center") == e); } diff --git a/manuals/meta_examples/functions_example.cpp b/manuals/meta_examples/functions_example.cpp index b2b08c4..a5f5873 100644 --- a/manuals/meta_examples/functions_example.cpp +++ b/manuals/meta_examples/functions_example.cpp @@ -59,7 +59,7 @@ TEST_CASE("meta/meta_examples/functions/usage") { CHECK(sub_function.is_invocable_with()); // calls the function and retrieves a returned value - const meta::value sub_result_value = sub_function.invoke(60, 18).value(); + const meta::value sub_result_value = sub_function.invoke(60, 18); // checks the type of the returned value CHECK(sub_result_value.get_type() == meta::resolve_type()); diff --git a/manuals/meta_examples/methods_example.cpp b/manuals/meta_examples/methods_example.cpp index ddd4a48..5d1f170 100644 --- a/manuals/meta_examples/methods_example.cpp +++ b/manuals/meta_examples/methods_example.cpp @@ -69,7 +69,7 @@ TEST_CASE("meta/meta_examples/methods/usage") { CHECK(ivec2_add.is_invocable_with()); // calls the method and retrieves a returned value - const meta::value ivec2_add_result_value = ivec2_add.invoke(v, ivec2{22, 11}).value(); + const meta::value ivec2_add_result_value = ivec2_add.invoke(v, ivec2{22, 11}); // checks the type and value of the result CHECK(ivec2_add_result_value.get_type() == meta::resolve_type()); From 14e68063d02655bc2bb9b33fe14832d39852bd88 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Mon, 24 Jan 2022 04:47:50 +0700 Subject: [PATCH 191/233] fix untests --- headers/meta.hpp/meta_utilities.hpp | 9 ++++----- headers/meta.hpp/meta_utilities/value.hpp | 16 ---------------- untests/meta_utilities/value_tests.cpp | 10 ++++------ 3 files changed, 8 insertions(+), 27 deletions(-) diff --git a/headers/meta.hpp/meta_utilities.hpp b/headers/meta.hpp/meta_utilities.hpp index c4ec2bb..5d3f16c 100644 --- a/headers/meta.hpp/meta_utilities.hpp +++ b/headers/meta.hpp/meta_utilities.hpp @@ -105,14 +105,13 @@ namespace meta_hpp class value final { public: value() = default; + ~value() = default; - value(value&& other) noexcept = default; + value(value&& other) = default; value(const value& other) = default; - value& operator=(value&& other) noexcept; - value& operator=(const value& other); - - ~value() = default; + value& operator=(value&& other) = default; + value& operator=(const value& other) = default; template < detail::decay_non_uvalue_kind T > requires detail::stdex::copy_constructible> diff --git a/headers/meta.hpp/meta_utilities/value.hpp b/headers/meta.hpp/meta_utilities/value.hpp index 9364fb0..dac1b7a 100644 --- a/headers/meta.hpp/meta_utilities/value.hpp +++ b/headers/meta.hpp/meta_utilities/value.hpp @@ -107,22 +107,6 @@ namespace meta_hpp namespace meta_hpp { - inline value& value::operator=(value&& other) noexcept { - if ( this != &other ) { - value temp{std::move(other)}; - swap(temp); - } - return *this; - } - - inline value& value::operator=(const value& other) { - if ( this != &other ) { - value temp{other}; - swap(temp); - } - return *this; - } - template < detail::decay_non_uvalue_kind T > requires detail::stdex::copy_constructible> value::value(T&& val) diff --git a/untests/meta_utilities/value_tests.cpp b/untests/meta_utilities/value_tests.cpp index 4f97bd6..007afdf 100644 --- a/untests/meta_utilities/value_tests.cpp +++ b/untests/meta_utilities/value_tests.cpp @@ -12,7 +12,7 @@ namespace int x{}; int y{}; - ivec2() = default; + ivec2() = delete; explicit ivec2(int v): x{v}, y{v} {} ivec2(int x, int y): x{x}, y{y} {} @@ -48,7 +48,7 @@ namespace int y{}; int z{}; - ivec3() = default; + ivec3() = delete; explicit ivec3(int v): x{v}, y{v}, z{v} {} ivec3(int x, int y, int z): x{x}, y{y}, z{z} {} }; @@ -73,7 +73,6 @@ TEST_CASE("meta/meta_utilities/value/ivec2") { namespace meta = meta_hpp; meta::class_() - .ctor_<>() .ctor_() .ctor_() .ctor_() @@ -86,7 +85,6 @@ TEST_CASE("meta/meta_utilities/value/ivec3") { namespace meta = meta_hpp; meta::class_() - .ctor_<>() .ctor_() .ctor_() .ctor_() @@ -362,7 +360,7 @@ TEST_CASE("meta/meta_utilities/value") { val_dst = std::move(val_src2); CHECK(val_dst == ivec2{1,2}); - CHECK(ivec2::move_ctor_counter == 4); + CHECK(ivec2::move_ctor_counter == 3); CHECK(ivec2::copy_ctor_counter == 0); } @@ -381,7 +379,7 @@ TEST_CASE("meta/meta_utilities/value") { val_dst = val_src2; CHECK(val_dst == ivec2{1,2}); - CHECK(ivec2::move_ctor_counter == 3); + CHECK(ivec2::move_ctor_counter == 2); CHECK(ivec2::copy_ctor_counter == 1); CHECK(val_src2 == ivec2{1,2}); From 1fd3992d97552f5998a1d8e060ae67b8df09ed86 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Mon, 24 Jan 2022 05:17:13 +0700 Subject: [PATCH 192/233] update readme --- TODO.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/TODO.md b/TODO.md index 65809e2..e7e6ecb 100644 --- a/TODO.md +++ b/TODO.md @@ -1,11 +1,12 @@ # meta.hpp +- exception class +- metadata + +* argument defaults * argument names -* exception class -* move-only value type support -* states and types metadata * type conversions -- (?) type names -- (?) argument defaults - (?) enum_type::create, number_type::create, and so on +- (?) move-only value type support +- (?) type names From 8d6a8e77890abfe3c9a611b643660a6ef6f9cc44 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Wed, 26 Jan 2022 17:48:00 +0700 Subject: [PATCH 193/233] rewrite value without std::any --- headers/meta.hpp/meta_base.hpp | 2 +- headers/meta.hpp/meta_utilities.hpp | 38 +- headers/meta.hpp/meta_utilities/value.hpp | 371 +++++++++++++------ untests/meta_utilities/value2_tests.cpp | 411 ++++++++++++++++++++++ untests/meta_utilities/value_tests.cpp | 2 +- 5 files changed, 713 insertions(+), 111 deletions(-) create mode 100644 untests/meta_utilities/value2_tests.cpp diff --git a/headers/meta.hpp/meta_base.hpp b/headers/meta.hpp/meta_base.hpp index 0ec657c..1cc4877 100644 --- a/headers/meta.hpp/meta_base.hpp +++ b/headers/meta.hpp/meta_base.hpp @@ -11,7 +11,6 @@ #include #include -#include #include #include #include @@ -27,6 +26,7 @@ #include #include #include +#include #include #include diff --git a/headers/meta.hpp/meta_utilities.hpp b/headers/meta.hpp/meta_utilities.hpp index 5d3f16c..ee58de7 100644 --- a/headers/meta.hpp/meta_utilities.hpp +++ b/headers/meta.hpp/meta_utilities.hpp @@ -31,7 +31,12 @@ namespace meta_hpp::detail }; template < typename From, typename To > - using copy_cvref_t = typename cvref_traits::template copy_to; + struct copy_cvref { + using type = typename cvref_traits::template copy_to; + }; + + template < typename From, typename To > + using copy_cvref_t = typename copy_cvref::type; } namespace meta_hpp::detail @@ -100,18 +105,29 @@ namespace meta_hpp::detail }; } +namespace meta_hpp::detail +{ + template < typename... Ts > + struct overloaded : Ts... { + using Ts::operator()...; + }; + + template < typename... Ts > + overloaded(Ts...) -> overloaded; +} + namespace meta_hpp { class value final { public: value() = default; - ~value() = default; + ~value() noexcept; - value(value&& other) = default; - value(const value& other) = default; + value(value&& other) noexcept; + value(const value& other); - value& operator=(value&& other) = default; - value& operator=(const value& other) = default; + value& operator=(value&& other) noexcept; + value& operator=(const value& other); template < detail::decay_non_uvalue_kind T > requires detail::stdex::copy_constructible> @@ -124,6 +140,7 @@ namespace meta_hpp [[nodiscard]] bool is_valid() const noexcept; [[nodiscard]] explicit operator bool() const noexcept; + void reset() noexcept; void swap(value& other) noexcept; [[nodiscard]] any_type get_type() const noexcept; @@ -158,9 +175,12 @@ namespace meta_hpp friend std::istream& operator>>(std::istream& is, value& v); friend std::ostream& operator<<(std::ostream& os, const value& v); private: - struct traits; - std::any raw_{}; - const traits* traits_{}; + struct vtable_t; + vtable_t* vtable_{}; + private: + using buffer_t = std::aligned_storage_t; + using storage_u = std::variant; + storage_u storage_{}; }; inline void swap(value& l, value& r) noexcept { diff --git a/headers/meta.hpp/meta_utilities/value.hpp b/headers/meta.hpp/meta_utilities/value.hpp index dac1b7a..cb3f1a2 100644 --- a/headers/meta.hpp/meta_utilities/value.hpp +++ b/headers/meta.hpp/meta_utilities/value.hpp @@ -18,14 +18,18 @@ namespace meta_hpp { - struct value::traits final { + struct value::vtable_t final { const any_type type; - void* (*const data)(value&) noexcept; - const void* (*const cdata)(const value&) noexcept; + void* (*const data)(storage_u& from) noexcept; + const void* (*const cdata)(const storage_u& from) noexcept; - value (*const deref)(const value&); - value (*const index)(const value&, std::size_t); + void (*const move)(value& from, value& to) noexcept; + void (*const copy)(const value& from, value& to); + void (*const destroy)(value& self) noexcept; + + value (*const deref)(const value& from); + value (*const index)(const value& from, std::size_t); bool (*const less)(const value&, const value&); bool (*const equals)(const value&, const value&); @@ -34,167 +38,334 @@ namespace meta_hpp std::ostream& (*const ostream)(std::ostream&, const value&); template < typename T > - static const traits* get() noexcept; + static T* storage_cast(buffer_t& buffer) noexcept { + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + return reinterpret_cast(&buffer); + } + + template < typename T > + static const T* storage_cast(const buffer_t& buffer) noexcept { + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + return reinterpret_cast(&buffer); + } + + template < typename T > + static T* storage_cast(storage_u& storage) noexcept { + return std::visit(detail::overloaded { + [](void* ptr) { return static_cast(ptr); }, + [](buffer_t& buffer) { return storage_cast(buffer); }, + [](...) -> T* { return nullptr; }, + }, storage); + } + + template < typename T > + static const T* storage_cast(const storage_u& storage) noexcept { + return std::visit(detail::overloaded { + [](const void* ptr) { return static_cast(ptr); }, + [](const buffer_t& buffer) { return storage_cast(buffer); }, + [](...) -> const T* { return nullptr; }, + }, storage); + } + + template < typename T > + static void construct(value& dst, T&& val) { + using Tp = std::decay_t; + + constexpr bool in_buffer = + sizeof(Tp) <= sizeof(buffer_t) && + alignof(Tp) <= alignof(buffer_t) && + std::is_nothrow_move_constructible_v; + + if constexpr ( in_buffer ) { + dst.storage_.emplace(); + std::construct_at(storage_cast(dst.storage_), std::forward(val)); + } else { + dst.storage_.emplace(std::make_unique(std::forward(val)).release()); + } + + dst.vtable_ = vtable_t::get(); + } + + static void swap(value& l, value& r) noexcept { + if ( (&l == &r) || (!l && !r) ) { + return; + } + + if ( l && r ) { + if ( std::holds_alternative(l.storage_) ) { + value temp; + r.vtable_->move(r, temp); + l.vtable_->move(l, r); + temp.vtable_->move(temp, l); + } else { + value temp; + l.vtable_->move(l, temp); + r.vtable_->move(r, l); + temp.vtable_->move(temp, r); + } + } else { + if ( l ) { + l.vtable_->move(l, r); + } else { + r.vtable_->move(r, l); + } + } + } + + template < typename Tp > + static vtable_t* get() { + static vtable_t table{ + .type = resolve_type(), + + .data = [](storage_u& from) noexcept -> void* { + return storage_cast(from); + }, + + .cdata = [](const storage_u& from) noexcept -> const void* { + return storage_cast(from); + }, + + .move = [](value& from, value& to) noexcept { + std::visit(detail::overloaded { + [&to](void* ptr) { + Tp* src = static_cast(ptr); + to.storage_.emplace(src); + }, + [&to](buffer_t& buffer) { + to.storage_.emplace(); + std::construct_at(storage_cast(to.storage_), std::move(*storage_cast(buffer))); + std::destroy_at(storage_cast(buffer)); + }, + [](...){} + }, from.storage_); + + to.vtable_ = from.vtable_; + from.vtable_ = nullptr; + }, + + .copy = [](const value& from, value& to){ + std::visit(detail::overloaded { + [&to](void* ptr) { + const Tp* src = static_cast(ptr); + to.storage_.emplace(new Tp{*src}); + }, + [&to](const buffer_t& buffer) { + to.storage_.emplace(); + std::construct_at(storage_cast(to.storage_), *storage_cast(buffer)); + }, + [](...){} + }, from.storage_); + + to.vtable_ = from.vtable_; + }, + + .destroy = [](value& self) noexcept { + std::visit(detail::overloaded { + [](void* ptr) { + Tp* src = static_cast(ptr); + std::unique_ptr{src}.reset(); + }, + [](buffer_t& buffer) { + std::destroy_at(storage_cast(buffer)); + }, + [](...){} + }, self.storage_); + + self.vtable_ = nullptr; + }, + + .deref = +[]([[maybe_unused]] const value& v) -> value { + if constexpr ( detail::has_value_deref_traits ) { + return detail::value_deref_traits{}(v.cast()); + } else { + throw std::logic_error("value type doesn't have value deref traits"); + } + }, + + .index = +[]([[maybe_unused]] const value& v, [[maybe_unused]] std::size_t index) -> value { + if constexpr ( detail::has_value_index_traits ) { + return detail::value_index_traits{}(v.cast(), index); + } else { + throw std::logic_error("value type doesn't have value index traits"); + } + }, + + .less = +[]([[maybe_unused]] const value& l, [[maybe_unused]] const value& r) -> bool { + if constexpr ( detail::has_value_less_traits ) { + return detail::value_less_traits{}(l.cast(), r.cast()); + } else { + throw std::logic_error("value type doesn't have value less traits"); + } + }, + + .equals = +[]([[maybe_unused]] const value& l, [[maybe_unused]] const value& r) -> bool { + if constexpr ( detail::has_value_equals_traits ) { + return detail::value_equals_traits{}(l.cast(), r.cast()); + } else { + throw std::logic_error("value type doesn't have value equals traits"); + } + }, + + .istream = +[]([[maybe_unused]] std::istream& is, [[maybe_unused]] value& v) -> std::istream& { + if constexpr ( detail::has_value_istream_traits ) { + return detail::value_istream_traits{}(is, v.cast()); + } else { + throw std::logic_error("value type doesn't have value istream traits"); + } + }, + + .ostream = +[]([[maybe_unused]] std::ostream& os, [[maybe_unused]] const value& v) -> std::ostream& { + if constexpr ( detail::has_value_ostream_traits ) { + return detail::value_ostream_traits{}(os, v.cast()); + } else { + throw std::logic_error("value type doesn't have value ostream traits"); + } + }, + }; + + return &table; + } }; - - template < typename T > - const value::traits* value::traits::get() noexcept { - static_assert(std::is_same_v>); - - static const traits traits{ - .type = resolve_type(), - - .data = +[](value& v) noexcept -> void* { - return v.try_cast(); - }, - - .cdata = +[](const value& v) noexcept -> const void* { - return v.try_cast(); - }, - - .deref = +[]([[maybe_unused]] const value& v) -> value { - if constexpr ( detail::has_value_deref_traits ) { - return detail::value_deref_traits{}(v.cast()); - } else { - throw std::logic_error("value type doesn't have value deref traits"); - } - }, - - .index = +[]([[maybe_unused]] const value& v, [[maybe_unused]] std::size_t index) -> value { - if constexpr ( detail::has_value_index_traits ) { - return detail::value_index_traits{}(v.cast(), index); - } else { - throw std::logic_error("value type doesn't have value index traits"); - } - }, - - .less = +[]([[maybe_unused]] const value& l, [[maybe_unused]] const value& r) -> bool { - if constexpr ( detail::has_value_less_traits ) { - return detail::value_less_traits{}(l.cast(), r.cast()); - } else { - throw std::logic_error("value type doesn't have value less traits"); - } - }, - - .equals = +[]([[maybe_unused]] const value& l, [[maybe_unused]] const value& r) -> bool { - if constexpr ( detail::has_value_equals_traits ) { - return detail::value_equals_traits{}(l.cast(), r.cast()); - } else { - throw std::logic_error("value type doesn't have value equals traits"); - } - }, - - .istream = +[]([[maybe_unused]] std::istream& is, [[maybe_unused]] value& v) -> std::istream& { - if constexpr ( detail::has_value_istream_traits ) { - return detail::value_istream_traits{}(is, v.cast()); - } else { - throw std::logic_error("value type doesn't have value istream traits"); - } - }, - - .ostream = +[]([[maybe_unused]] std::ostream& os, [[maybe_unused]] const value& v) -> std::ostream& { - if constexpr ( detail::has_value_ostream_traits ) { - return detail::value_ostream_traits{}(os, v.cast()); - } else { - throw std::logic_error("value type doesn't have value ostream traits"); - } - }, - }; - - return &traits; - } } namespace meta_hpp { + inline value::~value() noexcept { + reset(); + } + + inline value::value(value&& other) noexcept { + if ( other.vtable_ != nullptr ) { + other.vtable_->move(other, *this); + } + } + + inline value::value(const value& other) { + if ( other.vtable_ != nullptr ) { + other.vtable_->copy(other, *this); + } + } + + inline value& value::operator=(value&& other) noexcept { + if ( this != &other ) { + value{std::move(other)}.swap(*this); + } + return *this; + } + + inline value& value::operator=(const value& other) { + if ( this != &other ) { + value{other}.swap(*this); + } + return *this; + } + template < detail::decay_non_uvalue_kind T > requires detail::stdex::copy_constructible> - value::value(T&& val) - : raw_{std::forward(val)} - , traits_{traits::get>()} {} + value::value(T&& val) { + vtable_t::construct(*this, std::forward(val)); + } template < detail::decay_non_uvalue_kind T > requires detail::stdex::copy_constructible> value& value::operator=(T&& val) { - value temp{std::forward(val)}; - swap(temp); + value{std::forward(val)}.swap(*this); return *this; } inline bool value::is_valid() const noexcept { - return raw_.has_value(); + return vtable_ != nullptr; } inline value::operator bool() const noexcept { return is_valid(); } + inline void value::reset() noexcept { + if ( vtable_ != nullptr ) { + vtable_->destroy(*this); + vtable_ = nullptr; + } + } + inline void value::swap(value& other) noexcept { - using std::swap; - swap(raw_, other.raw_); - swap(traits_, other.traits_); + vtable_t::swap(*this, other); } inline any_type value::get_type() const noexcept { - return traits_ != nullptr - ? traits_->type - : resolve_type(); + return vtable_ != nullptr ? vtable_->type : resolve_type(); } inline void* value::data() noexcept { - return traits_ != nullptr ? traits_->data(*this) : nullptr; + return vtable_ != nullptr ? vtable_->data(storage_) : nullptr; } inline const void* value::data() const noexcept { - return traits_ != nullptr ? traits_->cdata(*this) : nullptr; + return vtable_ != nullptr ? vtable_->cdata(storage_) : nullptr; } inline const void* value::cdata() const noexcept { - return traits_ != nullptr ? traits_->cdata(*this) : nullptr; + return vtable_ != nullptr ? vtable_->cdata(storage_) : nullptr; } inline value value::operator*() const { - return traits_ != nullptr ? traits_->deref(*this) : value{}; + return vtable_ != nullptr ? vtable_->deref(*this) : value{}; } inline value value::operator[](std::size_t index) const { - return traits_ != nullptr ? traits_->index(*this, index) : value{}; + return vtable_ != nullptr ? vtable_->index(*this, index) : value{}; } template < typename T > std::decay_t& value::cast() & { using Tp = std::decay_t; - return std::any_cast(raw_); + if ( Tp* ptr = try_cast() ) { + return *ptr; + } + throw std::logic_error("bad value cast"); } template < typename T > std::decay_t&& value::cast() && { using Tp = std::decay_t; - return std::move(std::any_cast(raw_)); + if ( Tp* ptr = try_cast() ) { + return std::move(*ptr); + } + throw std::logic_error("bad value cast"); } template < typename T > const std::decay_t& value::cast() const & { using Tp = std::decay_t; - return std::any_cast(raw_); + if ( const Tp* ptr = try_cast() ) { + return *ptr; + } + throw std::logic_error("bad value cast"); } template < typename T > const std::decay_t&& value::cast() const && { using Tp = std::decay_t; - return std::move(std::any_cast(raw_)); + if ( const Tp* ptr = try_cast() ) { + return std::move(*ptr); + } + throw std::logic_error("bad value cast"); } template < typename T > std::decay_t* value::try_cast() noexcept { using Tp = std::decay_t; - return std::any_cast(&raw_); + return get_type() == resolve_type() + ? vtable_t::storage_cast(storage_) + : nullptr; } template < typename T > const std::decay_t* value::try_cast() const noexcept { using Tp = std::decay_t; - return std::any_cast(&raw_); + return get_type() == resolve_type() + ? vtable_t::storage_cast(storage_) + : nullptr; } } @@ -232,7 +403,7 @@ namespace meta_hpp } return (l.get_type() < r.get_type()) - || (l.get_type() == r.get_type() && l.traits_->less(l, r)); + || (l.get_type() == r.get_type() && l.vtable_->less(l, r)); } } @@ -268,17 +439,17 @@ namespace meta_hpp } return l.get_type() == r.get_type() - && l.traits_->equals(l, r); + && l.vtable_->equals(l, r); } } namespace meta_hpp { inline std::istream& operator>>(std::istream& is, value& v) { - return v.traits_->istream(is, v); + return v.vtable_->istream(is, v); } inline std::ostream& operator<<(std::ostream& os, const value& v) { - return v.traits_->ostream(os, v); + return v.vtable_->ostream(os, v); } } diff --git a/untests/meta_utilities/value2_tests.cpp b/untests/meta_utilities/value2_tests.cpp new file mode 100644 index 0000000..58588bc --- /dev/null +++ b/untests/meta_utilities/value2_tests.cpp @@ -0,0 +1,411 @@ +/******************************************************************************* + * 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 ivec2 final { + int x{}; + int y{}; + + ivec2() = delete; + explicit ivec2(int v): x{v}, y{v} {} + ivec2(int x, int y): x{x}, y{y} {} + + ivec2(ivec2&& other) noexcept + : x{other.x} + , y{other.y} { + other.x = 0; + other.y = 0; + ++move_ctor_counter; + } + + ivec2(const ivec2& other) noexcept + : x{other.x} + , y{other.y} { + ++copy_ctor_counter; + } + + ~ivec2() noexcept { + ++dtor_counter; + } + + ivec2& operator=(ivec2&& other) = delete; + ivec2& operator=(const ivec2& other) = delete; + + static int dtor_counter; + static int move_ctor_counter; + static int copy_ctor_counter; + }; + + struct ivec2_big final { + int x{}; + int y{}; + + int dummy[42]{}; + + ivec2_big() = delete; + explicit ivec2_big(int v): x{v}, y{v} {} + ivec2_big(int x, int y): x{x}, y{y} {} + + ivec2_big(ivec2_big&& other) noexcept + : x{other.x} + , y{other.y} { + other.x = 0; + other.y = 0; + ++move_ctor_counter; + } + + ivec2_big(const ivec2_big& other) noexcept + : x{other.x} + , y{other.y} { + ++copy_ctor_counter; + } + + ~ivec2_big() noexcept { + ++dtor_counter; + } + + ivec2_big& operator=(ivec2_big&& other) = delete; + ivec2_big& operator=(const ivec2_big& other) = delete; + + static int dtor_counter; + static int move_ctor_counter; + static int copy_ctor_counter; + }; + + [[maybe_unused]] bool operator==(const ivec2& l, const ivec2& r) noexcept { + return l.x == r.x && l.y == r.y; + } + + [[maybe_unused]] bool operator==(const ivec2_big& l, const ivec2_big& r) noexcept { + return l.x == r.x && l.y == r.y; + } + + int ivec2::dtor_counter{0}; + int ivec2::move_ctor_counter{0}; + int ivec2::copy_ctor_counter{0}; + + int ivec2_big::dtor_counter{0}; + int ivec2_big::move_ctor_counter{0}; + int ivec2_big::copy_ctor_counter{0}; +} + +TEST_CASE("meta/meta_utilities/value2") { + namespace meta = meta_hpp; + + meta::class_() + .ctor_() + .ctor_() + .ctor_() + .ctor_() + .member_("x", &ivec2::x) + .member_("y", &ivec2::y); + + meta::class_() + .ctor_() + .ctor_() + .ctor_() + .ctor_() + .member_("x", &ivec2_big::x) + .member_("y", &ivec2_big::y); +} + +TEST_CASE("meta/meta_utilities/value2/counters/small") { + namespace meta = meta_hpp; + + ivec2::dtor_counter = 0; + ivec2::move_ctor_counter = 0; + ivec2::copy_ctor_counter = 0; + + SUBCASE("def ctor") { + { + meta::value v{}; + CHECK(ivec2::dtor_counter == 0); + CHECK(ivec2::move_ctor_counter == 0); + CHECK(ivec2::copy_ctor_counter == 0); + } + CHECK(ivec2::dtor_counter == 0); + CHECK(ivec2::move_ctor_counter == 0); + CHECK(ivec2::copy_ctor_counter == 0); + } + + SUBCASE("val ctor") { + { + meta::value v{ivec2{1,2}}; + CHECK(ivec2::dtor_counter == 1); + CHECK(ivec2::move_ctor_counter == 1); + CHECK(ivec2::copy_ctor_counter == 0); + } + CHECK(ivec2::dtor_counter == 2); + CHECK(ivec2::move_ctor_counter == 1); + CHECK(ivec2::copy_ctor_counter == 0); + } + + SUBCASE("move ctor") { + { + meta::value v1{ivec2{1,2}}; + meta::value v2{std::move(v1)}; + + CHECK_FALSE(v1); + CHECK(v2.cast().x == 1); + + CHECK(ivec2::dtor_counter == 2); + CHECK(ivec2::move_ctor_counter == 2); + CHECK(ivec2::copy_ctor_counter == 0); + } + CHECK(ivec2::dtor_counter == 3); + CHECK(ivec2::move_ctor_counter == 2); + CHECK(ivec2::copy_ctor_counter == 0); + } + + SUBCASE("copy ctor") { + { + meta::value v1{ivec2{1,2}}; + meta::value v2{std::as_const(v1)}; + + CHECK(v1.cast().x == 1); + CHECK(v2.cast().y == 2); + + CHECK(ivec2::dtor_counter == 1); + CHECK(ivec2::move_ctor_counter == 1); + CHECK(ivec2::copy_ctor_counter == 1); + } + CHECK(ivec2::dtor_counter == 3); + CHECK(ivec2::move_ctor_counter == 1); + CHECK(ivec2::copy_ctor_counter == 1); + } + + SUBCASE("swap") { + { + meta::value v1{ivec2{1,2}}; + meta::value v2{ivec2{3,4}}; + CHECK(ivec2::dtor_counter == 2); + CHECK(ivec2::move_ctor_counter == 2); + CHECK(ivec2::copy_ctor_counter == 0); + + v1.swap(v2); + CHECK(v1.cast().x == 3); + CHECK(v2.cast().x == 1); + + CHECK(ivec2::dtor_counter == 5); + CHECK(ivec2::move_ctor_counter == 5); + CHECK(ivec2::copy_ctor_counter == 0); + } + CHECK(ivec2::dtor_counter == 7); + CHECK(ivec2::move_ctor_counter == 5); + CHECK(ivec2::copy_ctor_counter == 0); + } +} + +TEST_CASE("meta/meta_utilities/value2/counters/big") { + namespace meta = meta_hpp; + + ivec2_big::dtor_counter = 0; + ivec2_big::move_ctor_counter = 0; + ivec2_big::copy_ctor_counter = 0; + + SUBCASE("def ctor") { + { + meta::value v{}; + CHECK(ivec2_big::dtor_counter == 0); + CHECK(ivec2_big::move_ctor_counter == 0); + CHECK(ivec2_big::copy_ctor_counter == 0); + } + CHECK(ivec2_big::dtor_counter == 0); + CHECK(ivec2_big::move_ctor_counter == 0); + CHECK(ivec2_big::copy_ctor_counter == 0); + } + + SUBCASE("val ctor") { + { + meta::value v{ivec2_big{1,2}}; + CHECK(ivec2_big::dtor_counter == 1); + CHECK(ivec2_big::move_ctor_counter == 1); + CHECK(ivec2_big::copy_ctor_counter == 0); + } + CHECK(ivec2_big::dtor_counter == 2); + CHECK(ivec2_big::move_ctor_counter == 1); + CHECK(ivec2_big::copy_ctor_counter == 0); + } + + SUBCASE("move ctor") { + { + meta::value v1{ivec2_big{1,2}}; + meta::value v2{std::move(v1)}; + + CHECK_FALSE(v1); + CHECK(v2.cast().x == 1); + + CHECK(ivec2_big::dtor_counter == 1); + CHECK(ivec2_big::move_ctor_counter == 1); + CHECK(ivec2_big::copy_ctor_counter == 0); + } + CHECK(ivec2_big::dtor_counter == 2); + CHECK(ivec2_big::move_ctor_counter == 1); + CHECK(ivec2_big::copy_ctor_counter == 0); + } + + SUBCASE("copy ctor") { + { + meta::value v1{ivec2_big{1,2}}; + meta::value v2{std::as_const(v1)}; + + CHECK(v1.cast().x == 1); + CHECK(v2.cast().y == 2); + + CHECK(ivec2_big::dtor_counter == 1); + CHECK(ivec2_big::move_ctor_counter == 1); + CHECK(ivec2_big::copy_ctor_counter == 1); + } + CHECK(ivec2_big::dtor_counter == 3); + CHECK(ivec2_big::move_ctor_counter == 1); + CHECK(ivec2_big::copy_ctor_counter == 1); + } + + SUBCASE("swap") { + { + meta::value v1{ivec2_big{1,2}}; + meta::value v2{ivec2_big{3,4}}; + CHECK(ivec2_big::dtor_counter == 2); + CHECK(ivec2_big::move_ctor_counter == 2); + CHECK(ivec2_big::copy_ctor_counter == 0); + + v1.swap(v2); + CHECK(v1.cast().x == 3); + CHECK(v2.cast().x == 1); + + CHECK(ivec2_big::dtor_counter == 2); + CHECK(ivec2_big::move_ctor_counter == 2); + CHECK(ivec2_big::copy_ctor_counter == 0); + } + CHECK(ivec2_big::dtor_counter == 4); + CHECK(ivec2_big::move_ctor_counter == 2); + CHECK(ivec2_big::copy_ctor_counter == 0); + } +} + +TEST_CASE("meta/meta_utilities/value2/counters/swap") { + namespace meta = meta_hpp; + + ivec2::dtor_counter = 0; + ivec2::move_ctor_counter = 0; + ivec2::copy_ctor_counter = 0; + + ivec2_big::dtor_counter = 0; + ivec2_big::move_ctor_counter = 0; + ivec2_big::copy_ctor_counter = 0; + + SUBCASE("empty/small") { + { + meta::value v1{}; + meta::value v2{ivec2{1,2}}; + + CHECK(ivec2::dtor_counter == 1); + CHECK(ivec2::move_ctor_counter == 1); + CHECK(ivec2::copy_ctor_counter == 0); + + v1.swap(v2); + CHECK(v1.cast().x == 1); + CHECK_FALSE(v2); + + CHECK(ivec2::dtor_counter == 2); + CHECK(ivec2::move_ctor_counter == 2); + CHECK(ivec2::copy_ctor_counter == 0); + + v1.swap(v2); + CHECK_FALSE(v1); + CHECK(v2.cast().y == 2); + + CHECK(ivec2::dtor_counter == 3); + CHECK(ivec2::move_ctor_counter == 3); + CHECK(ivec2::copy_ctor_counter == 0); + } + + CHECK(ivec2::dtor_counter == 4); + CHECK(ivec2::move_ctor_counter == 3); + CHECK(ivec2::copy_ctor_counter == 0); + } + + SUBCASE("empty/big") { + { + meta::value v1{}; + meta::value v2{ivec2_big{3,4}}; + + CHECK(ivec2_big::dtor_counter == 1); + CHECK(ivec2_big::move_ctor_counter == 1); + CHECK(ivec2_big::copy_ctor_counter == 0); + + v1.swap(v2); + CHECK(v1.cast().x == 3); + CHECK_FALSE(v2); + + CHECK(ivec2_big::dtor_counter == 1); + CHECK(ivec2_big::move_ctor_counter == 1); + CHECK(ivec2_big::copy_ctor_counter == 0); + + v1.swap(v2); + CHECK_FALSE(v1); + CHECK(v2.cast().y == 4); + + CHECK(ivec2_big::dtor_counter == 1); + CHECK(ivec2_big::move_ctor_counter == 1); + CHECK(ivec2_big::copy_ctor_counter == 0); + } + + CHECK(ivec2_big::dtor_counter == 2); + CHECK(ivec2_big::move_ctor_counter == 1); + CHECK(ivec2_big::copy_ctor_counter == 0); + } + + SUBCASE("small/big") { + { + meta::value v1{ivec2{1,2}}; + meta::value v2{ivec2_big{3,4}}; + + CHECK(ivec2::dtor_counter == 1); + CHECK(ivec2::move_ctor_counter == 1); + CHECK(ivec2::copy_ctor_counter == 0); + + CHECK(ivec2_big::dtor_counter == 1); + CHECK(ivec2_big::move_ctor_counter == 1); + CHECK(ivec2_big::copy_ctor_counter == 0); + + v1.swap(v2); + CHECK(v1.cast().x == 3); + CHECK(v2.cast().x == 1); + + CHECK(ivec2::dtor_counter == 2); + CHECK(ivec2::move_ctor_counter == 2); + CHECK(ivec2::copy_ctor_counter == 0); + + CHECK(ivec2_big::dtor_counter == 1); + CHECK(ivec2_big::move_ctor_counter == 1); + CHECK(ivec2_big::copy_ctor_counter == 0); + + v1.swap(v2); + CHECK(v1.cast().y == 2); + CHECK(v2.cast().y == 4); + + CHECK(ivec2::dtor_counter == 3); + CHECK(ivec2::move_ctor_counter == 3); + CHECK(ivec2::copy_ctor_counter == 0); + + CHECK(ivec2_big::dtor_counter == 1); + CHECK(ivec2_big::move_ctor_counter == 1); + CHECK(ivec2_big::copy_ctor_counter == 0); + } + + CHECK(ivec2::dtor_counter == 4); + CHECK(ivec2::move_ctor_counter == 3); + CHECK(ivec2::copy_ctor_counter == 0); + + CHECK(ivec2_big::dtor_counter == 2); + CHECK(ivec2_big::move_ctor_counter == 1); + CHECK(ivec2_big::copy_ctor_counter == 0); + } +} diff --git a/untests/meta_utilities/value_tests.cpp b/untests/meta_utilities/value_tests.cpp index 007afdf..591ab58 100644 --- a/untests/meta_utilities/value_tests.cpp +++ b/untests/meta_utilities/value_tests.cpp @@ -395,7 +395,7 @@ TEST_CASE("meta/meta_utilities/value") { val1.swap(val2); CHECK(val1 == ivec2{1,2}); CHECK(val2 == "world"s); - CHECK(ivec2::move_ctor_counter == 3); + CHECK(ivec2::move_ctor_counter == 2); CHECK(ivec2::copy_ctor_counter == 0); swap(val1, val2); From aa362ab556f6c7d2245881c7f99c2d18a1403a18 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Wed, 26 Jan 2022 18:22:51 +0700 Subject: [PATCH 194/233] remove std::construct_at and std::destroy_at usage --- headers/meta.hpp/meta_utilities/value.hpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/headers/meta.hpp/meta_utilities/value.hpp b/headers/meta.hpp/meta_utilities/value.hpp index cb3f1a2..e673d72 100644 --- a/headers/meta.hpp/meta_utilities/value.hpp +++ b/headers/meta.hpp/meta_utilities/value.hpp @@ -78,7 +78,7 @@ namespace meta_hpp if constexpr ( in_buffer ) { dst.storage_.emplace(); - std::construct_at(storage_cast(dst.storage_), std::forward(val)); + ::new (storage_cast(dst.storage_)) Tp(std::forward(val)); } else { dst.storage_.emplace(std::make_unique(std::forward(val)).release()); } @@ -132,9 +132,9 @@ namespace meta_hpp to.storage_.emplace(src); }, [&to](buffer_t& buffer) { - to.storage_.emplace(); - std::construct_at(storage_cast(to.storage_), std::move(*storage_cast(buffer))); - std::destroy_at(storage_cast(buffer)); + Tp* src = storage_cast(buffer); + ::new (&to.storage_.emplace()) Tp(std::move(*src)); + src->~Tp(); }, [](...){} }, from.storage_); @@ -150,8 +150,8 @@ namespace meta_hpp to.storage_.emplace(new Tp{*src}); }, [&to](const buffer_t& buffer) { - to.storage_.emplace(); - std::construct_at(storage_cast(to.storage_), *storage_cast(buffer)); + const Tp* src = storage_cast(buffer); + ::new (&to.storage_.emplace()) Tp(*src); }, [](...){} }, from.storage_); @@ -166,7 +166,7 @@ namespace meta_hpp std::unique_ptr{src}.reset(); }, [](buffer_t& buffer) { - std::destroy_at(storage_cast(buffer)); + storage_cast(buffer)->~Tp(); }, [](...){} }, self.storage_); From ca24eff3ad55dbd3d9941577c07f1c5894fe5bdf Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Wed, 26 Jan 2022 18:33:26 +0700 Subject: [PATCH 195/233] fix msvc tests --- untests/meta_utilities/value_tests.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/untests/meta_utilities/value_tests.cpp b/untests/meta_utilities/value_tests.cpp index 591ab58..88f2239 100644 --- a/untests/meta_utilities/value_tests.cpp +++ b/untests/meta_utilities/value_tests.cpp @@ -502,15 +502,15 @@ TEST_CASE("meta/meta_utilities/value") { CHECK(ivec2::copy_ctor_counter == 0); [[maybe_unused]] meta::value vv1{*vp}; - CHECK(ivec2::move_ctor_counter == 0); + CHECK((ivec2::move_ctor_counter == 0 || ivec2::move_ctor_counter == 2)); CHECK(ivec2::copy_ctor_counter == 1); [[maybe_unused]] meta::value vv2{*std::move(vp)}; - CHECK(ivec2::move_ctor_counter == 0); + CHECK((ivec2::move_ctor_counter == 0 || ivec2::move_ctor_counter == 4)); CHECK(ivec2::copy_ctor_counter == 2); [[maybe_unused]] meta::value vv3{*std::as_const(vp)}; - CHECK(ivec2::move_ctor_counter == 0); + CHECK((ivec2::move_ctor_counter == 0 || ivec2::move_ctor_counter == 6)); CHECK(ivec2::copy_ctor_counter == 3); } { From 3cd2c65caa58ac8bd6b15c6270049118d95e9677 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 28 Jan 2022 04:10:21 +0700 Subject: [PATCH 196/233] rename registry to binds --- headers/meta.hpp/meta_all.hpp | 10 +++++----- headers/meta.hpp/{meta_registry.hpp => meta_binds.hpp} | 0 .../{meta_registry => meta_binds}/class_bind.hpp | 2 +- .../{meta_registry => meta_binds}/enum_bind.hpp | 2 +- .../{meta_registry => meta_binds}/scope_bind.hpp | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) rename headers/meta.hpp/{meta_registry.hpp => meta_binds.hpp} (100%) rename headers/meta.hpp/{meta_registry => meta_binds}/class_bind.hpp (99%) rename headers/meta.hpp/{meta_registry => meta_binds}/enum_bind.hpp (96%) rename headers/meta.hpp/{meta_registry => meta_binds}/scope_bind.hpp (98%) diff --git a/headers/meta.hpp/meta_all.hpp b/headers/meta.hpp/meta_all.hpp index 432a9f8..feea92d 100644 --- a/headers/meta.hpp/meta_all.hpp +++ b/headers/meta.hpp/meta_all.hpp @@ -8,12 +8,12 @@ #include "meta_base.hpp" -#include "meta_kinds.hpp" +#include "meta_binds.hpp" +#include "meta_binds/class_bind.hpp" +#include "meta_binds/enum_bind.hpp" +#include "meta_binds/scope_bind.hpp" -#include "meta_registry.hpp" -#include "meta_registry/class_bind.hpp" -#include "meta_registry/enum_bind.hpp" -#include "meta_registry/scope_bind.hpp" +#include "meta_kinds.hpp" #include "meta_states.hpp" #include "meta_states/ctor.hpp" diff --git a/headers/meta.hpp/meta_registry.hpp b/headers/meta.hpp/meta_binds.hpp similarity index 100% rename from headers/meta.hpp/meta_registry.hpp rename to headers/meta.hpp/meta_binds.hpp diff --git a/headers/meta.hpp/meta_registry/class_bind.hpp b/headers/meta.hpp/meta_binds/class_bind.hpp similarity index 99% rename from headers/meta.hpp/meta_registry/class_bind.hpp rename to headers/meta.hpp/meta_binds/class_bind.hpp index c2388f8..3633f6c 100644 --- a/headers/meta.hpp/meta_registry/class_bind.hpp +++ b/headers/meta.hpp/meta_binds/class_bind.hpp @@ -7,7 +7,7 @@ #pragma once #include "../meta_base.hpp" -#include "../meta_registry.hpp" +#include "../meta_binds.hpp" namespace meta_hpp { diff --git a/headers/meta.hpp/meta_registry/enum_bind.hpp b/headers/meta.hpp/meta_binds/enum_bind.hpp similarity index 96% rename from headers/meta.hpp/meta_registry/enum_bind.hpp rename to headers/meta.hpp/meta_binds/enum_bind.hpp index b6ab51e..2543892 100644 --- a/headers/meta.hpp/meta_registry/enum_bind.hpp +++ b/headers/meta.hpp/meta_binds/enum_bind.hpp @@ -7,7 +7,7 @@ #pragma once #include "../meta_base.hpp" -#include "../meta_registry.hpp" +#include "../meta_binds.hpp" namespace meta_hpp { diff --git a/headers/meta.hpp/meta_registry/scope_bind.hpp b/headers/meta.hpp/meta_binds/scope_bind.hpp similarity index 98% rename from headers/meta.hpp/meta_registry/scope_bind.hpp rename to headers/meta.hpp/meta_binds/scope_bind.hpp index e31b32d..6f4c03c 100644 --- a/headers/meta.hpp/meta_registry/scope_bind.hpp +++ b/headers/meta.hpp/meta_binds/scope_bind.hpp @@ -7,7 +7,7 @@ #pragma once #include "../meta_base.hpp" -#include "../meta_registry.hpp" +#include "../meta_binds.hpp" namespace meta_hpp { From bb2a3ead6ba086993210fde24f2280a9b25e9c79 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 28 Jan 2022 06:34:51 +0700 Subject: [PATCH 197/233] disable vendor install targets --- .clang-tidy | 1 + CMakeLists.txt | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.clang-tidy b/.clang-tidy index 71ae3bb..3def598 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -6,6 +6,7 @@ Checks: '-*, concurrency-*, cppcoreguidelines-*, + -cppcoreguidelines-macro-usage, modernize-*, -modernize-use-trailing-return-type, diff --git a/CMakeLists.txt b/CMakeLists.txt index 3756690..ef3f146 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,6 +27,7 @@ target_compile_options(${PROJECT_NAME} $<$,$>: -Wno-c++98-compat -Wno-c++98-compat-pedantic + -Wno-covered-switch-default -Wno-ctad-maybe-unsupported -Wno-exit-time-destructors -Wno-extra-semi-stmt @@ -38,14 +39,19 @@ target_compile_options(${PROJECT_NAME} -Wno-shadow-field -Wno-shadow-field-in-constructor -Wno-unknown-warning-option + -Wno-unused-macros -Wno-weak-vtables -Wno-zero-as-null-pointer-constant >) if(BUILD_AS_STANDALONE) - enable_testing() + set(DOCTEST_NO_INSTALL ON CACHE BOOL "Don't install doctest") add_subdirectory(vendors/doctest) + + set(FMT_INSTALL OFF CACHE BOOL "Don't install fmtlib") add_subdirectory(vendors/fmtlib) + + enable_testing() add_subdirectory(manuals) add_subdirectory(untests) endif() From fd0d5ed4b2e7ff85a96d0c7b44e569aac0f8ed90 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sat, 5 Feb 2022 05:56:22 +0700 Subject: [PATCH 198/233] huge structure refactoring --- CMakeLists.txt | 3 - headers/meta.hpp/meta_all.hpp | 39 +- headers/meta.hpp/meta_base.hpp | 115 +- headers/meta.hpp/meta_base/cvref_traits.hpp | 39 + headers/meta.hpp/meta_base/enum.hpp | 1436 +++++++++++++++++ headers/meta.hpp/meta_base/enum_bitflags.hpp | 332 ++++ headers/meta.hpp/meta_base/noncopyable.hpp | 21 + headers/meta.hpp/meta_base/overloaded.hpp | 18 + .../meta.hpp/meta_base/select_overload.hpp | 40 + headers/meta.hpp/meta_base/stdex.hpp | 56 + headers/meta.hpp/meta_base/type_id.hpp | 62 + .../type_kinds.hpp} | 134 +- headers/meta.hpp/meta_base/type_list.hpp | 26 + headers/meta.hpp/meta_binds/class_bind.hpp | 8 +- headers/meta.hpp/meta_binds/enum_bind.hpp | 4 +- headers/meta.hpp/meta_binds/scope_bind.hpp | 9 +- headers/meta.hpp/meta_detail/state_family.hpp | 28 + .../meta.hpp/meta_detail/state_registry.hpp | 54 + headers/meta.hpp/meta_detail/type_family.hpp | 34 + .../meta.hpp/meta_detail/type_registry.hpp | 265 +++ .../type_traits}/array_traits.hpp | 13 +- .../type_traits}/class_traits.hpp | 24 +- .../type_traits}/ctor_traits.hpp | 16 +- .../type_traits}/dtor_traits.hpp | 12 +- .../type_traits}/enum_traits.hpp | 12 +- .../type_traits}/function_traits.hpp | 16 +- .../type_traits}/member_traits.hpp | 12 +- .../type_traits}/method_traits.hpp | 19 +- .../type_traits}/number_traits.hpp | 15 +- .../type_traits}/pointer_traits.hpp | 12 +- .../type_traits}/reference_traits.hpp | 14 +- .../value_traits/deref_traits.hpp | 16 +- .../value_traits/equals_traits.hpp | 10 +- .../value_traits/index_traits.hpp | 20 +- .../value_traits/istream_traits.hpp | 10 +- .../value_traits/less_traits.hpp | 10 +- .../value_traits/ostream_traits.hpp | 10 +- .../value_utilities}/arg.hpp | 190 ++- .../meta_detail/value_utilities/inst.hpp | 210 +++ .../meta_detail/value_utilities/utraits.hpp | 145 ++ headers/meta.hpp/meta_indices.hpp | 150 ++ headers/meta.hpp/meta_indices/ctor_index.hpp | 36 + headers/meta.hpp/meta_indices/dtor_index.hpp | 36 + .../meta.hpp/meta_indices/evalue_index.hpp | 41 + .../meta.hpp/meta_indices/function_index.hpp | 41 + .../meta.hpp/meta_indices/member_index.hpp | 41 + .../meta.hpp/meta_indices/method_index.hpp | 41 + headers/meta.hpp/meta_indices/scope_index.hpp | 35 + .../meta.hpp/meta_indices/variable_index.hpp | 41 + headers/meta.hpp/meta_states.hpp | 131 +- headers/meta.hpp/meta_states/ctor.hpp | 6 +- headers/meta.hpp/meta_states/dtor.hpp | 6 +- headers/meta.hpp/meta_states/evalue.hpp | 7 +- headers/meta.hpp/meta_states/function.hpp | 8 +- headers/meta.hpp/meta_states/member.hpp | 9 +- headers/meta.hpp/meta_states/method.hpp | 9 +- headers/meta.hpp/meta_states/scope.hpp | 34 +- headers/meta.hpp/meta_states/variable.hpp | 8 +- headers/meta.hpp/meta_traits.hpp | 118 -- headers/meta.hpp/meta_types.hpp | 425 +---- headers/meta.hpp/meta_types/any_type.hpp | 29 +- headers/meta.hpp/meta_types/array_type.hpp | 9 +- headers/meta.hpp/meta_types/class_type.hpp | 37 +- headers/meta.hpp/meta_types/ctor_type.hpp | 11 +- headers/meta.hpp/meta_types/dtor_type.hpp | 9 +- headers/meta.hpp/meta_types/enum_type.hpp | 14 +- headers/meta.hpp/meta_types/function_type.hpp | 11 +- headers/meta.hpp/meta_types/member_type.hpp | 9 +- headers/meta.hpp/meta_types/method_type.hpp | 11 +- headers/meta.hpp/meta_types/nullptr_type.hpp | 6 - headers/meta.hpp/meta_types/number_type.hpp | 8 +- headers/meta.hpp/meta_types/pointer_type.hpp | 9 +- .../meta.hpp/meta_types/reference_type.hpp | 9 +- headers/meta.hpp/meta_types/void_type.hpp | 6 - headers/meta.hpp/meta_utilities.hpp | 351 ---- headers/meta.hpp/meta_utilities/inst.hpp | 209 --- headers/meta.hpp/meta_value.hpp | 94 ++ .../{meta_utilities => meta_value}/value.hpp | 99 +- .../vinvoke.hpp | 5 +- manuals/meta_examples/classes_example.cpp | 2 +- manuals/meta_examples/enums_examples.cpp | 2 +- manuals/meta_examples/functions_example.cpp | 2 +- manuals/meta_examples/variables_example.cpp | 2 +- untests/meta_features/diamond_tests.cpp | 74 +- untests/meta_states/evalue_tests.cpp | 6 +- untests/meta_states/function_tests.cpp | 8 +- untests/meta_types/class_type_tests.cpp | 8 +- untests/meta_types/enum_type_tests.cpp | 4 +- untests/meta_untests.cpp | 11 + untests/meta_utilities/arg_tests.cpp | 4 +- untests/meta_utilities/inst_tests.cpp | 4 +- 91 files changed, 4056 insertions(+), 1739 deletions(-) create mode 100644 headers/meta.hpp/meta_base/cvref_traits.hpp create mode 100644 headers/meta.hpp/meta_base/enum.hpp create mode 100644 headers/meta.hpp/meta_base/enum_bitflags.hpp create mode 100644 headers/meta.hpp/meta_base/noncopyable.hpp create mode 100644 headers/meta.hpp/meta_base/overloaded.hpp create mode 100644 headers/meta.hpp/meta_base/select_overload.hpp create mode 100644 headers/meta.hpp/meta_base/stdex.hpp create mode 100644 headers/meta.hpp/meta_base/type_id.hpp rename headers/meta.hpp/{meta_kinds.hpp => meta_base/type_kinds.hpp} (50%) create mode 100644 headers/meta.hpp/meta_base/type_list.hpp create mode 100644 headers/meta.hpp/meta_detail/state_family.hpp create mode 100644 headers/meta.hpp/meta_detail/state_registry.hpp create mode 100644 headers/meta.hpp/meta_detail/type_family.hpp create mode 100644 headers/meta.hpp/meta_detail/type_registry.hpp rename headers/meta.hpp/{meta_traits => meta_detail/type_traits}/array_traits.hpp (82%) rename headers/meta.hpp/{meta_traits => meta_detail/type_traits}/class_traits.hpp (86%) rename headers/meta.hpp/{meta_traits => meta_detail/type_traits}/ctor_traits.hpp (83%) rename headers/meta.hpp/{meta_traits => meta_detail/type_traits}/dtor_traits.hpp (81%) rename headers/meta.hpp/{meta_traits => meta_detail/type_traits}/enum_traits.hpp (82%) rename headers/meta.hpp/{meta_traits => meta_detail/type_traits}/function_traits.hpp (85%) rename headers/meta.hpp/{meta_traits => meta_detail/type_traits}/member_traits.hpp (82%) rename headers/meta.hpp/{meta_traits => meta_detail/type_traits}/method_traits.hpp (94%) rename headers/meta.hpp/{meta_traits => meta_detail/type_traits}/number_traits.hpp (81%) rename headers/meta.hpp/{meta_traits => meta_detail/type_traits}/pointer_traits.hpp (81%) rename headers/meta.hpp/{meta_traits => meta_detail/type_traits}/reference_traits.hpp (81%) rename headers/meta.hpp/{meta_utilities => meta_detail}/value_traits/deref_traits.hpp (74%) rename headers/meta.hpp/{meta_utilities => meta_detail}/value_traits/equals_traits.hpp (75%) rename headers/meta.hpp/{meta_utilities => meta_detail}/value_traits/index_traits.hpp (75%) rename headers/meta.hpp/{meta_utilities => meta_detail}/value_traits/istream_traits.hpp (75%) rename headers/meta.hpp/{meta_utilities => meta_detail}/value_traits/less_traits.hpp (76%) rename headers/meta.hpp/{meta_utilities => meta_detail}/value_traits/ostream_traits.hpp (75%) rename headers/meta.hpp/{meta_utilities => meta_detail/value_utilities}/arg.hpp (69%) create mode 100644 headers/meta.hpp/meta_detail/value_utilities/inst.hpp create mode 100644 headers/meta.hpp/meta_detail/value_utilities/utraits.hpp create mode 100644 headers/meta.hpp/meta_indices.hpp create mode 100644 headers/meta.hpp/meta_indices/ctor_index.hpp create mode 100644 headers/meta.hpp/meta_indices/dtor_index.hpp create mode 100644 headers/meta.hpp/meta_indices/evalue_index.hpp create mode 100644 headers/meta.hpp/meta_indices/function_index.hpp create mode 100644 headers/meta.hpp/meta_indices/member_index.hpp create mode 100644 headers/meta.hpp/meta_indices/method_index.hpp create mode 100644 headers/meta.hpp/meta_indices/scope_index.hpp create mode 100644 headers/meta.hpp/meta_indices/variable_index.hpp delete mode 100644 headers/meta.hpp/meta_traits.hpp delete mode 100644 headers/meta.hpp/meta_utilities.hpp delete mode 100644 headers/meta.hpp/meta_utilities/inst.hpp create mode 100644 headers/meta.hpp/meta_value.hpp rename headers/meta.hpp/{meta_utilities => meta_value}/value.hpp (81%) rename headers/meta.hpp/{meta_utilities => meta_value}/vinvoke.hpp (97%) create mode 100644 untests/meta_untests.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index ef3f146..a08a874 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,10 +9,7 @@ endif() project(meta.hpp) -add_subdirectory(vendors/enum.hpp) - add_library(${PROJECT_NAME} INTERFACE) -target_link_libraries(${PROJECT_NAME} INTERFACE enum.hpp) target_compile_features(${PROJECT_NAME} INTERFACE cxx_std_20) target_include_directories(${PROJECT_NAME} INTERFACE headers) diff --git a/headers/meta.hpp/meta_all.hpp b/headers/meta.hpp/meta_all.hpp index feea92d..0a44744 100644 --- a/headers/meta.hpp/meta_all.hpp +++ b/headers/meta.hpp/meta_all.hpp @@ -13,7 +13,15 @@ #include "meta_binds/enum_bind.hpp" #include "meta_binds/scope_bind.hpp" -#include "meta_kinds.hpp" +#include "meta_indices.hpp" +#include "meta_indices/ctor_index.hpp" +#include "meta_indices/dtor_index.hpp" +#include "meta_indices/evalue_index.hpp" +#include "meta_indices/function_index.hpp" +#include "meta_indices/member_index.hpp" +#include "meta_indices/method_index.hpp" +#include "meta_indices/scope_index.hpp" +#include "meta_indices/variable_index.hpp" #include "meta_states.hpp" #include "meta_states/ctor.hpp" @@ -25,19 +33,6 @@ #include "meta_states/scope.hpp" #include "meta_states/variable.hpp" -#include "meta_traits.hpp" -#include "meta_traits/array_traits.hpp" -#include "meta_traits/class_traits.hpp" -#include "meta_traits/ctor_traits.hpp" -#include "meta_traits/dtor_traits.hpp" -#include "meta_traits/enum_traits.hpp" -#include "meta_traits/function_traits.hpp" -#include "meta_traits/member_traits.hpp" -#include "meta_traits/method_traits.hpp" -#include "meta_traits/number_traits.hpp" -#include "meta_traits/pointer_traits.hpp" -#include "meta_traits/reference_traits.hpp" - #include "meta_types.hpp" #include "meta_types/any_type.hpp" #include "meta_types/array_type.hpp" @@ -54,8 +49,14 @@ #include "meta_types/reference_type.hpp" #include "meta_types/void_type.hpp" -#include "meta_utilities.hpp" -#include "meta_utilities/arg.hpp" -#include "meta_utilities/inst.hpp" -#include "meta_utilities/value.hpp" -#include "meta_utilities/vinvoke.hpp" +#include "meta_value.hpp" +#include "meta_value/value.hpp" +#include "meta_value/vinvoke.hpp" + +namespace meta_hpp +{ + using detail::resolve_type; + using detail::resolve_polymorphic_type; + + using detail::resolve_scope; +} diff --git a/headers/meta.hpp/meta_base.hpp b/headers/meta.hpp/meta_base.hpp index 1cc4877..24c5330 100644 --- a/headers/meta.hpp/meta_base.hpp +++ b/headers/meta.hpp/meta_base.hpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -25,47 +26,34 @@ #include #include #include +#include +#include #include #include #include -#include -#include +#include "meta_base/cvref_traits.hpp" +#include "meta_base/enum_bitflags.hpp" +#include "meta_base/enum.hpp" +#include "meta_base/noncopyable.hpp" +#include "meta_base/overloaded.hpp" +#include "meta_base/select_overload.hpp" +#include "meta_base/stdex.hpp" +#include "meta_base/type_id.hpp" +#include "meta_base/type_kinds.hpp" +#include "meta_base/type_list.hpp" namespace meta_hpp { - template < typename Enum > - using bitflags = enum_hpp::bitflags::bitflags; -} + using detail::select_const; + using detail::select_non_const; + using detail::select_overload; -namespace meta_hpp -{ - template < typename Signature > - constexpr auto select(Signature* func) noexcept -> Signature* { - return func; - } + using detail::type_id; + using detail::type_kind; + using detail::type_list; - template < typename Signature, typename Class > - constexpr auto select(Signature Class::*func) noexcept -> Signature Class::* { - return func; - } - - namespace detail - { - template < typename... Types > - struct type_list {}; - - template < std::size_t Index, typename TypeList > - struct type_list_at; - - template < std::size_t Index, typename... Types > - struct type_list_at> { - using type = std::tuple_element_t>; - }; - - template < std::size_t Index, typename TypeList > - using type_list_at_t = typename type_list_at::type; - } + using enum_hpp::bitflags::bitflags; } namespace meta_hpp @@ -168,14 +156,14 @@ namespace meta_hpp namespace meta_hpp { - struct ctor_index; - struct dtor_index; - struct evalue_index; - struct function_index; - struct member_index; - struct method_index; - struct scope_index; - struct variable_index; + class ctor_index; + class dtor_index; + class evalue_index; + class function_index; + class member_index; + class method_index; + class scope_index; + class variable_index; using class_set = std::set>; using class_map = std::map>; @@ -192,50 +180,3 @@ namespace meta_hpp using scope_map = std::map>; using variable_map = std::map>; } - -namespace meta_hpp::detail::stdex -{ - template < typename T > - [[nodiscard]] constexpr std::underlying_type_t to_underlying(T v) noexcept { - return static_cast>(v); - } -} - -namespace meta_hpp::detail::stdex -{ - template < typename T, typename U > - concept same_as = - std::is_same_v && - std::is_same_v; - - template < typename Derived, typename Base > - concept derived_from = - std::is_base_of_v && - std::is_convertible_v; - - template < typename From, typename To > - concept convertible_to = - std::is_convertible_v && - requires { static_cast(std::declval()); }; - - template < typename T > - concept destructible = - std::is_nothrow_destructible_v; - - template < typename T, typename... Args > - concept constructible_from = - destructible && - std::is_constructible_v; - - template < typename T > - concept move_constructible = - constructible_from && - convertible_to; - - template - concept copy_constructible = - move_constructible && - constructible_from && convertible_to && - constructible_from && convertible_to && - constructible_from && convertible_to; -} diff --git a/headers/meta.hpp/meta_base/cvref_traits.hpp b/headers/meta.hpp/meta_base/cvref_traits.hpp new file mode 100644 index 0000000..743bba1 --- /dev/null +++ b/headers/meta.hpp/meta_base/cvref_traits.hpp @@ -0,0 +1,39 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include + +namespace meta_hpp::detail +{ + template < typename From > + struct cvref_traits { + static constexpr bool is_lvalue = std::is_lvalue_reference_v; + static constexpr bool is_rvalue = std::is_rvalue_reference_v; + static constexpr bool is_const = std::is_const_v>; + static constexpr bool is_volatile = std::is_volatile_v>; + + template < bool yesno, template < typename > typename Q, typename V > + using apply_t_if = std::conditional_t, V>; + + template < typename To > + using copy_to = + apply_t_if>>>>; + }; + + template < typename From, typename To > + struct copy_cvref { + using type = typename cvref_traits::template copy_to; + }; + + template < typename From, typename To > + using copy_cvref_t = typename copy_cvref::type; +} diff --git a/headers/meta.hpp/meta_base/enum.hpp b/headers/meta.hpp/meta_base/enum.hpp new file mode 100644 index 0000000..6cbe035 --- /dev/null +++ b/headers/meta.hpp/meta_base/enum.hpp @@ -0,0 +1,1436 @@ +/******************************************************************************* + * This file is part of the "https://github.com/blackmatov/enum.hpp" + * For conditions of distribution and use, see copyright notice in LICENSE.md + * Copyright (C) 2019-2022, by Matvey Cherevko (blackmatov@gmail.com) + ******************************************************************************/ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +#if !defined(__cpp_exceptions) && !defined(__EXCEPTIONS) && !defined(_CPPUNWIND) +# define ENUM_HPP_NO_EXCEPTIONS +#endif + +namespace enum_hpp +{ + constexpr std::size_t invalid_index = std::size_t(-1); + constexpr std::string_view empty_string = std::string_view(); + + class exception final : public std::runtime_error { + public: + explicit exception(const char* what) + : std::runtime_error(what) {} + }; +} + +namespace enum_hpp +{ + template < typename Enum > + using traits_t = decltype(enum_hpp_adl_find_registered_traits(std::declval())); + + template < typename Enum > + using underlying_type = typename traits_t::underlying_type; + + template < typename Enum > + constexpr std::size_t size() noexcept { + return traits_t::size; + } + + template < typename Enum > + constexpr const std::array()>& values() noexcept { + return traits_t::values; + } + + template < typename Enum > + constexpr const std::array()>& names() noexcept { + return traits_t::names; + } + + template < typename Enum > + constexpr typename traits_t::underlying_type to_underlying(Enum e) noexcept { + return traits_t::to_underlying(e); + } + + template < typename Enum > + constexpr std::optional to_string(Enum e) noexcept { + return traits_t::to_string(e); + } + + template < typename Enum > + constexpr std::string_view to_string_or_empty(Enum e) noexcept { + return traits_t::to_string_or_empty(e); + } + + template < typename Enum > + std::string_view to_string_or_throw(Enum e) { + return traits_t::to_string_or_throw(e); + } + + template < typename Enum > + constexpr std::optional from_string(std::string_view name) noexcept { + return traits_t::from_string(name); + } + + template < typename Enum > + constexpr Enum from_string_or_default(std::string_view name, Enum def) noexcept { + return traits_t::from_string_or_default(name, def); + } + + template < typename Enum > + Enum from_string_or_throw(std::string_view name) { + return traits_t::from_string_or_throw(name); + } + + template < typename Enum > + constexpr std::optional to_index(Enum e) noexcept { + return traits_t::to_index(e); + } + + template < typename Enum > + constexpr std::size_t to_index_or_invalid(Enum e) noexcept { + return traits_t::to_index_or_invalid(e); + } + + template < typename Enum > + std::size_t to_index_or_throw(Enum e) { + return traits_t::to_index_or_throw(e); + } + + template < typename Enum > + constexpr std::optional from_index(std::size_t index) noexcept { + return traits_t::from_index(index); + } + + template < typename Enum > + constexpr Enum from_index_or_default(std::size_t index, Enum def) noexcept { + return traits_t::from_index_or_default(index, def); + } + + template < typename Enum > + Enum from_index_or_throw(std::size_t index) { + return traits_t::from_index_or_throw(index); + } +} + +namespace enum_hpp::detail +{ + inline void throw_exception_with [[noreturn]] (const char* what) { + #ifndef ENUM_HPP_NO_EXCEPTIONS + throw ::enum_hpp::exception(what); + #else + (void)what; + std::abort(); + #endif + } + + template < typename Enum > + struct ignore_assign final { + Enum value; + + constexpr explicit ignore_assign(Enum value) noexcept + : value(value) {} + + template < typename Other > + // NOLINTNEXTLINE(readability-named-parameter) + constexpr ignore_assign& operator=(const Other&) noexcept { + return *this; + } + }; + + constexpr bool is_end_of_name(char ch) noexcept { + switch ( ch ) { + case ' ': + case '=': + case '\r': + case '\n': + case '\t': + return true; + default: + return false; + } + } + + constexpr std::string_view trim_raw_name(std::string_view raw_name) noexcept { + for ( std::size_t i = 0; i < raw_name.size(); ++i ) { + if ( is_end_of_name(raw_name[i]) ) { + return raw_name.substr(0, i); + } + } + return raw_name; + } +} + +// +// ENUM_HPP_GENERATE_FIELDS +// + +#define ENUM_HPP_GENERATE_FIELDS_OP(d, i, x)\ + x, + +#define ENUM_HPP_GENERATE_FIELDS(Fields)\ + ENUM_HPP_PP_SEQ_FOR_EACH(ENUM_HPP_GENERATE_FIELDS_OP, _, Fields) + +// +// ENUM_HPP_GENERATE_VALUES +// + +#define ENUM_HPP_GENERATE_VALUES_OP(Enum, i, x)\ + ((::enum_hpp::detail::ignore_assign)Enum::x).value, + +#define ENUM_HPP_GENERATE_VALUES(Enum, Fields)\ + ENUM_HPP_PP_SEQ_FOR_EACH(ENUM_HPP_GENERATE_VALUES_OP, Enum, Fields) + +// +// ENUM_HPP_GENERATE_NAMES +// + +#define ENUM_HPP_GENERATE_NAMES_OP(d, i, x)\ + ::enum_hpp::detail::trim_raw_name(ENUM_HPP_PP_STRINGIZE(x)), + +#define ENUM_HPP_GENERATE_NAMES(Fields)\ + ENUM_HPP_PP_SEQ_FOR_EACH(ENUM_HPP_GENERATE_NAMES_OP, _, Fields) + +// +// ENUM_HPP_GENERATE_VALUE_TO_NAME_CASES +// + +#define ENUM_HPP_GENERATE_VALUE_TO_NAME_CASES_OP(Enum, i, x)\ + case values[i]: return names[i]; + +#define ENUM_HPP_GENERATE_VALUE_TO_NAME_CASES(Enum, Fields)\ + ENUM_HPP_PP_SEQ_FOR_EACH(ENUM_HPP_GENERATE_VALUE_TO_NAME_CASES_OP, Enum, Fields) + +// +// ENUM_HPP_GENERATE_VALUE_TO_INDEX_CASES +// + +#define ENUM_HPP_GENERATE_VALUE_TO_INDEX_CASES_OP(Enum, i, x)\ + case values[i]: return i; + +#define ENUM_HPP_GENERATE_VALUE_TO_INDEX_CASES(Enum, Fields)\ + ENUM_HPP_PP_SEQ_FOR_EACH(ENUM_HPP_GENERATE_VALUE_TO_INDEX_CASES_OP, Enum, Fields) + +// +// ENUM_HPP_DECL +// + +#define ENUM_HPP_DECL(Enum, Type, Fields)\ + enum Enum : Type {\ + ENUM_HPP_GENERATE_FIELDS(Fields)\ + };\ + ENUM_HPP_TRAITS_DECL(Enum, Fields) + +// +// ENUM_HPP_CLASS_DECL +// + +#define ENUM_HPP_CLASS_DECL(Enum, Type, Fields)\ + enum class Enum : Type {\ + ENUM_HPP_GENERATE_FIELDS(Fields)\ + };\ + ENUM_HPP_TRAITS_DECL(Enum, Fields) + +// +// ENUM_HPP_TRAITS_DECL +// + +#define ENUM_HPP_TRAITS_DECL(Enum, Fields)\ + struct Enum##_traits final {\ + private:\ + enum enum_names_for_this_score_ {\ + ENUM_HPP_GENERATE_FIELDS(Fields)\ + };\ + public:\ + using enum_type = Enum;\ + using underlying_type = std::underlying_type_t;\ + static constexpr std::size_t size = ENUM_HPP_PP_SEQ_SIZE(Fields);\ + \ + static constexpr const std::array values = {\ + { ENUM_HPP_GENERATE_VALUES(Enum, Fields) }\ + };\ + \ + static constexpr const std::array names = {\ + { ENUM_HPP_GENERATE_NAMES(Fields) }\ + };\ + public:\ + [[maybe_unused]] static constexpr underlying_type to_underlying(enum_type e) noexcept {\ + return static_cast(e);\ + }\ + [[maybe_unused]] static constexpr std::optional to_string(enum_type e) noexcept {\ + switch ( e ) {\ + ENUM_HPP_GENERATE_VALUE_TO_NAME_CASES(Enum, Fields)\ + default: return std::nullopt;\ + }\ + }\ + [[maybe_unused]] static constexpr std::string_view to_string_or_empty(enum_type e) noexcept {\ + if ( auto s = to_string(e) ) {\ + return *s;\ + }\ + return ::enum_hpp::empty_string;\ + }\ + [[maybe_unused]] static std::string_view to_string_or_throw(enum_type e) {\ + if ( auto s = to_string(e) ) {\ + return *s;\ + }\ + ::enum_hpp::detail::throw_exception_with(#Enum "_traits::to_string_or_throw(): invalid argument");\ + }\ + [[maybe_unused]] static constexpr std::optional from_string(std::string_view name) noexcept {\ + for ( std::size_t i = 0; i < size; ++i) {\ + if ( name == names[i] ) {\ + return values[i];\ + }\ + }\ + return std::nullopt;\ + }\ + [[maybe_unused]] static constexpr enum_type from_string_or_default(std::string_view name, enum_type def) noexcept {\ + if ( auto e = from_string(name) ) {\ + return *e;\ + }\ + return def;\ + }\ + [[maybe_unused]] static enum_type from_string_or_throw(std::string_view name) {\ + if ( auto e = from_string(name) ) {\ + return *e;\ + }\ + ::enum_hpp::detail::throw_exception_with(#Enum "_traits::from_string_or_throw(): invalid argument");\ + }\ + [[maybe_unused]] static constexpr std::optional to_index(enum_type e) noexcept {\ + switch ( e ) {\ + ENUM_HPP_GENERATE_VALUE_TO_INDEX_CASES(Enum, Fields)\ + default: return std::nullopt;\ + }\ + }\ + [[maybe_unused]] static constexpr std::size_t to_index_or_invalid(enum_type e) noexcept {\ + if ( auto i = to_index(e) ) {\ + return *i;\ + }\ + return ::enum_hpp::invalid_index;\ + }\ + [[maybe_unused]] static std::size_t to_index_or_throw(enum_type e) {\ + if ( auto i = to_index(e) ) {\ + return *i;\ + }\ + ::enum_hpp::detail::throw_exception_with(#Enum "_traits::to_index_or_throw(): invalid argument");\ + }\ + [[maybe_unused]] static constexpr std::optional from_index(std::size_t index) noexcept {\ + if ( index < size ) {\ + return values[index];\ + }\ + return std::nullopt;\ + }\ + [[maybe_unused]] static constexpr enum_type from_index_or_default(std::size_t index, enum_type def) noexcept {\ + if ( auto e = from_index(index) ) {\ + return *e;\ + }\ + return def;\ + }\ + [[maybe_unused]] static enum_type from_index_or_throw(std::size_t index) {\ + if ( auto e = from_index(index) ) {\ + return *e;\ + }\ + ::enum_hpp::detail::throw_exception_with(#Enum "_traits::from_index_or_throw(): invalid argument");\ + }\ + }; + +// +// ENUM_HPP_REGISTER_TRAITS +// + +#define ENUM_HPP_REGISTER_TRAITS(Enum)\ + constexpr Enum##_traits enum_hpp_adl_find_registered_traits [[maybe_unused]] (Enum) noexcept {\ + return Enum##_traits{};\ + } + +// ----------------------------------------------------------------------------- +// +// ENUM_HPP_PP +// +// ----------------------------------------------------------------------------- + +// +// ENUM_HPP_PP_CAT +// + +#define ENUM_HPP_PP_CAT(x, y) ENUM_HPP_PP_CAT_I(x, y) +#define ENUM_HPP_PP_CAT_I(x, y) x ## y + +// +// ENUM_HPP_PP_STRINGIZE +// + +#define ENUM_HPP_PP_STRINGIZE(x) ENUM_HPP_PP_STRINGIZE_I(x) +#define ENUM_HPP_PP_STRINGIZE_I(x) #x + +// +// ENUM_HPP_PP_SEQ_HEAD +// + +#define ENUM_HPP_PP_SEQ_HEAD(seq) ENUM_HPP_PP_SEQ_HEAD_II((ENUM_HPP_PP_SEQ_HEAD_I seq)) +#define ENUM_HPP_PP_SEQ_HEAD_I(x) x, ENUM_HPP_PP_NOTHING +#define ENUM_HPP_PP_SEQ_HEAD_II(p) ENUM_HPP_PP_SEQ_HEAD_III p +#define ENUM_HPP_PP_SEQ_HEAD_III(x, _) x + +// +// ENUM_HPP_PP_SEQ_TAIL +// + +#define ENUM_HPP_PP_SEQ_TAIL(seq) ENUM_HPP_PP_SEQ_TAIL_I seq +#define ENUM_HPP_PP_SEQ_TAIL_I(_) + +// +// ENUM_HPP_PP_INC +// + +#define ENUM_HPP_PP_INC(x) ENUM_HPP_PP_INC_I(x) +#define ENUM_HPP_PP_INC_I(x) ENUM_HPP_PP_INC_ ## x + +#define ENUM_HPP_PP_INC_0 1 +#define ENUM_HPP_PP_INC_1 2 +#define ENUM_HPP_PP_INC_2 3 +#define ENUM_HPP_PP_INC_3 4 +#define ENUM_HPP_PP_INC_4 5 +#define ENUM_HPP_PP_INC_5 6 +#define ENUM_HPP_PP_INC_6 7 +#define ENUM_HPP_PP_INC_7 8 +#define ENUM_HPP_PP_INC_8 9 +#define ENUM_HPP_PP_INC_9 10 +#define ENUM_HPP_PP_INC_10 11 +#define ENUM_HPP_PP_INC_11 12 +#define ENUM_HPP_PP_INC_12 13 +#define ENUM_HPP_PP_INC_13 14 +#define ENUM_HPP_PP_INC_14 15 +#define ENUM_HPP_PP_INC_15 16 +#define ENUM_HPP_PP_INC_16 17 +#define ENUM_HPP_PP_INC_17 18 +#define ENUM_HPP_PP_INC_18 19 +#define ENUM_HPP_PP_INC_19 20 +#define ENUM_HPP_PP_INC_20 21 +#define ENUM_HPP_PP_INC_21 22 +#define ENUM_HPP_PP_INC_22 23 +#define ENUM_HPP_PP_INC_23 24 +#define ENUM_HPP_PP_INC_24 25 +#define ENUM_HPP_PP_INC_25 26 +#define ENUM_HPP_PP_INC_26 27 +#define ENUM_HPP_PP_INC_27 28 +#define ENUM_HPP_PP_INC_28 29 +#define ENUM_HPP_PP_INC_29 30 +#define ENUM_HPP_PP_INC_30 31 +#define ENUM_HPP_PP_INC_31 32 +#define ENUM_HPP_PP_INC_32 33 +#define ENUM_HPP_PP_INC_33 34 +#define ENUM_HPP_PP_INC_34 35 +#define ENUM_HPP_PP_INC_35 36 +#define ENUM_HPP_PP_INC_36 37 +#define ENUM_HPP_PP_INC_37 38 +#define ENUM_HPP_PP_INC_38 39 +#define ENUM_HPP_PP_INC_39 40 +#define ENUM_HPP_PP_INC_40 41 +#define ENUM_HPP_PP_INC_41 42 +#define ENUM_HPP_PP_INC_42 43 +#define ENUM_HPP_PP_INC_43 44 +#define ENUM_HPP_PP_INC_44 45 +#define ENUM_HPP_PP_INC_45 46 +#define ENUM_HPP_PP_INC_46 47 +#define ENUM_HPP_PP_INC_47 48 +#define ENUM_HPP_PP_INC_48 49 +#define ENUM_HPP_PP_INC_49 50 +#define ENUM_HPP_PP_INC_50 51 +#define ENUM_HPP_PP_INC_51 52 +#define ENUM_HPP_PP_INC_52 53 +#define ENUM_HPP_PP_INC_53 54 +#define ENUM_HPP_PP_INC_54 55 +#define ENUM_HPP_PP_INC_55 56 +#define ENUM_HPP_PP_INC_56 57 +#define ENUM_HPP_PP_INC_57 58 +#define ENUM_HPP_PP_INC_58 59 +#define ENUM_HPP_PP_INC_59 60 +#define ENUM_HPP_PP_INC_60 61 +#define ENUM_HPP_PP_INC_61 62 +#define ENUM_HPP_PP_INC_62 63 +#define ENUM_HPP_PP_INC_63 64 +#define ENUM_HPP_PP_INC_64 65 +#define ENUM_HPP_PP_INC_65 66 +#define ENUM_HPP_PP_INC_66 67 +#define ENUM_HPP_PP_INC_67 68 +#define ENUM_HPP_PP_INC_68 69 +#define ENUM_HPP_PP_INC_69 70 +#define ENUM_HPP_PP_INC_70 71 +#define ENUM_HPP_PP_INC_71 72 +#define ENUM_HPP_PP_INC_72 73 +#define ENUM_HPP_PP_INC_73 74 +#define ENUM_HPP_PP_INC_74 75 +#define ENUM_HPP_PP_INC_75 76 +#define ENUM_HPP_PP_INC_76 77 +#define ENUM_HPP_PP_INC_77 78 +#define ENUM_HPP_PP_INC_78 79 +#define ENUM_HPP_PP_INC_79 80 +#define ENUM_HPP_PP_INC_80 81 +#define ENUM_HPP_PP_INC_81 82 +#define ENUM_HPP_PP_INC_82 83 +#define ENUM_HPP_PP_INC_83 84 +#define ENUM_HPP_PP_INC_84 85 +#define ENUM_HPP_PP_INC_85 86 +#define ENUM_HPP_PP_INC_86 87 +#define ENUM_HPP_PP_INC_87 88 +#define ENUM_HPP_PP_INC_88 89 +#define ENUM_HPP_PP_INC_89 90 +#define ENUM_HPP_PP_INC_90 91 +#define ENUM_HPP_PP_INC_91 92 +#define ENUM_HPP_PP_INC_92 93 +#define ENUM_HPP_PP_INC_93 94 +#define ENUM_HPP_PP_INC_94 95 +#define ENUM_HPP_PP_INC_95 96 +#define ENUM_HPP_PP_INC_96 97 +#define ENUM_HPP_PP_INC_97 98 +#define ENUM_HPP_PP_INC_98 99 +#define ENUM_HPP_PP_INC_99 100 +#define ENUM_HPP_PP_INC_100 101 +#define ENUM_HPP_PP_INC_101 102 +#define ENUM_HPP_PP_INC_102 103 +#define ENUM_HPP_PP_INC_103 104 +#define ENUM_HPP_PP_INC_104 105 +#define ENUM_HPP_PP_INC_105 106 +#define ENUM_HPP_PP_INC_106 107 +#define ENUM_HPP_PP_INC_107 108 +#define ENUM_HPP_PP_INC_108 109 +#define ENUM_HPP_PP_INC_109 110 +#define ENUM_HPP_PP_INC_110 111 +#define ENUM_HPP_PP_INC_111 112 +#define ENUM_HPP_PP_INC_112 113 +#define ENUM_HPP_PP_INC_113 114 +#define ENUM_HPP_PP_INC_114 115 +#define ENUM_HPP_PP_INC_115 116 +#define ENUM_HPP_PP_INC_116 117 +#define ENUM_HPP_PP_INC_117 118 +#define ENUM_HPP_PP_INC_118 119 +#define ENUM_HPP_PP_INC_119 120 +#define ENUM_HPP_PP_INC_120 121 +#define ENUM_HPP_PP_INC_121 122 +#define ENUM_HPP_PP_INC_122 123 +#define ENUM_HPP_PP_INC_123 124 +#define ENUM_HPP_PP_INC_124 125 +#define ENUM_HPP_PP_INC_125 126 +#define ENUM_HPP_PP_INC_126 127 +#define ENUM_HPP_PP_INC_127 128 +#define ENUM_HPP_PP_INC_128 129 +#define ENUM_HPP_PP_INC_129 130 +#define ENUM_HPP_PP_INC_130 131 +#define ENUM_HPP_PP_INC_131 132 +#define ENUM_HPP_PP_INC_132 133 +#define ENUM_HPP_PP_INC_133 134 +#define ENUM_HPP_PP_INC_134 135 +#define ENUM_HPP_PP_INC_135 136 +#define ENUM_HPP_PP_INC_136 137 +#define ENUM_HPP_PP_INC_137 138 +#define ENUM_HPP_PP_INC_138 139 +#define ENUM_HPP_PP_INC_139 140 +#define ENUM_HPP_PP_INC_140 141 +#define ENUM_HPP_PP_INC_141 142 +#define ENUM_HPP_PP_INC_142 143 +#define ENUM_HPP_PP_INC_143 144 +#define ENUM_HPP_PP_INC_144 145 +#define ENUM_HPP_PP_INC_145 146 +#define ENUM_HPP_PP_INC_146 147 +#define ENUM_HPP_PP_INC_147 148 +#define ENUM_HPP_PP_INC_148 149 +#define ENUM_HPP_PP_INC_149 150 +#define ENUM_HPP_PP_INC_150 151 +#define ENUM_HPP_PP_INC_151 152 +#define ENUM_HPP_PP_INC_152 153 +#define ENUM_HPP_PP_INC_153 154 +#define ENUM_HPP_PP_INC_154 155 +#define ENUM_HPP_PP_INC_155 156 +#define ENUM_HPP_PP_INC_156 157 +#define ENUM_HPP_PP_INC_157 158 +#define ENUM_HPP_PP_INC_158 159 +#define ENUM_HPP_PP_INC_159 160 +#define ENUM_HPP_PP_INC_160 161 +#define ENUM_HPP_PP_INC_161 162 +#define ENUM_HPP_PP_INC_162 163 +#define ENUM_HPP_PP_INC_163 164 +#define ENUM_HPP_PP_INC_164 165 +#define ENUM_HPP_PP_INC_165 166 +#define ENUM_HPP_PP_INC_166 167 +#define ENUM_HPP_PP_INC_167 168 +#define ENUM_HPP_PP_INC_168 169 +#define ENUM_HPP_PP_INC_169 170 +#define ENUM_HPP_PP_INC_170 171 +#define ENUM_HPP_PP_INC_171 172 +#define ENUM_HPP_PP_INC_172 173 +#define ENUM_HPP_PP_INC_173 174 +#define ENUM_HPP_PP_INC_174 175 +#define ENUM_HPP_PP_INC_175 176 +#define ENUM_HPP_PP_INC_176 177 +#define ENUM_HPP_PP_INC_177 178 +#define ENUM_HPP_PP_INC_178 179 +#define ENUM_HPP_PP_INC_179 180 +#define ENUM_HPP_PP_INC_180 181 +#define ENUM_HPP_PP_INC_181 182 +#define ENUM_HPP_PP_INC_182 183 +#define ENUM_HPP_PP_INC_183 184 +#define ENUM_HPP_PP_INC_184 185 +#define ENUM_HPP_PP_INC_185 186 +#define ENUM_HPP_PP_INC_186 187 +#define ENUM_HPP_PP_INC_187 188 +#define ENUM_HPP_PP_INC_188 189 +#define ENUM_HPP_PP_INC_189 190 +#define ENUM_HPP_PP_INC_190 191 +#define ENUM_HPP_PP_INC_191 192 +#define ENUM_HPP_PP_INC_192 193 +#define ENUM_HPP_PP_INC_193 194 +#define ENUM_HPP_PP_INC_194 195 +#define ENUM_HPP_PP_INC_195 196 +#define ENUM_HPP_PP_INC_196 197 +#define ENUM_HPP_PP_INC_197 198 +#define ENUM_HPP_PP_INC_198 199 +#define ENUM_HPP_PP_INC_199 200 +#define ENUM_HPP_PP_INC_200 201 +#define ENUM_HPP_PP_INC_201 202 +#define ENUM_HPP_PP_INC_202 203 +#define ENUM_HPP_PP_INC_203 204 +#define ENUM_HPP_PP_INC_204 205 +#define ENUM_HPP_PP_INC_205 206 +#define ENUM_HPP_PP_INC_206 207 +#define ENUM_HPP_PP_INC_207 208 +#define ENUM_HPP_PP_INC_208 209 +#define ENUM_HPP_PP_INC_209 210 +#define ENUM_HPP_PP_INC_210 211 +#define ENUM_HPP_PP_INC_211 212 +#define ENUM_HPP_PP_INC_212 213 +#define ENUM_HPP_PP_INC_213 214 +#define ENUM_HPP_PP_INC_214 215 +#define ENUM_HPP_PP_INC_215 216 +#define ENUM_HPP_PP_INC_216 217 +#define ENUM_HPP_PP_INC_217 218 +#define ENUM_HPP_PP_INC_218 219 +#define ENUM_HPP_PP_INC_219 220 +#define ENUM_HPP_PP_INC_220 221 +#define ENUM_HPP_PP_INC_221 222 +#define ENUM_HPP_PP_INC_222 223 +#define ENUM_HPP_PP_INC_223 224 +#define ENUM_HPP_PP_INC_224 225 +#define ENUM_HPP_PP_INC_225 226 +#define ENUM_HPP_PP_INC_226 227 +#define ENUM_HPP_PP_INC_227 228 +#define ENUM_HPP_PP_INC_228 229 +#define ENUM_HPP_PP_INC_229 230 +#define ENUM_HPP_PP_INC_230 231 +#define ENUM_HPP_PP_INC_231 232 +#define ENUM_HPP_PP_INC_232 233 +#define ENUM_HPP_PP_INC_233 234 +#define ENUM_HPP_PP_INC_234 235 +#define ENUM_HPP_PP_INC_235 236 +#define ENUM_HPP_PP_INC_236 237 +#define ENUM_HPP_PP_INC_237 238 +#define ENUM_HPP_PP_INC_238 239 +#define ENUM_HPP_PP_INC_239 240 +#define ENUM_HPP_PP_INC_240 241 +#define ENUM_HPP_PP_INC_241 242 +#define ENUM_HPP_PP_INC_242 243 +#define ENUM_HPP_PP_INC_243 244 +#define ENUM_HPP_PP_INC_244 245 +#define ENUM_HPP_PP_INC_245 246 +#define ENUM_HPP_PP_INC_246 247 +#define ENUM_HPP_PP_INC_247 248 +#define ENUM_HPP_PP_INC_248 249 +#define ENUM_HPP_PP_INC_249 250 +#define ENUM_HPP_PP_INC_250 251 +#define ENUM_HPP_PP_INC_251 252 +#define ENUM_HPP_PP_INC_252 253 +#define ENUM_HPP_PP_INC_253 254 +#define ENUM_HPP_PP_INC_254 255 +#define ENUM_HPP_PP_INC_255 256 + +// +// ENUM_HPP_PP_SEQ_SIZE +// + +#define ENUM_HPP_PP_SEQ_SIZE(seq)\ + ENUM_HPP_PP_CAT(ENUM_HPP_PP_SEQ_SIZE_, ENUM_HPP_PP_SEQ_SIZE_0 seq) + +#define ENUM_HPP_PP_SEQ_SIZE_0(_) ENUM_HPP_PP_SEQ_SIZE_1 +#define ENUM_HPP_PP_SEQ_SIZE_1(_) ENUM_HPP_PP_SEQ_SIZE_2 +#define ENUM_HPP_PP_SEQ_SIZE_2(_) ENUM_HPP_PP_SEQ_SIZE_3 +#define ENUM_HPP_PP_SEQ_SIZE_3(_) ENUM_HPP_PP_SEQ_SIZE_4 +#define ENUM_HPP_PP_SEQ_SIZE_4(_) ENUM_HPP_PP_SEQ_SIZE_5 +#define ENUM_HPP_PP_SEQ_SIZE_5(_) ENUM_HPP_PP_SEQ_SIZE_6 +#define ENUM_HPP_PP_SEQ_SIZE_6(_) ENUM_HPP_PP_SEQ_SIZE_7 +#define ENUM_HPP_PP_SEQ_SIZE_7(_) ENUM_HPP_PP_SEQ_SIZE_8 +#define ENUM_HPP_PP_SEQ_SIZE_8(_) ENUM_HPP_PP_SEQ_SIZE_9 +#define ENUM_HPP_PP_SEQ_SIZE_9(_) ENUM_HPP_PP_SEQ_SIZE_10 +#define ENUM_HPP_PP_SEQ_SIZE_10(_) ENUM_HPP_PP_SEQ_SIZE_11 +#define ENUM_HPP_PP_SEQ_SIZE_11(_) ENUM_HPP_PP_SEQ_SIZE_12 +#define ENUM_HPP_PP_SEQ_SIZE_12(_) ENUM_HPP_PP_SEQ_SIZE_13 +#define ENUM_HPP_PP_SEQ_SIZE_13(_) ENUM_HPP_PP_SEQ_SIZE_14 +#define ENUM_HPP_PP_SEQ_SIZE_14(_) ENUM_HPP_PP_SEQ_SIZE_15 +#define ENUM_HPP_PP_SEQ_SIZE_15(_) ENUM_HPP_PP_SEQ_SIZE_16 +#define ENUM_HPP_PP_SEQ_SIZE_16(_) ENUM_HPP_PP_SEQ_SIZE_17 +#define ENUM_HPP_PP_SEQ_SIZE_17(_) ENUM_HPP_PP_SEQ_SIZE_18 +#define ENUM_HPP_PP_SEQ_SIZE_18(_) ENUM_HPP_PP_SEQ_SIZE_19 +#define ENUM_HPP_PP_SEQ_SIZE_19(_) ENUM_HPP_PP_SEQ_SIZE_20 +#define ENUM_HPP_PP_SEQ_SIZE_20(_) ENUM_HPP_PP_SEQ_SIZE_21 +#define ENUM_HPP_PP_SEQ_SIZE_21(_) ENUM_HPP_PP_SEQ_SIZE_22 +#define ENUM_HPP_PP_SEQ_SIZE_22(_) ENUM_HPP_PP_SEQ_SIZE_23 +#define ENUM_HPP_PP_SEQ_SIZE_23(_) ENUM_HPP_PP_SEQ_SIZE_24 +#define ENUM_HPP_PP_SEQ_SIZE_24(_) ENUM_HPP_PP_SEQ_SIZE_25 +#define ENUM_HPP_PP_SEQ_SIZE_25(_) ENUM_HPP_PP_SEQ_SIZE_26 +#define ENUM_HPP_PP_SEQ_SIZE_26(_) ENUM_HPP_PP_SEQ_SIZE_27 +#define ENUM_HPP_PP_SEQ_SIZE_27(_) ENUM_HPP_PP_SEQ_SIZE_28 +#define ENUM_HPP_PP_SEQ_SIZE_28(_) ENUM_HPP_PP_SEQ_SIZE_29 +#define ENUM_HPP_PP_SEQ_SIZE_29(_) ENUM_HPP_PP_SEQ_SIZE_30 +#define ENUM_HPP_PP_SEQ_SIZE_30(_) ENUM_HPP_PP_SEQ_SIZE_31 +#define ENUM_HPP_PP_SEQ_SIZE_31(_) ENUM_HPP_PP_SEQ_SIZE_32 +#define ENUM_HPP_PP_SEQ_SIZE_32(_) ENUM_HPP_PP_SEQ_SIZE_33 +#define ENUM_HPP_PP_SEQ_SIZE_33(_) ENUM_HPP_PP_SEQ_SIZE_34 +#define ENUM_HPP_PP_SEQ_SIZE_34(_) ENUM_HPP_PP_SEQ_SIZE_35 +#define ENUM_HPP_PP_SEQ_SIZE_35(_) ENUM_HPP_PP_SEQ_SIZE_36 +#define ENUM_HPP_PP_SEQ_SIZE_36(_) ENUM_HPP_PP_SEQ_SIZE_37 +#define ENUM_HPP_PP_SEQ_SIZE_37(_) ENUM_HPP_PP_SEQ_SIZE_38 +#define ENUM_HPP_PP_SEQ_SIZE_38(_) ENUM_HPP_PP_SEQ_SIZE_39 +#define ENUM_HPP_PP_SEQ_SIZE_39(_) ENUM_HPP_PP_SEQ_SIZE_40 +#define ENUM_HPP_PP_SEQ_SIZE_40(_) ENUM_HPP_PP_SEQ_SIZE_41 +#define ENUM_HPP_PP_SEQ_SIZE_41(_) ENUM_HPP_PP_SEQ_SIZE_42 +#define ENUM_HPP_PP_SEQ_SIZE_42(_) ENUM_HPP_PP_SEQ_SIZE_43 +#define ENUM_HPP_PP_SEQ_SIZE_43(_) ENUM_HPP_PP_SEQ_SIZE_44 +#define ENUM_HPP_PP_SEQ_SIZE_44(_) ENUM_HPP_PP_SEQ_SIZE_45 +#define ENUM_HPP_PP_SEQ_SIZE_45(_) ENUM_HPP_PP_SEQ_SIZE_46 +#define ENUM_HPP_PP_SEQ_SIZE_46(_) ENUM_HPP_PP_SEQ_SIZE_47 +#define ENUM_HPP_PP_SEQ_SIZE_47(_) ENUM_HPP_PP_SEQ_SIZE_48 +#define ENUM_HPP_PP_SEQ_SIZE_48(_) ENUM_HPP_PP_SEQ_SIZE_49 +#define ENUM_HPP_PP_SEQ_SIZE_49(_) ENUM_HPP_PP_SEQ_SIZE_50 +#define ENUM_HPP_PP_SEQ_SIZE_50(_) ENUM_HPP_PP_SEQ_SIZE_51 +#define ENUM_HPP_PP_SEQ_SIZE_51(_) ENUM_HPP_PP_SEQ_SIZE_52 +#define ENUM_HPP_PP_SEQ_SIZE_52(_) ENUM_HPP_PP_SEQ_SIZE_53 +#define ENUM_HPP_PP_SEQ_SIZE_53(_) ENUM_HPP_PP_SEQ_SIZE_54 +#define ENUM_HPP_PP_SEQ_SIZE_54(_) ENUM_HPP_PP_SEQ_SIZE_55 +#define ENUM_HPP_PP_SEQ_SIZE_55(_) ENUM_HPP_PP_SEQ_SIZE_56 +#define ENUM_HPP_PP_SEQ_SIZE_56(_) ENUM_HPP_PP_SEQ_SIZE_57 +#define ENUM_HPP_PP_SEQ_SIZE_57(_) ENUM_HPP_PP_SEQ_SIZE_58 +#define ENUM_HPP_PP_SEQ_SIZE_58(_) ENUM_HPP_PP_SEQ_SIZE_59 +#define ENUM_HPP_PP_SEQ_SIZE_59(_) ENUM_HPP_PP_SEQ_SIZE_60 +#define ENUM_HPP_PP_SEQ_SIZE_60(_) ENUM_HPP_PP_SEQ_SIZE_61 +#define ENUM_HPP_PP_SEQ_SIZE_61(_) ENUM_HPP_PP_SEQ_SIZE_62 +#define ENUM_HPP_PP_SEQ_SIZE_62(_) ENUM_HPP_PP_SEQ_SIZE_63 +#define ENUM_HPP_PP_SEQ_SIZE_63(_) ENUM_HPP_PP_SEQ_SIZE_64 +#define ENUM_HPP_PP_SEQ_SIZE_64(_) ENUM_HPP_PP_SEQ_SIZE_65 +#define ENUM_HPP_PP_SEQ_SIZE_65(_) ENUM_HPP_PP_SEQ_SIZE_66 +#define ENUM_HPP_PP_SEQ_SIZE_66(_) ENUM_HPP_PP_SEQ_SIZE_67 +#define ENUM_HPP_PP_SEQ_SIZE_67(_) ENUM_HPP_PP_SEQ_SIZE_68 +#define ENUM_HPP_PP_SEQ_SIZE_68(_) ENUM_HPP_PP_SEQ_SIZE_69 +#define ENUM_HPP_PP_SEQ_SIZE_69(_) ENUM_HPP_PP_SEQ_SIZE_70 +#define ENUM_HPP_PP_SEQ_SIZE_70(_) ENUM_HPP_PP_SEQ_SIZE_71 +#define ENUM_HPP_PP_SEQ_SIZE_71(_) ENUM_HPP_PP_SEQ_SIZE_72 +#define ENUM_HPP_PP_SEQ_SIZE_72(_) ENUM_HPP_PP_SEQ_SIZE_73 +#define ENUM_HPP_PP_SEQ_SIZE_73(_) ENUM_HPP_PP_SEQ_SIZE_74 +#define ENUM_HPP_PP_SEQ_SIZE_74(_) ENUM_HPP_PP_SEQ_SIZE_75 +#define ENUM_HPP_PP_SEQ_SIZE_75(_) ENUM_HPP_PP_SEQ_SIZE_76 +#define ENUM_HPP_PP_SEQ_SIZE_76(_) ENUM_HPP_PP_SEQ_SIZE_77 +#define ENUM_HPP_PP_SEQ_SIZE_77(_) ENUM_HPP_PP_SEQ_SIZE_78 +#define ENUM_HPP_PP_SEQ_SIZE_78(_) ENUM_HPP_PP_SEQ_SIZE_79 +#define ENUM_HPP_PP_SEQ_SIZE_79(_) ENUM_HPP_PP_SEQ_SIZE_80 +#define ENUM_HPP_PP_SEQ_SIZE_80(_) ENUM_HPP_PP_SEQ_SIZE_81 +#define ENUM_HPP_PP_SEQ_SIZE_81(_) ENUM_HPP_PP_SEQ_SIZE_82 +#define ENUM_HPP_PP_SEQ_SIZE_82(_) ENUM_HPP_PP_SEQ_SIZE_83 +#define ENUM_HPP_PP_SEQ_SIZE_83(_) ENUM_HPP_PP_SEQ_SIZE_84 +#define ENUM_HPP_PP_SEQ_SIZE_84(_) ENUM_HPP_PP_SEQ_SIZE_85 +#define ENUM_HPP_PP_SEQ_SIZE_85(_) ENUM_HPP_PP_SEQ_SIZE_86 +#define ENUM_HPP_PP_SEQ_SIZE_86(_) ENUM_HPP_PP_SEQ_SIZE_87 +#define ENUM_HPP_PP_SEQ_SIZE_87(_) ENUM_HPP_PP_SEQ_SIZE_88 +#define ENUM_HPP_PP_SEQ_SIZE_88(_) ENUM_HPP_PP_SEQ_SIZE_89 +#define ENUM_HPP_PP_SEQ_SIZE_89(_) ENUM_HPP_PP_SEQ_SIZE_90 +#define ENUM_HPP_PP_SEQ_SIZE_90(_) ENUM_HPP_PP_SEQ_SIZE_91 +#define ENUM_HPP_PP_SEQ_SIZE_91(_) ENUM_HPP_PP_SEQ_SIZE_92 +#define ENUM_HPP_PP_SEQ_SIZE_92(_) ENUM_HPP_PP_SEQ_SIZE_93 +#define ENUM_HPP_PP_SEQ_SIZE_93(_) ENUM_HPP_PP_SEQ_SIZE_94 +#define ENUM_HPP_PP_SEQ_SIZE_94(_) ENUM_HPP_PP_SEQ_SIZE_95 +#define ENUM_HPP_PP_SEQ_SIZE_95(_) ENUM_HPP_PP_SEQ_SIZE_96 +#define ENUM_HPP_PP_SEQ_SIZE_96(_) ENUM_HPP_PP_SEQ_SIZE_97 +#define ENUM_HPP_PP_SEQ_SIZE_97(_) ENUM_HPP_PP_SEQ_SIZE_98 +#define ENUM_HPP_PP_SEQ_SIZE_98(_) ENUM_HPP_PP_SEQ_SIZE_99 +#define ENUM_HPP_PP_SEQ_SIZE_99(_) ENUM_HPP_PP_SEQ_SIZE_100 +#define ENUM_HPP_PP_SEQ_SIZE_100(_) ENUM_HPP_PP_SEQ_SIZE_101 +#define ENUM_HPP_PP_SEQ_SIZE_101(_) ENUM_HPP_PP_SEQ_SIZE_102 +#define ENUM_HPP_PP_SEQ_SIZE_102(_) ENUM_HPP_PP_SEQ_SIZE_103 +#define ENUM_HPP_PP_SEQ_SIZE_103(_) ENUM_HPP_PP_SEQ_SIZE_104 +#define ENUM_HPP_PP_SEQ_SIZE_104(_) ENUM_HPP_PP_SEQ_SIZE_105 +#define ENUM_HPP_PP_SEQ_SIZE_105(_) ENUM_HPP_PP_SEQ_SIZE_106 +#define ENUM_HPP_PP_SEQ_SIZE_106(_) ENUM_HPP_PP_SEQ_SIZE_107 +#define ENUM_HPP_PP_SEQ_SIZE_107(_) ENUM_HPP_PP_SEQ_SIZE_108 +#define ENUM_HPP_PP_SEQ_SIZE_108(_) ENUM_HPP_PP_SEQ_SIZE_109 +#define ENUM_HPP_PP_SEQ_SIZE_109(_) ENUM_HPP_PP_SEQ_SIZE_110 +#define ENUM_HPP_PP_SEQ_SIZE_110(_) ENUM_HPP_PP_SEQ_SIZE_111 +#define ENUM_HPP_PP_SEQ_SIZE_111(_) ENUM_HPP_PP_SEQ_SIZE_112 +#define ENUM_HPP_PP_SEQ_SIZE_112(_) ENUM_HPP_PP_SEQ_SIZE_113 +#define ENUM_HPP_PP_SEQ_SIZE_113(_) ENUM_HPP_PP_SEQ_SIZE_114 +#define ENUM_HPP_PP_SEQ_SIZE_114(_) ENUM_HPP_PP_SEQ_SIZE_115 +#define ENUM_HPP_PP_SEQ_SIZE_115(_) ENUM_HPP_PP_SEQ_SIZE_116 +#define ENUM_HPP_PP_SEQ_SIZE_116(_) ENUM_HPP_PP_SEQ_SIZE_117 +#define ENUM_HPP_PP_SEQ_SIZE_117(_) ENUM_HPP_PP_SEQ_SIZE_118 +#define ENUM_HPP_PP_SEQ_SIZE_118(_) ENUM_HPP_PP_SEQ_SIZE_119 +#define ENUM_HPP_PP_SEQ_SIZE_119(_) ENUM_HPP_PP_SEQ_SIZE_120 +#define ENUM_HPP_PP_SEQ_SIZE_120(_) ENUM_HPP_PP_SEQ_SIZE_121 +#define ENUM_HPP_PP_SEQ_SIZE_121(_) ENUM_HPP_PP_SEQ_SIZE_122 +#define ENUM_HPP_PP_SEQ_SIZE_122(_) ENUM_HPP_PP_SEQ_SIZE_123 +#define ENUM_HPP_PP_SEQ_SIZE_123(_) ENUM_HPP_PP_SEQ_SIZE_124 +#define ENUM_HPP_PP_SEQ_SIZE_124(_) ENUM_HPP_PP_SEQ_SIZE_125 +#define ENUM_HPP_PP_SEQ_SIZE_125(_) ENUM_HPP_PP_SEQ_SIZE_126 +#define ENUM_HPP_PP_SEQ_SIZE_126(_) ENUM_HPP_PP_SEQ_SIZE_127 +#define ENUM_HPP_PP_SEQ_SIZE_127(_) ENUM_HPP_PP_SEQ_SIZE_128 +#define ENUM_HPP_PP_SEQ_SIZE_128(_) ENUM_HPP_PP_SEQ_SIZE_129 +#define ENUM_HPP_PP_SEQ_SIZE_129(_) ENUM_HPP_PP_SEQ_SIZE_130 +#define ENUM_HPP_PP_SEQ_SIZE_130(_) ENUM_HPP_PP_SEQ_SIZE_131 +#define ENUM_HPP_PP_SEQ_SIZE_131(_) ENUM_HPP_PP_SEQ_SIZE_132 +#define ENUM_HPP_PP_SEQ_SIZE_132(_) ENUM_HPP_PP_SEQ_SIZE_133 +#define ENUM_HPP_PP_SEQ_SIZE_133(_) ENUM_HPP_PP_SEQ_SIZE_134 +#define ENUM_HPP_PP_SEQ_SIZE_134(_) ENUM_HPP_PP_SEQ_SIZE_135 +#define ENUM_HPP_PP_SEQ_SIZE_135(_) ENUM_HPP_PP_SEQ_SIZE_136 +#define ENUM_HPP_PP_SEQ_SIZE_136(_) ENUM_HPP_PP_SEQ_SIZE_137 +#define ENUM_HPP_PP_SEQ_SIZE_137(_) ENUM_HPP_PP_SEQ_SIZE_138 +#define ENUM_HPP_PP_SEQ_SIZE_138(_) ENUM_HPP_PP_SEQ_SIZE_139 +#define ENUM_HPP_PP_SEQ_SIZE_139(_) ENUM_HPP_PP_SEQ_SIZE_140 +#define ENUM_HPP_PP_SEQ_SIZE_140(_) ENUM_HPP_PP_SEQ_SIZE_141 +#define ENUM_HPP_PP_SEQ_SIZE_141(_) ENUM_HPP_PP_SEQ_SIZE_142 +#define ENUM_HPP_PP_SEQ_SIZE_142(_) ENUM_HPP_PP_SEQ_SIZE_143 +#define ENUM_HPP_PP_SEQ_SIZE_143(_) ENUM_HPP_PP_SEQ_SIZE_144 +#define ENUM_HPP_PP_SEQ_SIZE_144(_) ENUM_HPP_PP_SEQ_SIZE_145 +#define ENUM_HPP_PP_SEQ_SIZE_145(_) ENUM_HPP_PP_SEQ_SIZE_146 +#define ENUM_HPP_PP_SEQ_SIZE_146(_) ENUM_HPP_PP_SEQ_SIZE_147 +#define ENUM_HPP_PP_SEQ_SIZE_147(_) ENUM_HPP_PP_SEQ_SIZE_148 +#define ENUM_HPP_PP_SEQ_SIZE_148(_) ENUM_HPP_PP_SEQ_SIZE_149 +#define ENUM_HPP_PP_SEQ_SIZE_149(_) ENUM_HPP_PP_SEQ_SIZE_150 +#define ENUM_HPP_PP_SEQ_SIZE_150(_) ENUM_HPP_PP_SEQ_SIZE_151 +#define ENUM_HPP_PP_SEQ_SIZE_151(_) ENUM_HPP_PP_SEQ_SIZE_152 +#define ENUM_HPP_PP_SEQ_SIZE_152(_) ENUM_HPP_PP_SEQ_SIZE_153 +#define ENUM_HPP_PP_SEQ_SIZE_153(_) ENUM_HPP_PP_SEQ_SIZE_154 +#define ENUM_HPP_PP_SEQ_SIZE_154(_) ENUM_HPP_PP_SEQ_SIZE_155 +#define ENUM_HPP_PP_SEQ_SIZE_155(_) ENUM_HPP_PP_SEQ_SIZE_156 +#define ENUM_HPP_PP_SEQ_SIZE_156(_) ENUM_HPP_PP_SEQ_SIZE_157 +#define ENUM_HPP_PP_SEQ_SIZE_157(_) ENUM_HPP_PP_SEQ_SIZE_158 +#define ENUM_HPP_PP_SEQ_SIZE_158(_) ENUM_HPP_PP_SEQ_SIZE_159 +#define ENUM_HPP_PP_SEQ_SIZE_159(_) ENUM_HPP_PP_SEQ_SIZE_160 +#define ENUM_HPP_PP_SEQ_SIZE_160(_) ENUM_HPP_PP_SEQ_SIZE_161 +#define ENUM_HPP_PP_SEQ_SIZE_161(_) ENUM_HPP_PP_SEQ_SIZE_162 +#define ENUM_HPP_PP_SEQ_SIZE_162(_) ENUM_HPP_PP_SEQ_SIZE_163 +#define ENUM_HPP_PP_SEQ_SIZE_163(_) ENUM_HPP_PP_SEQ_SIZE_164 +#define ENUM_HPP_PP_SEQ_SIZE_164(_) ENUM_HPP_PP_SEQ_SIZE_165 +#define ENUM_HPP_PP_SEQ_SIZE_165(_) ENUM_HPP_PP_SEQ_SIZE_166 +#define ENUM_HPP_PP_SEQ_SIZE_166(_) ENUM_HPP_PP_SEQ_SIZE_167 +#define ENUM_HPP_PP_SEQ_SIZE_167(_) ENUM_HPP_PP_SEQ_SIZE_168 +#define ENUM_HPP_PP_SEQ_SIZE_168(_) ENUM_HPP_PP_SEQ_SIZE_169 +#define ENUM_HPP_PP_SEQ_SIZE_169(_) ENUM_HPP_PP_SEQ_SIZE_170 +#define ENUM_HPP_PP_SEQ_SIZE_170(_) ENUM_HPP_PP_SEQ_SIZE_171 +#define ENUM_HPP_PP_SEQ_SIZE_171(_) ENUM_HPP_PP_SEQ_SIZE_172 +#define ENUM_HPP_PP_SEQ_SIZE_172(_) ENUM_HPP_PP_SEQ_SIZE_173 +#define ENUM_HPP_PP_SEQ_SIZE_173(_) ENUM_HPP_PP_SEQ_SIZE_174 +#define ENUM_HPP_PP_SEQ_SIZE_174(_) ENUM_HPP_PP_SEQ_SIZE_175 +#define ENUM_HPP_PP_SEQ_SIZE_175(_) ENUM_HPP_PP_SEQ_SIZE_176 +#define ENUM_HPP_PP_SEQ_SIZE_176(_) ENUM_HPP_PP_SEQ_SIZE_177 +#define ENUM_HPP_PP_SEQ_SIZE_177(_) ENUM_HPP_PP_SEQ_SIZE_178 +#define ENUM_HPP_PP_SEQ_SIZE_178(_) ENUM_HPP_PP_SEQ_SIZE_179 +#define ENUM_HPP_PP_SEQ_SIZE_179(_) ENUM_HPP_PP_SEQ_SIZE_180 +#define ENUM_HPP_PP_SEQ_SIZE_180(_) ENUM_HPP_PP_SEQ_SIZE_181 +#define ENUM_HPP_PP_SEQ_SIZE_181(_) ENUM_HPP_PP_SEQ_SIZE_182 +#define ENUM_HPP_PP_SEQ_SIZE_182(_) ENUM_HPP_PP_SEQ_SIZE_183 +#define ENUM_HPP_PP_SEQ_SIZE_183(_) ENUM_HPP_PP_SEQ_SIZE_184 +#define ENUM_HPP_PP_SEQ_SIZE_184(_) ENUM_HPP_PP_SEQ_SIZE_185 +#define ENUM_HPP_PP_SEQ_SIZE_185(_) ENUM_HPP_PP_SEQ_SIZE_186 +#define ENUM_HPP_PP_SEQ_SIZE_186(_) ENUM_HPP_PP_SEQ_SIZE_187 +#define ENUM_HPP_PP_SEQ_SIZE_187(_) ENUM_HPP_PP_SEQ_SIZE_188 +#define ENUM_HPP_PP_SEQ_SIZE_188(_) ENUM_HPP_PP_SEQ_SIZE_189 +#define ENUM_HPP_PP_SEQ_SIZE_189(_) ENUM_HPP_PP_SEQ_SIZE_190 +#define ENUM_HPP_PP_SEQ_SIZE_190(_) ENUM_HPP_PP_SEQ_SIZE_191 +#define ENUM_HPP_PP_SEQ_SIZE_191(_) ENUM_HPP_PP_SEQ_SIZE_192 +#define ENUM_HPP_PP_SEQ_SIZE_192(_) ENUM_HPP_PP_SEQ_SIZE_193 +#define ENUM_HPP_PP_SEQ_SIZE_193(_) ENUM_HPP_PP_SEQ_SIZE_194 +#define ENUM_HPP_PP_SEQ_SIZE_194(_) ENUM_HPP_PP_SEQ_SIZE_195 +#define ENUM_HPP_PP_SEQ_SIZE_195(_) ENUM_HPP_PP_SEQ_SIZE_196 +#define ENUM_HPP_PP_SEQ_SIZE_196(_) ENUM_HPP_PP_SEQ_SIZE_197 +#define ENUM_HPP_PP_SEQ_SIZE_197(_) ENUM_HPP_PP_SEQ_SIZE_198 +#define ENUM_HPP_PP_SEQ_SIZE_198(_) ENUM_HPP_PP_SEQ_SIZE_199 +#define ENUM_HPP_PP_SEQ_SIZE_199(_) ENUM_HPP_PP_SEQ_SIZE_200 +#define ENUM_HPP_PP_SEQ_SIZE_200(_) ENUM_HPP_PP_SEQ_SIZE_201 +#define ENUM_HPP_PP_SEQ_SIZE_201(_) ENUM_HPP_PP_SEQ_SIZE_202 +#define ENUM_HPP_PP_SEQ_SIZE_202(_) ENUM_HPP_PP_SEQ_SIZE_203 +#define ENUM_HPP_PP_SEQ_SIZE_203(_) ENUM_HPP_PP_SEQ_SIZE_204 +#define ENUM_HPP_PP_SEQ_SIZE_204(_) ENUM_HPP_PP_SEQ_SIZE_205 +#define ENUM_HPP_PP_SEQ_SIZE_205(_) ENUM_HPP_PP_SEQ_SIZE_206 +#define ENUM_HPP_PP_SEQ_SIZE_206(_) ENUM_HPP_PP_SEQ_SIZE_207 +#define ENUM_HPP_PP_SEQ_SIZE_207(_) ENUM_HPP_PP_SEQ_SIZE_208 +#define ENUM_HPP_PP_SEQ_SIZE_208(_) ENUM_HPP_PP_SEQ_SIZE_209 +#define ENUM_HPP_PP_SEQ_SIZE_209(_) ENUM_HPP_PP_SEQ_SIZE_210 +#define ENUM_HPP_PP_SEQ_SIZE_210(_) ENUM_HPP_PP_SEQ_SIZE_211 +#define ENUM_HPP_PP_SEQ_SIZE_211(_) ENUM_HPP_PP_SEQ_SIZE_212 +#define ENUM_HPP_PP_SEQ_SIZE_212(_) ENUM_HPP_PP_SEQ_SIZE_213 +#define ENUM_HPP_PP_SEQ_SIZE_213(_) ENUM_HPP_PP_SEQ_SIZE_214 +#define ENUM_HPP_PP_SEQ_SIZE_214(_) ENUM_HPP_PP_SEQ_SIZE_215 +#define ENUM_HPP_PP_SEQ_SIZE_215(_) ENUM_HPP_PP_SEQ_SIZE_216 +#define ENUM_HPP_PP_SEQ_SIZE_216(_) ENUM_HPP_PP_SEQ_SIZE_217 +#define ENUM_HPP_PP_SEQ_SIZE_217(_) ENUM_HPP_PP_SEQ_SIZE_218 +#define ENUM_HPP_PP_SEQ_SIZE_218(_) ENUM_HPP_PP_SEQ_SIZE_219 +#define ENUM_HPP_PP_SEQ_SIZE_219(_) ENUM_HPP_PP_SEQ_SIZE_220 +#define ENUM_HPP_PP_SEQ_SIZE_220(_) ENUM_HPP_PP_SEQ_SIZE_221 +#define ENUM_HPP_PP_SEQ_SIZE_221(_) ENUM_HPP_PP_SEQ_SIZE_222 +#define ENUM_HPP_PP_SEQ_SIZE_222(_) ENUM_HPP_PP_SEQ_SIZE_223 +#define ENUM_HPP_PP_SEQ_SIZE_223(_) ENUM_HPP_PP_SEQ_SIZE_224 +#define ENUM_HPP_PP_SEQ_SIZE_224(_) ENUM_HPP_PP_SEQ_SIZE_225 +#define ENUM_HPP_PP_SEQ_SIZE_225(_) ENUM_HPP_PP_SEQ_SIZE_226 +#define ENUM_HPP_PP_SEQ_SIZE_226(_) ENUM_HPP_PP_SEQ_SIZE_227 +#define ENUM_HPP_PP_SEQ_SIZE_227(_) ENUM_HPP_PP_SEQ_SIZE_228 +#define ENUM_HPP_PP_SEQ_SIZE_228(_) ENUM_HPP_PP_SEQ_SIZE_229 +#define ENUM_HPP_PP_SEQ_SIZE_229(_) ENUM_HPP_PP_SEQ_SIZE_230 +#define ENUM_HPP_PP_SEQ_SIZE_230(_) ENUM_HPP_PP_SEQ_SIZE_231 +#define ENUM_HPP_PP_SEQ_SIZE_231(_) ENUM_HPP_PP_SEQ_SIZE_232 +#define ENUM_HPP_PP_SEQ_SIZE_232(_) ENUM_HPP_PP_SEQ_SIZE_233 +#define ENUM_HPP_PP_SEQ_SIZE_233(_) ENUM_HPP_PP_SEQ_SIZE_234 +#define ENUM_HPP_PP_SEQ_SIZE_234(_) ENUM_HPP_PP_SEQ_SIZE_235 +#define ENUM_HPP_PP_SEQ_SIZE_235(_) ENUM_HPP_PP_SEQ_SIZE_236 +#define ENUM_HPP_PP_SEQ_SIZE_236(_) ENUM_HPP_PP_SEQ_SIZE_237 +#define ENUM_HPP_PP_SEQ_SIZE_237(_) ENUM_HPP_PP_SEQ_SIZE_238 +#define ENUM_HPP_PP_SEQ_SIZE_238(_) ENUM_HPP_PP_SEQ_SIZE_239 +#define ENUM_HPP_PP_SEQ_SIZE_239(_) ENUM_HPP_PP_SEQ_SIZE_240 +#define ENUM_HPP_PP_SEQ_SIZE_240(_) ENUM_HPP_PP_SEQ_SIZE_241 +#define ENUM_HPP_PP_SEQ_SIZE_241(_) ENUM_HPP_PP_SEQ_SIZE_242 +#define ENUM_HPP_PP_SEQ_SIZE_242(_) ENUM_HPP_PP_SEQ_SIZE_243 +#define ENUM_HPP_PP_SEQ_SIZE_243(_) ENUM_HPP_PP_SEQ_SIZE_244 +#define ENUM_HPP_PP_SEQ_SIZE_244(_) ENUM_HPP_PP_SEQ_SIZE_245 +#define ENUM_HPP_PP_SEQ_SIZE_245(_) ENUM_HPP_PP_SEQ_SIZE_246 +#define ENUM_HPP_PP_SEQ_SIZE_246(_) ENUM_HPP_PP_SEQ_SIZE_247 +#define ENUM_HPP_PP_SEQ_SIZE_247(_) ENUM_HPP_PP_SEQ_SIZE_248 +#define ENUM_HPP_PP_SEQ_SIZE_248(_) ENUM_HPP_PP_SEQ_SIZE_249 +#define ENUM_HPP_PP_SEQ_SIZE_249(_) ENUM_HPP_PP_SEQ_SIZE_250 +#define ENUM_HPP_PP_SEQ_SIZE_250(_) ENUM_HPP_PP_SEQ_SIZE_251 +#define ENUM_HPP_PP_SEQ_SIZE_251(_) ENUM_HPP_PP_SEQ_SIZE_252 +#define ENUM_HPP_PP_SEQ_SIZE_252(_) ENUM_HPP_PP_SEQ_SIZE_253 +#define ENUM_HPP_PP_SEQ_SIZE_253(_) ENUM_HPP_PP_SEQ_SIZE_254 +#define ENUM_HPP_PP_SEQ_SIZE_254(_) ENUM_HPP_PP_SEQ_SIZE_255 +#define ENUM_HPP_PP_SEQ_SIZE_255(_) ENUM_HPP_PP_SEQ_SIZE_256 + +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_0 0 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_1 1 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_2 2 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_3 3 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_4 4 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_5 5 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_6 6 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_7 7 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_8 8 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_9 9 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_10 10 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_11 11 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_12 12 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_13 13 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_14 14 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_15 15 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_16 16 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_17 17 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_18 18 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_19 19 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_20 20 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_21 21 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_22 22 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_23 23 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_24 24 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_25 25 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_26 26 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_27 27 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_28 28 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_29 29 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_30 30 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_31 31 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_32 32 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_33 33 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_34 34 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_35 35 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_36 36 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_37 37 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_38 38 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_39 39 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_40 40 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_41 41 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_42 42 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_43 43 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_44 44 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_45 45 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_46 46 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_47 47 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_48 48 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_49 49 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_50 50 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_51 51 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_52 52 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_53 53 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_54 54 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_55 55 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_56 56 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_57 57 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_58 58 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_59 59 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_60 60 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_61 61 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_62 62 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_63 63 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_64 64 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_65 65 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_66 66 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_67 67 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_68 68 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_69 69 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_70 70 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_71 71 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_72 72 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_73 73 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_74 74 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_75 75 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_76 76 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_77 77 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_78 78 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_79 79 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_80 80 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_81 81 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_82 82 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_83 83 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_84 84 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_85 85 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_86 86 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_87 87 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_88 88 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_89 89 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_90 90 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_91 91 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_92 92 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_93 93 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_94 94 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_95 95 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_96 96 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_97 97 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_98 98 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_99 99 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_100 100 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_101 101 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_102 102 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_103 103 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_104 104 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_105 105 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_106 106 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_107 107 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_108 108 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_109 109 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_110 110 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_111 111 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_112 112 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_113 113 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_114 114 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_115 115 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_116 116 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_117 117 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_118 118 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_119 119 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_120 120 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_121 121 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_122 122 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_123 123 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_124 124 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_125 125 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_126 126 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_127 127 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_128 128 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_129 129 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_130 130 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_131 131 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_132 132 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_133 133 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_134 134 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_135 135 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_136 136 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_137 137 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_138 138 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_139 139 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_140 140 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_141 141 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_142 142 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_143 143 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_144 144 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_145 145 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_146 146 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_147 147 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_148 148 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_149 149 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_150 150 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_151 151 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_152 152 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_153 153 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_154 154 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_155 155 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_156 156 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_157 157 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_158 158 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_159 159 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_160 160 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_161 161 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_162 162 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_163 163 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_164 164 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_165 165 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_166 166 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_167 167 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_168 168 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_169 169 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_170 170 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_171 171 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_172 172 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_173 173 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_174 174 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_175 175 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_176 176 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_177 177 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_178 178 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_179 179 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_180 180 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_181 181 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_182 182 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_183 183 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_184 184 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_185 185 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_186 186 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_187 187 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_188 188 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_189 189 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_190 190 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_191 191 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_192 192 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_193 193 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_194 194 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_195 195 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_196 196 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_197 197 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_198 198 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_199 199 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_200 200 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_201 201 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_202 202 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_203 203 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_204 204 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_205 205 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_206 206 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_207 207 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_208 208 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_209 209 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_210 210 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_211 211 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_212 212 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_213 213 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_214 214 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_215 215 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_216 216 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_217 217 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_218 218 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_219 219 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_220 220 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_221 221 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_222 222 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_223 223 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_224 224 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_225 225 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_226 226 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_227 227 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_228 228 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_229 229 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_230 230 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_231 231 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_232 232 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_233 233 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_234 234 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_235 235 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_236 236 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_237 237 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_238 238 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_239 239 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_240 240 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_241 241 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_242 242 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_243 243 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_244 244 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_245 245 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_246 246 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_247 247 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_248 248 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_249 249 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_250 250 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_251 251 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_252 252 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_253 253 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_254 254 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_255 255 +# define ENUM_HPP_PP_SEQ_SIZE_ENUM_HPP_PP_SEQ_SIZE_256 256 + +// +// ENUM_HPP_PP_SEQ_FOR_EACH +// + +#define ENUM_HPP_PP_SEQ_FOR_EACH(m, d, s)\ + ENUM_HPP_PP_CAT(ENUM_HPP_PP_SEQ_FOR_EACH_, ENUM_HPP_PP_SEQ_SIZE(s)) (m, d, 0, s) + +#define ENUM_HPP_PP_SEQ_FOR_EACH_1(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_2(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_1(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_3(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_2(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_4(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_3(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_5(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_4(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_6(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_5(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_7(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_6(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_8(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_7(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_9(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_8(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_10(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_9(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_11(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_10(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_12(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_11(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_13(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_12(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_14(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_13(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_15(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_14(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_16(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_15(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_17(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_16(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_18(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_17(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_19(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_18(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_20(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_19(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_21(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_20(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_22(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_21(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_23(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_22(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_24(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_23(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_25(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_24(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_26(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_25(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_27(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_26(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_28(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_27(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_29(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_28(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_30(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_29(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_31(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_30(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_32(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_31(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_33(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_32(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_34(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_33(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_35(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_34(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_36(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_35(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_37(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_36(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_38(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_37(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_39(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_38(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_40(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_39(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_41(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_40(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_42(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_41(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_43(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_42(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_44(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_43(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_45(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_44(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_46(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_45(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_47(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_46(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_48(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_47(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_49(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_48(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_50(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_49(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_51(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_50(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_52(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_51(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_53(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_52(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_54(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_53(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_55(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_54(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_56(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_55(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_57(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_56(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_58(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_57(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_59(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_58(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_60(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_59(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_61(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_60(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_62(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_61(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_63(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_62(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_64(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_63(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_65(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_64(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_66(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_65(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_67(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_66(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_68(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_67(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_69(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_68(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_70(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_69(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_71(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_70(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_72(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_71(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_73(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_72(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_74(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_73(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_75(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_74(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_76(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_75(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_77(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_76(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_78(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_77(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_79(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_78(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_80(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_79(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_81(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_80(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_82(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_81(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_83(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_82(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_84(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_83(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_85(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_84(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_86(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_85(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_87(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_86(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_88(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_87(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_89(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_88(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_90(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_89(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_91(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_90(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_92(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_91(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_93(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_92(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_94(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_93(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_95(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_94(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_96(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_95(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_97(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_96(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_98(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_97(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_99(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_98(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_100(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_99(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_101(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_100(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_102(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_101(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_103(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_102(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_104(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_103(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_105(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_104(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_106(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_105(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_107(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_106(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_108(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_107(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_109(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_108(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_110(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_109(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_111(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_110(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_112(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_111(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_113(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_112(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_114(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_113(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_115(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_114(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_116(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_115(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_117(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_116(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_118(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_117(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_119(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_118(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_120(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_119(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_121(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_120(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_122(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_121(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_123(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_122(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_124(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_123(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_125(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_124(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_126(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_125(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_127(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_126(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_128(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_127(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_129(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_128(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_130(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_129(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_131(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_130(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_132(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_131(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_133(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_132(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_134(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_133(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_135(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_134(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_136(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_135(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_137(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_136(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_138(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_137(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_139(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_138(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_140(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_139(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_141(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_140(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_142(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_141(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_143(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_142(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_144(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_143(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_145(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_144(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_146(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_145(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_147(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_146(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_148(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_147(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_149(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_148(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_150(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_149(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_151(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_150(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_152(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_151(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_153(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_152(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_154(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_153(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_155(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_154(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_156(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_155(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_157(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_156(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_158(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_157(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_159(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_158(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_160(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_159(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_161(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_160(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_162(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_161(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_163(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_162(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_164(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_163(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_165(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_164(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_166(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_165(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_167(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_166(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_168(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_167(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_169(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_168(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_170(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_169(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_171(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_170(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_172(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_171(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_173(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_172(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_174(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_173(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_175(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_174(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_176(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_175(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_177(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_176(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_178(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_177(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_179(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_178(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_180(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_179(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_181(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_180(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_182(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_181(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_183(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_182(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_184(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_183(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_185(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_184(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_186(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_185(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_187(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_186(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_188(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_187(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_189(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_188(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_190(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_189(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_191(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_190(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_192(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_191(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_193(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_192(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_194(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_193(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_195(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_194(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_196(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_195(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_197(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_196(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_198(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_197(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_199(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_198(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_200(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_199(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_201(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_200(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_202(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_201(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_203(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_202(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_204(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_203(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_205(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_204(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_206(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_205(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_207(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_206(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_208(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_207(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_209(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_208(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_210(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_209(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_211(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_210(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_212(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_211(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_213(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_212(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_214(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_213(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_215(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_214(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_216(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_215(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_217(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_216(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_218(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_217(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_219(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_218(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_220(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_219(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_221(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_220(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_222(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_221(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_223(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_222(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_224(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_223(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_225(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_224(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_226(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_225(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_227(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_226(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_228(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_227(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_229(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_228(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_230(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_229(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_231(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_230(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_232(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_231(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_233(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_232(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_234(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_233(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_235(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_234(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_236(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_235(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_237(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_236(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_238(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_237(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_239(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_238(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_240(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_239(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_241(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_240(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_242(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_241(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_243(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_242(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_244(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_243(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_245(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_244(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_246(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_245(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_247(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_246(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_248(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_247(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_249(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_248(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_250(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_249(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_251(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_250(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_252(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_251(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_253(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_252(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_254(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_253(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_255(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_254(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) +#define ENUM_HPP_PP_SEQ_FOR_EACH_256(m, d, i, s) m(d, i, ENUM_HPP_PP_SEQ_HEAD(s)) ENUM_HPP_PP_SEQ_FOR_EACH_255(m, d, ENUM_HPP_PP_INC(i), ENUM_HPP_PP_SEQ_TAIL(s)) diff --git a/headers/meta.hpp/meta_base/enum_bitflags.hpp b/headers/meta.hpp/meta_base/enum_bitflags.hpp new file mode 100644 index 0000000..5b021cb --- /dev/null +++ b/headers/meta.hpp/meta_base/enum_bitflags.hpp @@ -0,0 +1,332 @@ +/******************************************************************************* + * This file is part of the "https://github.com/blackmatov/enum.hpp" + * For conditions of distribution and use, see copyright notice in LICENSE.md + * Copyright (C) 2019-2022, by Matvey Cherevko (blackmatov@gmail.com) + ******************************************************************************/ + +#pragma once + +#include +#include +#include + +namespace enum_hpp::bitflags +{ + template < typename Enum > + class bitflags final { + static_assert(std::is_enum_v); + public: + using enum_type = Enum; + using underlying_type = std::underlying_type_t; + + bitflags() = default; + bitflags(const bitflags&) = default; + bitflags& operator=(const bitflags&) = default; + bitflags(bitflags&&) noexcept = default; + bitflags& operator=(bitflags&&) noexcept = default; + ~bitflags() = default; + + constexpr bitflags(enum_type flags) + : flags_(static_cast(flags)) {} + + constexpr explicit bitflags(underlying_type flags) + : flags_(flags) {} + + constexpr void swap(bitflags& other) noexcept { + using std::swap; + swap(flags_, other.flags_); + } + + constexpr explicit operator bool() const noexcept { + return !!flags_; + } + + constexpr underlying_type as_raw() const noexcept { + return flags_; + } + + constexpr enum_type as_enum() const noexcept { + return static_cast(flags_); + } + + constexpr bool has(bitflags flags) const noexcept { + return flags.flags_ == (flags_ & flags.flags_); + } + + constexpr bitflags& set(bitflags flags) noexcept { + flags_ |= flags.flags_; + return *this; + } + + constexpr bitflags& toggle(bitflags flags) noexcept { + flags_ ^= flags.flags_; + return *this; + } + + constexpr bitflags& clear(bitflags flags) noexcept { + flags_ &= ~flags.flags_; + return *this; + } + private: + underlying_type flags_{}; + }; + + template < typename Enum > + constexpr void swap(bitflags& l, bitflags& r) noexcept { + l.swap(r); + } +} + +namespace std +{ + template < typename Enum > + struct hash> { + size_t operator()(enum_hpp::bitflags::bitflags bf) const noexcept { + return hash{}(bf.as_enum()); + } + }; +} + +namespace enum_hpp::bitflags +{ + #define ENUM_HPP_DEFINE_BINARY_OPERATOR(op)\ + template < typename Enum >\ + constexpr bool operator op(Enum l, bitflags r) noexcept {\ + return l op r.as_enum();\ + }\ + template < typename Enum >\ + constexpr bool operator op(bitflags l, Enum r) noexcept {\ + return l.as_enum() op r;\ + }\ + template < typename Enum >\ + constexpr bool operator op(std::underlying_type_t l, bitflags r) noexcept {\ + return l op r.as_raw();\ + }\ + template < typename Enum >\ + constexpr bool operator op(bitflags l, std::underlying_type_t r) noexcept {\ + return l.as_raw() op r;\ + }\ + template < typename Enum >\ + constexpr bool operator op(bitflags l, bitflags r) noexcept {\ + return l.as_raw() op r.as_raw();\ + } + ENUM_HPP_DEFINE_BINARY_OPERATOR(<) + ENUM_HPP_DEFINE_BINARY_OPERATOR(>) + ENUM_HPP_DEFINE_BINARY_OPERATOR(<=) + ENUM_HPP_DEFINE_BINARY_OPERATOR(>=) + ENUM_HPP_DEFINE_BINARY_OPERATOR(==) + ENUM_HPP_DEFINE_BINARY_OPERATOR(!=) + #undef ENUM_HPP_DEFINE_BINARY_OPERATOR +} + +namespace enum_hpp::bitflags +{ + template < typename Enum > + constexpr bitflags operator~(bitflags l) noexcept { + return static_cast(~l.as_raw()); + } + + #define ENUM_HPP_DEFINE_BINARY_OPERATOR(op)\ + template < typename Enum >\ + constexpr bitflags operator op (Enum l, bitflags r) noexcept {\ + return bitflags{l} op r;\ + }\ + template < typename Enum >\ + constexpr bitflags operator op (bitflags l, Enum r) noexcept {\ + return l op bitflags{r};\ + }\ + template < typename Enum >\ + constexpr bitflags operator op (bitflags l, bitflags r) noexcept {\ + return static_cast(l.as_raw() op r.as_raw());\ + }\ + template < typename Enum >\ + constexpr bitflags& operator op##= (bitflags& l, Enum r) noexcept {\ + return l = l op bitflags{r};\ + }\ + template < typename Enum >\ + constexpr bitflags& operator op##= (bitflags& l, bitflags r) noexcept {\ + return l = l op r;\ + } + ENUM_HPP_DEFINE_BINARY_OPERATOR(|) + ENUM_HPP_DEFINE_BINARY_OPERATOR(&) + ENUM_HPP_DEFINE_BINARY_OPERATOR(^) + #undef ENUM_HPP_DEFINE_BINARY_OPERATOR +} + +namespace enum_hpp::bitflags +{ + // + // any + // + + template < typename Enum + , std::enable_if_t, int> = 0 > + constexpr bool any(Enum flags) noexcept { + return any(bitflags{flags}); + } + + template < typename Enum > + constexpr bool any(bitflags flags) noexcept { + return 0 != flags.as_raw(); + } + + // + // none + // + + template < typename Enum + , std::enable_if_t, int> = 0 > + constexpr bool none(Enum flags) noexcept { + return none(bitflags{flags}); + } + + template < typename Enum > + constexpr bool none(bitflags flags) noexcept { + return 0 == flags.as_raw(); + } + + // + // all_of + // + + template < typename Enum + , std::enable_if_t, int> = 0 > + constexpr bool all_of(Enum flags, Enum mask) noexcept { + return all_of(bitflags{flags}, bitflags{mask}); + } + + template < typename Enum > + constexpr bool all_of(Enum flags, bitflags mask) noexcept { + return all_of(bitflags{flags}, mask); + } + + template < typename Enum > + constexpr bool all_of(bitflags flags, Enum mask) noexcept { + return all_of(flags, bitflags{mask}); + } + + template < typename Enum > + constexpr bool all_of(bitflags flags, bitflags mask) noexcept { + return (flags.as_raw() & mask.as_raw()) == mask.as_raw(); + } + + // + // any_of + // + + template < typename Enum + , std::enable_if_t, int> = 0 > + constexpr bool any_of(Enum flags, Enum mask) noexcept { + return any_of(bitflags{flags}, bitflags{mask}); + } + + template < typename Enum > + constexpr bool any_of(Enum flags, bitflags mask) noexcept { + return any_of(bitflags{flags}, mask); + } + + template < typename Enum > + constexpr bool any_of(bitflags flags, Enum mask) noexcept { + return any_of(flags, bitflags{mask}); + } + + template < typename Enum > + constexpr bool any_of(bitflags flags, bitflags mask) noexcept { + return mask.as_raw() == 0 + || (flags.as_raw() & mask.as_raw()) != 0; + } + + // + // none_of + // + + template < typename Enum + , std::enable_if_t, int> = 0 > + constexpr bool none_of(Enum flags, Enum mask) noexcept { + return none_of(bitflags{flags}, bitflags{mask}); + } + + template < typename Enum > + constexpr bool none_of(Enum flags, bitflags mask) noexcept { + return none_of(bitflags{flags}, mask); + } + + template < typename Enum > + constexpr bool none_of(bitflags flags, Enum mask) noexcept { + return none_of(flags, bitflags{mask}); + } + + template < typename Enum > + constexpr bool none_of(bitflags flags, bitflags mask) noexcept { + return mask.as_raw() != 0 + && (flags.as_raw() & mask.as_raw()) == 0; + } + + // + // any_except + // + + template < typename Enum + , std::enable_if_t, int> = 0 > + constexpr bool any_except(Enum flags, Enum mask) noexcept { + return any_except(bitflags{flags}, bitflags{mask}); + } + + template < typename Enum > + constexpr bool any_except(Enum flags, bitflags mask) noexcept { + return any_except(bitflags{flags}, mask); + } + + template < typename Enum > + constexpr bool any_except(bitflags flags, Enum mask) noexcept { + return any_except(flags, bitflags{mask}); + } + + template < typename Enum > + constexpr bool any_except(bitflags flags, bitflags mask) noexcept { + return any_of(flags, ~mask); + } + + // + // none_except + // + + template < typename Enum + , std::enable_if_t, int> = 0 > + constexpr bool none_except(Enum flags, Enum mask) noexcept { + return none_except(bitflags{flags}, bitflags{mask}); + } + + template < typename Enum > + constexpr bool none_except(Enum flags, bitflags mask) noexcept { + return none_except(bitflags{flags}, mask); + } + + template < typename Enum > + constexpr bool none_except(bitflags flags, Enum mask) noexcept { + return none_except(flags, bitflags{mask}); + } + + template < typename Enum > + constexpr bool none_except(bitflags flags, bitflags mask) noexcept { + return none_of(flags, ~mask); + } +} + +// +// ENUM_HPP_OPERATORS_DECL +// + +#define ENUM_HPP_OPERATORS_DECL(Enum)\ + constexpr ::enum_hpp::bitflags::bitflags operator~ [[maybe_unused]] (Enum l) noexcept {\ + return ~::enum_hpp::bitflags::bitflags(l);\ + }\ + constexpr ::enum_hpp::bitflags::bitflags operator| [[maybe_unused]] (Enum l, Enum r) noexcept {\ + return ::enum_hpp::bitflags::bitflags(l) | ::enum_hpp::bitflags::bitflags(r);\ + }\ + constexpr ::enum_hpp::bitflags::bitflags operator& [[maybe_unused]] (Enum l, Enum r) noexcept {\ + return ::enum_hpp::bitflags::bitflags(l) & ::enum_hpp::bitflags::bitflags(r);\ + }\ + constexpr ::enum_hpp::bitflags::bitflags operator^ [[maybe_unused]] (Enum l, Enum r) noexcept {\ + return ::enum_hpp::bitflags::bitflags(l) ^ ::enum_hpp::bitflags::bitflags(r);\ + } diff --git a/headers/meta.hpp/meta_base/noncopyable.hpp b/headers/meta.hpp/meta_base/noncopyable.hpp new file mode 100644 index 0000000..2f26483 --- /dev/null +++ b/headers/meta.hpp/meta_base/noncopyable.hpp @@ -0,0 +1,21 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +namespace meta_hpp::detail +{ + class noncopyable { + protected: + noncopyable() = default; + ~noncopyable() = default; + public: + noncopyable(noncopyable&&) = delete; + noncopyable(const noncopyable&) = delete; + noncopyable& operator=(noncopyable&&) = delete; + noncopyable& operator=(const noncopyable&) = delete; + }; +} diff --git a/headers/meta.hpp/meta_base/overloaded.hpp b/headers/meta.hpp/meta_base/overloaded.hpp new file mode 100644 index 0000000..4135fef --- /dev/null +++ b/headers/meta.hpp/meta_base/overloaded.hpp @@ -0,0 +1,18 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +namespace meta_hpp::detail +{ + template < typename... Ts > + struct overloaded : Ts... { + using Ts::operator()...; + }; + + template < typename... Ts > + overloaded(Ts...) -> overloaded; +} diff --git a/headers/meta.hpp/meta_base/select_overload.hpp b/headers/meta.hpp/meta_base/select_overload.hpp new file mode 100644 index 0000000..f561a5c --- /dev/null +++ b/headers/meta.hpp/meta_base/select_overload.hpp @@ -0,0 +1,40 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +namespace meta_hpp::detail +{ + template < typename C, typename R, typename... Args > + constexpr auto select_const(R (C::*func)(Args...) const) -> decltype(func) { + return func; + } + + template < typename C, typename R, typename... Args > + constexpr auto select_const(R (C::*func)(Args...) const noexcept) -> decltype(func) { + return func; + } + + template < typename C, typename R, typename... Args > + constexpr auto select_non_const(R (C::*func)(Args...)) -> decltype(func) { + return func; + } + + template < typename C, typename R, typename... Args > + constexpr auto select_non_const(R (C::*func)(Args...) noexcept) -> decltype(func) { + return func; + } + + template < typename Signature > + constexpr auto select_overload(Signature* func) noexcept -> decltype(func) { + return func; + } + + template < typename Signature, typename C > + constexpr auto select_overload(Signature C::*func) noexcept -> decltype(func) { + return func; + } +} diff --git a/headers/meta.hpp/meta_base/stdex.hpp b/headers/meta.hpp/meta_base/stdex.hpp new file mode 100644 index 0000000..5e6e30d --- /dev/null +++ b/headers/meta.hpp/meta_base/stdex.hpp @@ -0,0 +1,56 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include + +namespace meta_hpp::stdex +{ + template < typename T, typename U > + concept same_as = + std::is_same_v && + std::is_same_v; + + template < typename Derived, typename Base > + concept derived_from = + std::is_base_of_v && + std::is_convertible_v; + + template < typename From, typename To > + concept convertible_to = + std::is_convertible_v && + requires { static_cast(std::declval()); }; + + template < typename T > + concept destructible = + std::is_nothrow_destructible_v; + + template < typename T, typename... Args > + concept constructible_from = + destructible && + std::is_constructible_v; + + template < typename T > + concept move_constructible = + constructible_from && + convertible_to; + + template + concept copy_constructible = + move_constructible && + constructible_from && convertible_to && + constructible_from && convertible_to && + constructible_from && convertible_to; +} + +namespace meta_hpp::stdex +{ + template < typename Enum > + [[nodiscard]] constexpr std::underlying_type_t to_underlying(Enum e) noexcept { + return static_cast>(e); + } +} diff --git a/headers/meta.hpp/meta_base/type_id.hpp b/headers/meta.hpp/meta_base/type_id.hpp new file mode 100644 index 0000000..7b0da4f --- /dev/null +++ b/headers/meta.hpp/meta_base/type_id.hpp @@ -0,0 +1,62 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include +#include +#include + +#include "type_list.hpp" + +namespace meta_hpp::detail +{ + class type_id final { + public: + template < typename T > + // NOLINTNEXTLINE(readability-named-parameter) + explicit type_id(type_list) noexcept + : id_{type_to_id()} {} + + type_id(type_id&&) = default; + type_id(const type_id&) = default; + + type_id& operator=(type_id&&) = default; + type_id& operator=(const type_id&) = default; + + ~type_id() = default; + + [[nodiscard]] std::size_t get_hash() const noexcept { + return std::hash{}(id_); + } + + [[nodiscard]] friend bool operator<(type_id l, type_id r) noexcept { + return l.id_ < r.id_; + } + + [[nodiscard]] friend bool operator==(type_id l, type_id r) noexcept { + return l.id_ == r.id_; + } + + [[nodiscard]] friend bool operator!=(type_id l, type_id r) noexcept { + return l.id_ != r.id_; + } + private: + using underlying_type = std::uint32_t; + underlying_type id_{}; + private: + [[nodiscard]] static underlying_type next() noexcept { + static std::atomic id{}; + return ++id; + } + + template < typename T > + [[nodiscard]] static underlying_type type_to_id() noexcept { + static const underlying_type id{next()}; + return id; + } + }; +} diff --git a/headers/meta.hpp/meta_kinds.hpp b/headers/meta.hpp/meta_base/type_kinds.hpp similarity index 50% rename from headers/meta.hpp/meta_kinds.hpp rename to headers/meta.hpp/meta_base/type_kinds.hpp index 72691a6..dd39caf 100644 --- a/headers/meta.hpp/meta_kinds.hpp +++ b/headers/meta.hpp/meta_base/type_kinds.hpp @@ -6,26 +6,8 @@ #pragma once -#include "meta_base.hpp" - -namespace meta_hpp -{ - enum class type_kind : std::uint32_t { - array_, - class_, - ctor_, - dtor_, - enum_, - function_, - member_, - method_, - nullptr_, - number_, - pointer_, - reference_, - void_, - }; -} +#include +#include namespace meta_hpp::detail { @@ -61,6 +43,25 @@ namespace meta_hpp::detail template < typename T > concept void_kind = std::is_void_v; +} + +namespace meta_hpp::detail +{ + enum class type_kind : std::uint32_t { + array_, + class_, + ctor_, + dtor_, + enum_, + function_, + member_, + method_, + nullptr_, + number_, + pointer_, + reference_, + void_, + }; template < typename T > constexpr type_kind make_type_kind() noexcept { @@ -77,96 +78,3 @@ namespace meta_hpp::detail if constexpr ( void_kind ) { return type_kind::void_; } } } - -namespace meta_hpp::detail -{ - template < type_kind Kind > - struct type_kind_traits; - - template <> - struct type_kind_traits { - using kind_type = array_type; - using kind_type_data = array_type_data; - }; - - template <> - struct type_kind_traits { - using kind_type = class_type; - using kind_type_data = class_type_data; - }; - - template <> - struct type_kind_traits { - using kind_type = ctor_type; - using kind_type_data = ctor_type_data; - }; - - template <> - struct type_kind_traits { - using kind_type = dtor_type; - using kind_type_data = dtor_type_data; - }; - - template <> - struct type_kind_traits { - using kind_type = enum_type; - using kind_type_data = enum_type_data; - }; - - template <> - struct type_kind_traits { - using kind_type = function_type; - using kind_type_data = function_type_data; - }; - - template <> - struct type_kind_traits { - using kind_type = member_type; - using kind_type_data = member_type_data; - }; - - template <> - struct type_kind_traits { - using kind_type = method_type; - using kind_type_data = method_type_data; - }; - - template <> - struct type_kind_traits { - using kind_type = nullptr_type; - using kind_type_data = nullptr_type_data; - }; - - template <> - struct type_kind_traits { - using kind_type = number_type; - using kind_type_data = number_type_data; - }; - - template <> - struct type_kind_traits { - using kind_type = pointer_type; - using kind_type_data = pointer_type_data; - }; - - template <> - struct type_kind_traits { - using kind_type = reference_type; - using kind_type_data = reference_type_data; - }; - - template <> - struct type_kind_traits { - using kind_type = void_type; - using kind_type_data = void_type_data; - }; - - template < typename T > - using kind_type = typename type_kind_traits()>::kind_type; - - template < typename T > - using kind_type_data = typename type_kind_traits()>::kind_type_data; - - template < typename T > - using kind_type_data_ptr = std::shared_ptr>; -} diff --git a/headers/meta.hpp/meta_base/type_list.hpp b/headers/meta.hpp/meta_base/type_list.hpp new file mode 100644 index 0000000..f6c5854 --- /dev/null +++ b/headers/meta.hpp/meta_base/type_list.hpp @@ -0,0 +1,26 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include + +namespace meta_hpp::detail +{ + template < typename... Types > + struct type_list {}; + + template < std::size_t Index, typename TypeList > + struct type_list_at; + + template < std::size_t Index, typename... Types > + struct type_list_at> { + using type = std::tuple_element_t>; + }; + + template < std::size_t Index, typename TypeList > + using type_list_at_t = typename type_list_at::type; +} diff --git a/headers/meta.hpp/meta_binds/class_bind.hpp b/headers/meta.hpp/meta_binds/class_bind.hpp index 3633f6c..ea00403 100644 --- a/headers/meta.hpp/meta_binds/class_bind.hpp +++ b/headers/meta.hpp/meta_binds/class_bind.hpp @@ -9,11 +9,13 @@ #include "../meta_base.hpp" #include "../meta_binds.hpp" +#include "../meta_detail/type_registry.hpp" + namespace meta_hpp { template < detail::class_kind Class > class_bind::class_bind() - : data_{detail::class_type_data::get_static()} {} + : data_{detail::type_access(detail::resolve_type())} {} template < detail::class_kind Class > class_bind::operator class_type() const noexcept { @@ -45,8 +47,8 @@ namespace meta_hpp class_bind& class_bind::base_() requires detail::class_bind_base_kind { - data_->bases.emplace(resolve_type()); - data_->bases_info.emplace(resolve_type(), detail::class_type_data::base_info{ + data_->bases.emplace(detail::resolve_type()); + data_->bases_info.emplace(detail::resolve_type(), detail::class_type_data::base_info{ .upcast = +[](void* derived) -> void* { return static_cast(static_cast(derived)); } diff --git a/headers/meta.hpp/meta_binds/enum_bind.hpp b/headers/meta.hpp/meta_binds/enum_bind.hpp index 2543892..28d91d6 100644 --- a/headers/meta.hpp/meta_binds/enum_bind.hpp +++ b/headers/meta.hpp/meta_binds/enum_bind.hpp @@ -9,11 +9,13 @@ #include "../meta_base.hpp" #include "../meta_binds.hpp" +#include "../meta_detail/type_registry.hpp" + namespace meta_hpp { template < detail::enum_kind Enum > enum_bind::enum_bind() - : data_{detail::enum_type_data::get_static()} {} + : data_{detail::type_access(detail::resolve_type())} {} template < detail::enum_kind Enum > enum_bind::operator enum_type() const noexcept { diff --git a/headers/meta.hpp/meta_binds/scope_bind.hpp b/headers/meta.hpp/meta_binds/scope_bind.hpp index 6f4c03c..9e3648a 100644 --- a/headers/meta.hpp/meta_binds/scope_bind.hpp +++ b/headers/meta.hpp/meta_binds/scope_bind.hpp @@ -9,6 +9,9 @@ #include "../meta_base.hpp" #include "../meta_binds.hpp" +#include "../meta_detail/state_registry.hpp" +#include "../meta_detail/type_registry.hpp" + namespace meta_hpp { // NOLINTNEXTLINE(readability-named-parameter) @@ -17,7 +20,7 @@ namespace meta_hpp // NOLINTNEXTLINE(readability-named-parameter) inline scope_bind::scope_bind(std::string_view name, static_tag) - : state_{detail::scope_state::get_static(name)} {} + : state_{detail::state_access(detail::resolve_scope(name))} {} inline scope_bind::operator scope() const noexcept { return scope{state_}; @@ -25,13 +28,13 @@ namespace meta_hpp template < detail::class_kind Class > scope_bind& scope_bind::class_(std::string name) { - state_->classes.emplace(std::move(name), resolve_type()); + state_->classes.emplace(std::move(name), detail::resolve_type()); return *this; } template < detail::enum_kind Enum > scope_bind& scope_bind::enum_(std::string name) { - state_->enums.emplace(std::move(name), resolve_type()); + state_->enums.emplace(std::move(name), detail::resolve_type()); return *this; } diff --git a/headers/meta.hpp/meta_detail/state_family.hpp b/headers/meta.hpp/meta_detail/state_family.hpp new file mode 100644 index 0000000..4954aa3 --- /dev/null +++ b/headers/meta.hpp/meta_detail/state_family.hpp @@ -0,0 +1,28 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" + +namespace meta_hpp::detail +{ + template < typename T > + concept state_family = + stdex::same_as || + stdex::same_as || + stdex::same_as || + stdex::same_as || + stdex::same_as || + stdex::same_as || + stdex::same_as || + stdex::same_as; + + template < state_family T > + [[nodiscard]] auto state_access(const T& state) { + return state.state_; + } +} diff --git a/headers/meta.hpp/meta_detail/state_registry.hpp b/headers/meta.hpp/meta_detail/state_registry.hpp new file mode 100644 index 0000000..9a21ced --- /dev/null +++ b/headers/meta.hpp/meta_detail/state_registry.hpp @@ -0,0 +1,54 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_states.hpp" + +namespace meta_hpp::detail +{ + class state_registry final { + public: + [[nodiscard]] static state_registry& instance() { + static state_registry instance; + return instance; + } + + [[nodiscard]] scope get_scope_by_name(std::string_view name) const noexcept { + if ( auto iter = scopes_.find(name); iter != scopes_.end() ) { + return iter->second; + } + return scope{}; + } + + [[nodiscard]] scope resolve_scope(std::string_view name) { + return ensure_scope(name); + } + private: + state_registry() = default; + + scope ensure_scope(std::string_view name) { + if ( auto iter = scopes_.find(name); iter != scopes_.end() ) { + return iter->second; + } + + return scopes_.emplace( + std::string{name}, + scope_state::make(std::string{name})).first->second; + } + private: + std::map> scopes_; + }; +} + +namespace meta_hpp::detail +{ + [[nodiscard]] inline scope resolve_scope(std::string_view name) { + state_registry& registry = state_registry::instance(); + return registry.resolve_scope(name); + } +} diff --git a/headers/meta.hpp/meta_detail/type_family.hpp b/headers/meta.hpp/meta_detail/type_family.hpp new file mode 100644 index 0000000..f6adfe3 --- /dev/null +++ b/headers/meta.hpp/meta_detail/type_family.hpp @@ -0,0 +1,34 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" + +namespace meta_hpp::detail +{ + template < typename T > + concept type_family = + stdex::same_as || + stdex::same_as || + stdex::same_as || + stdex::same_as || + stdex::same_as || + stdex::same_as || + stdex::same_as || + stdex::same_as || + stdex::same_as || + stdex::same_as || + stdex::same_as || + stdex::same_as || + stdex::same_as || + stdex::same_as; + + template < type_family T > + [[nodiscard]] auto type_access(const T& type) { + return type.data_; + } +} diff --git a/headers/meta.hpp/meta_detail/type_registry.hpp b/headers/meta.hpp/meta_detail/type_registry.hpp new file mode 100644 index 0000000..be9fb0d --- /dev/null +++ b/headers/meta.hpp/meta_detail/type_registry.hpp @@ -0,0 +1,265 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_types.hpp" + +namespace meta_hpp::detail +{ + class type_registry final { + public: + [[nodiscard]] static type_registry& instance() { + static type_registry instance; + return instance; + } + + [[nodiscard]] any_type get_type_by_id(type_id id) const noexcept { + if ( auto iter = type_by_id_.find(id); iter != type_by_id_.end() ) { + return iter->second; + } + return any_type{}; + } + + [[nodiscard]] any_type get_type_by_rtti(const std::type_index& index) const noexcept { + if ( auto iter = type_by_rtti_.find(index); iter != type_by_rtti_.end() ) { + return iter->second; + } + return any_type{}; + } + + // + // + // + + template < array_kind Array > + [[nodiscard]] array_type resolve_type() { return resolve_array_type(); } + + template < class_kind Class > + [[nodiscard]] class_type resolve_type() { return resolve_class_type(); } + + template < enum_kind Enum > + [[nodiscard]] enum_type resolve_type() { return resolve_enum_type(); } + + template < function_kind Function > + [[nodiscard]] function_type resolve_type() { return resolve_function_type(); } + + template < member_kind Member > + [[nodiscard]] member_type resolve_type() { return resolve_member_type(); } + + template < method_kind Method > + [[nodiscard]] method_type resolve_type() { return resolve_method_type(); } + + template < nullptr_kind Nullptr > + [[nodiscard]] nullptr_type resolve_type() { return resolve_nullptr_type(); } + + template < number_kind Number > + [[nodiscard]] number_type resolve_type() { return resolve_number_type(); } + + template < pointer_kind Pointer > + [[nodiscard]] pointer_type resolve_type() { return resolve_pointer_type(); } + + template < reference_kind Reference > + [[nodiscard]] reference_type resolve_type() { return resolve_reference_type(); } + + template < void_kind Void > + [[nodiscard]] void_type resolve_type() { return resolve_void_type(); } + + // + // + // + + template < array_kind Array > + [[nodiscard]] array_type resolve_array_type() { return array_type{resolve_array_type_data()}; } + + template < class_kind Class > + [[nodiscard]] class_type resolve_class_type() { return class_type{resolve_class_type_data()}; } + + template < class_kind Class, typename... Args > + [[nodiscard]] ctor_type resolve_ctor_type() { return ctor_type{resolve_ctor_type_data()}; } + + template < class_kind Class > + [[nodiscard]] dtor_type resolve_dtor_type() { return dtor_type{resolve_dtor_type_data()}; } + + template < enum_kind Enum > + [[nodiscard]] enum_type resolve_enum_type() { return enum_type{resolve_enum_type_data()}; } + + template < function_kind Function > + [[nodiscard]] function_type resolve_function_type() { return function_type{resolve_function_type_data()}; } + + template < member_kind Member > + [[nodiscard]] member_type resolve_member_type() { return member_type{resolve_member_type_data()}; } + + template < method_kind Method > + [[nodiscard]] method_type resolve_method_type() { return method_type{resolve_method_type_data()}; } + + template < nullptr_kind Nullptr > + [[nodiscard]] nullptr_type resolve_nullptr_type() { return nullptr_type{resolve_nullptr_type_data()}; } + + template < number_kind Number > + [[nodiscard]] number_type resolve_number_type() { return number_type{resolve_number_type_data()}; } + + template < pointer_kind Pointer > + [[nodiscard]] pointer_type resolve_pointer_type() { return pointer_type{resolve_pointer_type_data()}; } + + template < reference_kind Reference > + [[nodiscard]] reference_type resolve_reference_type() { return reference_type{resolve_reference_type_data()}; } + + template < void_kind Void > + [[nodiscard]] void_type resolve_void_type() { return void_type{resolve_void_type_data()}; } + + // + // + // + + template < array_kind Array > + [[nodiscard]] array_type_data_ptr resolve_array_type_data() { + static array_type_data_ptr data{std::make_shared(type_list{})}; + return ensure_type(data); + } + + template < class_kind Class > + [[nodiscard]] class_type_data_ptr resolve_class_type_data() { + static class_type_data_ptr data{std::make_shared(type_list{})}; + return ensure_type(data); + } + + template < class_kind Class, typename... Args > + [[nodiscard]] ctor_type_data_ptr resolve_ctor_type_data() { + static ctor_type_data_ptr data{std::make_shared(type_list{}, type_list{})}; + return data; + } + + template < class_kind Class > + [[nodiscard]] dtor_type_data_ptr resolve_dtor_type_data() { + static dtor_type_data_ptr data{std::make_shared(type_list{})}; + return data; + } + + template < enum_kind Enum > + [[nodiscard]] enum_type_data_ptr resolve_enum_type_data() { + static enum_type_data_ptr data{std::make_shared(type_list{})}; + return ensure_type(data); + } + + template < function_kind Function > + [[nodiscard]] function_type_data_ptr resolve_function_type_data() { + static function_type_data_ptr data{std::make_shared(type_list{})}; + return ensure_type(data); + } + + template < member_kind Member > + [[nodiscard]] member_type_data_ptr resolve_member_type_data() { + static member_type_data_ptr data{std::make_shared(type_list{})}; + return ensure_type(data); + } + + template < method_kind Method > + [[nodiscard]] method_type_data_ptr resolve_method_type_data() { + static method_type_data_ptr data{std::make_shared(type_list{})}; + return ensure_type(data); + } + + template < nullptr_kind Nullptr > + [[nodiscard]] nullptr_type_data_ptr resolve_nullptr_type_data() { + static nullptr_type_data_ptr data{std::make_shared(type_list{})}; + return ensure_type(data); + } + + template < number_kind Number > + [[nodiscard]] number_type_data_ptr resolve_number_type_data() { + static number_type_data_ptr data{std::make_shared(type_list{})}; + return ensure_type(data); + } + + template < pointer_kind Pointer > + [[nodiscard]] pointer_type_data_ptr resolve_pointer_type_data() { + static pointer_type_data_ptr data{std::make_shared(type_list{})}; + return ensure_type(data); + } + + template < reference_kind Reference > + [[nodiscard]] reference_type_data_ptr resolve_reference_type_data() { + static reference_type_data_ptr data{std::make_shared(type_list{})}; + return ensure_type(data); + } + + template < void_kind Void > + [[nodiscard]] void_type_data_ptr resolve_void_type_data() { + static void_type_data_ptr data{std::make_shared(type_list{})}; + return ensure_type(data); + } + private: + type_registry() = default; + + template < typename Type, typename TypeData > + TypeData ensure_type(const TypeData& type_data) { + static std::once_flag init_flag{}; + std::call_once(init_flag, [this, &type_data](){ + type_by_id_[type_data->id] = any_type{type_data}; + type_by_rtti_[typeid(Type)] = any_type{type_data}; + }); + return type_data; + } + private: + std::map> type_by_id_; + std::map> type_by_rtti_; + }; +} + +namespace meta_hpp::detail +{ + template < typename T > + [[nodiscard]] auto resolve_type() { + type_registry& registry = type_registry::instance(); + return registry.resolve_type>(); + } + + template < typename... Ts > + [[nodiscard]] std::vector resolve_types() { + return { resolve_type()... }; + } +} + +namespace meta_hpp::detail +{ + template < class_kind Class, typename... Args > + ctor_type resolve_ctor_type() { + type_registry& registry = type_registry::instance(); + return registry.resolve_ctor_type(); + } + + template < class_kind Class > + dtor_type resolve_dtor_type() { + type_registry& registry = type_registry::instance(); + return registry.resolve_dtor_type(); + } +} + +namespace meta_hpp::detail +{ + template < typename T > + // NOLINTNEXTLINE(readability-named-parameter) + [[nodiscard]] auto resolve_type(T&&) { + return resolve_type>(); + } + + template < typename... Ts > + // NOLINTNEXTLINE(readability-named-parameter) + [[nodiscard]] std::vector resolve_types(type_list) { + return { resolve_type()... }; + } +} + +namespace meta_hpp::detail +{ + template < typename T > + [[nodiscard]] any_type resolve_polymorphic_type(T&& v) noexcept { + type_registry& registry = type_registry::instance(); + return registry.get_type_by_rtti(typeid(v)); + } +} diff --git a/headers/meta.hpp/meta_traits/array_traits.hpp b/headers/meta.hpp/meta_detail/type_traits/array_traits.hpp similarity index 82% rename from headers/meta.hpp/meta_traits/array_traits.hpp rename to headers/meta.hpp/meta_detail/type_traits/array_traits.hpp index ce73e58..a5439bf 100644 --- a/headers/meta.hpp/meta_traits/array_traits.hpp +++ b/headers/meta.hpp/meta_detail/type_traits/array_traits.hpp @@ -6,8 +6,17 @@ #pragma once -#include "../meta_base.hpp" -#include "../meta_traits.hpp" +#include "../../meta_base.hpp" + +namespace meta_hpp::detail +{ + enum class array_flags : std::uint32_t { + is_bounded = 1 << 0, + is_unbounded = 1 << 1, + }; + + ENUM_HPP_OPERATORS_DECL(array_flags) +} namespace meta_hpp::detail { diff --git a/headers/meta.hpp/meta_traits/class_traits.hpp b/headers/meta.hpp/meta_detail/type_traits/class_traits.hpp similarity index 86% rename from headers/meta.hpp/meta_traits/class_traits.hpp rename to headers/meta.hpp/meta_detail/type_traits/class_traits.hpp index e95665b..d5e8591 100644 --- a/headers/meta.hpp/meta_traits/class_traits.hpp +++ b/headers/meta.hpp/meta_detail/type_traits/class_traits.hpp @@ -6,8 +6,20 @@ #pragma once -#include "../meta_base.hpp" -#include "../meta_traits.hpp" +#include "../../meta_base.hpp" + +namespace meta_hpp::detail +{ + enum class class_flags : std::uint32_t { + is_empty = 1 << 0, + is_final = 1 << 1, + is_abstract = 1 << 2, + is_polymorphic = 1 << 3, + is_template_instantiation = 1 << 4, + }; + + ENUM_HPP_OPERATORS_DECL(class_flags) +} namespace meta_hpp::detail { @@ -22,10 +34,6 @@ namespace meta_hpp::detail [[nodiscard]] static constexpr bitflags make_flags() noexcept { return {}; } - - [[nodiscard]] static std::vector make_argument_types() { - return {}; - } }; template < template < typename... > typename Class, typename... Args > @@ -37,10 +45,6 @@ namespace meta_hpp::detail [[nodiscard]] static constexpr bitflags make_flags() noexcept { return class_flags::is_template_instantiation; } - - [[nodiscard]] static std::vector make_argument_types() { - return { resolve_type()... }; - } }; } diff --git a/headers/meta.hpp/meta_traits/ctor_traits.hpp b/headers/meta.hpp/meta_detail/type_traits/ctor_traits.hpp similarity index 83% rename from headers/meta.hpp/meta_traits/ctor_traits.hpp rename to headers/meta.hpp/meta_detail/type_traits/ctor_traits.hpp index e80e899..e910274 100644 --- a/headers/meta.hpp/meta_traits/ctor_traits.hpp +++ b/headers/meta.hpp/meta_detail/type_traits/ctor_traits.hpp @@ -6,8 +6,16 @@ #pragma once -#include "../meta_base.hpp" -#include "../meta_traits.hpp" +#include "../../meta_base.hpp" + +namespace meta_hpp::detail +{ + enum class ctor_flags : std::uint32_t { + is_noexcept = 1 << 0, + }; + + ENUM_HPP_OPERATORS_DECL(ctor_flags) +} namespace meta_hpp::detail { @@ -27,9 +35,5 @@ namespace meta_hpp::detail return flags; } - - [[nodiscard]] static std::vector make_argument_types() { - return { resolve_type()... }; - } }; } diff --git a/headers/meta.hpp/meta_traits/dtor_traits.hpp b/headers/meta.hpp/meta_detail/type_traits/dtor_traits.hpp similarity index 81% rename from headers/meta.hpp/meta_traits/dtor_traits.hpp rename to headers/meta.hpp/meta_detail/type_traits/dtor_traits.hpp index 1838343..8037180 100644 --- a/headers/meta.hpp/meta_traits/dtor_traits.hpp +++ b/headers/meta.hpp/meta_detail/type_traits/dtor_traits.hpp @@ -6,8 +6,16 @@ #pragma once -#include "../meta_base.hpp" -#include "../meta_traits.hpp" +#include "../../meta_base.hpp" + +namespace meta_hpp::detail +{ + enum class dtor_flags : std::uint32_t { + is_noexcept = 1 << 0, + }; + + ENUM_HPP_OPERATORS_DECL(dtor_flags) +} namespace meta_hpp::detail { diff --git a/headers/meta.hpp/meta_traits/enum_traits.hpp b/headers/meta.hpp/meta_detail/type_traits/enum_traits.hpp similarity index 82% rename from headers/meta.hpp/meta_traits/enum_traits.hpp rename to headers/meta.hpp/meta_detail/type_traits/enum_traits.hpp index 45265a6..f347d8f 100644 --- a/headers/meta.hpp/meta_traits/enum_traits.hpp +++ b/headers/meta.hpp/meta_detail/type_traits/enum_traits.hpp @@ -6,8 +6,16 @@ #pragma once -#include "../meta_base.hpp" -#include "../meta_traits.hpp" +#include "../../meta_base.hpp" + +namespace meta_hpp::detail +{ + enum class enum_flags : std::uint32_t { + is_scoped = 1 << 0, + }; + + ENUM_HPP_OPERATORS_DECL(enum_flags) +} namespace meta_hpp::detail { diff --git a/headers/meta.hpp/meta_traits/function_traits.hpp b/headers/meta.hpp/meta_detail/type_traits/function_traits.hpp similarity index 85% rename from headers/meta.hpp/meta_traits/function_traits.hpp rename to headers/meta.hpp/meta_detail/type_traits/function_traits.hpp index 0046345..e82fb71 100644 --- a/headers/meta.hpp/meta_traits/function_traits.hpp +++ b/headers/meta.hpp/meta_detail/type_traits/function_traits.hpp @@ -6,8 +6,16 @@ #pragma once -#include "../meta_base.hpp" -#include "../meta_traits.hpp" +#include "../../meta_base.hpp" + +namespace meta_hpp::detail +{ + enum class function_flags : std::uint32_t { + is_noexcept = 1 << 0, + }; + + ENUM_HPP_OPERATORS_DECL(function_flags) +} namespace meta_hpp::detail { @@ -24,10 +32,6 @@ namespace meta_hpp::detail [[nodiscard]] static constexpr bitflags make_flags() noexcept { return {}; } - - [[nodiscard]] static std::vector make_argument_types() { - return { resolve_type()... }; - } }; template < typename R, typename... Args > diff --git a/headers/meta.hpp/meta_traits/member_traits.hpp b/headers/meta.hpp/meta_detail/type_traits/member_traits.hpp similarity index 82% rename from headers/meta.hpp/meta_traits/member_traits.hpp rename to headers/meta.hpp/meta_detail/type_traits/member_traits.hpp index 8bf227a..adaf932 100644 --- a/headers/meta.hpp/meta_traits/member_traits.hpp +++ b/headers/meta.hpp/meta_detail/type_traits/member_traits.hpp @@ -6,8 +6,16 @@ #pragma once -#include "../meta_base.hpp" -#include "../meta_traits.hpp" +#include "../../meta_base.hpp" + +namespace meta_hpp::detail +{ + enum class member_flags : std::uint32_t { + is_readonly = 1 << 0, + }; + + ENUM_HPP_OPERATORS_DECL(member_flags) +} namespace meta_hpp::detail { diff --git a/headers/meta.hpp/meta_traits/method_traits.hpp b/headers/meta.hpp/meta_detail/type_traits/method_traits.hpp similarity index 94% rename from headers/meta.hpp/meta_traits/method_traits.hpp rename to headers/meta.hpp/meta_detail/type_traits/method_traits.hpp index c82eea8..75384d5 100644 --- a/headers/meta.hpp/meta_traits/method_traits.hpp +++ b/headers/meta.hpp/meta_detail/type_traits/method_traits.hpp @@ -6,8 +6,19 @@ #pragma once -#include "../meta_base.hpp" -#include "../meta_traits.hpp" +#include "../../meta_base.hpp" + +namespace meta_hpp::detail +{ + enum class method_flags : std::uint32_t { + is_const = 1 << 0, + is_noexcept = 1 << 1, + is_lvalue_qualified = 1 << 2, + is_rvalue_qualified = 1 << 3, + }; + + ENUM_HPP_OPERATORS_DECL(method_flags) +} namespace meta_hpp::detail { @@ -26,10 +37,6 @@ namespace meta_hpp::detail [[nodiscard]] static constexpr bitflags make_flags() noexcept { return {}; } - - [[nodiscard]] static std::vector make_argument_types() { - return { resolve_type()... }; - } }; template < typename R, typename C, typename... Args > diff --git a/headers/meta.hpp/meta_traits/number_traits.hpp b/headers/meta.hpp/meta_detail/type_traits/number_traits.hpp similarity index 81% rename from headers/meta.hpp/meta_traits/number_traits.hpp rename to headers/meta.hpp/meta_detail/type_traits/number_traits.hpp index d6ec6df..c438770 100644 --- a/headers/meta.hpp/meta_traits/number_traits.hpp +++ b/headers/meta.hpp/meta_detail/type_traits/number_traits.hpp @@ -6,8 +6,19 @@ #pragma once -#include "../meta_base.hpp" -#include "../meta_traits.hpp" +#include "../../meta_base.hpp" + +namespace meta_hpp::detail +{ + enum class number_flags : std::uint32_t { + is_signed = 1 << 0, + is_unsigned = 1 << 1, + is_integral = 1 << 2, + is_floating_point = 1 << 3, + }; + + ENUM_HPP_OPERATORS_DECL(number_flags) +} namespace meta_hpp::detail { diff --git a/headers/meta.hpp/meta_traits/pointer_traits.hpp b/headers/meta.hpp/meta_detail/type_traits/pointer_traits.hpp similarity index 81% rename from headers/meta.hpp/meta_traits/pointer_traits.hpp rename to headers/meta.hpp/meta_detail/type_traits/pointer_traits.hpp index f33682e..beebc8a 100644 --- a/headers/meta.hpp/meta_traits/pointer_traits.hpp +++ b/headers/meta.hpp/meta_detail/type_traits/pointer_traits.hpp @@ -6,8 +6,16 @@ #pragma once -#include "../meta_base.hpp" -#include "../meta_traits.hpp" +#include "../../meta_base.hpp" + +namespace meta_hpp::detail +{ + enum class pointer_flags : std::uint32_t { + is_readonly = 1 << 0, + }; + + ENUM_HPP_OPERATORS_DECL(pointer_flags) +} namespace meta_hpp::detail { diff --git a/headers/meta.hpp/meta_traits/reference_traits.hpp b/headers/meta.hpp/meta_detail/type_traits/reference_traits.hpp similarity index 81% rename from headers/meta.hpp/meta_traits/reference_traits.hpp rename to headers/meta.hpp/meta_detail/type_traits/reference_traits.hpp index ce04482..efd179e 100644 --- a/headers/meta.hpp/meta_traits/reference_traits.hpp +++ b/headers/meta.hpp/meta_detail/type_traits/reference_traits.hpp @@ -6,8 +6,18 @@ #pragma once -#include "../meta_base.hpp" -#include "../meta_traits.hpp" +#include "../../meta_base.hpp" + +namespace meta_hpp::detail +{ + enum class reference_flags : std::uint32_t { + is_readonly = 1 << 0, + is_lvalue = 1 << 1, + is_rvalue = 1 << 2, + }; + + ENUM_HPP_OPERATORS_DECL(reference_flags) +} namespace meta_hpp::detail { diff --git a/headers/meta.hpp/meta_utilities/value_traits/deref_traits.hpp b/headers/meta.hpp/meta_detail/value_traits/deref_traits.hpp similarity index 74% rename from headers/meta.hpp/meta_utilities/value_traits/deref_traits.hpp rename to headers/meta.hpp/meta_detail/value_traits/deref_traits.hpp index 6ac5ad0..b7a5f3f 100644 --- a/headers/meta.hpp/meta_utilities/value_traits/deref_traits.hpp +++ b/headers/meta.hpp/meta_detail/value_traits/deref_traits.hpp @@ -7,44 +7,44 @@ #pragma once #include "../../meta_base.hpp" -#include "../../meta_utilities.hpp" +#include "../../meta_value.hpp" namespace meta_hpp::detail { template < typename T > - struct value_deref_traits; + struct deref_traits; template < typename T > - concept has_value_deref_traits = requires(const T& v) { - { value_deref_traits{}(v) } -> stdex::convertible_to; + concept has_deref_traits = requires(const T& v) { + { deref_traits{}(v) } -> stdex::convertible_to; }; } namespace meta_hpp::detail { template < stdex::copy_constructible T > - struct value_deref_traits { + struct deref_traits { value operator()(T* v) const { return value{*v}; } }; template < stdex::copy_constructible T > - struct value_deref_traits { + struct deref_traits { value operator()(const T* v) const { return value{*v}; } }; template < stdex::copy_constructible T > - struct value_deref_traits> { + struct deref_traits> { value operator()(const std::shared_ptr& v) const { return value{*v}; } }; template < stdex::copy_constructible T > - struct value_deref_traits> { + struct deref_traits> { value operator()(const std::unique_ptr& v) const { return value{*v}; } diff --git a/headers/meta.hpp/meta_utilities/value_traits/equals_traits.hpp b/headers/meta.hpp/meta_detail/value_traits/equals_traits.hpp similarity index 75% rename from headers/meta.hpp/meta_utilities/value_traits/equals_traits.hpp rename to headers/meta.hpp/meta_detail/value_traits/equals_traits.hpp index 23ce64b..bd87246 100644 --- a/headers/meta.hpp/meta_utilities/value_traits/equals_traits.hpp +++ b/headers/meta.hpp/meta_detail/value_traits/equals_traits.hpp @@ -7,16 +7,16 @@ #pragma once #include "../../meta_base.hpp" -#include "../../meta_utilities.hpp" +#include "../../meta_value.hpp" namespace meta_hpp::detail { template < typename T > - struct value_equals_traits; + struct equals_traits; template < typename T > - concept has_value_equals_traits = requires(const T& l, const T& r) { - { value_equals_traits{}(l, r) } -> stdex::convertible_to; + concept has_equals_traits = requires(const T& l, const T& r) { + { equals_traits{}(l, r) } -> stdex::convertible_to; }; } @@ -26,7 +26,7 @@ namespace meta_hpp::detail requires requires(const T& l, const T& r) { { l == r } -> stdex::convertible_to; } - struct value_equals_traits { + struct equals_traits { bool operator()(const T& l, const T& r) const { return l == r; } diff --git a/headers/meta.hpp/meta_utilities/value_traits/index_traits.hpp b/headers/meta.hpp/meta_detail/value_traits/index_traits.hpp similarity index 75% rename from headers/meta.hpp/meta_utilities/value_traits/index_traits.hpp rename to headers/meta.hpp/meta_detail/value_traits/index_traits.hpp index 2382f84..22c5cce 100644 --- a/headers/meta.hpp/meta_utilities/value_traits/index_traits.hpp +++ b/headers/meta.hpp/meta_detail/value_traits/index_traits.hpp @@ -7,58 +7,58 @@ #pragma once #include "../../meta_base.hpp" -#include "../../meta_utilities.hpp" +#include "../../meta_value.hpp" namespace meta_hpp::detail { template < typename T > - struct value_index_traits; + struct index_traits; template < typename T > - concept has_value_index_traits = requires(const T& v, std::size_t i) { - { value_index_traits{}(v, i) } -> stdex::convertible_to; + concept has_index_traits = requires(const T& v, std::size_t i) { + { index_traits{}(v, i) } -> stdex::convertible_to; }; } namespace meta_hpp::detail { template < stdex::copy_constructible T > - struct value_index_traits { + struct index_traits { value operator()(T* v, std::size_t i) const { return value{*(v + i)}; } }; template < stdex::copy_constructible T > - struct value_index_traits { + struct index_traits { value operator()(const T* v, std::size_t i) const { return value{*(v + i)}; } }; template < stdex::copy_constructible T, std::size_t Size > - struct value_index_traits> { + struct index_traits> { value operator()(const std::array& v, std::size_t i) const { return value{v[i]}; } }; template < stdex::copy_constructible T, std::size_t Extent > - struct value_index_traits> { + struct index_traits> { value operator()(const std::span& v, std::size_t i) const { return value{v[i]}; } }; template < stdex::copy_constructible T, typename Traits, typename Allocator > - struct value_index_traits> { + struct index_traits> { value operator()(const std::basic_string& v, std::size_t i) const { return value{v[i]}; } }; template < stdex::copy_constructible T, typename Allocator > - struct value_index_traits> { + struct index_traits> { value operator()(const std::vector& v, std::size_t i) { return value{v[i]}; } diff --git a/headers/meta.hpp/meta_utilities/value_traits/istream_traits.hpp b/headers/meta.hpp/meta_detail/value_traits/istream_traits.hpp similarity index 75% rename from headers/meta.hpp/meta_utilities/value_traits/istream_traits.hpp rename to headers/meta.hpp/meta_detail/value_traits/istream_traits.hpp index 9d0f333..112a98a 100644 --- a/headers/meta.hpp/meta_utilities/value_traits/istream_traits.hpp +++ b/headers/meta.hpp/meta_detail/value_traits/istream_traits.hpp @@ -7,16 +7,16 @@ #pragma once #include "../../meta_base.hpp" -#include "../../meta_utilities.hpp" +#include "../../meta_value.hpp" namespace meta_hpp::detail { template < typename T > - struct value_istream_traits; + struct istream_traits; template < typename T > - concept has_value_istream_traits = requires(std::istream& is, T& v) { - { value_istream_traits{}(is, v) } -> stdex::convertible_to; + concept has_istream_traits = requires(std::istream& is, T& v) { + { istream_traits{}(is, v) } -> stdex::convertible_to; }; } @@ -26,7 +26,7 @@ namespace meta_hpp::detail requires requires(std::istream& is, T& v) { { is >> v } -> stdex::convertible_to; } - struct value_istream_traits { + struct istream_traits { std::istream& operator()(std::istream& is, T& v) const { return is >> v; } diff --git a/headers/meta.hpp/meta_utilities/value_traits/less_traits.hpp b/headers/meta.hpp/meta_detail/value_traits/less_traits.hpp similarity index 76% rename from headers/meta.hpp/meta_utilities/value_traits/less_traits.hpp rename to headers/meta.hpp/meta_detail/value_traits/less_traits.hpp index e79e1b2..ac39ce4 100644 --- a/headers/meta.hpp/meta_utilities/value_traits/less_traits.hpp +++ b/headers/meta.hpp/meta_detail/value_traits/less_traits.hpp @@ -7,16 +7,16 @@ #pragma once #include "../../meta_base.hpp" -#include "../../meta_utilities.hpp" +#include "../../meta_value.hpp" namespace meta_hpp::detail { template < typename T > - struct value_less_traits; + struct less_traits; template < typename T > - concept has_value_less_traits = requires(const T& l, const T& r) { - { value_less_traits{}(l, r) } -> stdex::convertible_to; + concept has_less_traits = requires(const T& l, const T& r) { + { less_traits{}(l, r) } -> stdex::convertible_to; }; } @@ -26,7 +26,7 @@ namespace meta_hpp::detail requires requires(const T& l, const T& r) { { l < r } -> stdex::convertible_to; } - struct value_less_traits { + struct less_traits { bool operator()(const T& l, const T& r) const { return l < r; } diff --git a/headers/meta.hpp/meta_utilities/value_traits/ostream_traits.hpp b/headers/meta.hpp/meta_detail/value_traits/ostream_traits.hpp similarity index 75% rename from headers/meta.hpp/meta_utilities/value_traits/ostream_traits.hpp rename to headers/meta.hpp/meta_detail/value_traits/ostream_traits.hpp index 95f8601..ee8b701 100644 --- a/headers/meta.hpp/meta_utilities/value_traits/ostream_traits.hpp +++ b/headers/meta.hpp/meta_detail/value_traits/ostream_traits.hpp @@ -7,16 +7,16 @@ #pragma once #include "../../meta_base.hpp" -#include "../../meta_utilities.hpp" +#include "../../meta_value.hpp" namespace meta_hpp::detail { template < typename T > - struct value_ostream_traits; + struct ostream_traits; template < typename T > - concept has_value_ostream_traits = requires(std::ostream& os, const T& v) { - { value_ostream_traits{}(os, v) } -> stdex::convertible_to; + concept has_ostream_traits = requires(std::ostream& os, const T& v) { + { ostream_traits{}(os, v) } -> stdex::convertible_to; }; } @@ -26,7 +26,7 @@ namespace meta_hpp::detail requires requires(std::ostream& os, const T& v) { { os << v } -> stdex::convertible_to; } - struct value_ostream_traits { + struct ostream_traits { std::ostream& operator()(std::ostream& os, const T& v) const { return os << v; } diff --git a/headers/meta.hpp/meta_utilities/arg.hpp b/headers/meta.hpp/meta_detail/value_utilities/arg.hpp similarity index 69% rename from headers/meta.hpp/meta_utilities/arg.hpp rename to headers/meta.hpp/meta_detail/value_utilities/arg.hpp index 9181066..efff645 100644 --- a/headers/meta.hpp/meta_utilities/arg.hpp +++ b/headers/meta.hpp/meta_detail/value_utilities/arg.hpp @@ -6,76 +6,140 @@ #pragma once -#include "../meta_base.hpp" -#include "../meta_utilities.hpp" +#include "../../meta_base.hpp" +#include "../../meta_value.hpp" + +#include "utraits.hpp" namespace meta_hpp::detail { - template < decay_value_kind T > - // NOLINTNEXTLINE(readability-named-parameter) - arg_base::arg_base(T&&) - : arg_base{type_list{}} {} + class arg_base { + public: + enum class ref_types { + lvalue, + const_lvalue, + rvalue, + const_rvalue, + }; + public: + arg_base() = delete; - template < decay_non_uvalue_kind T > - // NOLINTNEXTLINE(readability-named-parameter) - arg_base::arg_base(T&&) - : arg_base{type_list{}} {} + arg_base(arg_base&&) = default; + arg_base(const arg_base&) = default; - template < arg_lvalue_ref_kind T > - // NOLINTNEXTLINE(readability-named-parameter) - arg_base::arg_base(type_list) - : ref_type_{std::is_const_v> - ? ref_types::const_lvalue - : ref_types::lvalue} - , raw_type_{resolve_type>()} {} + arg_base& operator=(arg_base&&) = delete; + arg_base& operator=(const arg_base&) = delete; - template < arg_rvalue_ref_kind T > - // NOLINTNEXTLINE(readability-named-parameter) - arg_base::arg_base(type_list) - : ref_type_{std::is_const_v> - ? ref_types::const_rvalue - : ref_types::rvalue} - , raw_type_{resolve_type>()} {} + virtual ~arg_base() = default; - inline arg_base::arg_base(value& v) - : ref_type_{ref_types::lvalue} - , raw_type_{v.get_type()} {} + template < decay_value_kind T > + // NOLINTNEXTLINE(readability-named-parameter) + explicit arg_base(T&&) + : arg_base{type_list{}} {} - inline arg_base::arg_base(const value& v) - : ref_type_{ref_types::const_lvalue} - , raw_type_{v.get_type()} {} + template < decay_non_uvalue_kind T > + // NOLINTNEXTLINE(readability-named-parameter) + explicit arg_base(T&&) + : arg_base{type_list{}} {} - inline arg_base::arg_base(value&& v) - : ref_type_{ref_types::rvalue} - , raw_type_{v.get_type()} {} + template < arg_lvalue_ref_kind T > + // NOLINTNEXTLINE(readability-named-parameter) + explicit arg_base(type_list) + : ref_type_{std::is_const_v> + ? ref_types::const_lvalue + : ref_types::lvalue} + , raw_type_{resolve_type>()} {} - inline arg_base::arg_base(const value&& v) - : ref_type_{ref_types::const_rvalue} - , raw_type_{v.get_type()} {} + template < arg_rvalue_ref_kind T > + // NOLINTNEXTLINE(readability-named-parameter) + explicit arg_base(type_list) + : ref_type_{std::is_const_v> + ? ref_types::const_rvalue + : ref_types::rvalue} + , raw_type_{resolve_type>()} {} - inline bool arg_base::is_const() const noexcept { - return ref_type_ == ref_types::const_lvalue - || ref_type_ == ref_types::const_rvalue; - } + explicit arg_base(value& v) + : ref_type_{ref_types::lvalue} + , raw_type_{v.get_type()} {} - inline bool arg_base::is_lvalue() const noexcept { - return ref_type_ == ref_types::lvalue - || ref_type_ == ref_types::const_lvalue; - } + explicit arg_base(const value& v) + : ref_type_{ref_types::const_lvalue} + , raw_type_{v.get_type()} {} - inline bool arg_base::is_rvalue() const noexcept { - return ref_type_ == ref_types::rvalue - || ref_type_ == ref_types::const_rvalue; - } + explicit arg_base(value&& v) + : ref_type_{ref_types::rvalue} + , raw_type_{v.get_type()} {} - inline arg_base::ref_types arg_base::get_ref_type() const noexcept { - return ref_type_; - } + explicit arg_base(const value&& v) + : ref_type_{ref_types::const_rvalue} + , raw_type_{v.get_type()} {} - inline const any_type& arg_base::get_raw_type() const noexcept { - return raw_type_; - } + [[nodiscard]] bool is_const() const noexcept { + return ref_type_ == ref_types::const_lvalue + || ref_type_ == ref_types::const_rvalue; + } + [[nodiscard]] bool is_lvalue() const noexcept { + return ref_type_ == ref_types::lvalue + || ref_type_ == ref_types::const_lvalue; + } + + [[nodiscard]] bool is_rvalue() const noexcept { + return ref_type_ == ref_types::rvalue + || ref_type_ == ref_types::const_rvalue; + } + + [[nodiscard]] ref_types get_ref_type() const noexcept { + return ref_type_; + } + + [[nodiscard]] const any_type& get_raw_type() const noexcept { + return raw_type_; + } + + template < typename To > + [[nodiscard]] bool can_cast_to() const noexcept; + private: + ref_types ref_type_{}; + any_type raw_type_{}; + }; +} + +namespace meta_hpp::detail +{ + class arg final : public arg_base { + public: + arg() = delete; + + arg(arg&&) = default; + arg(const arg&) = default; + + arg& operator=(arg&&) = delete; + arg& operator=(const arg&) = delete; + + ~arg() override = default; + + template < decay_value_kind T > + explicit arg(T&& v) + : arg_base{std::forward(v)} + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast) + , data_{const_cast(v.data())} {} + + template < decay_non_uvalue_kind T > + explicit arg(T&& v) + : arg_base{std::forward(v)} + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast) + , data_{const_cast*>(std::addressof(v))} {} + + template < typename To > + [[nodiscard]] To cast() const; + private: + void* data_{}; + }; +} + +namespace meta_hpp::detail +{ template < typename To > // NOLINTNEXTLINE(readability-function-cognitive-complexity) bool arg_base::can_cast_to() const noexcept { @@ -182,18 +246,6 @@ namespace meta_hpp::detail namespace meta_hpp::detail { - template < decay_value_kind T > - arg::arg(T&& v) - : arg_base{std::forward(v)} - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast) - , data_{const_cast(v.data())} {} - - template < decay_non_uvalue_kind T > - arg::arg(T&& v) - : arg_base{std::forward(v)} - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast) - , data_{const_cast*>(std::addressof(v))} {} - template < typename To > // NOLINTNEXTLINE(readability-function-cognitive-complexity) To arg::cast() const { @@ -227,7 +279,7 @@ namespace meta_hpp::detail const class_type& to_data_class = to_data_type.as_class(); const class_type& from_data_class = from_data_type.as_class(); - void* to_ptr = detail::pointer_upcast(data_, from_data_class, to_data_class); + void* to_ptr = pointer_upcast(data_, from_data_class, to_data_class); return static_cast(to_ptr); } } @@ -249,7 +301,7 @@ namespace meta_hpp::detail const class_type& to_data_class = to_data_type.as_class(); const class_type& from_data_class = from_data_type.as_class(); - void* to_ptr = detail::pointer_upcast(*from_data_ptr, from_data_class, to_data_class); + void* to_ptr = pointer_upcast(*from_data_ptr, from_data_class, to_data_class); return static_cast(to_ptr); } } @@ -270,7 +322,7 @@ namespace meta_hpp::detail const class_type& to_class = to_type.as_class(); const class_type& from_class = from_type.as_class(); - void* to_ptr = detail::pointer_upcast(data_, from_class, to_class); + void* to_ptr = pointer_upcast(data_, from_class, to_class); if constexpr ( std::is_lvalue_reference_v ) { return *static_cast(to_ptr); diff --git a/headers/meta.hpp/meta_detail/value_utilities/inst.hpp b/headers/meta.hpp/meta_detail/value_utilities/inst.hpp new file mode 100644 index 0000000..e1dc7eb --- /dev/null +++ b/headers/meta.hpp/meta_detail/value_utilities/inst.hpp @@ -0,0 +1,210 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../../meta_base.hpp" +#include "../../meta_value.hpp" + +#include "utraits.hpp" + +namespace meta_hpp::detail +{ + class inst_base { + public: + enum class ref_types { + lvalue, + const_lvalue, + rvalue, + const_rvalue, + }; + public: + inst_base() = delete; + + inst_base(inst_base&&) = default; + inst_base(const inst_base&) = default; + + inst_base& operator=(inst_base&&) = delete; + inst_base& operator=(const inst_base&) = delete; + + virtual ~inst_base() = default; + + template < decay_value_kind T > + // NOLINTNEXTLINE(readability-named-parameter) + explicit inst_base(T&&) + : inst_base{type_list{}} {} + + template < decay_non_uvalue_kind T > + // NOLINTNEXTLINE(readability-named-parameter) + explicit inst_base(T&&) + : inst_base{type_list{}} {} + + template < inst_class_lvalue_ref_kind T > + // NOLINTNEXTLINE(readability-named-parameter) + explicit inst_base(type_list) + : ref_type_{std::is_const_v> + ? ref_types::const_lvalue + : ref_types::lvalue} + , raw_type_{resolve_type>()} {} + + template < inst_class_rvalue_ref_kind T > + // NOLINTNEXTLINE(readability-named-parameter) + explicit inst_base(type_list) + : ref_type_{std::is_const_v> + ? ref_types::const_rvalue + : ref_types::rvalue} + , raw_type_{resolve_type>()} {} + + explicit inst_base(value& v) + : ref_type_{ref_types::lvalue} + , raw_type_{v.get_type()} {} + + explicit inst_base(const value& v) + : ref_type_{ref_types::const_lvalue} + , raw_type_{v.get_type()} {} + + explicit inst_base(value&& v) + : ref_type_{ref_types::rvalue} + , raw_type_{v.get_type()} {} + + explicit inst_base(const value&& v) + : ref_type_{ref_types::const_rvalue} + , raw_type_{v.get_type()} {} + + [[nodiscard]] bool is_const() const noexcept { + return ref_type_ == ref_types::const_lvalue + || ref_type_ == ref_types::const_rvalue; + } + + [[nodiscard]] bool is_lvalue() const noexcept { + return ref_type_ == ref_types::lvalue + || ref_type_ == ref_types::const_lvalue; + } + + [[nodiscard]] bool is_rvalue() const noexcept { + return ref_type_ == ref_types::rvalue + || ref_type_ == ref_types::const_rvalue; + } + + [[nodiscard]] ref_types get_ref_type() const noexcept { + return ref_type_; + } + + [[nodiscard]] const any_type& get_raw_type() const noexcept { + return raw_type_; + } + + template < inst_class_ref_kind Q > + [[nodiscard]] bool can_cast_to() const noexcept; + private: + ref_types ref_type_{}; + any_type raw_type_{}; + }; +} + +namespace meta_hpp::detail +{ + class inst final : public inst_base { + public: + inst() = delete; + + inst(inst&&) = default; + inst(const inst&) = default; + + inst& operator=(inst&&) = delete; + inst& operator=(const inst&) = delete; + + ~inst() override = default; + + template < decay_value_kind T > + explicit inst(T&& v) + : inst_base{std::forward(v)} + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast) + , data_{const_cast(v.data())} {} + + template < decay_non_uvalue_kind T > + explicit inst(T&& v) + : inst_base{std::forward(v)} + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast) + , data_{const_cast*>(std::addressof(v))} {} + + template < inst_class_ref_kind Q > + [[nodiscard]] decltype(auto) cast() const; + private: + void* data_{}; + }; +} + +namespace meta_hpp::detail +{ + template < inst_class_ref_kind Q > + bool inst_base::can_cast_to() const noexcept { + using inst_class = typename inst_traits::class_type; + using inst_method = typename inst_traits::method_type; + + const any_type& from_type = get_raw_type(); + const any_type& to_type = resolve_type(); + + const auto is_a = [](const any_type& base, const any_type& derived){ + return (base == derived) + || (base.is_class() && derived.is_class() && base.as_class().is_base_of(derived.as_class())); + }; + + const auto is_invocable = [this](){ + switch ( get_ref_type() ) { + case ref_types::lvalue: + return std::is_invocable_v; + case ref_types::const_lvalue: + return std::is_invocable_v; + case ref_types::rvalue: + return std::is_invocable_v; + case ref_types::const_rvalue: + return std::is_invocable_v; + default: + return false; + } + }; + + return is_a(to_type, from_type) && is_invocable(); + } +} + +namespace meta_hpp::detail +{ + template < inst_class_ref_kind Q > + decltype(auto) inst::cast() const { + if ( !can_cast_to() ) { + throw std::logic_error("bad instance cast"); + } + + using inst_class_cv = std::remove_reference_t; + using inst_class = std::remove_cv_t; + + const any_type& from_type = get_raw_type(); + const any_type& to_type = resolve_type(); + + if ( from_type.is_class() && to_type.is_class() ) { + const class_type& from_class = from_type.as_class(); + const class_type& to_class = to_type.as_class(); + + void* to_ptr = pointer_upcast(data_, from_class, to_class); + + if constexpr ( !std::is_reference_v ) { + return *static_cast(to_ptr); + } + + if constexpr ( std::is_lvalue_reference_v ) { + return *static_cast(to_ptr); + } + + if constexpr ( std::is_rvalue_reference_v ) { + return std::move(*static_cast(to_ptr)); + } + } + + throw std::logic_error("bad instance cast"); + } +} diff --git a/headers/meta.hpp/meta_detail/value_utilities/utraits.hpp b/headers/meta.hpp/meta_detail/value_utilities/utraits.hpp new file mode 100644 index 0000000..5e1b18c --- /dev/null +++ b/headers/meta.hpp/meta_detail/value_utilities/utraits.hpp @@ -0,0 +1,145 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../../meta_base.hpp" +#include "../../meta_value.hpp" + +namespace meta_hpp::detail +{ + template < typename T > + concept uvalue_kind = + stdex::same_as || + stdex::same_as || + stdex::same_as || + stdex::same_as || + stdex::same_as; + + template < typename T > + concept decay_uvalue_kind = uvalue_kind>; + + template < typename T > + concept decay_non_uvalue_kind = !decay_uvalue_kind; +} + +namespace meta_hpp::detail +{ + template < typename T > + concept arg_lvalue_ref_kind = + (decay_non_uvalue_kind) && + (std::is_lvalue_reference_v); + + template < typename T > + concept arg_rvalue_ref_kind = + (decay_non_uvalue_kind) && + (!std::is_reference_v || std::is_rvalue_reference_v); +} + +namespace meta_hpp::detail +{ + template < typename T > + concept inst_class_ref_kind = + (std::is_class_v) || + (std::is_reference_v && std::is_class_v>); + + template < typename T > + concept inst_class_lvalue_ref_kind = + (decay_non_uvalue_kind) && + (std::is_lvalue_reference_v && std::is_class_v>); + + template < typename T > + concept inst_class_rvalue_ref_kind = + (decay_non_uvalue_kind) && + (std::is_class_v || (std::is_rvalue_reference_v && std::is_class_v>)); +} + +namespace meta_hpp::detail +{ + namespace impl + { + template < inst_class_ref_kind Q, bool is_const, bool is_lvalue, bool is_rvalue > + struct inst_traits_impl; + + template < inst_class_ref_kind Q > + struct inst_traits_impl { + using class_type = std::remove_cvref_t; + using method_type = void(class_type::*)(); + }; + + template < inst_class_ref_kind Q > + struct inst_traits_impl { + using class_type = std::remove_cvref_t; + using method_type = void(class_type::*)() &; + }; + + template < inst_class_ref_kind Q > + struct inst_traits_impl { + using class_type = std::remove_cvref_t; + using method_type = void(class_type::*)() &&; + }; + + template < inst_class_ref_kind Q > + struct inst_traits_impl { + using class_type = std::remove_cvref_t; + using method_type = void(class_type::*)() const; + }; + + template < inst_class_ref_kind Q > + struct inst_traits_impl { + using class_type = std::remove_cvref_t; + using method_type = void(class_type::*)() const &; + }; + + template < inst_class_ref_kind Q > + struct inst_traits_impl { + using class_type = std::remove_cvref_t; + using method_type = void(class_type::*)() const &&; + }; + } + + template < inst_class_ref_kind Q > + struct inst_traits final : impl::inst_traits_impl::is_const, + cvref_traits::is_lvalue, + cvref_traits::is_rvalue> {}; +} + +namespace meta_hpp::detail +{ + [[nodiscard]] inline void* pointer_upcast(void* ptr, const class_type& from, const class_type& to) { + if ( nullptr == ptr || !from || !to ) { + return nullptr; + } + + if ( from == to ) { + return ptr; + } + + for ( auto&& [base, base_info] : type_access(from)->bases_info ) { + if ( base == to ) { + return base_info.upcast(ptr); + } + + if ( base.is_derived_from(to) ) { + return pointer_upcast(base_info.upcast(ptr), base, to); + } + } + + return nullptr; + } + + template < class_kind To, class_kind From > + [[nodiscard]] To* pointer_upcast(From* ptr) { + return static_cast(pointer_upcast(ptr, resolve_type(), resolve_type())); + } + + template < class_kind To, class_kind From > + [[nodiscard]] const To* pointer_upcast(const From* ptr) { + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast) + return pointer_upcast(const_cast(ptr)); + } +} diff --git a/headers/meta.hpp/meta_indices.hpp b/headers/meta.hpp/meta_indices.hpp new file mode 100644 index 0000000..581de66 --- /dev/null +++ b/headers/meta.hpp/meta_indices.hpp @@ -0,0 +1,150 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "meta_base.hpp" +#include "meta_types.hpp" + +namespace meta_hpp +{ + class ctor_index final { + public: + ctor_index() = delete; + + template < detail::class_kind Class, typename... Args > + [[nodiscard]] static ctor_index make(); + + [[nodiscard]] const ctor_type& get_type() const noexcept; + private: + explicit ctor_index(ctor_type type); + friend bool operator<(const ctor_index& l, const ctor_index& r) noexcept; + friend bool operator==(const ctor_index& l, const ctor_index& r) noexcept; + private: + ctor_type type_; + }; + + class dtor_index final { + public: + dtor_index() = delete; + + template < detail::class_kind Class > + [[nodiscard]] static dtor_index make(); + + [[nodiscard]] const dtor_type& get_type() const noexcept; + private: + explicit dtor_index(dtor_type type); + friend bool operator<(const dtor_index& l, const dtor_index& r) noexcept; + friend bool operator==(const dtor_index& l, const dtor_index& r) noexcept; + private: + dtor_type type_; + }; + + class evalue_index final { + public: + evalue_index() = delete; + + template < detail::enum_kind Enum > + [[nodiscard]] static evalue_index make(std::string name); + + [[nodiscard]] const enum_type& get_type() const noexcept; + [[nodiscard]] const std::string& get_name() const noexcept; + private: + explicit evalue_index(enum_type type, std::string name); + friend bool operator<(const evalue_index& l, const evalue_index& r) noexcept; + friend bool operator==(const evalue_index& l, const evalue_index& r) noexcept; + private: + enum_type type_; + std::string name_; + }; + + class function_index final { + public: + function_index() = delete; + + template < detail::function_kind Function > + [[nodiscard]] static function_index make(std::string name); + + [[nodiscard]] const function_type& get_type() const noexcept; + [[nodiscard]] const std::string& get_name() const noexcept; + private: + explicit function_index(function_type type, std::string name); + friend bool operator<(const function_index& l, const function_index& r) noexcept; + friend bool operator==(const function_index& l, const function_index& r) noexcept; + private: + function_type type_; + std::string name_; + }; + + class member_index final { + public: + member_index() = delete; + + template < detail::member_kind Member > + [[nodiscard]] static member_index make(std::string name); + + [[nodiscard]] const member_type& get_type() const noexcept; + [[nodiscard]] const std::string& get_name() const noexcept; + private: + explicit member_index(member_type type, std::string name); + friend bool operator<(const member_index& l, const member_index& r) noexcept; + friend bool operator==(const member_index& l, const member_index& r) noexcept; + private: + member_type type_; + std::string name_; + }; + + class method_index final { + public: + method_index() = delete; + + template < detail::method_kind Method > + [[nodiscard]] static method_index make(std::string name); + + [[nodiscard]] const method_type& get_type() const noexcept; + [[nodiscard]] const std::string& get_name() const noexcept; + private: + explicit method_index(method_type type, std::string name); + friend bool operator<(const method_index& l, const method_index& r) noexcept; + friend bool operator==(const method_index& l, const method_index& r) noexcept; + private: + method_type type_; + std::string name_; + }; + + class scope_index final { + public: + scope_index() = delete; + + [[nodiscard]] static scope_index make(std::string name); + + [[nodiscard]] const std::string& get_name() const noexcept; + private: + explicit scope_index(std::string name); + friend bool operator<(const scope_index& l, const scope_index& r) noexcept; + friend bool operator==(const scope_index& l, const scope_index& r) noexcept; + private: + std::string name_; + }; + + class variable_index final { + public: + variable_index() = delete; + + template < detail::pointer_kind Pointer > + [[nodiscard]] static variable_index make(std::string name); + + [[nodiscard]] const pointer_type& get_type() const noexcept; + [[nodiscard]] const std::string& get_name() const noexcept; + private: + explicit variable_index(pointer_type type, std::string name); + friend bool operator<(const variable_index& l, const variable_index& r) noexcept; + friend bool operator==(const variable_index& l, const variable_index& r) noexcept; + private: + pointer_type type_; + std::string name_; + }; +} diff --git a/headers/meta.hpp/meta_indices/ctor_index.hpp b/headers/meta.hpp/meta_indices/ctor_index.hpp new file mode 100644 index 0000000..0d83eb6 --- /dev/null +++ b/headers/meta.hpp/meta_indices/ctor_index.hpp @@ -0,0 +1,36 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_indices.hpp" +#include "../meta_types.hpp" + +#include "../meta_detail/type_registry.hpp" + +namespace meta_hpp +{ + inline ctor_index::ctor_index(ctor_type type) + : type_{std::move(type)} {} + + template < detail::class_kind Class, typename... Args > + ctor_index ctor_index::make() { + return ctor_index{detail::resolve_ctor_type()}; + } + + inline const ctor_type& ctor_index::get_type() const noexcept { + return type_; + } + + inline bool operator<(const ctor_index& l, const ctor_index& r) noexcept { + return l.type_ < r.type_; + } + + inline bool operator==(const ctor_index& l, const ctor_index& r) noexcept { + return l.type_ == r.type_; + } +} diff --git a/headers/meta.hpp/meta_indices/dtor_index.hpp b/headers/meta.hpp/meta_indices/dtor_index.hpp new file mode 100644 index 0000000..e62828d --- /dev/null +++ b/headers/meta.hpp/meta_indices/dtor_index.hpp @@ -0,0 +1,36 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_indices.hpp" +#include "../meta_types.hpp" + +#include "../meta_detail/type_registry.hpp" + +namespace meta_hpp +{ + inline dtor_index::dtor_index(dtor_type type) + : type_{std::move(type)} {} + + template < detail::class_kind Class > + dtor_index dtor_index::make() { + return dtor_index{detail::resolve_dtor_type()}; + } + + inline const dtor_type& dtor_index::get_type() const noexcept { + return type_; + } + + inline bool operator<(const dtor_index& l, const dtor_index& r) noexcept { + return l.type_ < r.type_; + } + + inline bool operator==(const dtor_index& l, const dtor_index& r) noexcept { + return l.type_ == r.type_; + } +} diff --git a/headers/meta.hpp/meta_indices/evalue_index.hpp b/headers/meta.hpp/meta_indices/evalue_index.hpp new file mode 100644 index 0000000..8381bc8 --- /dev/null +++ b/headers/meta.hpp/meta_indices/evalue_index.hpp @@ -0,0 +1,41 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_indices.hpp" +#include "../meta_types.hpp" + +#include "../meta_detail/type_registry.hpp" + +namespace meta_hpp +{ + inline evalue_index::evalue_index(enum_type type, std::string name) + : type_{std::move(type)} + , name_{std::move(name)} {} + + template < detail::enum_kind Enum > + evalue_index evalue_index::make(std::string name) { + return evalue_index{detail::resolve_type(), std::move(name)}; + } + + inline const enum_type& evalue_index::get_type() const noexcept { + return type_; + } + + inline const std::string& evalue_index::get_name() const noexcept { + return name_; + } + + inline bool operator<(const evalue_index& l, const evalue_index& r) noexcept { + return l.type_ < r.type_ || (l.type_ == r.type_ && l.name_ < r.name_); + } + + inline bool operator==(const evalue_index& l, const evalue_index& r) noexcept { + return l.type_ == r.type_ && l.name_ == r.name_; + } +} diff --git a/headers/meta.hpp/meta_indices/function_index.hpp b/headers/meta.hpp/meta_indices/function_index.hpp new file mode 100644 index 0000000..a63aaad --- /dev/null +++ b/headers/meta.hpp/meta_indices/function_index.hpp @@ -0,0 +1,41 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_indices.hpp" +#include "../meta_types.hpp" + +#include "../meta_detail/type_registry.hpp" + +namespace meta_hpp +{ + inline function_index::function_index(function_type type, std::string name) + : type_{std::move(type)} + , name_{std::move(name)} {} + + template < detail::function_kind Function > + function_index function_index::make(std::string name) { + return function_index{detail::resolve_type(), std::move(name)}; + } + + inline const function_type& function_index::get_type() const noexcept { + return type_; + } + + inline const std::string& function_index::get_name() const noexcept { + return name_; + } + + inline bool operator<(const function_index& l, const function_index& r) noexcept { + return l.type_ < r.type_ || (l.type_ == r.type_ && l.name_ < r.name_); + } + + inline bool operator==(const function_index& l, const function_index& r) noexcept { + return l.type_ == r.type_ && l.name_ == r.name_; + } +} diff --git a/headers/meta.hpp/meta_indices/member_index.hpp b/headers/meta.hpp/meta_indices/member_index.hpp new file mode 100644 index 0000000..3101f0f --- /dev/null +++ b/headers/meta.hpp/meta_indices/member_index.hpp @@ -0,0 +1,41 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_indices.hpp" +#include "../meta_types.hpp" + +#include "../meta_detail/type_registry.hpp" + +namespace meta_hpp +{ + inline member_index::member_index(member_type type, std::string name) + : type_{std::move(type)} + , name_{std::move(name)} {} + + template < detail::member_kind Member > + member_index member_index::make(std::string name) { + return member_index{detail::resolve_type(), std::move(name)}; + } + + inline const member_type& member_index::get_type() const noexcept { + return type_; + } + + inline const std::string& member_index::get_name() const noexcept { + return name_; + } + + inline bool operator<(const member_index& l, const member_index& r) noexcept { + return l.type_ < r.type_ || (l.type_ == r.type_ && l.name_ < r.name_); + } + + inline bool operator==(const member_index& l, const member_index& r) noexcept { + return l.type_ == r.type_ && l.name_ == r.name_; + } +} diff --git a/headers/meta.hpp/meta_indices/method_index.hpp b/headers/meta.hpp/meta_indices/method_index.hpp new file mode 100644 index 0000000..8ad0a3a --- /dev/null +++ b/headers/meta.hpp/meta_indices/method_index.hpp @@ -0,0 +1,41 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_indices.hpp" +#include "../meta_types.hpp" + +#include "../meta_detail/type_registry.hpp" + +namespace meta_hpp +{ + inline method_index::method_index(method_type type, std::string name) + : type_{std::move(type)} + , name_{std::move(name)} {} + + template < detail::method_kind Method > + method_index method_index::make(std::string name) { + return method_index{detail::resolve_type(), std::move(name)}; + } + + inline const method_type& method_index::get_type() const noexcept { + return type_; + } + + inline const std::string& method_index::get_name() const noexcept { + return name_; + } + + inline bool operator<(const method_index& l, const method_index& r) noexcept { + return l.type_ < r.type_ || (l.type_ == r.type_ && l.name_ < r.name_); + } + + inline bool operator==(const method_index& l, const method_index& r) noexcept { + return l.type_ == r.type_ && l.name_ == r.name_; + } +} diff --git a/headers/meta.hpp/meta_indices/scope_index.hpp b/headers/meta.hpp/meta_indices/scope_index.hpp new file mode 100644 index 0000000..2beb83a --- /dev/null +++ b/headers/meta.hpp/meta_indices/scope_index.hpp @@ -0,0 +1,35 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_indices.hpp" +#include "../meta_states.hpp" + +#include "../meta_detail/type_registry.hpp" + +namespace meta_hpp +{ + inline scope_index::scope_index(std::string name) + : name_{std::move(name)} {} + + inline scope_index scope_index::make(std::string name) { + return scope_index{std::move(name)}; + } + + inline const std::string& scope_index::get_name() const noexcept { + return name_; + } + + inline bool operator<(const scope_index& l, const scope_index& r) noexcept { + return l.name_ < r.name_; + } + + inline bool operator==(const scope_index& l, const scope_index& r) noexcept { + return l.name_ == r.name_; + } +} diff --git a/headers/meta.hpp/meta_indices/variable_index.hpp b/headers/meta.hpp/meta_indices/variable_index.hpp new file mode 100644 index 0000000..1bc700f --- /dev/null +++ b/headers/meta.hpp/meta_indices/variable_index.hpp @@ -0,0 +1,41 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_indices.hpp" +#include "../meta_types.hpp" + +#include "../meta_detail/type_registry.hpp" + +namespace meta_hpp +{ + inline variable_index::variable_index(pointer_type type, std::string name) + : type_{std::move(type)} + , name_{std::move(name)} {} + + template < detail::pointer_kind Pointer > + variable_index variable_index::make(std::string name) { + return variable_index{detail::resolve_type(), std::move(name)}; + } + + inline const pointer_type& variable_index::get_type() const noexcept { + return type_; + } + + inline const std::string& variable_index::get_name() const noexcept { + return name_; + } + + inline bool operator<(const variable_index& l, const variable_index& r) noexcept { + return l.type_ < r.type_ || (l.type_ == r.type_ && l.name_ < r.name_); + } + + inline bool operator==(const variable_index& l, const variable_index& r) noexcept { + return l.type_ == r.type_ && l.name_ == r.name_; + } +} diff --git a/headers/meta.hpp/meta_states.hpp b/headers/meta.hpp/meta_states.hpp index 578024f..5d6f667 100644 --- a/headers/meta.hpp/meta_states.hpp +++ b/headers/meta.hpp/meta_states.hpp @@ -7,56 +7,11 @@ #pragma once #include "meta_base.hpp" +#include "meta_indices.hpp" #include "meta_types.hpp" -#include "meta_utilities.hpp" +#include "meta_value.hpp" -namespace meta_hpp -{ - namespace detail - { - template < typename T > - concept state_family = - std::is_same_v || - std::is_same_v || - std::is_same_v || - std::is_same_v || - std::is_same_v || - std::is_same_v || - std::is_same_v || - std::is_same_v; - } - - template < detail::state_family T, detail::state_family U > - [[nodiscard]] bool operator<(const T& l, const U& r) noexcept { - if ( !static_cast(r) ) { - return false; - } - - if ( !static_cast(l) ) { - return true; - } - - return l.get_index() < r.get_index(); - } - - template < detail::state_family T, detail::state_family U > - [[nodiscard]] bool operator==(const T& l, const U& r) noexcept { - if ( static_cast(l) != static_cast(r) ) { - return false; - } - - if ( !static_cast(l) ) { - return true; - } - - return l.get_index() == r.get_index(); - } - - template < detail::state_family T, detail::state_family U > - [[nodiscard]] bool operator!=(const T& l, const U& r) noexcept { - return !(l == r); - } -} +#include "meta_detail/state_family.hpp" namespace meta_hpp { @@ -97,33 +52,33 @@ namespace meta_hpp template < typename Policy > concept ctor_policy_kind = - detail::stdex::same_as || - detail::stdex::same_as || - detail::stdex::same_as; + stdex::same_as || + stdex::same_as || + stdex::same_as; template < typename Policy > concept function_policy_kind = - detail::stdex::same_as || - detail::stdex::same_as || - detail::stdex::same_as; + stdex::same_as || + stdex::same_as || + stdex::same_as; template < typename Policy > concept member_policy_kind = - detail::stdex::same_as || - detail::stdex::same_as || - detail::stdex::same_as; + stdex::same_as || + stdex::same_as || + stdex::same_as; template < typename Policy > concept method_policy_kind = - detail::stdex::same_as || - detail::stdex::same_as || - detail::stdex::same_as; + stdex::same_as || + stdex::same_as || + stdex::same_as; template < typename Policy > concept variable_policy_kind = - detail::stdex::same_as || - detail::stdex::same_as || - detail::stdex::same_as; + stdex::same_as || + stdex::same_as || + stdex::same_as; } namespace meta_hpp @@ -152,6 +107,7 @@ namespace meta_hpp [[nodiscard]] bool is_invocable_with(Args&&... args) const noexcept; private: detail::ctor_state_ptr state_; + friend auto detail::state_access(const ctor&); }; class dtor final { @@ -178,6 +134,7 @@ namespace meta_hpp [[nodiscard]] bool is_invocable_with(Arg&& ptr) const noexcept; private: detail::dtor_state_ptr state_; + friend auto detail::state_access(const dtor&); }; class evalue final { @@ -196,6 +153,7 @@ namespace meta_hpp [[nodiscard]] const value& get_underlying_value() const noexcept; private: detail::evalue_state_ptr state_; + friend auto detail::state_access(const evalue&); }; class function final { @@ -223,6 +181,7 @@ namespace meta_hpp [[nodiscard]] bool is_invocable_with(Args&&... args) const noexcept; private: detail::function_state_ptr state_; + friend auto detail::state_access(const function&); }; class member final { @@ -262,6 +221,7 @@ namespace meta_hpp [[nodiscard]] bool is_settable_with(Instance&& instance, Value&& value) const noexcept; private: detail::member_state_ptr state_; + friend auto detail::state_access(const member&); }; class method final { @@ -289,6 +249,7 @@ namespace meta_hpp [[nodiscard]] bool is_invocable_with(Instance&& instance, Args&&... args) const noexcept; private: detail::method_state_ptr state_; + friend auto detail::state_access(const method&); }; class scope final { @@ -318,6 +279,7 @@ namespace meta_hpp [[nodiscard]] function get_function_with(std::string_view name, std::initializer_list args) const noexcept; private: detail::scope_state_ptr state_; + friend auto detail::state_access(const scope&); }; class variable final { @@ -349,9 +311,44 @@ namespace meta_hpp [[nodiscard]] bool is_settable_with(Value&& value) const noexcept; private: detail::variable_state_ptr state_; + friend auto detail::state_access(const variable&); }; } +namespace meta_hpp +{ + template < detail::state_family T, detail::state_family U > + [[nodiscard]] bool operator<(const T& l, const U& r) noexcept { + if ( !static_cast(r) ) { + return false; + } + + if ( !static_cast(l) ) { + return true; + } + + return l.get_index() < r.get_index(); + } + + template < detail::state_family T, detail::state_family U > + [[nodiscard]] bool operator==(const T& l, const U& r) noexcept { + if ( static_cast(l) != static_cast(r) ) { + return false; + } + + if ( !static_cast(l) ) { + return true; + } + + return l.get_index() == r.get_index(); + } + + template < detail::state_family T, detail::state_family U > + [[nodiscard]] bool operator!=(const T& l, const U& r) noexcept { + return !(l == r); + } +} + namespace meta_hpp::detail { struct ctor_state final { @@ -437,7 +434,6 @@ namespace meta_hpp::detail variable_map variables{}; [[nodiscard]] static scope_state_ptr make(std::string name); - [[nodiscard]] static scope_state_ptr get_static(std::string_view name); }; struct variable_state final { @@ -454,10 +450,3 @@ namespace meta_hpp::detail [[nodiscard]] static variable_state_ptr make(std::string name, Pointer pointer); }; } - -namespace meta_hpp -{ - [[nodiscard]] inline scope resolve_scope(std::string_view name) { - return scope{detail::scope_state::get_static(name)}; - } -} diff --git a/headers/meta.hpp/meta_states/ctor.hpp b/headers/meta.hpp/meta_states/ctor.hpp index 9726713..e278d09 100644 --- a/headers/meta.hpp/meta_states/ctor.hpp +++ b/headers/meta.hpp/meta_states/ctor.hpp @@ -10,6 +10,7 @@ #include "../meta_states.hpp" #include "../meta_types/ctor_type.hpp" +#include "../meta_detail/value_utilities/arg.hpp" namespace meta_hpp::detail { @@ -95,9 +96,8 @@ namespace meta_hpp::detail { 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(ctor_state{ - .index{std::move(index)}, + .index{ctor_index::make()}, .invoke{make_ctor_invoke()}, .is_invocable_with{make_ctor_is_invocable_with()}, }); @@ -122,7 +122,7 @@ namespace meta_hpp } inline const ctor_type& ctor::get_type() const noexcept { - return state_->index.type; + return state_->index.get_type(); } template < typename... Args > diff --git a/headers/meta.hpp/meta_states/dtor.hpp b/headers/meta.hpp/meta_states/dtor.hpp index fdee5bd..06e6d22 100644 --- a/headers/meta.hpp/meta_states/dtor.hpp +++ b/headers/meta.hpp/meta_states/dtor.hpp @@ -10,6 +10,7 @@ #include "../meta_states.hpp" #include "../meta_types/dtor_type.hpp" +#include "../meta_detail/value_utilities/arg.hpp" namespace meta_hpp::detail { @@ -56,9 +57,8 @@ namespace meta_hpp::detail { template < class_kind Class > dtor_state_ptr dtor_state::make() { - dtor_index index{dtor_type_data::get_static()}; return std::make_shared(dtor_state{ - .index{std::move(index)}, + .index{dtor_index::make()}, .invoke{make_dtor_invoke()}, .is_invocable_with{make_dtor_is_invocable_with()}, }); @@ -83,7 +83,7 @@ namespace meta_hpp } inline const dtor_type& dtor::get_type() const noexcept { - return state_->index.type; + return state_->index.get_type(); } template < typename Arg > diff --git a/headers/meta.hpp/meta_states/evalue.hpp b/headers/meta.hpp/meta_states/evalue.hpp index 26e6f6e..a46da97 100644 --- a/headers/meta.hpp/meta_states/evalue.hpp +++ b/headers/meta.hpp/meta_states/evalue.hpp @@ -15,9 +15,8 @@ namespace meta_hpp::detail { template < enum_kind Enum > evalue_state_ptr evalue_state::make(std::string name, Enum evalue) { - evalue_index index{enum_type_data::get_static(), std::move(name)}; return std::make_shared(evalue_state{ - .index{std::move(index)}, + .index{evalue_index::make(std::move(name))}, .enum_value{value{evalue}}, .underlying_value{value{stdex::to_underlying(evalue)}}, }); @@ -42,11 +41,11 @@ namespace meta_hpp } inline const enum_type& evalue::get_type() const noexcept { - return state_->index.type; + return state_->index.get_type(); } inline const std::string& evalue::get_name() const noexcept { - return state_->index.name; + return state_->index.get_name(); } inline const value& evalue::get_value() const noexcept { diff --git a/headers/meta.hpp/meta_states/function.hpp b/headers/meta.hpp/meta_states/function.hpp index 3f7299f..d177062 100644 --- a/headers/meta.hpp/meta_states/function.hpp +++ b/headers/meta.hpp/meta_states/function.hpp @@ -10,6 +10,7 @@ #include "../meta_states.hpp" #include "../meta_types/function_type.hpp" +#include "../meta_detail/value_utilities/arg.hpp" namespace meta_hpp::detail { @@ -99,9 +100,8 @@ namespace meta_hpp::detail { 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(function_state{ - .index{std::move(index)}, + .index{function_index::make(std::move(name))}, .invoke{make_function_invoke(std::move(function))}, .is_invocable_with{make_function_is_invocable_with()}, }); @@ -126,11 +126,11 @@ namespace meta_hpp } inline const function_type& function::get_type() const noexcept { - return state_->index.type; + return state_->index.get_type(); } inline const std::string& function::get_name() const noexcept { - return state_->index.name; + return state_->index.get_name(); } template < typename... Args > diff --git a/headers/meta.hpp/meta_states/member.hpp b/headers/meta.hpp/meta_states/member.hpp index 50287ab..c93eec8 100644 --- a/headers/meta.hpp/meta_states/member.hpp +++ b/headers/meta.hpp/meta_states/member.hpp @@ -10,6 +10,8 @@ #include "../meta_states.hpp" #include "../meta_types/member_type.hpp" +#include "../meta_detail/value_utilities/arg.hpp" +#include "../meta_detail/value_utilities/inst.hpp" namespace meta_hpp::detail { @@ -146,9 +148,8 @@ namespace meta_hpp::detail { 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(member_state{ - .index{std::move(index)}, + .index{member_index::make(std::move(name))}, .getter{make_member_getter(std::move(member))}, .setter{make_member_setter(std::move(member))}, .is_gettable_with{make_member_is_gettable_with()}, @@ -175,11 +176,11 @@ namespace meta_hpp } inline const member_type& member::get_type() const noexcept { - return state_->index.type; + return state_->index.get_type(); } inline const std::string& member::get_name() const noexcept { - return state_->index.name; + return state_->index.get_name(); } template < typename Instance > diff --git a/headers/meta.hpp/meta_states/method.hpp b/headers/meta.hpp/meta_states/method.hpp index deb11a6..b59fbc2 100644 --- a/headers/meta.hpp/meta_states/method.hpp +++ b/headers/meta.hpp/meta_states/method.hpp @@ -10,6 +10,8 @@ #include "../meta_states.hpp" #include "../meta_types/method_type.hpp" +#include "../meta_detail/value_utilities/arg.hpp" +#include "../meta_detail/value_utilities/inst.hpp" namespace meta_hpp::detail { @@ -112,9 +114,8 @@ namespace meta_hpp::detail { 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(method_state{ - .index{std::move(index)}, + .index{method_index::make(std::move(name))}, .invoke{make_method_invoke(std::move(method))}, .is_invocable_with{make_method_is_invocable_with()}, }); @@ -139,11 +140,11 @@ namespace meta_hpp } inline const method_type& method::get_type() const noexcept { - return state_->index.type; + return state_->index.get_type(); } inline const std::string& method::get_name() const noexcept { - return state_->index.name; + return state_->index.get_name(); } template < typename Instance, typename... Args > diff --git a/headers/meta.hpp/meta_states/scope.hpp b/headers/meta.hpp/meta_states/scope.hpp index 49b4016..81b56d9 100644 --- a/headers/meta.hpp/meta_states/scope.hpp +++ b/headers/meta.hpp/meta_states/scope.hpp @@ -8,25 +8,23 @@ #include "../meta_base.hpp" #include "../meta_states.hpp" +#include "../meta_types.hpp" + +#include "../meta_types/class_type.hpp" +#include "../meta_types/enum_type.hpp" + +#include "../meta_states/function.hpp" +#include "../meta_states/variable.hpp" + +#include "../meta_detail/type_registry.hpp" namespace meta_hpp::detail { inline scope_state_ptr scope_state::make(std::string name) { - scope_index index{std::move(name)}; return std::make_shared(scope_state{ - .index{std::move(index)}, + .index{scope_index::make(std::move(name))}, }); } - - inline scope_state_ptr scope_state::get_static(std::string_view name) { - static std::map> states; - - if ( auto iter = states.find(name); iter != states.end() ) { - return iter->second; - } - - return states.emplace(std::string{name}, make(std::string{name})).first->second; - } } namespace meta_hpp @@ -47,7 +45,7 @@ namespace meta_hpp } inline const std::string& scope::get_name() const noexcept { - return state_->index.name; + return state_->index.get_name(); } inline const class_map& scope::get_classes() const noexcept { @@ -82,7 +80,7 @@ namespace meta_hpp inline function scope::get_function(std::string_view name) const noexcept { for ( auto&& [index, function] : state_->functions ) { - if ( index.name == name ) { + if ( index.get_name() == name ) { return function; } } @@ -91,7 +89,7 @@ namespace meta_hpp inline variable scope::get_variable(std::string_view name) const noexcept { for ( auto&& [index, variable] : state_->variables ) { - if ( index.name == name ) { + if ( index.get_name() == name ) { return variable; } } @@ -100,12 +98,12 @@ namespace meta_hpp template < typename... Args > function scope::get_function_with(std::string_view name) const noexcept { - return get_function_with(name, {resolve_type()...}); + return get_function_with(name, {detail::resolve_type()...}); } inline function scope::get_function_with(std::string_view name, const std::vector& args) const noexcept { for ( auto&& [index, function] : state_->functions ) { - if ( index.name != name ) { + if ( index.get_name() != name ) { continue; } @@ -123,7 +121,7 @@ namespace meta_hpp inline function scope::get_function_with(std::string_view name, std::initializer_list args) const noexcept { for ( auto&& [index, function] : state_->functions ) { - if ( index.name != name ) { + if ( index.get_name() != name ) { continue; } diff --git a/headers/meta.hpp/meta_states/variable.hpp b/headers/meta.hpp/meta_states/variable.hpp index 52e404f..fac956f 100644 --- a/headers/meta.hpp/meta_states/variable.hpp +++ b/headers/meta.hpp/meta_states/variable.hpp @@ -10,6 +10,7 @@ #include "../meta_states.hpp" #include "../meta_types/pointer_type.hpp" +#include "../meta_detail/value_utilities/arg.hpp" namespace meta_hpp::detail { @@ -95,9 +96,8 @@ namespace meta_hpp::detail { 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(variable_state{ - .index{std::move(index)}, + .index{variable_index::make(std::move(name))}, .getter{make_variable_getter(std::move(pointer))}, .setter{make_variable_setter(std::move(pointer))}, .is_settable_with{make_variable_is_settable_with()}, @@ -123,11 +123,11 @@ namespace meta_hpp } inline const pointer_type& variable::get_type() const noexcept { - return state_->index.type; + return state_->index.get_type(); } inline const std::string& variable::get_name() const noexcept { - return state_->index.name; + return state_->index.get_name(); } inline value variable::get() const { diff --git a/headers/meta.hpp/meta_traits.hpp b/headers/meta.hpp/meta_traits.hpp deleted file mode 100644 index 5ce4006..0000000 --- a/headers/meta.hpp/meta_traits.hpp +++ /dev/null @@ -1,118 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "meta_base.hpp" -#include "meta_kinds.hpp" - -namespace meta_hpp::detail -{ - template < array_kind Array > - struct array_traits; - - template < class_kind Class > - struct class_traits; - - template < class_kind Class, typename... Args > - struct ctor_traits; - - template < class_kind Class > - struct dtor_traits; - - template < enum_kind Enum > - struct enum_traits; - - template < function_kind Function > - struct function_traits; - - template < member_kind Member > - struct member_traits; - - template < method_kind Method > - struct method_traits; - - template < number_kind Number > - struct number_traits; - - template < pointer_kind Pointer > - struct pointer_traits; - - template < reference_kind Reference > - struct reference_traits; -} - -namespace meta_hpp -{ - enum class array_flags : std::uint32_t { - is_bounded = 1 << 0, - is_unbounded = 1 << 1, - }; - - enum class class_flags : std::uint32_t { - is_empty = 1 << 0, - is_final = 1 << 1, - is_abstract = 1 << 2, - is_polymorphic = 1 << 3, - is_template_instantiation = 1 << 4, - }; - - enum class ctor_flags : std::uint32_t { - is_noexcept = 1 << 0, - }; - - enum class dtor_flags : std::uint32_t { - is_noexcept = 1 << 0, - }; - - enum class enum_flags : std::uint32_t { - is_scoped = 1 << 0, - }; - - enum class function_flags : std::uint32_t { - is_noexcept = 1 << 0, - }; - - enum class member_flags : std::uint32_t { - is_readonly = 1 << 0, - }; - - enum class method_flags : std::uint32_t { - is_const = 1 << 0, - is_noexcept = 1 << 1, - is_lvalue_qualified = 1 << 2, - is_rvalue_qualified = 1 << 3, - }; - - enum class number_flags : std::uint32_t { - is_signed = 1 << 0, - is_unsigned = 1 << 1, - is_integral = 1 << 2, - is_floating_point = 1 << 3, - }; - - enum class pointer_flags : std::uint32_t { - is_readonly = 1 << 0, - }; - - enum class reference_flags : std::uint32_t { - is_readonly = 1 << 0, - is_lvalue = 1 << 1, - is_rvalue = 1 << 2, - }; - - ENUM_HPP_OPERATORS_DECL(array_flags) - ENUM_HPP_OPERATORS_DECL(class_flags) - ENUM_HPP_OPERATORS_DECL(ctor_flags) - ENUM_HPP_OPERATORS_DECL(dtor_flags) - ENUM_HPP_OPERATORS_DECL(enum_flags) - ENUM_HPP_OPERATORS_DECL(function_flags) - ENUM_HPP_OPERATORS_DECL(member_flags) - ENUM_HPP_OPERATORS_DECL(method_flags) - ENUM_HPP_OPERATORS_DECL(number_flags) - ENUM_HPP_OPERATORS_DECL(pointer_flags) - ENUM_HPP_OPERATORS_DECL(reference_flags) -} diff --git a/headers/meta.hpp/meta_types.hpp b/headers/meta.hpp/meta_types.hpp index dd7b014..c1e38b0 100644 --- a/headers/meta.hpp/meta_types.hpp +++ b/headers/meta.hpp/meta_types.hpp @@ -7,114 +7,34 @@ #pragma once #include "meta_base.hpp" -#include "meta_traits.hpp" + +#include "meta_detail/type_family.hpp" + +#include "meta_detail/type_traits/array_traits.hpp" +#include "meta_detail/type_traits/class_traits.hpp" +#include "meta_detail/type_traits/ctor_traits.hpp" +#include "meta_detail/type_traits/dtor_traits.hpp" +#include "meta_detail/type_traits/enum_traits.hpp" +#include "meta_detail/type_traits/function_traits.hpp" +#include "meta_detail/type_traits/member_traits.hpp" +#include "meta_detail/type_traits/method_traits.hpp" +#include "meta_detail/type_traits/number_traits.hpp" +#include "meta_detail/type_traits/pointer_traits.hpp" +#include "meta_detail/type_traits/reference_traits.hpp" namespace meta_hpp { - class type_id final { - public: - template < typename T > - // NOLINTNEXTLINE(readability-named-parameter) - explicit type_id(detail::type_list) noexcept - : id_{type_to_id()} {} - - type_id(type_id&&) = default; - type_id(const type_id&) = default; - - type_id& operator=(type_id&&) = default; - type_id& operator=(const type_id&) = default; - - ~type_id() = default; - - [[nodiscard]] std::size_t get_hash() const noexcept { - return std::hash{}(id_); - } - - [[nodiscard]] friend bool operator<(type_id l, type_id r) noexcept { - return l.id_ < r.id_; - } - - [[nodiscard]] friend bool operator==(type_id l, type_id r) noexcept { - return l.id_ == r.id_; - } - - [[nodiscard]] friend bool operator!=(type_id l, type_id r) noexcept { - return l.id_ != r.id_; - } - private: - using underlying_type = std::uint32_t; - underlying_type id_{}; - private: - [[nodiscard]] static underlying_type next() noexcept { - static std::atomic id{}; - return ++id; - } - - template < typename T > - [[nodiscard]] static underlying_type type_to_id() noexcept { - static const underlying_type id{next()}; - return id; - } - }; -} - -namespace meta_hpp -{ - namespace detail - { - template < typename T > - concept type_family = - std::is_same_v || - std::is_same_v || - std::is_same_v || - std::is_same_v || - std::is_same_v || - std::is_same_v || - std::is_same_v || - std::is_same_v || - std::is_same_v || - std::is_same_v || - std::is_same_v || - std::is_same_v || - std::is_same_v || - std::is_same_v; - - template < type_family T > - [[nodiscard]] auto data_access(const T& type) { - return type.data_; - } - } - - template < detail::type_family T, detail::type_family U > - [[nodiscard]] bool operator<(const T& l, const U& r) noexcept { - if ( !static_cast(r) ) { - return false; - } - - if ( !static_cast(l) ) { - return true; - } - - return l.get_id() < r.get_id(); - } - - template < detail::type_family T, detail::type_family U > - [[nodiscard]] bool operator==(const T& l, const U& r) noexcept { - if ( static_cast(l) != static_cast(r) ) { - return false; - } - - if ( !static_cast(l) ) { - return true; - } - - return l.get_id() == r.get_id(); - } - - template < detail::type_family T, detail::type_family U > - [[nodiscard]] bool operator!=(const T& l, const U& r) noexcept { - return !(l == r); - } + using array_flags = detail::array_flags; + using class_flags = detail::class_flags; + using ctor_flags = detail::ctor_flags; + using dtor_flags = detail::dtor_flags; + using enum_flags = detail::enum_flags; + using function_flags = detail::function_flags; + using member_flags = detail::member_flags; + using method_flags = detail::method_flags; + using number_flags = detail::number_flags; + using pointer_flags = detail::pointer_flags; + using reference_flags = detail::reference_flags; } namespace meta_hpp @@ -122,7 +42,6 @@ namespace meta_hpp class any_type final { public: explicit any_type() = default; - explicit any_type(detail::type_data_base_ptr data); [[nodiscard]] bool is_valid() const noexcept; [[nodiscard]] explicit operator bool() const noexcept; @@ -173,7 +92,7 @@ namespace meta_hpp [[nodiscard]] void_type as_void() const noexcept; private: detail::type_data_base_ptr data_; - friend auto detail::data_access(const any_type&); + friend auto detail::type_access(const any_type&); }; class array_type final { @@ -191,7 +110,7 @@ namespace meta_hpp [[nodiscard]] any_type get_data_type() const noexcept; private: detail::array_type_data_ptr data_; - friend auto detail::data_access(const array_type&); + friend auto detail::type_access(const array_type&); }; class class_type final { @@ -257,7 +176,7 @@ namespace meta_hpp [[nodiscard]] method get_method_with(std::string_view name, std::initializer_list args) const noexcept; private: detail::class_type_data_ptr data_; - friend auto detail::data_access(const class_type&); + friend auto detail::type_access(const class_type&); }; class ctor_type final { @@ -277,7 +196,7 @@ namespace meta_hpp [[nodiscard]] const std::vector& get_argument_types() const noexcept; private: detail::ctor_type_data_ptr data_; - friend auto detail::data_access(const ctor_type&); + friend auto detail::type_access(const ctor_type&); }; class dtor_type final { @@ -294,7 +213,7 @@ namespace meta_hpp [[nodiscard]] any_type get_class_type() const noexcept; private: detail::dtor_type_data_ptr data_; - friend auto detail::data_access(const dtor_type&); + friend auto detail::type_access(const dtor_type&); }; class enum_type final { @@ -319,7 +238,7 @@ namespace meta_hpp [[nodiscard]] value name_to_value(std::string_view name) const noexcept; private: detail::enum_type_data_ptr data_; - friend auto detail::data_access(const enum_type&); + friend auto detail::type_access(const enum_type&); }; class function_type final { @@ -339,7 +258,7 @@ namespace meta_hpp [[nodiscard]] const std::vector& get_argument_types() const noexcept; private: detail::function_type_data_ptr data_; - friend auto detail::data_access(const function_type&); + friend auto detail::type_access(const function_type&); }; class member_type final { @@ -357,7 +276,7 @@ namespace meta_hpp [[nodiscard]] any_type get_value_type() const noexcept; private: detail::member_type_data_ptr data_; - friend auto detail::data_access(const member_type&); + friend auto detail::type_access(const member_type&); }; class method_type final { @@ -378,7 +297,7 @@ namespace meta_hpp [[nodiscard]] const std::vector& get_argument_types() const noexcept; private: detail::method_type_data_ptr data_; - friend auto detail::data_access(const method_type&); + friend auto detail::type_access(const method_type&); }; class nullptr_type final { @@ -392,7 +311,7 @@ namespace meta_hpp [[nodiscard]] type_id get_id() const noexcept; private: detail::nullptr_type_data_ptr data_; - friend auto detail::data_access(const nullptr_type&); + friend auto detail::type_access(const nullptr_type&); }; class number_type final { @@ -409,7 +328,7 @@ namespace meta_hpp [[nodiscard]] std::size_t get_size() const noexcept; private: detail::number_type_data_ptr data_; - friend auto detail::data_access(const number_type&); + friend auto detail::type_access(const number_type&); }; class pointer_type final { @@ -426,7 +345,7 @@ namespace meta_hpp [[nodiscard]] any_type get_data_type() const noexcept; private: detail::pointer_type_data_ptr data_; - friend auto detail::data_access(const pointer_type&); + friend auto detail::type_access(const pointer_type&); }; class reference_type final { @@ -443,7 +362,7 @@ namespace meta_hpp [[nodiscard]] any_type get_data_type() const noexcept; private: detail::reference_type_data_ptr data_; - friend auto detail::data_access(const reference_type&); + friend auto detail::type_access(const reference_type&); }; class void_type final { @@ -457,10 +376,44 @@ namespace meta_hpp [[nodiscard]] type_id get_id() const noexcept; private: detail::void_type_data_ptr data_; - friend auto detail::data_access(const void_type&); + friend auto detail::type_access(const void_type&); }; } +namespace meta_hpp +{ + template < detail::type_family T, detail::type_family U > + [[nodiscard]] bool operator<(const T& l, const U& r) noexcept { + if ( !static_cast(r) ) { + return false; + } + + if ( !static_cast(l) ) { + return true; + } + + return l.get_id() < r.get_id(); + } + + template < detail::type_family T, detail::type_family U > + [[nodiscard]] bool operator==(const T& l, const U& r) noexcept { + if ( static_cast(l) != static_cast(r) ) { + return false; + } + + if ( !static_cast(l) ) { + return true; + } + + return l.get_id() == r.get_id(); + } + + template < detail::type_family T, detail::type_family U > + [[nodiscard]] bool operator!=(const T& l, const U& r) noexcept { + return !(l == r); + } +} + namespace meta_hpp::detail { struct type_data_base { @@ -479,9 +432,6 @@ namespace meta_hpp::detail template < array_kind Array > explicit array_type_data(type_list); - - template < array_kind Array > - [[nodiscard]] static array_type_data_ptr get_static(); }; struct class_type_data final : type_data_base { @@ -507,9 +457,6 @@ namespace meta_hpp::detail template < class_kind Class > explicit class_type_data(type_list); - - template < class_kind Class > - [[nodiscard]] static class_type_data_ptr get_static(); }; struct ctor_type_data final : type_data_base { @@ -519,9 +466,6 @@ namespace meta_hpp::detail template < class_kind Class, typename... Args > explicit ctor_type_data(type_list, type_list); - - template < class_kind Class, typename... Args > - [[nodiscard]] static ctor_type_data_ptr get_static(); }; struct dtor_type_data final : type_data_base { @@ -530,9 +474,6 @@ namespace meta_hpp::detail template < class_kind Class > explicit dtor_type_data(type_list); - - template < class_kind Class > - [[nodiscard]] static dtor_type_data_ptr get_static(); }; struct enum_type_data final : type_data_base { @@ -543,9 +484,6 @@ namespace meta_hpp::detail template < enum_kind Enum > explicit enum_type_data(type_list); - - template < enum_kind Enum > - [[nodiscard]] static enum_type_data_ptr get_static(); }; struct function_type_data final : type_data_base { @@ -555,9 +493,6 @@ namespace meta_hpp::detail template < function_kind Function > explicit function_type_data(type_list); - - template < function_kind Function > - [[nodiscard]] static function_type_data_ptr get_static(); }; struct member_type_data final : type_data_base { @@ -567,9 +502,6 @@ namespace meta_hpp::detail template < member_kind Member > explicit member_type_data(type_list); - - template < member_kind Member > - [[nodiscard]] static member_type_data_ptr get_static(); }; struct method_type_data final : type_data_base { @@ -580,17 +512,11 @@ namespace meta_hpp::detail template < method_kind Method > explicit method_type_data(type_list); - - template < method_kind Method > - [[nodiscard]] static method_type_data_ptr get_static(); }; struct nullptr_type_data final : type_data_base { template < nullptr_kind Nullptr > explicit nullptr_type_data(type_list); - - template < nullptr_kind Nullptr > - [[nodiscard]] static nullptr_type_data_ptr get_static(); }; struct number_type_data final : type_data_base { @@ -599,9 +525,6 @@ namespace meta_hpp::detail template < number_kind Number > explicit number_type_data(type_list); - - template < number_kind Number > - [[nodiscard]] static number_type_data_ptr get_static(); }; struct pointer_type_data final : type_data_base { @@ -610,9 +533,6 @@ namespace meta_hpp::detail template < pointer_kind Pointer > explicit pointer_type_data(type_list); - - template < pointer_kind Pointer > - [[nodiscard]] static pointer_type_data_ptr get_static(); }; struct reference_type_data final : type_data_base { @@ -621,209 +541,10 @@ namespace meta_hpp::detail template < reference_kind Reference > explicit reference_type_data(type_list); - - template < reference_kind Reference > - [[nodiscard]] static reference_type_data_ptr get_static(); }; struct void_type_data final : type_data_base { template < void_kind Void > explicit void_type_data(type_list); - - template < void_kind Void > - [[nodiscard]] static void_type_data_ptr get_static(); }; } - -namespace meta_hpp -{ - struct ctor_index final { - const ctor_type type; - - explicit ctor_index(ctor_type type) - : type{std::move(type)} {} - - [[nodiscard]] friend bool operator<(const ctor_index& l, const ctor_index& r) noexcept { - return l.type < r.type; - } - - [[nodiscard]] friend bool operator==(const ctor_index& l, const ctor_index& r) noexcept { - return l.type == r.type; - } - }; - - struct dtor_index final { - const dtor_type type; - - explicit dtor_index(dtor_type type) - : type{std::move(type)} {} - - [[nodiscard]] friend bool operator<(const dtor_index& l, const dtor_index& r) noexcept { - return l.type < r.type; - } - - [[nodiscard]] friend bool operator==(const dtor_index& l, const dtor_index& r) noexcept { - return l.type == r.type; - } - }; - - struct evalue_index final { - const enum_type type; - const std::string name; - - explicit evalue_index(enum_type type, std::string name) - : type{std::move(type)} - , name{std::move(name)} {} - - [[nodiscard]] friend bool operator<(const evalue_index& l, const evalue_index& r) noexcept { - return (l.type < r.type) || (l.type == r.type && l.name < r.name); - } - - [[nodiscard]] friend bool operator==(const evalue_index& l, const evalue_index& r) noexcept { - return l.type == r.type && l.name == r.name; - } - }; - - struct function_index final { - const function_type type; - const std::string name; - - explicit function_index(function_type type, std::string name) - : type{std::move(type)} - , name{std::move(name)} {} - - [[nodiscard]] friend bool operator<(const function_index& l, const function_index& r) noexcept { - return (l.type < r.type) || (l.type == r.type && l.name < r.name); - } - - [[nodiscard]] friend bool operator==(const function_index& l, const function_index& r) noexcept { - return l.type == r.type && l.name == r.name; - } - }; - - struct member_index final { - const member_type type; - const std::string name; - - explicit member_index(member_type type, std::string name) - : type{std::move(type)} - , name{std::move(name)} {} - - [[nodiscard]] friend bool operator<(const member_index& l, const member_index& r) noexcept { - return (l.type < r.type) || (l.type == r.type && l.name < r.name); - } - - [[nodiscard]] friend bool operator==(const member_index& l, const member_index& r) noexcept { - return l.type == r.type && l.name == r.name; - } - }; - - struct method_index final { - const method_type type; - const std::string name; - - explicit method_index(method_type type, std::string name) - : type{std::move(type)} - , name{std::move(name)} {} - - [[nodiscard]] friend bool operator<(const method_index& l, const method_index& r) noexcept { - return (l.type < r.type) || (l.type == r.type && l.name < r.name); - } - - [[nodiscard]] friend bool operator==(const method_index& l, const method_index& r) noexcept { - return l.type == r.type && l.name == r.name; - } - }; - - struct scope_index final { - const std::string name; - - explicit scope_index(std::string name) - : name{std::move(name)} {} - - [[nodiscard]] friend bool operator<(const scope_index& l, const scope_index& r) noexcept { - return l.name < r.name; - } - - [[nodiscard]] friend bool operator==(const scope_index& l, const scope_index& r) noexcept { - return l.name == r.name; - } - }; - - struct variable_index final { - const pointer_type type; - const std::string name; - - explicit variable_index(pointer_type type, std::string name) - : type{std::move(type)} - , name{std::move(name)} {} - - [[nodiscard]] friend bool operator<(const variable_index& l, const variable_index& r) noexcept { - return (l.type < r.type) || (l.type == r.type && l.name < r.name); - } - - [[nodiscard]] friend bool operator==(const variable_index& l, const variable_index& r) noexcept { - return l.type == r.type && l.name == r.name; - } - }; -} - -namespace meta_hpp -{ - template < typename T > - [[nodiscard]] auto resolve_type() { - using raw_type = std::remove_cv_t; - - using kind_type = detail::kind_type; - using kind_type_data = detail::kind_type_data; - - return kind_type{kind_type_data::template get_static()}; - } - - template < typename T > - // NOLINTNEXTLINE(readability-named-parameter) - [[nodiscard]] auto resolve_type(const T&) { - return resolve_type>(); - } -} - -namespace meta_hpp -{ - namespace detail - { - [[nodiscard]] inline void* pointer_upcast(void* ptr, const class_type& from, const class_type& to) { - if ( nullptr == ptr || !from || !to ) { - return nullptr; - } - - if ( from == to ) { - return ptr; - } - - for ( auto&& [base, base_info] : data_access(from)->bases_info ) { - if ( base == to ) { - return base_info.upcast(ptr); - } - - if ( base.is_derived_from(to) ) { - return pointer_upcast(base_info.upcast(ptr), base, to); - } - } - - return nullptr; - } - } - - template < detail::class_kind Base, detail::class_kind Derived > - [[nodiscard]] Base* pointer_upcast(Derived* ptr) { - const class_type& base = resolve_type(); - const class_type& derived = resolve_type(); - return static_cast(detail::pointer_upcast(ptr, derived, base)); - } - - template < detail::class_kind Base, detail::class_kind Derived > - [[nodiscard]] const Base* pointer_upcast(const Derived* ptr) { - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast) - return pointer_upcast(const_cast(ptr)); - } -} diff --git a/headers/meta.hpp/meta_types/any_type.hpp b/headers/meta.hpp/meta_types/any_type.hpp index a545ee5..b94a4cf 100644 --- a/headers/meta.hpp/meta_types/any_type.hpp +++ b/headers/meta.hpp/meta_types/any_type.hpp @@ -11,9 +11,6 @@ namespace meta_hpp { - inline any_type::any_type(detail::type_data_base_ptr data) - : data_{std::move(data)} {} - inline bool any_type::is_valid() const noexcept { return !!data_; } @@ -31,43 +28,43 @@ namespace meta_hpp } inline any_type::any_type(const array_type& other) noexcept - : data_{detail::data_access(other)} {} + : data_{detail::type_access(other)} {} inline any_type::any_type(const class_type& other) noexcept - : data_{detail::data_access(other)} {} + : data_{detail::type_access(other)} {} inline any_type::any_type(const ctor_type& other) noexcept - : data_{detail::data_access(other)} {} + : data_{detail::type_access(other)} {} inline any_type::any_type(const dtor_type& other) noexcept - : data_{detail::data_access(other)} {} + : data_{detail::type_access(other)} {} inline any_type::any_type(const enum_type& other) noexcept - : data_{detail::data_access(other)} {} + : data_{detail::type_access(other)} {} inline any_type::any_type(const function_type& other) noexcept - : data_{detail::data_access(other)} {} + : data_{detail::type_access(other)} {} inline any_type::any_type(const member_type& other) noexcept - : data_{detail::data_access(other)} {} + : data_{detail::type_access(other)} {} inline any_type::any_type(const method_type& other) noexcept - : data_{detail::data_access(other)} {} + : data_{detail::type_access(other)} {} inline any_type::any_type(const nullptr_type& other) noexcept - : data_{detail::data_access(other)} {} + : data_{detail::type_access(other)} {} inline any_type::any_type(const number_type& other) noexcept - : data_{detail::data_access(other)} {} + : data_{detail::type_access(other)} {} inline any_type::any_type(const pointer_type& other) noexcept - : data_{detail::data_access(other)} {} + : data_{detail::type_access(other)} {} inline any_type::any_type(const reference_type& other) noexcept - : data_{detail::data_access(other)} {} + : data_{detail::type_access(other)} {} inline any_type::any_type(const void_type& other) noexcept - : data_{detail::data_access(other)} {} + : data_{detail::type_access(other)} {} inline bool any_type::is_array() const noexcept { return data_ && data_->kind == type_kind::array_; diff --git a/headers/meta.hpp/meta_types/array_type.hpp b/headers/meta.hpp/meta_types/array_type.hpp index f9db315..0fa628c 100644 --- a/headers/meta.hpp/meta_types/array_type.hpp +++ b/headers/meta.hpp/meta_types/array_type.hpp @@ -9,7 +9,8 @@ #include "../meta_base.hpp" #include "../meta_types.hpp" -#include "../meta_traits/array_traits.hpp" +#include "../meta_detail/type_registry.hpp" +#include "../meta_detail/type_traits/array_traits.hpp" namespace meta_hpp::detail { @@ -23,12 +24,6 @@ namespace meta_hpp::detail , flags{array_traits::make_flags()} , extent{array_traits::extent} , data_type{resolve_type::data_type>()} {} - - template < array_kind Array > - array_type_data_ptr array_type_data::get_static() { - static array_type_data_ptr data = std::make_shared(type_list{}); - return data; - } } namespace meta_hpp diff --git a/headers/meta.hpp/meta_types/class_type.hpp b/headers/meta.hpp/meta_types/class_type.hpp index 09d2459..f9a0f12 100644 --- a/headers/meta.hpp/meta_types/class_type.hpp +++ b/headers/meta.hpp/meta_types/class_type.hpp @@ -15,7 +15,8 @@ #include "../meta_states/method.hpp" #include "../meta_states/variable.hpp" -#include "../meta_traits/class_traits.hpp" +#include "../meta_detail/type_registry.hpp" +#include "../meta_detail/type_traits/class_traits.hpp" namespace meta_hpp::detail { @@ -28,13 +29,7 @@ namespace meta_hpp::detail : type_data_base{type_id{type_list>{}}, type_kind::class_} , flags{class_traits::make_flags()} , size{class_traits::size} - , argument_types{class_traits::make_argument_types()} {} - - template < class_kind Class > - class_type_data_ptr class_type_data::get_static() { - static class_type_data_ptr data = std::make_shared(type_list{}); - return data; - } + , argument_types{resolve_types(typename class_traits::argument_types{})} {} } namespace meta_hpp @@ -130,7 +125,7 @@ namespace meta_hpp template < detail::class_kind Derived > bool class_type::is_base_of() const noexcept { - return is_base_of(resolve_type()); + return is_base_of(detail::resolve_type()); } inline bool class_type::is_base_of(const class_type& derived) const noexcept { @@ -153,7 +148,7 @@ namespace meta_hpp template < detail::class_kind Base > bool class_type::is_derived_from() const noexcept { - return is_derived_from(resolve_type()); + return is_derived_from(detail::resolve_type()); } inline bool class_type::is_derived_from(const class_type& base) const noexcept { @@ -176,7 +171,7 @@ namespace meta_hpp inline function class_type::get_function(std::string_view name) const noexcept { for ( auto&& [index, function] : data_->functions ) { - if ( index.name == name ) { + if ( index.get_name() == name ) { return function; } } @@ -192,7 +187,7 @@ namespace meta_hpp inline member class_type::get_member(std::string_view name) const noexcept { for ( auto&& [index, member] : data_->members ) { - if ( index.name == name ) { + if ( index.get_name() == name ) { return member; } } @@ -208,7 +203,7 @@ namespace meta_hpp inline method class_type::get_method(std::string_view name) const noexcept { for ( auto&& [index, method] : data_->methods ) { - if ( index.name == name ) { + if ( index.get_name() == name ) { return method; } } @@ -224,7 +219,7 @@ namespace meta_hpp inline variable class_type::get_variable(std::string_view name) const noexcept { for ( auto&& [index, variable] : data_->variables ) { - if ( index.name == name ) { + if ( index.get_name() == name ) { return variable; } } @@ -244,7 +239,7 @@ namespace meta_hpp template < typename... Args > ctor class_type::get_ctor_with() const noexcept { - return get_ctor_with({resolve_type()...}); + return get_ctor_with({detail::resolve_type()...}); } inline ctor class_type::get_ctor_with(const std::vector& args) const noexcept { @@ -283,12 +278,12 @@ namespace meta_hpp template < typename... Args > function class_type::get_function_with(std::string_view name) const noexcept { - return get_function_with(name, {resolve_type()...}); + return get_function_with(name, {detail::resolve_type()...}); } inline function class_type::get_function_with(std::string_view name, const std::vector& args) const noexcept { for ( auto&& [index, function] : data_->functions ) { - if ( index.name != name ) { + if ( index.get_name() != name ) { continue; } @@ -313,7 +308,7 @@ namespace meta_hpp inline function class_type::get_function_with(std::string_view name, std::initializer_list args) const noexcept { for ( auto&& [index, function] : data_->functions ) { - if ( index.name != name ) { + if ( index.get_name() != name ) { continue; } @@ -342,12 +337,12 @@ namespace meta_hpp template < typename... Args > method class_type::get_method_with(std::string_view name) const noexcept { - return get_method_with(name, {resolve_type()...}); + return get_method_with(name, {detail::resolve_type()...}); } inline method class_type::get_method_with(std::string_view name, const std::vector& args) const noexcept { for ( auto&& [index, method] : data_->methods ) { - if ( index.name != name ) { + if ( index.get_name() != name ) { continue; } @@ -372,7 +367,7 @@ namespace meta_hpp inline method class_type::get_method_with(std::string_view name, std::initializer_list args) const noexcept { for ( auto&& [index, method] : data_->methods ) { - if ( index.name != name ) { + if ( index.get_name() != name ) { continue; } diff --git a/headers/meta.hpp/meta_types/ctor_type.hpp b/headers/meta.hpp/meta_types/ctor_type.hpp index 893c2f3..b719b58 100644 --- a/headers/meta.hpp/meta_types/ctor_type.hpp +++ b/headers/meta.hpp/meta_types/ctor_type.hpp @@ -9,7 +9,8 @@ #include "../meta_base.hpp" #include "../meta_types.hpp" -#include "../meta_traits/ctor_traits.hpp" +#include "../meta_detail/type_registry.hpp" +#include "../meta_detail/type_traits/ctor_traits.hpp" namespace meta_hpp::detail { @@ -22,13 +23,7 @@ namespace meta_hpp::detail : type_data_base{type_id{type_list>{}}, type_kind::ctor_} , flags{ctor_traits::make_flags()} , class_type{resolve_type::class_type>()} - , argument_types{ctor_traits::make_argument_types()} {} - - template < class_kind Class, typename... Args > - ctor_type_data_ptr ctor_type_data::get_static() { - static ctor_type_data_ptr data = std::make_shared(type_list{}, type_list{}); - return data; - } + , argument_types{resolve_types(typename ctor_traits::argument_types{})} {} } namespace meta_hpp diff --git a/headers/meta.hpp/meta_types/dtor_type.hpp b/headers/meta.hpp/meta_types/dtor_type.hpp index 5e2c3da..f24413c 100644 --- a/headers/meta.hpp/meta_types/dtor_type.hpp +++ b/headers/meta.hpp/meta_types/dtor_type.hpp @@ -9,7 +9,8 @@ #include "../meta_base.hpp" #include "../meta_types.hpp" -#include "../meta_traits/dtor_traits.hpp" +#include "../meta_detail/type_registry.hpp" +#include "../meta_detail/type_traits/dtor_traits.hpp" namespace meta_hpp::detail { @@ -22,12 +23,6 @@ namespace meta_hpp::detail : type_data_base{type_id{type_list>{}}, type_kind::dtor_} , flags{dtor_traits::make_flags()} , class_type{resolve_type::class_type>()} {} - - template < class_kind Class > - dtor_type_data_ptr dtor_type_data::get_static() { - static dtor_type_data_ptr data = std::make_shared(type_list{}); - return data; - } } namespace meta_hpp diff --git a/headers/meta.hpp/meta_types/enum_type.hpp b/headers/meta.hpp/meta_types/enum_type.hpp index 1b84bb1..db20134 100644 --- a/headers/meta.hpp/meta_types/enum_type.hpp +++ b/headers/meta.hpp/meta_types/enum_type.hpp @@ -11,7 +11,9 @@ #include "../meta_states/evalue.hpp" -#include "../meta_traits/enum_traits.hpp" +#include "../meta_detail/type_registry.hpp" +#include "../meta_detail/type_traits/enum_traits.hpp" +#include "../meta_detail/value_utilities/arg.hpp" namespace meta_hpp::detail { @@ -24,12 +26,6 @@ namespace meta_hpp::detail : type_data_base{type_id{type_list>{}}, type_kind::enum_} , flags{enum_traits::make_flags()} , underlying_type{resolve_type::underlying_type>()} {} - - template < enum_kind Enum > - enum_type_data_ptr enum_type_data::get_static() { - static enum_type_data_ptr data = std::make_shared(type_list{}); - return data; - } } namespace meta_hpp @@ -63,7 +59,7 @@ namespace meta_hpp inline evalue enum_type::get_evalue(std::string_view name) const noexcept { for ( auto&& [index, evalue] : data_->evalues ) { - if ( index.name == name ) { + if ( index.get_name() == name ) { return evalue; } } @@ -80,7 +76,7 @@ namespace meta_hpp for ( auto&& evalue : data_->evalues ) { if ( evalue.second.get_value() == value ) { - return evalue.second.get_index().name; + return evalue.second.get_index().get_name(); } } diff --git a/headers/meta.hpp/meta_types/function_type.hpp b/headers/meta.hpp/meta_types/function_type.hpp index 2580b9e..551c4a4 100644 --- a/headers/meta.hpp/meta_types/function_type.hpp +++ b/headers/meta.hpp/meta_types/function_type.hpp @@ -9,7 +9,8 @@ #include "../meta_base.hpp" #include "../meta_types.hpp" -#include "../meta_traits/function_traits.hpp" +#include "../meta_detail/type_registry.hpp" +#include "../meta_detail/type_traits/function_traits.hpp" namespace meta_hpp::detail { @@ -22,13 +23,7 @@ namespace meta_hpp::detail : type_data_base{type_id{type_list>{}}, type_kind::function_} , flags{function_traits::make_flags()} , return_type{resolve_type::return_type>()} - , argument_types{function_traits::make_argument_types()} {} - - template < function_kind Function > - function_type_data_ptr function_type_data::get_static() { - static function_type_data_ptr data = std::make_shared(type_list{}); - return data; - } + , argument_types{resolve_types(typename function_traits::argument_types{})} {} } namespace meta_hpp diff --git a/headers/meta.hpp/meta_types/member_type.hpp b/headers/meta.hpp/meta_types/member_type.hpp index 7935e22..60964fb 100644 --- a/headers/meta.hpp/meta_types/member_type.hpp +++ b/headers/meta.hpp/meta_types/member_type.hpp @@ -9,7 +9,8 @@ #include "../meta_base.hpp" #include "../meta_types.hpp" -#include "../meta_traits/member_traits.hpp" +#include "../meta_detail/type_registry.hpp" +#include "../meta_detail/type_traits/member_traits.hpp" namespace meta_hpp::detail { @@ -23,12 +24,6 @@ namespace meta_hpp::detail , flags{member_traits::make_flags()} , owner_type{resolve_type::class_type>()} , value_type{resolve_type::value_type>()} {} - - template < member_kind Member > - member_type_data_ptr member_type_data::get_static() { - static member_type_data_ptr data = std::make_shared(type_list{}); - return data; - } } namespace meta_hpp diff --git a/headers/meta.hpp/meta_types/method_type.hpp b/headers/meta.hpp/meta_types/method_type.hpp index 7fdaa1c..8e97769 100644 --- a/headers/meta.hpp/meta_types/method_type.hpp +++ b/headers/meta.hpp/meta_types/method_type.hpp @@ -9,7 +9,8 @@ #include "../meta_base.hpp" #include "../meta_types.hpp" -#include "../meta_traits/method_traits.hpp" +#include "../meta_detail/type_registry.hpp" +#include "../meta_detail/type_traits/method_traits.hpp" namespace meta_hpp::detail { @@ -23,13 +24,7 @@ namespace meta_hpp::detail , flags{method_traits::make_flags()} , owner_type{resolve_type::class_type>()} , return_type{resolve_type::return_type>()} - , argument_types{method_traits::make_argument_types()} {} - - template < method_kind Method > - method_type_data_ptr method_type_data::get_static() { - static method_type_data_ptr data = std::make_shared(type_list{}); - return data; - } + , argument_types{resolve_types(typename method_traits::argument_types{})} {} } namespace meta_hpp diff --git a/headers/meta.hpp/meta_types/nullptr_type.hpp b/headers/meta.hpp/meta_types/nullptr_type.hpp index c566a9b..fe1b7bd 100644 --- a/headers/meta.hpp/meta_types/nullptr_type.hpp +++ b/headers/meta.hpp/meta_types/nullptr_type.hpp @@ -18,12 +18,6 @@ namespace meta_hpp::detail // NOLINTNEXTLINE(readability-named-parameter) nullptr_type_data::nullptr_type_data(type_list) : type_data_base{type_id{type_list>{}}, type_kind::nullptr_} {} - - template < nullptr_kind Nullptr > - nullptr_type_data_ptr nullptr_type_data::get_static() { - static nullptr_type_data_ptr data = std::make_shared(type_list{}); - return data; - } } namespace meta_hpp diff --git a/headers/meta.hpp/meta_types/number_type.hpp b/headers/meta.hpp/meta_types/number_type.hpp index 066e78c..cbf65b2 100644 --- a/headers/meta.hpp/meta_types/number_type.hpp +++ b/headers/meta.hpp/meta_types/number_type.hpp @@ -9,7 +9,7 @@ #include "../meta_base.hpp" #include "../meta_types.hpp" -#include "../meta_traits/number_traits.hpp" +#include "../meta_detail/type_traits/number_traits.hpp" namespace meta_hpp::detail { @@ -22,12 +22,6 @@ namespace meta_hpp::detail : type_data_base{type_id{type_list>{}}, type_kind::number_} , flags{number_traits::make_flags()} , size{number_traits::size} {} - - template < number_kind Number > - number_type_data_ptr number_type_data::get_static() { - static number_type_data_ptr data = std::make_shared(type_list{}); - return data; - } } namespace meta_hpp diff --git a/headers/meta.hpp/meta_types/pointer_type.hpp b/headers/meta.hpp/meta_types/pointer_type.hpp index b9b763a..485f227 100644 --- a/headers/meta.hpp/meta_types/pointer_type.hpp +++ b/headers/meta.hpp/meta_types/pointer_type.hpp @@ -9,7 +9,8 @@ #include "../meta_base.hpp" #include "../meta_types.hpp" -#include "../meta_traits/pointer_traits.hpp" +#include "../meta_detail/type_registry.hpp" +#include "../meta_detail/type_traits/pointer_traits.hpp" namespace meta_hpp::detail { @@ -22,12 +23,6 @@ namespace meta_hpp::detail : type_data_base{type_id{type_list>{}}, type_kind::pointer_} , flags{pointer_traits::make_flags()} , data_type{resolve_type::data_type>()} {} - - template < pointer_kind Pointer > - pointer_type_data_ptr pointer_type_data::get_static() { - static pointer_type_data_ptr data = std::make_shared(type_list{}); - return data; - } } namespace meta_hpp diff --git a/headers/meta.hpp/meta_types/reference_type.hpp b/headers/meta.hpp/meta_types/reference_type.hpp index e7c04b8..aed33d1 100644 --- a/headers/meta.hpp/meta_types/reference_type.hpp +++ b/headers/meta.hpp/meta_types/reference_type.hpp @@ -9,7 +9,8 @@ #include "../meta_base.hpp" #include "../meta_types.hpp" -#include "../meta_traits/reference_traits.hpp" +#include "../meta_detail/type_registry.hpp" +#include "../meta_detail/type_traits/reference_traits.hpp" namespace meta_hpp::detail { @@ -22,12 +23,6 @@ namespace meta_hpp::detail : type_data_base{type_id{type_list>{}}, type_kind::reference_} , flags{reference_traits::make_flags()} , data_type{resolve_type::data_type>()} {} - - template < reference_kind Reference > - reference_type_data_ptr reference_type_data::get_static() { - static reference_type_data_ptr data = std::make_shared(type_list{}); - return data; - } } namespace meta_hpp diff --git a/headers/meta.hpp/meta_types/void_type.hpp b/headers/meta.hpp/meta_types/void_type.hpp index a314920..19dc923 100644 --- a/headers/meta.hpp/meta_types/void_type.hpp +++ b/headers/meta.hpp/meta_types/void_type.hpp @@ -18,12 +18,6 @@ namespace meta_hpp::detail // NOLINTNEXTLINE(readability-named-parameter) void_type_data::void_type_data(type_list) : type_data_base{type_id{type_list>{}}, type_kind::void_} {} - - template < void_kind Void > - void_type_data_ptr void_type_data::get_static() { - static void_type_data_ptr data = std::make_shared(type_list{}); - return data; - } } namespace meta_hpp diff --git a/headers/meta.hpp/meta_utilities.hpp b/headers/meta.hpp/meta_utilities.hpp deleted file mode 100644 index ee58de7..0000000 --- a/headers/meta.hpp/meta_utilities.hpp +++ /dev/null @@ -1,351 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "meta_base.hpp" -#include "meta_types.hpp" - -namespace meta_hpp::detail -{ - template < typename From > - struct cvref_traits { - static constexpr bool is_lvalue = std::is_lvalue_reference_v; - static constexpr bool is_rvalue = std::is_rvalue_reference_v; - static constexpr bool is_const = std::is_const_v>; - static constexpr bool is_volatile = std::is_volatile_v>; - - template < bool yesno, template < typename > typename Q, typename V > - using apply_t_if = std::conditional_t, V>; - - template < typename To > - using copy_to = - apply_t_if>>>>; - }; - - template < typename From, typename To > - struct copy_cvref { - using type = typename cvref_traits::template copy_to; - }; - - template < typename From, typename To > - using copy_cvref_t = typename copy_cvref::type; -} - -namespace meta_hpp::detail -{ - template < typename T > - concept value_kind = - std::is_same_v; - - template < typename T > - concept decay_value_kind = - value_kind>; - - template < typename T > - concept uvalue_kind = - std::is_same_v || - std::is_same_v || - std::is_same_v || - std::is_same_v || - std::is_same_v; - - template < typename T > - concept decay_uvalue_kind = - uvalue_kind>; - - template < typename T > - concept decay_non_uvalue_kind = - (!decay_uvalue_kind); - - template < typename T > - concept arg_lvalue_ref_kind = - (decay_non_uvalue_kind) && - (std::is_lvalue_reference_v); - - template < typename T > - concept arg_rvalue_ref_kind = - (decay_non_uvalue_kind) && - (!std::is_reference_v || std::is_rvalue_reference_v); - - template < typename T > - concept inst_class_ref_kind = - (std::is_class_v) || - (std::is_reference_v && std::is_class_v>); - - template < typename T > - concept inst_class_lvalue_ref_kind = - (decay_non_uvalue_kind) && - (std::is_lvalue_reference_v && std::is_class_v>); - - template < typename T > - concept inst_class_rvalue_ref_kind = - (decay_non_uvalue_kind) && - (std::is_class_v || (std::is_rvalue_reference_v && std::is_class_v>)); -} - -namespace meta_hpp::detail -{ - class noncopyable { - protected: - noncopyable() = default; - ~noncopyable() = default; - public: - noncopyable(noncopyable&&) = delete; - noncopyable(const noncopyable&) = delete; - noncopyable& operator=(noncopyable&&) = delete; - noncopyable& operator=(const noncopyable&) = delete; - }; -} - -namespace meta_hpp::detail -{ - template < typename... Ts > - struct overloaded : Ts... { - using Ts::operator()...; - }; - - template < typename... Ts > - overloaded(Ts...) -> overloaded; -} - -namespace meta_hpp -{ - class value final { - public: - value() = default; - ~value() noexcept; - - value(value&& other) noexcept; - value(const value& other); - - value& operator=(value&& other) noexcept; - value& operator=(const value& other); - - template < detail::decay_non_uvalue_kind T > - requires detail::stdex::copy_constructible> - explicit value(T&& val); - - template < detail::decay_non_uvalue_kind T > - requires detail::stdex::copy_constructible> - value& operator=(T&& val); - - [[nodiscard]] bool is_valid() const noexcept; - [[nodiscard]] explicit operator bool() const noexcept; - - void reset() noexcept; - void swap(value& other) noexcept; - - [[nodiscard]] any_type get_type() const noexcept; - - [[nodiscard]] void* data() noexcept; - [[nodiscard]] const void* data() const noexcept; - [[nodiscard]] const void* cdata() const noexcept; - - [[nodiscard]] value operator*() const; - [[nodiscard]] value operator[](std::size_t index) const; - - template < typename T > - [[nodiscard]] std::decay_t& cast() &; - - template < typename T > - [[nodiscard]] std::decay_t&& cast() &&; - - template < typename T > - [[nodiscard]] const std::decay_t& cast() const &; - - template < typename T > - [[nodiscard]] const std::decay_t&& cast() const &&; - - template < typename T > - [[nodiscard]] std::decay_t* try_cast() noexcept; - - template < typename T > - [[nodiscard]] const std::decay_t* try_cast() const noexcept; - - friend bool operator<(const value& l, const value& r); - friend bool operator==(const value& l, const value& r); - friend std::istream& operator>>(std::istream& is, value& v); - friend std::ostream& operator<<(std::ostream& os, const value& v); - private: - struct vtable_t; - vtable_t* vtable_{}; - private: - using buffer_t = std::aligned_storage_t; - using storage_u = std::variant; - storage_u storage_{}; - }; - - inline void swap(value& l, value& r) noexcept { - l.swap(r); - } -} - -namespace meta_hpp::detail -{ - class arg_base { - public: - enum class ref_types { - lvalue, - const_lvalue, - rvalue, - const_rvalue, - }; - public: - arg_base() = delete; - - arg_base(arg_base&&) = default; - arg_base(const arg_base&) = default; - - arg_base& operator=(arg_base&&) = delete; - arg_base& operator=(const arg_base&) = delete; - - virtual ~arg_base() = default; - - template < decay_value_kind T > - explicit arg_base(T&& v); - - template < decay_non_uvalue_kind T > - explicit arg_base(T&& v); - - template < arg_lvalue_ref_kind T > - explicit arg_base(type_list); - - template < arg_rvalue_ref_kind T > - explicit arg_base(type_list); - - explicit arg_base(value& v); - explicit arg_base(const value& v); - - explicit arg_base(value&& v); - explicit arg_base(const value&& v); - - [[nodiscard]] bool is_const() const noexcept; - [[nodiscard]] bool is_lvalue() const noexcept; - [[nodiscard]] bool is_rvalue() const noexcept; - - [[nodiscard]] ref_types get_ref_type() const noexcept; - [[nodiscard]] const any_type& get_raw_type() const noexcept; - - template < typename To > - [[nodiscard]] bool can_cast_to() const noexcept; - private: - ref_types ref_type_{}; - any_type raw_type_{}; - }; -} - -namespace meta_hpp::detail -{ - class arg final : public arg_base { - public: - arg() = delete; - - arg(arg&&) = default; - arg(const arg&) = default; - - arg& operator=(arg&&) = delete; - arg& operator=(const arg&) = delete; - - ~arg() override = default; - - template < decay_value_kind T > - explicit arg(T&& v); - - template < decay_non_uvalue_kind T > - explicit arg(T&& v); - - template < typename To > - [[nodiscard]] To cast() const; - private: - void* data_{}; - }; -} - -namespace meta_hpp::detail -{ - class inst_base { - public: - enum class ref_types { - lvalue, - const_lvalue, - rvalue, - const_rvalue, - }; - public: - inst_base() = delete; - - inst_base(inst_base&&) = default; - inst_base(const inst_base&) = default; - - inst_base& operator=(inst_base&&) = delete; - inst_base& operator=(const inst_base&) = delete; - - virtual ~inst_base() = default; - - template < decay_value_kind T > - explicit inst_base(T&& v); - - template < decay_non_uvalue_kind T > - explicit inst_base(T&& v); - - template < inst_class_lvalue_ref_kind T > - explicit inst_base(type_list); - - template < inst_class_rvalue_ref_kind T > - explicit inst_base(type_list); - - explicit inst_base(value& v); - explicit inst_base(const value& v); - - explicit inst_base(value&& v); - explicit inst_base(const value&& v); - - [[nodiscard]] bool is_const() const noexcept; - [[nodiscard]] bool is_lvalue() const noexcept; - [[nodiscard]] bool is_rvalue() const noexcept; - - [[nodiscard]] ref_types get_ref_type() const noexcept; - [[nodiscard]] const any_type& get_raw_type() const noexcept; - - template < inst_class_ref_kind Q > - [[nodiscard]] bool can_cast_to() const noexcept; - private: - ref_types ref_type_{}; - any_type raw_type_{}; - }; -} - -namespace meta_hpp::detail -{ - class inst final : public inst_base { - public: - inst() = delete; - - inst(inst&&) = default; - inst(const inst&) = default; - - inst& operator=(inst&&) = delete; - inst& operator=(const inst&) = delete; - - ~inst() override = default; - - template < decay_value_kind T > - explicit inst(T&& v); - - template < decay_non_uvalue_kind T > - explicit inst(T&& v); - - template < inst_class_ref_kind Q > - [[nodiscard]] decltype(auto) cast() const; - private: - void* data_{}; - }; -} diff --git a/headers/meta.hpp/meta_utilities/inst.hpp b/headers/meta.hpp/meta_utilities/inst.hpp deleted file mode 100644 index b49c9f5..0000000 --- a/headers/meta.hpp/meta_utilities/inst.hpp +++ /dev/null @@ -1,209 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "../meta_base.hpp" -#include "../meta_utilities.hpp" - -namespace meta_hpp::detail -{ - namespace impl - { - template < inst_class_ref_kind Q, bool is_const, bool is_lvalue, bool is_rvalue > - struct inst_traits_impl; - - template < inst_class_ref_kind Q > - struct inst_traits_impl { - using class_type = std::remove_cvref_t; - using method_type = void(class_type::*)(); - }; - - template < inst_class_ref_kind Q > - struct inst_traits_impl { - using class_type = std::remove_cvref_t; - using method_type = void(class_type::*)() &; - }; - - template < inst_class_ref_kind Q > - struct inst_traits_impl { - using class_type = std::remove_cvref_t; - using method_type = void(class_type::*)() &&; - }; - - template < inst_class_ref_kind Q > - struct inst_traits_impl { - using class_type = std::remove_cvref_t; - using method_type = void(class_type::*)() const; - }; - - template < inst_class_ref_kind Q > - struct inst_traits_impl { - using class_type = std::remove_cvref_t; - using method_type = void(class_type::*)() const &; - }; - - template < inst_class_ref_kind Q > - struct inst_traits_impl { - using class_type = std::remove_cvref_t; - using method_type = void(class_type::*)() const &&; - }; - } - - template < inst_class_ref_kind Q > - struct inst_traits final : impl::inst_traits_impl::is_const, - cvref_traits::is_lvalue, - cvref_traits::is_rvalue> {}; -} - -namespace meta_hpp::detail -{ - template < decay_value_kind T > - // NOLINTNEXTLINE(readability-named-parameter) - inst_base::inst_base(T&&) - : inst_base{type_list{}} {} - - template < decay_non_uvalue_kind T > - // NOLINTNEXTLINE(readability-named-parameter) - inst_base::inst_base(T&&) - : inst_base{type_list{}} {} - - template < inst_class_lvalue_ref_kind T > - // NOLINTNEXTLINE(readability-named-parameter) - inst_base::inst_base(type_list) - : ref_type_{std::is_const_v> - ? ref_types::const_lvalue - : ref_types::lvalue} - , raw_type_{resolve_type>()} {} - - template < inst_class_rvalue_ref_kind T > - // NOLINTNEXTLINE(readability-named-parameter) - inst_base::inst_base(type_list) - : ref_type_{std::is_const_v> - ? ref_types::const_rvalue - : ref_types::rvalue} - , raw_type_{resolve_type>()} {} - - inline inst_base::inst_base(value& v) - : ref_type_{ref_types::lvalue} - , raw_type_{v.get_type()} {} - - inline inst_base::inst_base(const value& v) - : ref_type_{ref_types::const_lvalue} - , raw_type_{v.get_type()} {} - - inline inst_base::inst_base(value&& v) - : ref_type_{ref_types::rvalue} - , raw_type_{v.get_type()} {} - - inline inst_base::inst_base(const value&& v) - : ref_type_{ref_types::const_rvalue} - , raw_type_{v.get_type()} {} - - inline bool inst_base::is_const() const noexcept { - return ref_type_ == ref_types::const_lvalue - || ref_type_ == ref_types::const_rvalue; - } - - inline bool inst_base::is_lvalue() const noexcept { - return ref_type_ == ref_types::lvalue - || ref_type_ == ref_types::const_lvalue; - } - - inline bool inst_base::is_rvalue() const noexcept { - return ref_type_ == ref_types::rvalue - || ref_type_ == ref_types::const_rvalue; - } - - inline inst_base::ref_types inst_base::get_ref_type() const noexcept { - return ref_type_; - } - - inline const any_type& inst_base::get_raw_type() const noexcept { - return raw_type_; - } - - template < inst_class_ref_kind Q > - bool inst_base::can_cast_to() const noexcept { - using inst_class = typename inst_traits::class_type; - using inst_method = typename inst_traits::method_type; - - const any_type& from_type = get_raw_type(); - const any_type& to_type = resolve_type(); - - const auto is_a = [](const any_type& base, const any_type& derived){ - return (base == derived) - || (base.is_class() && derived.is_class() && base.as_class().is_base_of(derived.as_class())); - }; - - const auto is_invocable = [this](){ - switch ( get_ref_type() ) { - case ref_types::lvalue: - return std::is_invocable_v; - case ref_types::const_lvalue: - return std::is_invocable_v; - case ref_types::rvalue: - return std::is_invocable_v; - case ref_types::const_rvalue: - return std::is_invocable_v; - default: - return false; - } - }; - - return is_a(to_type, from_type) && is_invocable(); - } -} - -namespace meta_hpp::detail -{ - template < decay_value_kind T > - inst::inst(T&& v) - : inst_base{std::forward(v)} - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast) - , data_{const_cast(v.data())} {} - - template < decay_non_uvalue_kind T > - inst::inst(T&& v) - : inst_base{std::forward(v)} - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast) - , data_{const_cast*>(std::addressof(v))} {} - - template < inst_class_ref_kind Q > - decltype(auto) inst::cast() const { - if ( !can_cast_to() ) { - throw std::logic_error("bad instance cast"); - } - - using inst_class_cv = std::remove_reference_t; - using inst_class = std::remove_cv_t; - - const any_type& from_type = get_raw_type(); - const any_type& to_type = resolve_type(); - - if ( from_type.is_class() && to_type.is_class() ) { - const class_type& from_class = from_type.as_class(); - const class_type& to_class = to_type.as_class(); - - void* to_ptr = detail::pointer_upcast(data_, from_class, to_class); - - if constexpr ( !std::is_reference_v ) { - return *static_cast(to_ptr); - } - - if constexpr ( std::is_lvalue_reference_v ) { - return *static_cast(to_ptr); - } - - if constexpr ( std::is_rvalue_reference_v ) { - return std::move(*static_cast(to_ptr)); - } - } - - throw std::logic_error("bad instance cast"); - } -} diff --git a/headers/meta.hpp/meta_value.hpp b/headers/meta.hpp/meta_value.hpp new file mode 100644 index 0000000..91d5c4b --- /dev/null +++ b/headers/meta.hpp/meta_value.hpp @@ -0,0 +1,94 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "meta_base.hpp" +#include "meta_types.hpp" + +namespace meta_hpp::detail +{ + template < typename T > + concept value_kind = stdex::same_as; + + template < typename T > + concept decay_value_kind = value_kind>; + + template < typename T > + concept decay_non_value_kind = !decay_value_kind; +} + +namespace meta_hpp +{ + class value final { + public: + value() = default; + ~value() noexcept; + + value(value&& other) noexcept; + value(const value& other); + + value& operator=(value&& other) noexcept; + value& operator=(const value& other); + + template < detail::decay_non_value_kind T > + requires stdex::copy_constructible> + explicit value(T&& val); + + template < detail::decay_non_value_kind T > + requires stdex::copy_constructible> + value& operator=(T&& val); + + [[nodiscard]] bool is_valid() const noexcept; + [[nodiscard]] explicit operator bool() const noexcept; + + void reset() noexcept; + void swap(value& other) noexcept; + + [[nodiscard]] const any_type& get_type() const noexcept; + + [[nodiscard]] void* data() noexcept; + [[nodiscard]] const void* data() const noexcept; + [[nodiscard]] const void* cdata() const noexcept; + + [[nodiscard]] value operator*() const; + [[nodiscard]] value operator[](std::size_t index) const; + + template < typename T > + [[nodiscard]] std::decay_t& cast() &; + + template < typename T > + [[nodiscard]] std::decay_t&& cast() &&; + + template < typename T > + [[nodiscard]] const std::decay_t& cast() const &; + + template < typename T > + [[nodiscard]] const std::decay_t&& cast() const &&; + + template < typename T > + [[nodiscard]] std::decay_t* try_cast() noexcept; + + template < typename T > + [[nodiscard]] const std::decay_t* try_cast() const noexcept; + + friend bool operator<(const value& l, const value& r); + friend bool operator==(const value& l, const value& r); + friend std::istream& operator>>(std::istream& is, value& v); + friend std::ostream& operator<<(std::ostream& os, const value& v); + private: + struct vtable_t; + vtable_t* vtable_{}; + private: + using buffer_t = std::aligned_storage_t; + using storage_u = std::variant; + storage_u storage_{}; + }; + + inline void swap(value& l, value& r) noexcept { + l.swap(r); + } +} diff --git a/headers/meta.hpp/meta_utilities/value.hpp b/headers/meta.hpp/meta_value/value.hpp similarity index 81% rename from headers/meta.hpp/meta_utilities/value.hpp rename to headers/meta.hpp/meta_value/value.hpp index e673d72..d301396 100644 --- a/headers/meta.hpp/meta_utilities/value.hpp +++ b/headers/meta.hpp/meta_value/value.hpp @@ -7,14 +7,16 @@ #pragma once #include "../meta_base.hpp" -#include "../meta_utilities.hpp" +#include "../meta_value.hpp" -#include "value_traits/deref_traits.hpp" -#include "value_traits/equals_traits.hpp" -#include "value_traits/index_traits.hpp" -#include "value_traits/istream_traits.hpp" -#include "value_traits/less_traits.hpp" -#include "value_traits/ostream_traits.hpp" +#include "../meta_detail/value_traits/deref_traits.hpp" +#include "../meta_detail/value_traits/equals_traits.hpp" +#include "../meta_detail/value_traits/index_traits.hpp" +#include "../meta_detail/value_traits/istream_traits.hpp" +#include "../meta_detail/value_traits/less_traits.hpp" +#include "../meta_detail/value_traits/ostream_traits.hpp" + +#include "../meta_detail/type_registry.hpp" namespace meta_hpp { @@ -115,7 +117,7 @@ namespace meta_hpp template < typename Tp > static vtable_t* get() { static vtable_t table{ - .type = resolve_type(), + .type = detail::resolve_type(), .data = [](storage_u& from) noexcept -> void* { return storage_cast(from); @@ -175,48 +177,48 @@ namespace meta_hpp }, .deref = +[]([[maybe_unused]] const value& v) -> value { - if constexpr ( detail::has_value_deref_traits ) { - return detail::value_deref_traits{}(v.cast()); + if constexpr ( detail::has_deref_traits ) { + return detail::deref_traits{}(v.cast()); } else { throw std::logic_error("value type doesn't have value deref traits"); } }, - .index = +[]([[maybe_unused]] const value& v, [[maybe_unused]] std::size_t index) -> value { - if constexpr ( detail::has_value_index_traits ) { - return detail::value_index_traits{}(v.cast(), index); + .index = +[]([[maybe_unused]] const value& v, [[maybe_unused]] std::size_t i) -> value { + if constexpr ( detail::has_index_traits ) { + return detail::index_traits{}(v.cast(), i); } else { throw std::logic_error("value type doesn't have value index traits"); } }, .less = +[]([[maybe_unused]] const value& l, [[maybe_unused]] const value& r) -> bool { - if constexpr ( detail::has_value_less_traits ) { - return detail::value_less_traits{}(l.cast(), r.cast()); + if constexpr ( detail::has_less_traits ) { + return detail::less_traits{}(l.cast(), r.cast()); } else { throw std::logic_error("value type doesn't have value less traits"); } }, .equals = +[]([[maybe_unused]] const value& l, [[maybe_unused]] const value& r) -> bool { - if constexpr ( detail::has_value_equals_traits ) { - return detail::value_equals_traits{}(l.cast(), r.cast()); + if constexpr ( detail::has_equals_traits ) { + return detail::equals_traits{}(l.cast(), r.cast()); } else { throw std::logic_error("value type doesn't have value equals traits"); } }, .istream = +[]([[maybe_unused]] std::istream& is, [[maybe_unused]] value& v) -> std::istream& { - if constexpr ( detail::has_value_istream_traits ) { - return detail::value_istream_traits{}(is, v.cast()); + if constexpr ( detail::has_istream_traits ) { + return detail::istream_traits{}(is, v.cast()); } else { throw std::logic_error("value type doesn't have value istream traits"); } }, .ostream = +[]([[maybe_unused]] std::ostream& os, [[maybe_unused]] const value& v) -> std::ostream& { - if constexpr ( detail::has_value_ostream_traits ) { - return detail::value_ostream_traits{}(os, v.cast()); + if constexpr ( detail::has_ostream_traits ) { + return detail::ostream_traits{}(os, v.cast()); } else { throw std::logic_error("value type doesn't have value ostream traits"); } @@ -260,14 +262,14 @@ namespace meta_hpp return *this; } - template < detail::decay_non_uvalue_kind T > - requires detail::stdex::copy_constructible> + template < detail::decay_non_value_kind T > + requires stdex::copy_constructible> value::value(T&& val) { vtable_t::construct(*this, std::forward(val)); } - template < detail::decay_non_uvalue_kind T > - requires detail::stdex::copy_constructible> + template < detail::decay_non_value_kind T > + requires stdex::copy_constructible> value& value::operator=(T&& val) { value{std::forward(val)}.swap(*this); return *this; @@ -292,8 +294,9 @@ namespace meta_hpp vtable_t::swap(*this, other); } - inline any_type value::get_type() const noexcept { - return vtable_ != nullptr ? vtable_->type : resolve_type(); + inline const any_type& value::get_type() const noexcept { + static any_type void_type = detail::resolve_type(); + return vtable_ != nullptr ? vtable_->type : void_type; } inline void* value::data() noexcept { @@ -355,7 +358,7 @@ namespace meta_hpp template < typename T > std::decay_t* value::try_cast() noexcept { using Tp = std::decay_t; - return get_type() == resolve_type() + return get_type() == detail::resolve_type() ? vtable_t::storage_cast(storage_) : nullptr; } @@ -363,7 +366,7 @@ namespace meta_hpp template < typename T > const std::decay_t* value::try_cast() const noexcept { using Tp = std::decay_t; - return get_type() == resolve_type() + return get_type() == detail::resolve_type() ? vtable_t::storage_cast(storage_) : nullptr; } @@ -377,9 +380,10 @@ namespace meta_hpp return true; } - const any_type& r_type = resolve_type(); - return (l.get_type() < r_type) - || (l.get_type() == r_type && std::less<>{}(l.cast(), r)); + const any_type& l_type = l.get_type(); + const any_type& r_type = detail::resolve_type(); + + return (l_type < r_type) || (l_type == r_type && l.cast() < r); } template < typename T > @@ -388,9 +392,10 @@ namespace meta_hpp return false; } - const any_type& l_type = resolve_type(); - return (l_type < r.get_type()) - || (l_type == r.get_type() && std::less<>{}(l, r.cast())); + const any_type& l_type = detail::resolve_type(); + const any_type& r_type = r.get_type(); + + return (l_type < r_type) || (l_type == r_type && l < r.cast()); } [[nodiscard]] inline bool operator<(const value& l, const value& r) { @@ -402,8 +407,10 @@ namespace meta_hpp return true; } - return (l.get_type() < r.get_type()) - || (l.get_type() == r.get_type() && l.vtable_->less(l, r)); + const any_type& l_type = l.get_type(); + const any_type& r_type = r.get_type(); + + return (l_type < r_type) || (l_type == r_type && l.vtable_->less(l, r)); } } @@ -415,8 +422,10 @@ namespace meta_hpp return false; } - return l.get_type() == resolve_type() - && std::equal_to<>{}(l.cast(), r); + const any_type& l_type = l.get_type(); + const any_type& r_type = detail::resolve_type(); + + return l_type == r_type && l.cast() == r; } template < typename T > @@ -425,8 +434,10 @@ namespace meta_hpp return false; } - return resolve_type() == r.get_type() - && std::equal_to<>{}(l, r.cast()); + const any_type& l_type = detail::resolve_type(); + const any_type& r_type = r.get_type(); + + return l_type == r_type && l == r.cast(); } [[nodiscard]] inline bool operator==(const value& l, const value& r) { @@ -438,8 +449,10 @@ namespace meta_hpp return true; } - return l.get_type() == r.get_type() - && l.vtable_->equals(l, r); + const any_type& l_type = l.get_type(); + const any_type& r_type = r.get_type(); + + return l_type == r_type && l.vtable_->equals(l, r); } } diff --git a/headers/meta.hpp/meta_utilities/vinvoke.hpp b/headers/meta.hpp/meta_value/vinvoke.hpp similarity index 97% rename from headers/meta.hpp/meta_utilities/vinvoke.hpp rename to headers/meta.hpp/meta_value/vinvoke.hpp index 5c786e8..6b96b04 100644 --- a/headers/meta.hpp/meta_utilities/vinvoke.hpp +++ b/headers/meta.hpp/meta_value/vinvoke.hpp @@ -8,7 +8,10 @@ #include "../meta_base.hpp" #include "../meta_states.hpp" -#include "../meta_utilities.hpp" +#include "../meta_value.hpp" + +#include "../meta_detail/value_utilities/arg.hpp" +#include "../meta_detail/value_utilities/inst.hpp" namespace meta_hpp { diff --git a/manuals/meta_examples/classes_example.cpp b/manuals/meta_examples/classes_example.cpp index ad71d88..0306c2a 100644 --- a/manuals/meta_examples/classes_example.cpp +++ b/manuals/meta_examples/classes_example.cpp @@ -57,7 +57,7 @@ TEST_CASE("meta/meta_examples/classes/type") { // prints all class methods fmt::print("* rectangle:\n"); for ( auto&& [index, method] : rectangle_type.get_methods() ) { - fmt::print(" + {}/{}\n", index.name, index.type.get_arity()); + fmt::print(" + {}/{}\n", index.get_name(), index.get_type().get_arity()); } } diff --git a/manuals/meta_examples/enums_examples.cpp b/manuals/meta_examples/enums_examples.cpp index 123444e..9ebfe00 100644 --- a/manuals/meta_examples/enums_examples.cpp +++ b/manuals/meta_examples/enums_examples.cpp @@ -36,7 +36,7 @@ TEST_CASE("meta/meta_examples/enums/type") { // prints all enumerators fmt::print("* align:\n"); for ( auto&& [index, evalue] : align_type.get_evalues() ) { - fmt::print(" - {}:{}\n", index.name, evalue.get_underlying_value()); + fmt::print(" - {}:{}\n", index.get_name(), evalue.get_underlying_value()); } } diff --git a/manuals/meta_examples/functions_example.cpp b/manuals/meta_examples/functions_example.cpp index a5f5873..294a625 100644 --- a/manuals/meta_examples/functions_example.cpp +++ b/manuals/meta_examples/functions_example.cpp @@ -73,6 +73,6 @@ TEST_CASE("meta/meta_examples/functions/usage") { // prints all functions in the scope fmt::print("* {}:\n", math_scope.get_name()); for ( auto&& [index, function] : math_scope.get_functions() ) { - fmt::print(" + {}/{}\n", index.name, function.get_type().get_arity()); + fmt::print(" + {}/{}\n", index.get_name(), function.get_type().get_arity()); } } diff --git a/manuals/meta_examples/variables_example.cpp b/manuals/meta_examples/variables_example.cpp index 87578cf..c3de612 100644 --- a/manuals/meta_examples/variables_example.cpp +++ b/manuals/meta_examples/variables_example.cpp @@ -42,6 +42,6 @@ TEST_CASE("meta/meta_examples/variables/usage") { // prints all variables in the scope fmt::print("* {}:\n", constants_scope.get_name()); for ( auto&& [index, variable] : constants_scope.get_variables() ) { - fmt::print(" - {}:{}\n", index.name, variable.get()); + fmt::print(" - {}:{}\n", index.get_name(), variable.get()); } } diff --git a/untests/meta_features/diamond_tests.cpp b/untests/meta_features/diamond_tests.cpp index 8cc2da8..6a7db53 100644 --- a/untests/meta_features/diamond_tests.cpp +++ b/untests/meta_features/diamond_tests.cpp @@ -116,45 +116,46 @@ TEST_CASE("meta/meta_features/diamond") { } SUBCASE("pointer_upcast") { + using meta::detail::pointer_upcast; { A a; - CHECK(meta::pointer_upcast(&a) == &a); - CHECK_FALSE(meta::pointer_upcast(&a)); - CHECK_FALSE(meta::pointer_upcast(&a)); - CHECK_FALSE(meta::pointer_upcast(&a)); - CHECK_FALSE(meta::pointer_upcast(&a)); + CHECK(pointer_upcast(&a) == &a); + CHECK_FALSE(pointer_upcast(&a)); + CHECK_FALSE(pointer_upcast(&a)); + CHECK_FALSE(pointer_upcast(&a)); + CHECK_FALSE(pointer_upcast(&a)); } { - B b; - CHECK(meta::pointer_upcast(&b) == &b); - CHECK(meta::pointer_upcast(&b) == &b); - CHECK_FALSE(meta::pointer_upcast(&b)); - CHECK_FALSE(meta::pointer_upcast(&b)); - CHECK_FALSE(meta::pointer_upcast(&b)); + const B b; + CHECK(pointer_upcast(&b) == &b); + CHECK(pointer_upcast(&b) == &b); + CHECK_FALSE(pointer_upcast(&b)); + CHECK_FALSE(pointer_upcast(&b)); + CHECK_FALSE(pointer_upcast(&b)); } { C c; - CHECK(meta::pointer_upcast(&c) == &c); - CHECK_FALSE(meta::pointer_upcast(&c)); - CHECK(meta::pointer_upcast(&c) == &c); - CHECK_FALSE(meta::pointer_upcast(&c)); - CHECK_FALSE(meta::pointer_upcast(&c)); + CHECK(pointer_upcast(&c) == &c); + CHECK_FALSE(pointer_upcast(&c)); + CHECK(pointer_upcast(&c) == &c); + CHECK_FALSE(pointer_upcast(&c)); + CHECK_FALSE(pointer_upcast(&c)); } { - D d; - CHECK(meta::pointer_upcast(&d) == &d); - CHECK(meta::pointer_upcast(&d) == &d); - CHECK(meta::pointer_upcast(&d) == &d); - CHECK(meta::pointer_upcast(&d) == &d); - CHECK_FALSE(meta::pointer_upcast(&d)); + const D d; + CHECK(pointer_upcast(&d) == &d); + CHECK(pointer_upcast(&d) == &d); + CHECK(pointer_upcast(&d) == &d); + CHECK(pointer_upcast(&d) == &d); + CHECK_FALSE(pointer_upcast(&d)); } { E e; - CHECK_FALSE(meta::pointer_upcast(&e)); - CHECK_FALSE(meta::pointer_upcast(&e)); - CHECK_FALSE(meta::pointer_upcast(&e)); - CHECK_FALSE(meta::pointer_upcast(&e)); - CHECK(meta::pointer_upcast(&e) == &e); + CHECK_FALSE(pointer_upcast(&e)); + CHECK_FALSE(pointer_upcast(&e)); + CHECK_FALSE(pointer_upcast(&e)); + CHECK_FALSE(pointer_upcast(&e)); + CHECK(pointer_upcast(&e) == &e); } } @@ -315,4 +316,23 @@ TEST_CASE("meta/meta_features/diamond") { CHECK(&e_inst.cast() == e_val.try_cast()); } } + + SUBCASE("resolve_polymorphic_type") { + const D d; + + const A& ad = d; + const B& bd = d; + const C& cd = d; + const D& dd = d; + + CHECK(meta::resolve_type(ad) == meta::resolve_type()); + CHECK(meta::resolve_type(bd) == meta::resolve_type()); + CHECK(meta::resolve_type(cd) == meta::resolve_type()); + CHECK(meta::resolve_type(dd) == meta::resolve_type()); + + CHECK(meta::resolve_polymorphic_type(ad) == meta::resolve_type()); + CHECK(meta::resolve_polymorphic_type(bd) == meta::resolve_type()); + CHECK(meta::resolve_polymorphic_type(cd) == meta::resolve_type()); + CHECK(meta::resolve_polymorphic_type(dd) == meta::resolve_type()); + } } diff --git a/untests/meta_states/evalue_tests.cpp b/untests/meta_states/evalue_tests.cpp index ea3e1c6..247bd1d 100644 --- a/untests/meta_states/evalue_tests.cpp +++ b/untests/meta_states/evalue_tests.cpp @@ -47,8 +47,8 @@ TEST_CASE("meta/meta_states/evalue") { const meta::evalue evalue = color_type.get_evalue("green"); REQUIRE(evalue); - CHECK(evalue.get_index().type == evalue.get_type()); - CHECK(evalue.get_index().name == "green"); + CHECK(evalue.get_index().get_type() == evalue.get_type()); + CHECK(evalue.get_index().get_name() == "green"); CHECK(evalue.get_type() == meta::resolve_type()); CHECK(evalue.get_name() == "green"); @@ -56,7 +56,7 @@ TEST_CASE("meta/meta_states/evalue") { CHECK(evalue.get_value() == color::green); CHECK(evalue.get_value().get_type() == color_type); - CHECK(evalue.get_underlying_value() == meta::detail::stdex::to_underlying(color::green)); + CHECK(evalue.get_underlying_value() == meta::stdex::to_underlying(color::green)); CHECK(evalue.get_underlying_value().get_type() == color_type.get_underlying_type()); } } diff --git a/untests/meta_states/function_tests.cpp b/untests/meta_states/function_tests.cpp index c7bdd78..880eadf 100644 --- a/untests/meta_states/function_tests.cpp +++ b/untests/meta_states/function_tests.cpp @@ -66,8 +66,8 @@ TEST_CASE("meta/meta_states/function") { const meta::function func = ivec2_type.get_function("iadd"); REQUIRE(func); - CHECK(func.get_index().type == func.get_type()); - CHECK(func.get_index().name == "iadd"); + CHECK(func.get_index().get_type() == func.get_type()); + CHECK(func.get_index().get_name() == "iadd"); CHECK(func.get_type() == meta::resolve_type(&ivec2::iadd)); CHECK(func.get_name() == "iadd"); @@ -95,8 +95,8 @@ TEST_CASE("meta/meta_states/function") { const meta::function func = ivec2_type.get_function("ilength2"); REQUIRE(func); - CHECK(func.get_index().type == func.get_type()); - CHECK(func.get_index().name == "ilength2"); + CHECK(func.get_index().get_type() == func.get_type()); + CHECK(func.get_index().get_name() == "ilength2"); CHECK(func.get_type() == meta::resolve_type(&ivec2::ilength2)); CHECK(func.get_name() == "ilength2"); diff --git a/untests/meta_types/class_type_tests.cpp b/untests/meta_types/class_type_tests.cpp index a200cbb..f09cf03 100644 --- a/untests/meta_types/class_type_tests.cpp +++ b/untests/meta_types/class_type_tests.cpp @@ -66,10 +66,10 @@ TEST_CASE("meta/meta_types/class_type") { .member_("base_member_1", &base_clazz_1::base_member_1) .method_("base_method_1", &base_clazz_1::base_method_1) .function_("base_function_1", &base_clazz_1::base_function_1) - .method_("base_method_1_overloaded", meta::select(&base_clazz_1::base_method_1_overloaded)) - .method_("base_method_1_overloaded", meta::select(&base_clazz_1::base_method_1_overloaded)) - .function_("base_function_1_overloaded", meta::select(&base_clazz_1::base_function_1_overloaded)) - .function_("base_function_1_overloaded", meta::select(&base_clazz_1::base_function_1_overloaded)) + .method_("base_method_1_overloaded", meta::select_overload(&base_clazz_1::base_method_1_overloaded)) + .method_("base_method_1_overloaded", meta::select_overload(&base_clazz_1::base_method_1_overloaded)) + .function_("base_function_1_overloaded", meta::select_overload(&base_clazz_1::base_function_1_overloaded)) + .function_("base_function_1_overloaded", meta::select_overload(&base_clazz_1::base_function_1_overloaded)) .variable_("base_variable_1", &base_clazz_1::base_variable_1); meta::class_() diff --git a/untests/meta_types/enum_type_tests.cpp b/untests/meta_types/enum_type_tests.cpp index c50d603..d1505e5 100644 --- a/untests/meta_types/enum_type_tests.cpp +++ b/untests/meta_types/enum_type_tests.cpp @@ -90,7 +90,7 @@ TEST_CASE("meta/meta_types/enum_type") { const meta::evalue green_value = color_type.get_evalue("green"); REQUIRE(green_value); CHECK(green_value.get_value() == color::green); - CHECK(green_value.get_underlying_value() == meta::detail::stdex::to_underlying(color::green)); + CHECK(green_value.get_underlying_value() == meta::stdex::to_underlying(color::green)); } { @@ -107,7 +107,7 @@ TEST_CASE("meta/meta_types/enum_type") { const meta::evalue green_value = ecolor_type.get_evalue("green"); REQUIRE(green_value); CHECK(green_value.get_value() == ecolor_green); - CHECK(green_value.get_underlying_value() == meta::detail::stdex::to_underlying(ecolor_green)); + CHECK(green_value.get_underlying_value() == meta::stdex::to_underlying(ecolor_green)); } { diff --git a/untests/meta_untests.cpp b/untests/meta_untests.cpp new file mode 100644 index 0000000..f9c6c27 --- /dev/null +++ b/untests/meta_untests.cpp @@ -0,0 +1,11 @@ +/******************************************************************************* + * 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" + +TEST_CASE("meta_hpp") { + namespace meta = meta_hpp; +} diff --git a/untests/meta_utilities/arg_tests.cpp b/untests/meta_utilities/arg_tests.cpp index ed1e59a..efa1d40 100644 --- a/untests/meta_utilities/arg_tests.cpp +++ b/untests/meta_utilities/arg_tests.cpp @@ -69,7 +69,7 @@ namespace #define META_HPP_CHECK_INVOCABLE(FromValue, FName, ToType)\ {\ using namespace meta::detail;\ - auto function_ptr = meta::select(&FName);\ + auto function_ptr = meta::select_overload(&FName);\ meta::function f_state{function_state::make("", function_ptr)};\ \ if ( std::is_invocable_v ) {\ @@ -93,7 +93,7 @@ namespace #define META_HPP_CHECK_INVOCABLE_2(FromValue, FName, FromType, ToType)\ {\ using namespace meta::detail;\ - auto function_ptr = meta::select(&FName);\ + auto function_ptr = meta::select_overload(&FName);\ meta::function f_state{function_state::make("", function_ptr)};\ \ if ( std::is_invocable_v ) {\ diff --git a/untests/meta_utilities/inst_tests.cpp b/untests/meta_utilities/inst_tests.cpp index 90b73d9..bf2936f 100644 --- a/untests/meta_utilities/inst_tests.cpp +++ b/untests/meta_utilities/inst_tests.cpp @@ -29,7 +29,7 @@ namespace #define META_HPP_CHECK_INVOCABLE(Inst, FName, Qualifiers)\ {\ using namespace meta::detail;\ - auto method_ptr = meta::select(&clazz::FName);\ + auto method_ptr = meta::select_overload(&clazz::FName);\ meta::method m_state{method_state::make("", method_ptr)};\ \ if ( std::is_invocable_v ) {\ @@ -53,7 +53,7 @@ namespace #define META_HPP_CHECK_INVOCABLE_2(FromValue, FName, FromType, ToQualifiers)\ {\ using namespace meta::detail;\ - auto method_ptr = meta::select(&clazz::FName);\ + auto method_ptr = meta::select_overload(&clazz::FName);\ meta::method m_state{method_state::make("", method_ptr)};\ \ if ( std::is_invocable_v ) {\ From 4180e35df5825e7b8a603e384c3224da4be3183e Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sat, 5 Feb 2022 07:28:32 +0700 Subject: [PATCH 199/233] fix clang ci compilation --- CMakeLists.txt | 3 + headers/meta.hpp/meta_detail/state_family.hpp | 21 ++++--- headers/meta.hpp/meta_detail/type_family.hpp | 33 ++++++----- .../meta_detail/value_utilities/utraits.hpp | 15 +++-- headers/meta.hpp/meta_states.hpp | 55 ++++++++++++------- manuals/CMakeLists.txt | 2 +- manuals/meta_manuals.hpp | 1 + untests/CMakeLists.txt | 2 +- 8 files changed, 80 insertions(+), 52 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a08a874..c091055 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,6 +13,9 @@ add_library(${PROJECT_NAME} INTERFACE) target_compile_features(${PROJECT_NAME} INTERFACE cxx_std_20) target_include_directories(${PROJECT_NAME} INTERFACE headers) +find_package(Threads REQUIRED) +target_link_libraries(${PROJECT_NAME} INTERFACE Threads::Threads) + target_compile_options(${PROJECT_NAME} INTERFACE $<$: diff --git a/headers/meta.hpp/meta_detail/state_family.hpp b/headers/meta.hpp/meta_detail/state_family.hpp index 4954aa3..a580340 100644 --- a/headers/meta.hpp/meta_detail/state_family.hpp +++ b/headers/meta.hpp/meta_detail/state_family.hpp @@ -11,15 +11,18 @@ namespace meta_hpp::detail { template < typename T > - concept state_family = - stdex::same_as || - stdex::same_as || - stdex::same_as || - stdex::same_as || - stdex::same_as || - stdex::same_as || - stdex::same_as || - stdex::same_as; + inline constexpr bool is_state_family_v = + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v; + + template < typename T > + concept state_family = is_state_family_v; template < state_family T > [[nodiscard]] auto state_access(const T& state) { diff --git a/headers/meta.hpp/meta_detail/type_family.hpp b/headers/meta.hpp/meta_detail/type_family.hpp index f6adfe3..66764e5 100644 --- a/headers/meta.hpp/meta_detail/type_family.hpp +++ b/headers/meta.hpp/meta_detail/type_family.hpp @@ -11,21 +11,24 @@ namespace meta_hpp::detail { template < typename T > - concept type_family = - stdex::same_as || - stdex::same_as || - stdex::same_as || - stdex::same_as || - stdex::same_as || - stdex::same_as || - stdex::same_as || - stdex::same_as || - stdex::same_as || - stdex::same_as || - stdex::same_as || - stdex::same_as || - stdex::same_as || - stdex::same_as; + inline constexpr bool is_type_family_v = + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v; + + template < typename T > + concept type_family = is_type_family_v; template < type_family T > [[nodiscard]] auto type_access(const T& type) { diff --git a/headers/meta.hpp/meta_detail/value_utilities/utraits.hpp b/headers/meta.hpp/meta_detail/value_utilities/utraits.hpp index 5e1b18c..e00ab79 100644 --- a/headers/meta.hpp/meta_detail/value_utilities/utraits.hpp +++ b/headers/meta.hpp/meta_detail/value_utilities/utraits.hpp @@ -12,12 +12,15 @@ namespace meta_hpp::detail { template < typename T > - concept uvalue_kind = - stdex::same_as || - stdex::same_as || - stdex::same_as || - stdex::same_as || - stdex::same_as; + inline constexpr bool is_uvalue_kind_v = + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v; + + template < typename T > + concept uvalue_kind = is_uvalue_kind_v; template < typename T > concept decay_uvalue_kind = uvalue_kind>; diff --git a/headers/meta.hpp/meta_states.hpp b/headers/meta.hpp/meta_states.hpp index 5d6f667..9f0b877 100644 --- a/headers/meta.hpp/meta_states.hpp +++ b/headers/meta.hpp/meta_states.hpp @@ -51,34 +51,49 @@ namespace meta_hpp } template < typename Policy > - concept ctor_policy_kind = - stdex::same_as || - stdex::same_as || - stdex::same_as; + inline constexpr bool is_ctor_policy_v = + std::is_same_v || + std::is_same_v || + std::is_same_v; template < typename Policy > - concept function_policy_kind = - stdex::same_as || - stdex::same_as || - stdex::same_as; + inline constexpr bool is_function_policy_v = + std::is_same_v || + std::is_same_v || + std::is_same_v; template < typename Policy > - concept member_policy_kind = - stdex::same_as || - stdex::same_as || - stdex::same_as; + inline constexpr bool is_member_policy_v = + std::is_same_v || + std::is_same_v || + std::is_same_v; template < typename Policy > - concept method_policy_kind = - stdex::same_as || - stdex::same_as || - stdex::same_as; + inline constexpr bool is_method_policy_v = + std::is_same_v || + std::is_same_v || + std::is_same_v; template < typename Policy > - concept variable_policy_kind = - stdex::same_as || - stdex::same_as || - stdex::same_as; + inline constexpr bool is_variable_policy_v = + std::is_same_v || + std::is_same_v || + std::is_same_v; + + template < typename Policy > + concept ctor_policy_kind = is_ctor_policy_v; + + template < typename Policy > + concept function_policy_kind = is_function_policy_v; + + template < typename Policy > + concept member_policy_kind = is_member_policy_v; + + template < typename Policy > + concept method_policy_kind = is_method_policy_v; + + template < typename Policy > + concept variable_policy_kind = is_variable_policy_v; } namespace meta_hpp diff --git a/manuals/CMakeLists.txt b/manuals/CMakeLists.txt index cd2d17e..11c5f73 100644 --- a/manuals/CMakeLists.txt +++ b/manuals/CMakeLists.txt @@ -18,7 +18,7 @@ endif() file(GLOB_RECURSE MANUALS_SOURCES "*.cpp" "*.hpp") add_executable(${PROJECT_NAME} ${MANUALS_SOURCES}) -target_link_libraries(${PROJECT_NAME} PRIVATE meta.hpp doctest_with_main fmt) +target_link_libraries(${PROJECT_NAME} PRIVATE meta.hpp doctest_with_main fmt-header-only) target_compile_options(${PROJECT_NAME} PRIVATE diff --git a/manuals/meta_manuals.hpp b/manuals/meta_manuals.hpp index cd7bd26..e98de26 100644 --- a/manuals/meta_manuals.hpp +++ b/manuals/meta_manuals.hpp @@ -9,6 +9,7 @@ #ifdef __clang__ #pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wc++20-compat" #pragma clang diagnostic ignored "-Wdocumentation-unknown-command" #pragma clang diagnostic ignored "-Wsigned-enum-bitfield" #pragma clang diagnostic ignored "-Wswitch-enum" diff --git a/untests/CMakeLists.txt b/untests/CMakeLists.txt index d2c23e2..cb187c3 100644 --- a/untests/CMakeLists.txt +++ b/untests/CMakeLists.txt @@ -18,7 +18,7 @@ endif() file(GLOB_RECURSE UNTESTS_SOURCES "*.cpp" "*.hpp") add_executable(${PROJECT_NAME} ${UNTESTS_SOURCES}) -target_link_libraries(${PROJECT_NAME} PRIVATE meta.hpp doctest_with_main fmt) +target_link_libraries(${PROJECT_NAME} PRIVATE meta.hpp doctest_with_main fmt-header-only) target_compile_options(${PROJECT_NAME} PRIVATE From c2b4aff6a0cbad827aa13f18c3d734f8125fefe2 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sat, 5 Feb 2022 08:09:47 +0700 Subject: [PATCH 200/233] warning fixes --- CMakeLists.txt | 7 +- headers/meta.hpp/meta_states/variable.hpp | 2 +- untests/CMakeLists.txt | 2 +- untests/meta_utilities/arg2_tests.cpp | 12 +- untests/meta_utilities/arg3_tests.cpp | 12 +- untests/meta_utilities/arg5_tests.cpp | 6 +- untests/meta_utilities/arg7_tests.cpp | 6 +- untests/meta_utilities/inst_tests.cpp | 288 +++++++++++----------- 8 files changed, 166 insertions(+), 169 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c091055..81720da 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,6 +10,8 @@ endif() project(meta.hpp) add_library(${PROJECT_NAME} INTERFACE) +add_library(${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME}) + target_compile_features(${PROJECT_NAME} INTERFACE cxx_std_20) target_include_directories(${PROJECT_NAME} INTERFACE headers) @@ -30,18 +32,13 @@ target_compile_options(${PROJECT_NAME} -Wno-covered-switch-default -Wno-ctad-maybe-unsupported -Wno-exit-time-destructors - -Wno-extra-semi-stmt -Wno-float-equal -Wno-global-constructors - -Wno-ordered-compare-function-pointers -Wno-padded - -Wno-reserved-identifier - -Wno-shadow-field -Wno-shadow-field-in-constructor -Wno-unknown-warning-option -Wno-unused-macros -Wno-weak-vtables - -Wno-zero-as-null-pointer-constant >) if(BUILD_AS_STANDALONE) diff --git a/headers/meta.hpp/meta_states/variable.hpp b/headers/meta.hpp/meta_states/variable.hpp index fac956f..dd7da54 100644 --- a/headers/meta.hpp/meta_states/variable.hpp +++ b/headers/meta.hpp/meta_states/variable.hpp @@ -67,7 +67,7 @@ namespace meta_hpp::detail using data_type = typename pt::data_type; return !std::is_const_v - && arg.can_cast_to();; + && arg.can_cast_to(); } } diff --git a/untests/CMakeLists.txt b/untests/CMakeLists.txt index cb187c3..6f61e2f 100644 --- a/untests/CMakeLists.txt +++ b/untests/CMakeLists.txt @@ -18,7 +18,7 @@ endif() file(GLOB_RECURSE UNTESTS_SOURCES "*.cpp" "*.hpp") add_executable(${PROJECT_NAME} ${UNTESTS_SOURCES}) -target_link_libraries(${PROJECT_NAME} PRIVATE meta.hpp doctest_with_main fmt-header-only) +target_link_libraries(${PROJECT_NAME} PRIVATE meta.hpp doctest_with_main) target_compile_options(${PROJECT_NAME} PRIVATE diff --git a/untests/meta_utilities/arg2_tests.cpp b/untests/meta_utilities/arg2_tests.cpp index 01a86bb..4fb27cc 100644 --- a/untests/meta_utilities/arg2_tests.cpp +++ b/untests/meta_utilities/arg2_tests.cpp @@ -29,18 +29,18 @@ namespace int A::move_ctors_{}; struct B : virtual A { - int i = 2; - [[maybe_unused, nodiscard]] int f() const { return i; } + int bi = 2; + [[maybe_unused, nodiscard]] int f() const { return bi; } }; struct C : virtual A { - int i = 3; - [[maybe_unused, nodiscard]] int f() const { return i; } + int ci = 3; + [[maybe_unused, nodiscard]] int f() const { return ci; } }; struct D : B, C { - int i = 4; - [[maybe_unused, nodiscard]] int f() const { return i; } + int di = 4; + [[maybe_unused, nodiscard]] int f() const { return di; } }; } diff --git a/untests/meta_utilities/arg3_tests.cpp b/untests/meta_utilities/arg3_tests.cpp index f0647cc..2b84f8d 100644 --- a/untests/meta_utilities/arg3_tests.cpp +++ b/untests/meta_utilities/arg3_tests.cpp @@ -22,18 +22,18 @@ namespace }; struct B : virtual A { - int i = 2; - [[maybe_unused, nodiscard]] int f() const { return i; } + int bi = 2; + [[maybe_unused, nodiscard]] int f() const { return bi; } }; struct C : virtual A { - int i = 3; - [[maybe_unused, nodiscard]] int f() const { return i; } + int ci = 3; + [[maybe_unused, nodiscard]] int f() const { return ci; } }; struct D : B, C { - int i = 4; - [[maybe_unused, nodiscard]] int f() const { return i; } + int di = 4; + [[maybe_unused, nodiscard]] int f() const { return di; } }; } diff --git a/untests/meta_utilities/arg5_tests.cpp b/untests/meta_utilities/arg5_tests.cpp index 3275e88..c8b9ae7 100644 --- a/untests/meta_utilities/arg5_tests.cpp +++ b/untests/meta_utilities/arg5_tests.cpp @@ -21,15 +21,15 @@ namespace }; struct B : virtual A { - int i = 2; + int bi = 2; }; struct C : virtual A { - int i = 3; + int ci = 3; }; struct D : B, C { - int i = 4; + int di = 4; }; } diff --git a/untests/meta_utilities/arg7_tests.cpp b/untests/meta_utilities/arg7_tests.cpp index bd515b9..0cc6239 100644 --- a/untests/meta_utilities/arg7_tests.cpp +++ b/untests/meta_utilities/arg7_tests.cpp @@ -21,15 +21,15 @@ namespace }; struct B : virtual A { - int i = 2; + int bi = 2; }; struct C : virtual A { - int i = 3; + int ci = 3; }; struct D : B, C { - int i = 4; + int di = 4; }; } diff --git a/untests/meta_utilities/inst_tests.cpp b/untests/meta_utilities/inst_tests.cpp index bf2936f..5c4c859 100644 --- a/untests/meta_utilities/inst_tests.cpp +++ b/untests/meta_utilities/inst_tests.cpp @@ -89,19 +89,19 @@ TEST_CASE("meta/meta_utilities/inst2/refs") { CHECK(i.get_ref_type() == meta::detail::inst::ref_types::lvalue); } - META_HPP_CHECK_INVOCABLE(LV(), m1, ); - META_HPP_CHECK_INVOCABLE(LV(), m2, &); - META_HPP_CHECK_INVOCABLE(LV(), m3, &&); - META_HPP_CHECK_INVOCABLE(LV(), m4, const); - META_HPP_CHECK_INVOCABLE(LV(), m5, const &); - META_HPP_CHECK_INVOCABLE(LV(), m6, const &&); + META_HPP_CHECK_INVOCABLE(LV(), m1, ) + META_HPP_CHECK_INVOCABLE(LV(), m2, &) + META_HPP_CHECK_INVOCABLE(LV(), m3, &&) + META_HPP_CHECK_INVOCABLE(LV(), m4, const) + META_HPP_CHECK_INVOCABLE(LV(), m5, const &) + META_HPP_CHECK_INVOCABLE(LV(), m6, const &&) - META_HPP_CHECK_INVOCABLE(LV2(), m1, ); - META_HPP_CHECK_INVOCABLE(LV2(), m2, &); - META_HPP_CHECK_INVOCABLE(LV2(), m3, &&); - META_HPP_CHECK_INVOCABLE(LV2(), m4, const); - META_HPP_CHECK_INVOCABLE(LV2(), m5, const &); - META_HPP_CHECK_INVOCABLE(LV2(), m6, const &&); + META_HPP_CHECK_INVOCABLE(LV2(), m1, ) + META_HPP_CHECK_INVOCABLE(LV2(), m2, &) + META_HPP_CHECK_INVOCABLE(LV2(), m3, &&) + META_HPP_CHECK_INVOCABLE(LV2(), m4, const) + META_HPP_CHECK_INVOCABLE(LV2(), m5, const &) + META_HPP_CHECK_INVOCABLE(LV2(), m6, const &&) } { @@ -115,19 +115,19 @@ TEST_CASE("meta/meta_utilities/inst2/refs") { CHECK(i.get_ref_type() == meta::detail::inst::ref_types::const_lvalue); } - META_HPP_CHECK_INVOCABLE(CLV(), m1, ); - META_HPP_CHECK_INVOCABLE(CLV(), m2, &); - META_HPP_CHECK_INVOCABLE(CLV(), m3, &&); - META_HPP_CHECK_INVOCABLE(CLV(), m4, const); - META_HPP_CHECK_INVOCABLE(CLV(), m5, const &); - META_HPP_CHECK_INVOCABLE(CLV(), m6, const &&); + META_HPP_CHECK_INVOCABLE(CLV(), m1, ) + META_HPP_CHECK_INVOCABLE(CLV(), m2, &) + META_HPP_CHECK_INVOCABLE(CLV(), m3, &&) + META_HPP_CHECK_INVOCABLE(CLV(), m4, const) + META_HPP_CHECK_INVOCABLE(CLV(), m5, const &) + META_HPP_CHECK_INVOCABLE(CLV(), m6, const &&) - META_HPP_CHECK_INVOCABLE(CLV2(), m1, ); - META_HPP_CHECK_INVOCABLE(CLV2(), m2, &); - META_HPP_CHECK_INVOCABLE(CLV2(), m3, &&); - META_HPP_CHECK_INVOCABLE(CLV2(), m4, const); - META_HPP_CHECK_INVOCABLE(CLV2(), m5, const &); - META_HPP_CHECK_INVOCABLE(CLV2(), m6, const &&); + META_HPP_CHECK_INVOCABLE(CLV2(), m1, ) + META_HPP_CHECK_INVOCABLE(CLV2(), m2, &) + META_HPP_CHECK_INVOCABLE(CLV2(), m3, &&) + META_HPP_CHECK_INVOCABLE(CLV2(), m4, const) + META_HPP_CHECK_INVOCABLE(CLV2(), m5, const &) + META_HPP_CHECK_INVOCABLE(CLV2(), m6, const &&) } { @@ -141,19 +141,19 @@ TEST_CASE("meta/meta_utilities/inst2/refs") { CHECK(i.get_ref_type() == meta::detail::inst::ref_types::rvalue); } - META_HPP_CHECK_INVOCABLE(XV(), m1, ); - META_HPP_CHECK_INVOCABLE(XV(), m2, &); - META_HPP_CHECK_INVOCABLE(XV(), m3, &&); - META_HPP_CHECK_INVOCABLE(XV(), m4, const); - META_HPP_CHECK_INVOCABLE(XV(), m5, const &); - META_HPP_CHECK_INVOCABLE(XV(), m6, const &&); + META_HPP_CHECK_INVOCABLE(XV(), m1, ) + META_HPP_CHECK_INVOCABLE(XV(), m2, &) + META_HPP_CHECK_INVOCABLE(XV(), m3, &&) + META_HPP_CHECK_INVOCABLE(XV(), m4, const) + META_HPP_CHECK_INVOCABLE(XV(), m5, const &) + META_HPP_CHECK_INVOCABLE(XV(), m6, const &&) - META_HPP_CHECK_INVOCABLE(XV2(), m1, ); - META_HPP_CHECK_INVOCABLE(XV2(), m2, &); - META_HPP_CHECK_INVOCABLE(XV2(), m3, &&); - META_HPP_CHECK_INVOCABLE(XV2(), m4, const); - META_HPP_CHECK_INVOCABLE(XV2(), m5, const &); - META_HPP_CHECK_INVOCABLE(XV2(), m6, const &&); + META_HPP_CHECK_INVOCABLE(XV2(), m1, ) + META_HPP_CHECK_INVOCABLE(XV2(), m2, &) + META_HPP_CHECK_INVOCABLE(XV2(), m3, &&) + META_HPP_CHECK_INVOCABLE(XV2(), m4, const) + META_HPP_CHECK_INVOCABLE(XV2(), m5, const &) + META_HPP_CHECK_INVOCABLE(XV2(), m6, const &&) } { @@ -167,19 +167,19 @@ TEST_CASE("meta/meta_utilities/inst2/refs") { CHECK(i.get_ref_type() == meta::detail::inst::ref_types::const_rvalue); } - META_HPP_CHECK_INVOCABLE(CXV(), m1, ); - META_HPP_CHECK_INVOCABLE(CXV(), m2, &); - META_HPP_CHECK_INVOCABLE(CXV(), m3, &&); - META_HPP_CHECK_INVOCABLE(CXV(), m4, const); - META_HPP_CHECK_INVOCABLE(CXV(), m5, const &); - META_HPP_CHECK_INVOCABLE(CXV(), m6, const &&); + META_HPP_CHECK_INVOCABLE(CXV(), m1, ) + META_HPP_CHECK_INVOCABLE(CXV(), m2, &) + META_HPP_CHECK_INVOCABLE(CXV(), m3, &&) + META_HPP_CHECK_INVOCABLE(CXV(), m4, const) + META_HPP_CHECK_INVOCABLE(CXV(), m5, const &) + META_HPP_CHECK_INVOCABLE(CXV(), m6, const &&) - META_HPP_CHECK_INVOCABLE(CXV2(), m1, ); - META_HPP_CHECK_INVOCABLE(CXV2(), m2, &); - META_HPP_CHECK_INVOCABLE(CXV2(), m3, &&); - META_HPP_CHECK_INVOCABLE(CXV2(), m4, const); - META_HPP_CHECK_INVOCABLE(CXV2(), m5, const &); - META_HPP_CHECK_INVOCABLE(CXV2(), m6, const &&); + META_HPP_CHECK_INVOCABLE(CXV2(), m1, ) + META_HPP_CHECK_INVOCABLE(CXV2(), m2, &) + META_HPP_CHECK_INVOCABLE(CXV2(), m3, &&) + META_HPP_CHECK_INVOCABLE(CXV2(), m4, const) + META_HPP_CHECK_INVOCABLE(CXV2(), m5, const &) + META_HPP_CHECK_INVOCABLE(CXV2(), m6, const &&) } { @@ -193,19 +193,19 @@ TEST_CASE("meta/meta_utilities/inst2/refs") { CHECK(i.get_ref_type() == meta::detail::inst::ref_types::rvalue); } - META_HPP_CHECK_INVOCABLE(PRV(), m1, ); - META_HPP_CHECK_INVOCABLE(PRV(), m2, &); - META_HPP_CHECK_INVOCABLE(PRV(), m3, &&); - META_HPP_CHECK_INVOCABLE(PRV(), m4, const); - META_HPP_CHECK_INVOCABLE(PRV(), m5, const &); - META_HPP_CHECK_INVOCABLE(PRV(), m6, const &&); + META_HPP_CHECK_INVOCABLE(PRV(), m1, ) + META_HPP_CHECK_INVOCABLE(PRV(), m2, &) + META_HPP_CHECK_INVOCABLE(PRV(), m3, &&) + META_HPP_CHECK_INVOCABLE(PRV(), m4, const) + META_HPP_CHECK_INVOCABLE(PRV(), m5, const &) + META_HPP_CHECK_INVOCABLE(PRV(), m6, const &&) - META_HPP_CHECK_INVOCABLE(PRV2(), m1, ); - META_HPP_CHECK_INVOCABLE(PRV2(), m2, &); - META_HPP_CHECK_INVOCABLE(PRV2(), m3, &&); - META_HPP_CHECK_INVOCABLE(PRV2(), m4, const); - META_HPP_CHECK_INVOCABLE(PRV2(), m5, const &); - META_HPP_CHECK_INVOCABLE(PRV2(), m6, const &&); + META_HPP_CHECK_INVOCABLE(PRV2(), m1, ) + META_HPP_CHECK_INVOCABLE(PRV2(), m2, &) + META_HPP_CHECK_INVOCABLE(PRV2(), m3, &&) + META_HPP_CHECK_INVOCABLE(PRV2(), m4, const) + META_HPP_CHECK_INVOCABLE(PRV2(), m5, const &) + META_HPP_CHECK_INVOCABLE(PRV2(), m6, const &&) } { @@ -219,19 +219,19 @@ TEST_CASE("meta/meta_utilities/inst2/refs") { CHECK(i.get_ref_type() == meta::detail::inst::ref_types::const_rvalue); } - META_HPP_CHECK_INVOCABLE(CPRV(), m1, ); - META_HPP_CHECK_INVOCABLE(CPRV(), m2, &); - META_HPP_CHECK_INVOCABLE(CPRV(), m3, &&); - META_HPP_CHECK_INVOCABLE(CPRV(), m4, const); - META_HPP_CHECK_INVOCABLE(CPRV(), m5, const &); - META_HPP_CHECK_INVOCABLE(CPRV(), m6, const &&); + META_HPP_CHECK_INVOCABLE(CPRV(), m1, ) + META_HPP_CHECK_INVOCABLE(CPRV(), m2, &) + META_HPP_CHECK_INVOCABLE(CPRV(), m3, &&) + META_HPP_CHECK_INVOCABLE(CPRV(), m4, const) + META_HPP_CHECK_INVOCABLE(CPRV(), m5, const &) + META_HPP_CHECK_INVOCABLE(CPRV(), m6, const &&) - META_HPP_CHECK_INVOCABLE(CPRV2(), m1, ); - META_HPP_CHECK_INVOCABLE(CPRV2(), m2, &); - META_HPP_CHECK_INVOCABLE(CPRV2(), m3, &&); - META_HPP_CHECK_INVOCABLE(CPRV2(), m4, const); - META_HPP_CHECK_INVOCABLE(CPRV2(), m5, const &); - META_HPP_CHECK_INVOCABLE(CPRV2(), m6, const &&); + META_HPP_CHECK_INVOCABLE(CPRV2(), m1, ) + META_HPP_CHECK_INVOCABLE(CPRV2(), m2, &) + META_HPP_CHECK_INVOCABLE(CPRV2(), m3, &&) + META_HPP_CHECK_INVOCABLE(CPRV2(), m4, const) + META_HPP_CHECK_INVOCABLE(CPRV2(), m5, const &) + META_HPP_CHECK_INVOCABLE(CPRV2(), m6, const &&) } } @@ -247,19 +247,19 @@ TEST_CASE("meta/meta_utilities/inst2/values") { CHECK(a.get_raw_type() == meta::resolve_type()); CHECK(a.get_ref_type() == meta::detail::arg::ref_types::lvalue); - META_HPP_CHECK_INVOCABLE_2(LV(), m1, clazz&, ); - META_HPP_CHECK_INVOCABLE_2(LV(), m2, clazz&, &); - META_HPP_CHECK_INVOCABLE_2(LV(), m3, clazz&, &&); - META_HPP_CHECK_INVOCABLE_2(LV(), m4, clazz&, const); - META_HPP_CHECK_INVOCABLE_2(LV(), m5, clazz&, const &); - META_HPP_CHECK_INVOCABLE_2(LV(), m6, clazz&, const &&); + META_HPP_CHECK_INVOCABLE_2(LV(), m1, clazz&, ) + META_HPP_CHECK_INVOCABLE_2(LV(), m2, clazz&, &) + META_HPP_CHECK_INVOCABLE_2(LV(), m3, clazz&, &&) + META_HPP_CHECK_INVOCABLE_2(LV(), m4, clazz&, const) + META_HPP_CHECK_INVOCABLE_2(LV(), m5, clazz&, const &) + META_HPP_CHECK_INVOCABLE_2(LV(), m6, clazz&, const &&) - META_HPP_CHECK_INVOCABLE_2(LV2(), m1, dclazz&, ); - META_HPP_CHECK_INVOCABLE_2(LV2(), m2, dclazz&, &); - META_HPP_CHECK_INVOCABLE_2(LV2(), m3, dclazz&, &&); - META_HPP_CHECK_INVOCABLE_2(LV2(), m4, dclazz&, const); - META_HPP_CHECK_INVOCABLE_2(LV2(), m5, dclazz&, const &); - META_HPP_CHECK_INVOCABLE_2(LV2(), m6, dclazz&, const &&); + META_HPP_CHECK_INVOCABLE_2(LV2(), m1, dclazz&, ) + META_HPP_CHECK_INVOCABLE_2(LV2(), m2, dclazz&, &) + META_HPP_CHECK_INVOCABLE_2(LV2(), m3, dclazz&, &&) + META_HPP_CHECK_INVOCABLE_2(LV2(), m4, dclazz&, const) + META_HPP_CHECK_INVOCABLE_2(LV2(), m5, dclazz&, const &) + META_HPP_CHECK_INVOCABLE_2(LV2(), m6, dclazz&, const &&) } { @@ -271,19 +271,19 @@ TEST_CASE("meta/meta_utilities/inst2/values") { CHECK(a.get_raw_type() == meta::resolve_type()); CHECK(a.get_ref_type() == meta::detail::arg::ref_types::const_lvalue); - META_HPP_CHECK_INVOCABLE_2(CLV(), m1, const clazz&, ); - META_HPP_CHECK_INVOCABLE_2(CLV(), m2, const clazz&, &); - META_HPP_CHECK_INVOCABLE_2(CLV(), m3, const clazz&, &&); - META_HPP_CHECK_INVOCABLE_2(CLV(), m4, const clazz&, const); - META_HPP_CHECK_INVOCABLE_2(CLV(), m5, const clazz&, const &); - META_HPP_CHECK_INVOCABLE_2(CLV(), m6, const clazz&, const &&); + META_HPP_CHECK_INVOCABLE_2(CLV(), m1, const clazz&, ) + META_HPP_CHECK_INVOCABLE_2(CLV(), m2, const clazz&, &) + META_HPP_CHECK_INVOCABLE_2(CLV(), m3, const clazz&, &&) + META_HPP_CHECK_INVOCABLE_2(CLV(), m4, const clazz&, const) + META_HPP_CHECK_INVOCABLE_2(CLV(), m5, const clazz&, const &) + META_HPP_CHECK_INVOCABLE_2(CLV(), m6, const clazz&, const &&) - META_HPP_CHECK_INVOCABLE_2(CLV2(), m1, const dclazz&, ); - META_HPP_CHECK_INVOCABLE_2(CLV2(), m2, const dclazz&, &); - META_HPP_CHECK_INVOCABLE_2(CLV2(), m3, const dclazz&, &&); - META_HPP_CHECK_INVOCABLE_2(CLV2(), m4, const dclazz&, const); - META_HPP_CHECK_INVOCABLE_2(CLV2(), m5, const dclazz&, const &); - META_HPP_CHECK_INVOCABLE_2(CLV2(), m6, const dclazz&, const &&); + META_HPP_CHECK_INVOCABLE_2(CLV2(), m1, const dclazz&, ) + META_HPP_CHECK_INVOCABLE_2(CLV2(), m2, const dclazz&, &) + META_HPP_CHECK_INVOCABLE_2(CLV2(), m3, const dclazz&, &&) + META_HPP_CHECK_INVOCABLE_2(CLV2(), m4, const dclazz&, const) + META_HPP_CHECK_INVOCABLE_2(CLV2(), m5, const dclazz&, const &) + META_HPP_CHECK_INVOCABLE_2(CLV2(), m6, const dclazz&, const &&) } { @@ -295,19 +295,19 @@ TEST_CASE("meta/meta_utilities/inst2/values") { CHECK(a.get_raw_type() == meta::resolve_type()); CHECK(a.get_ref_type() == meta::detail::arg::ref_types::rvalue); - META_HPP_CHECK_INVOCABLE_2(XV(), m1, clazz&&, ); - META_HPP_CHECK_INVOCABLE_2(XV(), m2, clazz&&, &); - META_HPP_CHECK_INVOCABLE_2(XV(), m3, clazz&&, &&); - META_HPP_CHECK_INVOCABLE_2(XV(), m4, clazz&&, const); - META_HPP_CHECK_INVOCABLE_2(XV(), m5, clazz&&, const &); - META_HPP_CHECK_INVOCABLE_2(XV(), m6, clazz&&, const &&); + META_HPP_CHECK_INVOCABLE_2(XV(), m1, clazz&&, ) + META_HPP_CHECK_INVOCABLE_2(XV(), m2, clazz&&, &) + META_HPP_CHECK_INVOCABLE_2(XV(), m3, clazz&&, &&) + META_HPP_CHECK_INVOCABLE_2(XV(), m4, clazz&&, const) + META_HPP_CHECK_INVOCABLE_2(XV(), m5, clazz&&, const &) + META_HPP_CHECK_INVOCABLE_2(XV(), m6, clazz&&, const &&) - META_HPP_CHECK_INVOCABLE_2(XV2(), m1, dclazz&&, ); - META_HPP_CHECK_INVOCABLE_2(XV2(), m2, dclazz&&, &); - META_HPP_CHECK_INVOCABLE_2(XV2(), m3, dclazz&&, &&); - META_HPP_CHECK_INVOCABLE_2(XV2(), m4, dclazz&&, const); - META_HPP_CHECK_INVOCABLE_2(XV2(), m5, dclazz&&, const &); - META_HPP_CHECK_INVOCABLE_2(XV2(), m6, dclazz&&, const &&); + META_HPP_CHECK_INVOCABLE_2(XV2(), m1, dclazz&&, ) + META_HPP_CHECK_INVOCABLE_2(XV2(), m2, dclazz&&, &) + META_HPP_CHECK_INVOCABLE_2(XV2(), m3, dclazz&&, &&) + META_HPP_CHECK_INVOCABLE_2(XV2(), m4, dclazz&&, const) + META_HPP_CHECK_INVOCABLE_2(XV2(), m5, dclazz&&, const &) + META_HPP_CHECK_INVOCABLE_2(XV2(), m6, dclazz&&, const &&) } { @@ -319,19 +319,19 @@ TEST_CASE("meta/meta_utilities/inst2/values") { CHECK(a.get_raw_type() == meta::resolve_type()); CHECK(a.get_ref_type() == meta::detail::arg::ref_types::const_rvalue); - META_HPP_CHECK_INVOCABLE_2(CXV(), m1, const clazz&&, ); - META_HPP_CHECK_INVOCABLE_2(CXV(), m2, const clazz&&, &); - META_HPP_CHECK_INVOCABLE_2(CXV(), m3, const clazz&&, &&); - META_HPP_CHECK_INVOCABLE_2(CXV(), m4, const clazz&&, const); - META_HPP_CHECK_INVOCABLE_2(CXV(), m5, const clazz&&, const &); - META_HPP_CHECK_INVOCABLE_2(CXV(), m6, const clazz&&, const &&); + META_HPP_CHECK_INVOCABLE_2(CXV(), m1, const clazz&&, ) + META_HPP_CHECK_INVOCABLE_2(CXV(), m2, const clazz&&, &) + META_HPP_CHECK_INVOCABLE_2(CXV(), m3, const clazz&&, &&) + META_HPP_CHECK_INVOCABLE_2(CXV(), m4, const clazz&&, const) + META_HPP_CHECK_INVOCABLE_2(CXV(), m5, const clazz&&, const &) + META_HPP_CHECK_INVOCABLE_2(CXV(), m6, const clazz&&, const &&) - META_HPP_CHECK_INVOCABLE_2(CXV2(), m1, const dclazz&&, ); - META_HPP_CHECK_INVOCABLE_2(CXV2(), m2, const dclazz&&, &); - META_HPP_CHECK_INVOCABLE_2(CXV2(), m3, const dclazz&&, &&); - META_HPP_CHECK_INVOCABLE_2(CXV2(), m4, const dclazz&&, const); - META_HPP_CHECK_INVOCABLE_2(CXV2(), m5, const dclazz&&, const &); - META_HPP_CHECK_INVOCABLE_2(CXV2(), m6, const dclazz&&, const &&); + META_HPP_CHECK_INVOCABLE_2(CXV2(), m1, const dclazz&&, ) + META_HPP_CHECK_INVOCABLE_2(CXV2(), m2, const dclazz&&, &) + META_HPP_CHECK_INVOCABLE_2(CXV2(), m3, const dclazz&&, &&) + META_HPP_CHECK_INVOCABLE_2(CXV2(), m4, const dclazz&&, const) + META_HPP_CHECK_INVOCABLE_2(CXV2(), m5, const dclazz&&, const &) + META_HPP_CHECK_INVOCABLE_2(CXV2(), m6, const dclazz&&, const &&) } { @@ -343,19 +343,19 @@ TEST_CASE("meta/meta_utilities/inst2/values") { CHECK(a.get_raw_type() == meta::resolve_type()); CHECK(a.get_ref_type() == meta::detail::arg::ref_types::rvalue); - META_HPP_CHECK_INVOCABLE_2(PRV(), m1, clazz, ); - META_HPP_CHECK_INVOCABLE_2(PRV(), m2, clazz, &); - META_HPP_CHECK_INVOCABLE_2(PRV(), m3, clazz, &&); - META_HPP_CHECK_INVOCABLE_2(PRV(), m4, clazz, const); - META_HPP_CHECK_INVOCABLE_2(PRV(), m5, clazz, const &); - META_HPP_CHECK_INVOCABLE_2(PRV(), m6, clazz, const &&); + META_HPP_CHECK_INVOCABLE_2(PRV(), m1, clazz, ) + META_HPP_CHECK_INVOCABLE_2(PRV(), m2, clazz, &) + META_HPP_CHECK_INVOCABLE_2(PRV(), m3, clazz, &&) + META_HPP_CHECK_INVOCABLE_2(PRV(), m4, clazz, const) + META_HPP_CHECK_INVOCABLE_2(PRV(), m5, clazz, const &) + META_HPP_CHECK_INVOCABLE_2(PRV(), m6, clazz, const &&) - META_HPP_CHECK_INVOCABLE_2(PRV2(), m1, dclazz, ); - META_HPP_CHECK_INVOCABLE_2(PRV2(), m2, dclazz, &); - META_HPP_CHECK_INVOCABLE_2(PRV2(), m3, dclazz, &&); - META_HPP_CHECK_INVOCABLE_2(PRV2(), m4, dclazz, const); - META_HPP_CHECK_INVOCABLE_2(PRV2(), m5, dclazz, const &); - META_HPP_CHECK_INVOCABLE_2(PRV2(), m6, dclazz, const &&); + META_HPP_CHECK_INVOCABLE_2(PRV2(), m1, dclazz, ) + META_HPP_CHECK_INVOCABLE_2(PRV2(), m2, dclazz, &) + META_HPP_CHECK_INVOCABLE_2(PRV2(), m3, dclazz, &&) + META_HPP_CHECK_INVOCABLE_2(PRV2(), m4, dclazz, const) + META_HPP_CHECK_INVOCABLE_2(PRV2(), m5, dclazz, const &) + META_HPP_CHECK_INVOCABLE_2(PRV2(), m6, dclazz, const &&) } { @@ -367,18 +367,18 @@ TEST_CASE("meta/meta_utilities/inst2/values") { CHECK(a.get_raw_type() == meta::resolve_type()); CHECK(a.get_ref_type() == meta::detail::arg::ref_types::const_rvalue); - META_HPP_CHECK_INVOCABLE_2(CPRV(), m1, const clazz, ); - META_HPP_CHECK_INVOCABLE_2(CPRV(), m2, const clazz, &); - META_HPP_CHECK_INVOCABLE_2(CPRV(), m3, const clazz, &&); - META_HPP_CHECK_INVOCABLE_2(CPRV(), m4, const clazz, const); - META_HPP_CHECK_INVOCABLE_2(CPRV(), m5, const clazz, const &); - META_HPP_CHECK_INVOCABLE_2(CPRV(), m6, const clazz, const &&); + META_HPP_CHECK_INVOCABLE_2(CPRV(), m1, const clazz, ) + META_HPP_CHECK_INVOCABLE_2(CPRV(), m2, const clazz, &) + META_HPP_CHECK_INVOCABLE_2(CPRV(), m3, const clazz, &&) + META_HPP_CHECK_INVOCABLE_2(CPRV(), m4, const clazz, const) + META_HPP_CHECK_INVOCABLE_2(CPRV(), m5, const clazz, const &) + META_HPP_CHECK_INVOCABLE_2(CPRV(), m6, const clazz, const &&) - META_HPP_CHECK_INVOCABLE_2(CPRV2(), m1, const dclazz, ); - META_HPP_CHECK_INVOCABLE_2(CPRV2(), m2, const dclazz, &); - META_HPP_CHECK_INVOCABLE_2(CPRV2(), m3, const dclazz, &&); - META_HPP_CHECK_INVOCABLE_2(CPRV2(), m4, const dclazz, const); - META_HPP_CHECK_INVOCABLE_2(CPRV2(), m5, const dclazz, const &); - META_HPP_CHECK_INVOCABLE_2(CPRV2(), m6, const dclazz, const &&); + META_HPP_CHECK_INVOCABLE_2(CPRV2(), m1, const dclazz, ) + META_HPP_CHECK_INVOCABLE_2(CPRV2(), m2, const dclazz, &) + META_HPP_CHECK_INVOCABLE_2(CPRV2(), m3, const dclazz, &&) + META_HPP_CHECK_INVOCABLE_2(CPRV2(), m4, const dclazz, const) + META_HPP_CHECK_INVOCABLE_2(CPRV2(), m5, const dclazz, const &) + META_HPP_CHECK_INVOCABLE_2(CPRV2(), m6, const dclazz, const &&) } } From 9116a7bcc4259324f18defc12e0b0bfdd4925c4d Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sat, 5 Feb 2022 08:52:42 +0700 Subject: [PATCH 201/233] fix more warnings --- CMakeLists.txt | 2 -- headers/meta.hpp/meta_base/enum_bitflags.hpp | 12 ++++++------ .../meta_detail/value_traits/equals_traits.hpp | 4 ++-- .../meta_detail/value_traits/less_traits.hpp | 4 ++-- headers/meta.hpp/meta_indices/evalue_index.hpp | 4 ++-- headers/meta.hpp/meta_indices/function_index.hpp | 4 ++-- headers/meta.hpp/meta_indices/member_index.hpp | 4 ++-- headers/meta.hpp/meta_indices/method_index.hpp | 4 ++-- headers/meta.hpp/meta_indices/scope_index.hpp | 4 ++-- headers/meta.hpp/meta_indices/variable_index.hpp | 4 ++-- 10 files changed, 22 insertions(+), 24 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 81720da..ab5d80a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,9 +30,7 @@ target_compile_options(${PROJECT_NAME} -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-covered-switch-default - -Wno-ctad-maybe-unsupported -Wno-exit-time-destructors - -Wno-float-equal -Wno-global-constructors -Wno-padded -Wno-shadow-field-in-constructor diff --git a/headers/meta.hpp/meta_base/enum_bitflags.hpp b/headers/meta.hpp/meta_base/enum_bitflags.hpp index 5b021cb..a98db15 100644 --- a/headers/meta.hpp/meta_base/enum_bitflags.hpp +++ b/headers/meta.hpp/meta_base/enum_bitflags.hpp @@ -133,7 +133,7 @@ namespace enum_hpp::bitflags }\ template < typename Enum >\ constexpr bitflags operator op (bitflags l, Enum r) noexcept {\ - return l op bitflags{r};\ + return l op bitflags{r};\ }\ template < typename Enum >\ constexpr bitflags operator op (bitflags l, bitflags r) noexcept {\ @@ -141,7 +141,7 @@ namespace enum_hpp::bitflags }\ template < typename Enum >\ constexpr bitflags& operator op##= (bitflags& l, Enum r) noexcept {\ - return l = l op bitflags{r};\ + return l = l op bitflags{r};\ }\ template < typename Enum >\ constexpr bitflags& operator op##= (bitflags& l, bitflags r) noexcept {\ @@ -319,14 +319,14 @@ namespace enum_hpp::bitflags #define ENUM_HPP_OPERATORS_DECL(Enum)\ constexpr ::enum_hpp::bitflags::bitflags operator~ [[maybe_unused]] (Enum l) noexcept {\ - return ~::enum_hpp::bitflags::bitflags(l);\ + return ~::enum_hpp::bitflags::bitflags(l);\ }\ constexpr ::enum_hpp::bitflags::bitflags operator| [[maybe_unused]] (Enum l, Enum r) noexcept {\ - return ::enum_hpp::bitflags::bitflags(l) | ::enum_hpp::bitflags::bitflags(r);\ + return ::enum_hpp::bitflags::bitflags(l) | ::enum_hpp::bitflags::bitflags(r);\ }\ constexpr ::enum_hpp::bitflags::bitflags operator& [[maybe_unused]] (Enum l, Enum r) noexcept {\ - return ::enum_hpp::bitflags::bitflags(l) & ::enum_hpp::bitflags::bitflags(r);\ + return ::enum_hpp::bitflags::bitflags(l) & ::enum_hpp::bitflags::bitflags(r);\ }\ constexpr ::enum_hpp::bitflags::bitflags operator^ [[maybe_unused]] (Enum l, Enum r) noexcept {\ - return ::enum_hpp::bitflags::bitflags(l) ^ ::enum_hpp::bitflags::bitflags(r);\ + return ::enum_hpp::bitflags::bitflags(l) ^ ::enum_hpp::bitflags::bitflags(r);\ } diff --git a/headers/meta.hpp/meta_detail/value_traits/equals_traits.hpp b/headers/meta.hpp/meta_detail/value_traits/equals_traits.hpp index bd87246..19bf177 100644 --- a/headers/meta.hpp/meta_detail/value_traits/equals_traits.hpp +++ b/headers/meta.hpp/meta_detail/value_traits/equals_traits.hpp @@ -24,11 +24,11 @@ namespace meta_hpp::detail { template < typename T > requires requires(const T& l, const T& r) { - { l == r } -> stdex::convertible_to; + { std::equal_to<>{}(l, r) } -> stdex::convertible_to; } struct equals_traits { bool operator()(const T& l, const T& r) const { - return l == r; + return std::equal_to<>{}(l, r); } }; } diff --git a/headers/meta.hpp/meta_detail/value_traits/less_traits.hpp b/headers/meta.hpp/meta_detail/value_traits/less_traits.hpp index ac39ce4..4140163 100644 --- a/headers/meta.hpp/meta_detail/value_traits/less_traits.hpp +++ b/headers/meta.hpp/meta_detail/value_traits/less_traits.hpp @@ -24,11 +24,11 @@ namespace meta_hpp::detail { template < typename T > requires requires(const T& l, const T& r) { - { l < r } -> stdex::convertible_to; + { std::less<>{}(l, r) } -> stdex::convertible_to; } struct less_traits { bool operator()(const T& l, const T& r) const { - return l < r; + return std::less<>{}(l, r); } }; } diff --git a/headers/meta.hpp/meta_indices/evalue_index.hpp b/headers/meta.hpp/meta_indices/evalue_index.hpp index 8381bc8..8d28db8 100644 --- a/headers/meta.hpp/meta_indices/evalue_index.hpp +++ b/headers/meta.hpp/meta_indices/evalue_index.hpp @@ -32,10 +32,10 @@ namespace meta_hpp } inline bool operator<(const evalue_index& l, const evalue_index& r) noexcept { - return l.type_ < r.type_ || (l.type_ == r.type_ && l.name_ < r.name_); + return l.type_ < r.type_ || (l.type_ == r.type_ && std::less<>{}(l.name_, r.name_)); } inline bool operator==(const evalue_index& l, const evalue_index& r) noexcept { - return l.type_ == r.type_ && l.name_ == r.name_; + return l.type_ == r.type_ && std::equal_to<>{}(l.name_, r.name_); } } diff --git a/headers/meta.hpp/meta_indices/function_index.hpp b/headers/meta.hpp/meta_indices/function_index.hpp index a63aaad..cc1e8af 100644 --- a/headers/meta.hpp/meta_indices/function_index.hpp +++ b/headers/meta.hpp/meta_indices/function_index.hpp @@ -32,10 +32,10 @@ namespace meta_hpp } inline bool operator<(const function_index& l, const function_index& r) noexcept { - return l.type_ < r.type_ || (l.type_ == r.type_ && l.name_ < r.name_); + return l.type_ < r.type_ || (l.type_ == r.type_ && std::less<>{}(l.name_, r.name_)); } inline bool operator==(const function_index& l, const function_index& r) noexcept { - return l.type_ == r.type_ && l.name_ == r.name_; + return l.type_ == r.type_ && std::equal_to<>{}(l.name_, r.name_); } } diff --git a/headers/meta.hpp/meta_indices/member_index.hpp b/headers/meta.hpp/meta_indices/member_index.hpp index 3101f0f..f9a8999 100644 --- a/headers/meta.hpp/meta_indices/member_index.hpp +++ b/headers/meta.hpp/meta_indices/member_index.hpp @@ -32,10 +32,10 @@ namespace meta_hpp } inline bool operator<(const member_index& l, const member_index& r) noexcept { - return l.type_ < r.type_ || (l.type_ == r.type_ && l.name_ < r.name_); + return l.type_ < r.type_ || (l.type_ == r.type_ && std::less<>{}(l.name_, r.name_)); } inline bool operator==(const member_index& l, const member_index& r) noexcept { - return l.type_ == r.type_ && l.name_ == r.name_; + return l.type_ == r.type_ && std::equal_to<>{}(l.name_, r.name_); } } diff --git a/headers/meta.hpp/meta_indices/method_index.hpp b/headers/meta.hpp/meta_indices/method_index.hpp index 8ad0a3a..5e7b0a3 100644 --- a/headers/meta.hpp/meta_indices/method_index.hpp +++ b/headers/meta.hpp/meta_indices/method_index.hpp @@ -32,10 +32,10 @@ namespace meta_hpp } inline bool operator<(const method_index& l, const method_index& r) noexcept { - return l.type_ < r.type_ || (l.type_ == r.type_ && l.name_ < r.name_); + return l.type_ < r.type_ || (l.type_ == r.type_ && std::less<>{}(l.name_, r.name_)); } inline bool operator==(const method_index& l, const method_index& r) noexcept { - return l.type_ == r.type_ && l.name_ == r.name_; + return l.type_ == r.type_ && std::equal_to<>{}(l.name_, r.name_); } } diff --git a/headers/meta.hpp/meta_indices/scope_index.hpp b/headers/meta.hpp/meta_indices/scope_index.hpp index 2beb83a..01efe9c 100644 --- a/headers/meta.hpp/meta_indices/scope_index.hpp +++ b/headers/meta.hpp/meta_indices/scope_index.hpp @@ -26,10 +26,10 @@ namespace meta_hpp } inline bool operator<(const scope_index& l, const scope_index& r) noexcept { - return l.name_ < r.name_; + return std::less<>{}(l.name_, r.name_); } inline bool operator==(const scope_index& l, const scope_index& r) noexcept { - return l.name_ == r.name_; + return std::equal_to<>{}(l.name_, r.name_); } } diff --git a/headers/meta.hpp/meta_indices/variable_index.hpp b/headers/meta.hpp/meta_indices/variable_index.hpp index 1bc700f..bdaa33a 100644 --- a/headers/meta.hpp/meta_indices/variable_index.hpp +++ b/headers/meta.hpp/meta_indices/variable_index.hpp @@ -32,10 +32,10 @@ namespace meta_hpp } inline bool operator<(const variable_index& l, const variable_index& r) noexcept { - return l.type_ < r.type_ || (l.type_ == r.type_ && l.name_ < r.name_); + return l.type_ < r.type_ || (l.type_ == r.type_ && std::less<>{}(l.name_, r.name_)); } inline bool operator==(const variable_index& l, const variable_index& r) noexcept { - return l.type_ == r.type_ && l.name_ == r.name_; + return l.type_ == r.type_ && std::equal_to<>{}(l.name_, r.name_); } } From b2e3349e0debe32b7f4a07a35a8c1fbbcfab244b Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sat, 5 Feb 2022 11:11:00 +0700 Subject: [PATCH 202/233] hide make function for indices --- headers/meta.hpp/meta_indices.hpp | 58 +++++++++++++++---------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/headers/meta.hpp/meta_indices.hpp b/headers/meta.hpp/meta_indices.hpp index 581de66..5be5774 100644 --- a/headers/meta.hpp/meta_indices.hpp +++ b/headers/meta.hpp/meta_indices.hpp @@ -14,11 +14,11 @@ namespace meta_hpp class ctor_index final { public: ctor_index() = delete; - + [[nodiscard]] const ctor_type& get_type() const noexcept; + private: + friend detail::ctor_state; template < detail::class_kind Class, typename... Args > [[nodiscard]] static ctor_index make(); - - [[nodiscard]] const ctor_type& get_type() const noexcept; private: explicit ctor_index(ctor_type type); friend bool operator<(const ctor_index& l, const ctor_index& r) noexcept; @@ -30,11 +30,11 @@ namespace meta_hpp class dtor_index final { public: dtor_index() = delete; - + [[nodiscard]] const dtor_type& get_type() const noexcept; + private: + friend detail::dtor_state; template < detail::class_kind Class > [[nodiscard]] static dtor_index make(); - - [[nodiscard]] const dtor_type& get_type() const noexcept; private: explicit dtor_index(dtor_type type); friend bool operator<(const dtor_index& l, const dtor_index& r) noexcept; @@ -46,12 +46,12 @@ namespace meta_hpp class evalue_index final { public: evalue_index() = delete; - - template < detail::enum_kind Enum > - [[nodiscard]] static evalue_index make(std::string name); - [[nodiscard]] const enum_type& get_type() const noexcept; [[nodiscard]] const std::string& get_name() const noexcept; + private: + friend detail::evalue_state; + template < detail::enum_kind Enum > + [[nodiscard]] static evalue_index make(std::string name); private: explicit evalue_index(enum_type type, std::string name); friend bool operator<(const evalue_index& l, const evalue_index& r) noexcept; @@ -64,12 +64,12 @@ namespace meta_hpp class function_index final { public: function_index() = delete; - - template < detail::function_kind Function > - [[nodiscard]] static function_index make(std::string name); - [[nodiscard]] const function_type& get_type() const noexcept; [[nodiscard]] const std::string& get_name() const noexcept; + private: + friend detail::function_state; + template < detail::function_kind Function > + [[nodiscard]] static function_index make(std::string name); private: explicit function_index(function_type type, std::string name); friend bool operator<(const function_index& l, const function_index& r) noexcept; @@ -82,12 +82,12 @@ namespace meta_hpp class member_index final { public: member_index() = delete; - - template < detail::member_kind Member > - [[nodiscard]] static member_index make(std::string name); - [[nodiscard]] const member_type& get_type() const noexcept; [[nodiscard]] const std::string& get_name() const noexcept; + private: + friend detail::member_state; + template < detail::member_kind Member > + [[nodiscard]] static member_index make(std::string name); private: explicit member_index(member_type type, std::string name); friend bool operator<(const member_index& l, const member_index& r) noexcept; @@ -100,12 +100,12 @@ namespace meta_hpp class method_index final { public: method_index() = delete; - - template < detail::method_kind Method > - [[nodiscard]] static method_index make(std::string name); - [[nodiscard]] const method_type& get_type() const noexcept; [[nodiscard]] const std::string& get_name() const noexcept; + private: + friend detail::method_state; + template < detail::method_kind Method > + [[nodiscard]] static method_index make(std::string name); private: explicit method_index(method_type type, std::string name); friend bool operator<(const method_index& l, const method_index& r) noexcept; @@ -118,10 +118,10 @@ namespace meta_hpp class scope_index final { public: scope_index() = delete; - - [[nodiscard]] static scope_index make(std::string name); - [[nodiscard]] const std::string& get_name() const noexcept; + private: + friend detail::scope_state; + [[nodiscard]] static scope_index make(std::string name); private: explicit scope_index(std::string name); friend bool operator<(const scope_index& l, const scope_index& r) noexcept; @@ -133,12 +133,12 @@ namespace meta_hpp class variable_index final { public: variable_index() = delete; - - template < detail::pointer_kind Pointer > - [[nodiscard]] static variable_index make(std::string name); - [[nodiscard]] const pointer_type& get_type() const noexcept; [[nodiscard]] const std::string& get_name() const noexcept; + private: + friend detail::variable_state; + template < detail::pointer_kind Pointer > + [[nodiscard]] static variable_index make(std::string name); private: explicit variable_index(pointer_type type, std::string name); friend bool operator<(const variable_index& l, const variable_index& r) noexcept; From 65b30fdbc24d31fafae6097f8503917bbb2e5372 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sun, 6 Feb 2022 11:59:51 +0700 Subject: [PATCH 203/233] fixed_function instead std::function --- headers/meta.hpp/meta_base.hpp | 1 + headers/meta.hpp/meta_base/fixed_function.hpp | 203 ++++++++++++++++++ headers/meta.hpp/meta_states.hpp | 80 +++---- headers/meta.hpp/meta_value.hpp | 9 +- headers/meta.hpp/meta_value/value.hpp | 37 ++-- untests/meta_base/fixed_function_tests.cpp | 122 +++++++++++ 6 files changed, 394 insertions(+), 58 deletions(-) create mode 100644 headers/meta.hpp/meta_base/fixed_function.hpp create mode 100644 untests/meta_base/fixed_function_tests.cpp diff --git a/headers/meta.hpp/meta_base.hpp b/headers/meta.hpp/meta_base.hpp index 24c5330..cec6fac 100644 --- a/headers/meta.hpp/meta_base.hpp +++ b/headers/meta.hpp/meta_base.hpp @@ -35,6 +35,7 @@ #include "meta_base/cvref_traits.hpp" #include "meta_base/enum_bitflags.hpp" #include "meta_base/enum.hpp" +#include "meta_base/fixed_function.hpp" #include "meta_base/noncopyable.hpp" #include "meta_base/overloaded.hpp" #include "meta_base/select_overload.hpp" diff --git a/headers/meta.hpp/meta_base/fixed_function.hpp b/headers/meta.hpp/meta_base/fixed_function.hpp new file mode 100644 index 0000000..8bac775 --- /dev/null +++ b/headers/meta.hpp/meta_base/fixed_function.hpp @@ -0,0 +1,203 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include +#include +#include +#include + +namespace meta_hpp::detail +{ + template < typename Function, std::size_t MaxFunctorSize = sizeof(void*) * 3 > + class fixed_function; + + template < typename R, typename... Args, std::size_t MaxFunctorSize > + class fixed_function final { + public: + fixed_function() = default; + ~fixed_function() { reset(); } + + fixed_function(const fixed_function& other) = delete; + fixed_function& operator=(const fixed_function& other) = delete; + + fixed_function(fixed_function&& other) noexcept { + if ( other.vtable_ ) { + other.vtable_->move(other, *this); + } + } + + fixed_function& operator=(fixed_function&& other) noexcept { + if ( this != &other ) { + fixed_function{std::move(other)}.swap(*this); + } + return *this; + } + + template < typename Functor > + fixed_function(Functor&& functor) { + vtable_t::construct(*this, std::forward(functor)); + } + + template < typename Functor > + fixed_function& operator=(Functor&& functor) { + fixed_function{std::forward(functor)}.swap(*this); + return *this; + } + + [[nodiscard]] bool is_valid() const noexcept { + return !!vtable_; + } + + [[nodiscard]] explicit operator bool() const noexcept { + return is_valid(); + } + + R operator()(Args... args) const { + return vtable_ + ? vtable_->call(*this, std::forward(args)...) + : throw std::bad_function_call(); + } + + void reset() noexcept { + if ( vtable_ ) { + vtable_->destroy(*this); + } + } + + void swap(fixed_function& other) noexcept { + vtable_t::swap(*this, other); + } + private: + struct vtable_t; + vtable_t* vtable_{}; + private: + using storage_t = std::aligned_storage_t; + storage_t storage_{}; + }; + + template < typename Function, std::size_t MaxFunctorSize > + inline void swap(fixed_function& l, fixed_function& r) noexcept { + l.swap(r); + } +} + +namespace meta_hpp::detail +{ + template < typename R, typename... Args, std::size_t MaxFunctorSize > + struct fixed_function::vtable_t final { + R (*const call)(const fixed_function& self, Args... args); + void (*const move)(fixed_function& from, fixed_function& to) noexcept; + void (*const destroy)(fixed_function& self); + + template < typename T > + static T* storage_cast(storage_t& storage) noexcept { + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + return reinterpret_cast(&storage); + } + + template < typename T > + static const T* storage_cast(const storage_t& storage) noexcept { + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + return reinterpret_cast(&storage); + } + + template < typename FunctionType > + static vtable_t* get() { + static vtable_t table{ + .call = +[](const fixed_function& self, Args... args) -> R { + assert(self); + + const FunctionType& src = *storage_cast(self.storage_); + return std::invoke(src, std::forward(args)...); + }, + .move = +[](fixed_function& from, fixed_function& to) noexcept { + assert(from && !to); + + FunctionType& src = *storage_cast(from.storage_); + ::new (&to.storage_) FunctionType(std::move(src)); + + to.vtable_ = from.vtable_; + from.vtable_->destroy(from); + }, + .destroy = +[](fixed_function& self){ + assert(self); + + FunctionType& src = *storage_cast(self.storage_); + src.~FunctionType(); + + self.vtable_ = nullptr; + }, + }; + return &table; + } + + template < typename Functor > + static void construct(fixed_function& dst, Functor&& functor) { + using Fp = std::decay_t; + + static_assert( + sizeof(Fp) <= MaxFunctorSize && + alignof(Fp) <= alignof(storage_t) && + std::is_invocable_r_v && + std::is_nothrow_move_constructible_v); + + ::new (&dst.storage_) Fp(std::forward(functor)); + dst.vtable_ = vtable_t::get(); + } + + static void swap(fixed_function& l, fixed_function& r) noexcept { + if ( (&l == &r) || (!l && !r) ) { + return; + } + + if ( l && r ) { + fixed_function temp; + r.vtable_->move(r, temp); + l.vtable_->move(l, r); + temp.vtable_->move(temp, l); + } else { + if ( l ) { + l.vtable_->move(l, r); + } else { + r.vtable_->move(r, l); + } + } + } + }; +} + +namespace meta_hpp::detail +{ + namespace impl + { + template < typename F > + struct strip_signature_impl; + + template < typename R, typename C, bool NoExcept, typename... Args > + struct strip_signature_impl { using type = R(Args...); }; + + template < typename R, typename C, bool NoExcept, typename... Args > + struct strip_signature_impl { using type = R(Args...); }; + + template < typename R, typename C, bool NoExcept, typename... Args > + struct strip_signature_impl { using type = R(Args...); }; + + template < typename R, typename C, bool NoExcept, typename... Args > + struct strip_signature_impl { using type = R(Args...); }; + + template < typename F > + using strip_signature_impl_t = typename strip_signature_impl::type; + } + + template < typename R, typename... Args > + fixed_function(R(*)(Args...)) -> fixed_function; + + template < typename Functor + , typename Signature = impl::strip_signature_impl_t > + fixed_function(Functor) -> fixed_function; +} diff --git a/headers/meta.hpp/meta_states.hpp b/headers/meta.hpp/meta_states.hpp index 9f0b877..3f590cd 100644 --- a/headers/meta.hpp/meta_states.hpp +++ b/headers/meta.hpp/meta_states.hpp @@ -367,81 +367,81 @@ namespace meta_hpp namespace meta_hpp::detail { struct ctor_state final { - using invoke_impl = std::function)>; - using is_invocable_with_impl = std::function)>; + using invoke_impl = fixed_function)>; + using is_invocable_with_impl = fixed_function)>; - const ctor_index index; - const invoke_impl invoke; - const is_invocable_with_impl is_invocable_with; + ctor_index index; + invoke_impl invoke; + is_invocable_with_impl is_invocable_with; template < ctor_policy_kind Policy, class_kind Class, typename... Args > [[nodiscard]] static ctor_state_ptr make(); }; struct dtor_state final { - using invoke_impl = std::function; - using is_invocable_with_impl = std::function; + using invoke_impl = fixed_function; + using is_invocable_with_impl = fixed_function; - const dtor_index index; - const invoke_impl invoke; - const is_invocable_with_impl is_invocable_with; + dtor_index index; + invoke_impl invoke; + is_invocable_with_impl is_invocable_with; template < class_kind Class > [[nodiscard]] static dtor_state_ptr make(); }; struct evalue_state final { - const evalue_index index; - const value enum_value; - const value underlying_value; + evalue_index index; + value enum_value; + value underlying_value; template < enum_kind Enum > [[nodiscard]] static evalue_state_ptr make(std::string name, Enum evalue); }; struct function_state final { - using invoke_impl = std::function)>; - using is_invocable_with_impl = std::function)>; + using invoke_impl = fixed_function)>; + using is_invocable_with_impl = fixed_function)>; - const function_index index; - const invoke_impl invoke; - const is_invocable_with_impl is_invocable_with; + function_index index; + invoke_impl invoke; + is_invocable_with_impl is_invocable_with; template < function_policy_kind Policy, function_kind Function > [[nodiscard]] static function_state_ptr make(std::string name, Function function); }; struct member_state final { - using getter_impl = std::function; - using setter_impl = std::function; + using getter_impl = fixed_function; + using setter_impl = fixed_function; - using is_gettable_with_impl = std::function; - using is_settable_with_impl = std::function; + using is_gettable_with_impl = fixed_function; + using is_settable_with_impl = fixed_function; - const member_index index; - const getter_impl getter; - const setter_impl setter; - const is_gettable_with_impl is_gettable_with; - const is_settable_with_impl is_settable_with; + member_index index; + getter_impl getter; + setter_impl setter; + is_gettable_with_impl is_gettable_with; + is_settable_with_impl is_settable_with; template < member_policy_kind Policy, member_kind Member > [[nodiscard]] static member_state_ptr make(std::string name, Member member); }; struct method_state final { - using invoke_impl = std::function)>; - using is_invocable_with_impl = std::function)>; + using invoke_impl = fixed_function)>; + using is_invocable_with_impl = fixed_function)>; - const method_index index; - const invoke_impl invoke; - const is_invocable_with_impl is_invocable_with; + method_index index; + invoke_impl invoke; + is_invocable_with_impl is_invocable_with; template < method_policy_kind Policy, method_kind Method > [[nodiscard]] static method_state_ptr make(std::string name, Method method); }; struct scope_state final { - const scope_index index; + scope_index index; class_map classes{}; enum_map enums{}; @@ -452,14 +452,14 @@ namespace meta_hpp::detail }; struct variable_state final { - using getter_impl = std::function; - using setter_impl = std::function; - using is_settable_with_impl = std::function; + using getter_impl = fixed_function; + using setter_impl = fixed_function; + using is_settable_with_impl = fixed_function; - const variable_index index; - const getter_impl getter; - const setter_impl setter; - const is_settable_with_impl is_settable_with; + variable_index index; + getter_impl getter; + setter_impl setter; + is_settable_with_impl is_settable_with; 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_value.hpp b/headers/meta.hpp/meta_value.hpp index 91d5c4b..0a08d50 100644 --- a/headers/meta.hpp/meta_value.hpp +++ b/headers/meta.hpp/meta_value.hpp @@ -12,7 +12,10 @@ namespace meta_hpp::detail { template < typename T > - concept value_kind = stdex::same_as; + inline constexpr bool is_value_kind_v = std::is_same_v; + + template < typename T > + concept value_kind = is_value_kind_v; template < typename T > concept decay_value_kind = value_kind>; @@ -26,7 +29,7 @@ namespace meta_hpp class value final { public: value() = default; - ~value() noexcept; + ~value(); value(value&& other) noexcept; value(const value& other); @@ -45,7 +48,7 @@ namespace meta_hpp [[nodiscard]] bool is_valid() const noexcept; [[nodiscard]] explicit operator bool() const noexcept; - void reset() noexcept; + void reset(); void swap(value& other) noexcept; [[nodiscard]] const any_type& get_type() const noexcept; diff --git a/headers/meta.hpp/meta_value/value.hpp b/headers/meta.hpp/meta_value/value.hpp index d301396..fcd7222 100644 --- a/headers/meta.hpp/meta_value/value.hpp +++ b/headers/meta.hpp/meta_value/value.hpp @@ -40,13 +40,13 @@ namespace meta_hpp std::ostream& (*const ostream)(std::ostream&, const value&); template < typename T > - static T* storage_cast(buffer_t& buffer) noexcept { + static T* buffer_cast(buffer_t& buffer) noexcept { // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) return reinterpret_cast(&buffer); } template < typename T > - static const T* storage_cast(const buffer_t& buffer) noexcept { + static const T* buffer_cast(const buffer_t& buffer) noexcept { // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) return reinterpret_cast(&buffer); } @@ -55,7 +55,7 @@ namespace meta_hpp static T* storage_cast(storage_u& storage) noexcept { return std::visit(detail::overloaded { [](void* ptr) { return static_cast(ptr); }, - [](buffer_t& buffer) { return storage_cast(buffer); }, + [](buffer_t& buffer) { return buffer_cast(buffer); }, [](...) -> T* { return nullptr; }, }, storage); } @@ -64,7 +64,7 @@ namespace meta_hpp static const T* storage_cast(const storage_u& storage) noexcept { return std::visit(detail::overloaded { [](const void* ptr) { return static_cast(ptr); }, - [](const buffer_t& buffer) { return storage_cast(buffer); }, + [](const buffer_t& buffer) { return buffer_cast(buffer); }, [](...) -> const T* { return nullptr; }, }, storage); } @@ -115,6 +115,7 @@ namespace meta_hpp } template < typename Tp > + // NOLINTNEXTLINE(readability-function-cognitive-complexity) static vtable_t* get() { static vtable_t table{ .type = detail::resolve_type(), @@ -128,15 +129,17 @@ namespace meta_hpp }, .move = [](value& from, value& to) noexcept { + assert(from && !to); + std::visit(detail::overloaded { [&to](void* ptr) { Tp* src = static_cast(ptr); to.storage_.emplace(src); }, [&to](buffer_t& buffer) { - Tp* src = storage_cast(buffer); - ::new (&to.storage_.emplace()) Tp(std::move(*src)); - src->~Tp(); + Tp& src = *buffer_cast(buffer); + ::new (&to.storage_.emplace()) Tp(std::move(src)); + src.~Tp(); }, [](...){} }, from.storage_); @@ -146,14 +149,16 @@ namespace meta_hpp }, .copy = [](const value& from, value& to){ + assert(from && !to); + std::visit(detail::overloaded { [&to](void* ptr) { - const Tp* src = static_cast(ptr); - to.storage_.emplace(new Tp{*src}); + const Tp& src = *static_cast(ptr); + to.storage_.emplace(new Tp(src)); }, [&to](const buffer_t& buffer) { - const Tp* src = storage_cast(buffer); - ::new (&to.storage_.emplace()) Tp(*src); + const Tp& src = *buffer_cast(buffer); + ::new (&to.storage_.emplace()) Tp(src); }, [](...){} }, from.storage_); @@ -162,13 +167,16 @@ namespace meta_hpp }, .destroy = [](value& self) noexcept { + assert(self); + std::visit(detail::overloaded { [](void* ptr) { Tp* src = static_cast(ptr); std::unique_ptr{src}.reset(); }, [](buffer_t& buffer) { - storage_cast(buffer)->~Tp(); + Tp& src = *buffer_cast(buffer); + src.~Tp(); }, [](...){} }, self.storage_); @@ -232,7 +240,7 @@ namespace meta_hpp namespace meta_hpp { - inline value::~value() noexcept { + inline value::~value() { reset(); } @@ -283,10 +291,9 @@ namespace meta_hpp return is_valid(); } - inline void value::reset() noexcept { + inline void value::reset() { if ( vtable_ != nullptr ) { vtable_->destroy(*this); - vtable_ = nullptr; } } diff --git a/untests/meta_base/fixed_function_tests.cpp b/untests/meta_base/fixed_function_tests.cpp new file mode 100644 index 0000000..45c8256 --- /dev/null +++ b/untests/meta_base/fixed_function_tests.cpp @@ -0,0 +1,122 @@ +/******************************************************************************* + * 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 +{ +} + +TEST_CASE("meta/meta_base/fixed_function") { + namespace meta = meta_hpp; + using meta::detail::fixed_function; + + SUBCASE("is_valid") { + { + fixed_function ff; + CHECK_FALSE(ff); + CHECK_FALSE(ff.is_valid()); + } + { + fixed_function ff = []{}; + CHECK(ff); + CHECK(ff.is_valid()); + } + } + + SUBCASE("ctor") { + { + auto f1 = []{return 1;}; + fixed_function ff{std::move(f1)}; + CHECK(ff() == 1); + + auto f2 = fixed_function{[]{return 2;}}; + ff = std::move(f2); + CHECK(ff() == 2); + } + } + + SUBCASE("reset") { + fixed_function ff = []{return 0;}; + + ff.reset(); + CHECK_FALSE(ff); + CHECK_FALSE(ff.is_valid()); + + ff = []{return 1;}; + CHECK(ff); + CHECK(ff.is_valid()); + + CHECK(ff() == 1); + } + + SUBCASE("move") { + fixed_function ff = []{return 1;}; + fixed_function ff2 = std::move(ff); + CHECK(ff2() == 1); + CHECK_FALSE(ff); + } + + SUBCASE("operator=") { + { + fixed_function ff; + ff = []{return 0;}; + CHECK(ff() == 0); + ff = []{return 1;}; + CHECK(ff() == 1); + + fixed_function ff2 = []{return 2;}; + ff = std::move(ff2); + CHECK(ff() == 2); + CHECK_FALSE(ff2); + } + } + + SUBCASE("swap") { + { + fixed_function ff1; + fixed_function ff2; + ff1.swap(ff2); + CHECK_FALSE(ff1); + CHECK_FALSE(ff2); + } + { + fixed_function ff1 = []{return 1;}; + fixed_function ff2 = []{return 2;}; + ff1.swap(ff2); + CHECK(ff1() == 2); + CHECK(ff2() == 1); + } + { + fixed_function ff1; + fixed_function ff2 = []{return 2;}; + + ff1.swap(ff2); + CHECK(ff1() == 2); + CHECK_FALSE(ff2); + + ff1.swap(ff2); + CHECK_FALSE(ff1); + CHECK(ff2() == 2); + } + } + + SUBCASE("-> int") { + auto f = [ + s = std::make_unique(10) + ](){ return 0; }; + fixed_function ff = std::move(f); + CHECK(ff() == 0); + } + + SUBCASE("-> void") { + auto f = [ + s = std::make_unique(10) + ](){}; + fixed_function ff = std::move(f); + CHECK_NOTHROW(ff()); + } +} From 33faf7f5f23331b09c6e8a79e476c4ee6851fc5d Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sun, 6 Feb 2022 12:08:45 +0700 Subject: [PATCH 204/233] fix fixed_function deduction guides --- headers/meta.hpp/meta_base/fixed_function.hpp | 26 ++++++++++++------- untests/meta_base/fixed_function_tests.cpp | 5 ++++ 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/headers/meta.hpp/meta_base/fixed_function.hpp b/headers/meta.hpp/meta_base/fixed_function.hpp index 8bac775..42466e3 100644 --- a/headers/meta.hpp/meta_base/fixed_function.hpp +++ b/headers/meta.hpp/meta_base/fixed_function.hpp @@ -178,17 +178,23 @@ namespace meta_hpp::detail template < typename F > struct strip_signature_impl; - template < typename R, typename C, bool NoExcept, typename... Args > - struct strip_signature_impl { using type = R(Args...); }; + template < typename R, typename C, typename... Args > + struct strip_signature_impl { using type = R(Args...); }; + template < typename R, typename C, typename... Args > + struct strip_signature_impl { using type = R(Args...); }; + template < typename R, typename C, typename... Args > + struct strip_signature_impl { using type = R(Args...); }; + template < typename R, typename C, typename... Args > + struct strip_signature_impl { using type = R(Args...); }; - template < typename R, typename C, bool NoExcept, typename... Args > - struct strip_signature_impl { using type = R(Args...); }; - - template < typename R, typename C, bool NoExcept, typename... Args > - struct strip_signature_impl { using type = R(Args...); }; - - template < typename R, typename C, bool NoExcept, typename... Args > - struct strip_signature_impl { using type = R(Args...); }; + template < typename R, typename C, typename... Args > + struct strip_signature_impl { using type = R(Args...); }; + template < typename R, typename C, typename... Args > + struct strip_signature_impl { using type = R(Args...); }; + template < typename R, typename C, typename... Args > + struct strip_signature_impl { using type = R(Args...); }; + template < typename R, typename C, typename... Args > + struct strip_signature_impl { using type = R(Args...); }; template < typename F > using strip_signature_impl_t = typename strip_signature_impl::type; diff --git a/untests/meta_base/fixed_function_tests.cpp b/untests/meta_base/fixed_function_tests.cpp index 45c8256..7d62185 100644 --- a/untests/meta_base/fixed_function_tests.cpp +++ b/untests/meta_base/fixed_function_tests.cpp @@ -37,6 +37,11 @@ TEST_CASE("meta/meta_base/fixed_function") { ff = std::move(f2); CHECK(ff() == 2); } + { + auto f1 = []() noexcept {return 1;}; + fixed_function ff{f1}; + CHECK(ff() == 1); + } } SUBCASE("reset") { From 41c2fbfae812ee1de7ac628e856fae82550baa99 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sun, 6 Feb 2022 12:25:26 +0700 Subject: [PATCH 205/233] style fixes --- headers/meta.hpp/meta_base/fixed_function.hpp | 8 +++++--- headers/meta.hpp/meta_states/function.hpp | 8 ++++---- headers/meta.hpp/meta_states/member.hpp | 14 +++++++------- headers/meta.hpp/meta_states/method.hpp | 11 +++++------ headers/meta.hpp/meta_states/variable.hpp | 12 ++++++------ 5 files changed, 27 insertions(+), 26 deletions(-) diff --git a/headers/meta.hpp/meta_base/fixed_function.hpp b/headers/meta.hpp/meta_base/fixed_function.hpp index 42466e3..b658e3b 100644 --- a/headers/meta.hpp/meta_base/fixed_function.hpp +++ b/headers/meta.hpp/meta_base/fixed_function.hpp @@ -13,12 +13,14 @@ namespace meta_hpp::detail { - template < typename Function, std::size_t MaxFunctorSize = sizeof(void*) * 3 > + template < typename Function, std::size_t MaxFunctorSize = sizeof(void*) * 2 > class fixed_function; template < typename R, typename... Args, std::size_t MaxFunctorSize > class fixed_function final { public: + using result_type = R; + fixed_function() = default; ~fixed_function() { reset(); } @@ -39,12 +41,12 @@ namespace meta_hpp::detail } template < typename Functor > - fixed_function(Functor&& functor) { + fixed_function(Functor&& functor) { vtable_t::construct(*this, std::forward(functor)); } template < typename Functor > - fixed_function& operator=(Functor&& functor) { + fixed_function& operator=(Functor&& functor) { fixed_function{std::forward(functor)}.swap(*this); return *this; } diff --git a/headers/meta.hpp/meta_states/function.hpp b/headers/meta.hpp/meta_states/function.hpp index d177062..a037297 100644 --- a/headers/meta.hpp/meta_states/function.hpp +++ b/headers/meta.hpp/meta_states/function.hpp @@ -15,7 +15,7 @@ namespace meta_hpp::detail { template < function_policy_kind Policy, function_kind Function > - value raw_function_invoke(Function function, std::span args) { + value raw_function_invoke(const Function& function, std::span args) { using ft = function_traits; using return_type = typename ft::return_type; using argument_types = typename ft::argument_types; @@ -39,7 +39,7 @@ namespace meta_hpp::detail } return std::invoke([ - args, function = std::move(function) + &function, args // NOLINTNEXTLINE(readability-named-parameter) ](std::index_sequence) -> value { if ( !(... && (args.data() + Is)->can_cast_to>()) ) { @@ -48,12 +48,12 @@ namespace meta_hpp::detail if constexpr ( as_void ) { std::ignore = std::invoke( - std::move(function), + function, (args.data() + Is)->cast>()...); return value{}; } else { return_type&& return_value = std::invoke( - std::move(function), + function, (args.data() + Is)->cast>()...); if constexpr ( ref_as_ptr ) { diff --git a/headers/meta.hpp/meta_states/member.hpp b/headers/meta.hpp/meta_states/member.hpp index c93eec8..7cbbb56 100644 --- a/headers/meta.hpp/meta_states/member.hpp +++ b/headers/meta.hpp/meta_states/member.hpp @@ -16,7 +16,7 @@ namespace meta_hpp::detail { template < member_policy_kind Policy, member_kind Member > - value raw_member_getter(Member member, const inst& inst) { + value raw_member_getter(const Member& member, const inst& inst) { using mt = member_traits; using class_type = typename mt::class_type; using value_type = typename mt::value_type; @@ -38,7 +38,7 @@ namespace meta_hpp::detail } if ( inst.is_const() ) { - auto&& return_value = std::invoke(std::move(member), inst.cast()); + auto&& return_value = std::invoke(member, inst.cast()); if constexpr ( as_copy ) { return value{std::forward(return_value)}; @@ -52,7 +52,7 @@ namespace meta_hpp::detail return value{std::ref(return_value)}; } } else { - auto&& return_value = std::invoke(std::move(member), inst.cast()); + auto&& return_value = std::invoke(member, inst.cast()); if constexpr ( as_copy ) { return value{std::forward(return_value)}; @@ -80,7 +80,7 @@ namespace meta_hpp::detail namespace meta_hpp::detail { template < member_kind Member > - void raw_member_setter([[maybe_unused]] Member member, const inst& inst, const arg& arg) { + void raw_member_setter([[maybe_unused]] const Member& member, const inst& inst, const arg& arg) { using mt = member_traits; using class_type = typename mt::class_type; using value_type = typename mt::value_type; @@ -100,7 +100,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(member, inst.cast()) = arg.cast(); } } @@ -150,8 +150,8 @@ namespace meta_hpp::detail member_state_ptr member_state::make(std::string name, Member member) { return std::make_shared(member_state{ .index{member_index::make(std::move(name))}, - .getter{make_member_getter(std::move(member))}, - .setter{make_member_setter(std::move(member))}, + .getter{make_member_getter(member)}, + .setter{make_member_setter(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 b59fbc2..c58da66 100644 --- a/headers/meta.hpp/meta_states/method.hpp +++ b/headers/meta.hpp/meta_states/method.hpp @@ -16,7 +16,7 @@ namespace meta_hpp::detail { template < method_policy_kind Policy, method_kind Method > - value raw_method_invoke(Method method, const inst& inst, std::span args) { + value raw_method_invoke(const 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; @@ -45,8 +45,7 @@ namespace meta_hpp::detail } return std::invoke([ - &inst, &args, - method = std::move(method) + &method, &inst, args // NOLINTNEXTLINE(readability-named-parameter) ](std::index_sequence) -> value { if ( !(... && (args.data() + Is)->can_cast_to>()) ) { @@ -55,13 +54,13 @@ namespace meta_hpp::detail if constexpr ( as_void ) { std::ignore = std::invoke( - std::move(method), + method, inst.cast(), (args.data() + Is)->cast>()...); return value{}; } else { return_type&& return_value = std::invoke( - std::move(method), + method, inst.cast(), (args.data() + Is)->cast>()...); @@ -89,7 +88,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()); } diff --git a/headers/meta.hpp/meta_states/variable.hpp b/headers/meta.hpp/meta_states/variable.hpp index dd7da54..8e1c188 100644 --- a/headers/meta.hpp/meta_states/variable.hpp +++ b/headers/meta.hpp/meta_states/variable.hpp @@ -15,7 +15,7 @@ namespace meta_hpp::detail { template < variable_policy_kind Policy, pointer_kind Pointer > - value raw_variable_getter(Pointer pointer) { + value raw_variable_getter(const Pointer& pointer) { using pt = pointer_traits; using data_type = typename pt::data_type; @@ -47,7 +47,7 @@ namespace meta_hpp::detail } template < pointer_kind Pointer > - void raw_variable_setter([[maybe_unused]] Pointer pointer, const arg& arg) { + void raw_variable_setter([[maybe_unused]] const Pointer& pointer, const arg& arg) { using pt = pointer_traits; using data_type = typename pt::data_type; @@ -76,13 +76,13 @@ namespace meta_hpp::detail 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, std::move(pointer)); } template < pointer_kind Pointer > variable_state::setter_impl make_variable_setter(Pointer pointer) { using namespace std::placeholders; - return std::bind(&raw_variable_setter, pointer, _1); + return std::bind(&raw_variable_setter, std::move(pointer), _1); } template < pointer_kind Pointer > @@ -98,8 +98,8 @@ namespace meta_hpp::detail variable_state_ptr variable_state::make(std::string name, Pointer pointer) { return std::make_shared(variable_state{ .index{variable_index::make(std::move(name))}, - .getter{make_variable_getter(std::move(pointer))}, - .setter{make_variable_setter(std::move(pointer))}, + .getter{make_variable_getter(pointer)}, + .setter{make_variable_setter(pointer)}, .is_settable_with{make_variable_is_settable_with()}, }); } From 39c00a169432193e8baecdfd2117b3ce6585ecd0 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sun, 6 Feb 2022 23:27:54 +0700 Subject: [PATCH 206/233] remove all std::bind usage --- headers/meta.hpp/meta_base/fixed_function.hpp | 11 +++++------ headers/meta.hpp/meta_states/ctor.hpp | 6 ++---- headers/meta.hpp/meta_states/dtor.hpp | 6 ++---- headers/meta.hpp/meta_states/function.hpp | 8 ++++---- headers/meta.hpp/meta_states/member.hpp | 16 ++++++++-------- headers/meta.hpp/meta_states/method.hpp | 8 ++++---- headers/meta.hpp/meta_states/variable.hpp | 13 +++++++------ headers/meta.hpp/meta_value.hpp | 2 +- 8 files changed, 33 insertions(+), 37 deletions(-) diff --git a/headers/meta.hpp/meta_base/fixed_function.hpp b/headers/meta.hpp/meta_base/fixed_function.hpp index b658e3b..75f8e32 100644 --- a/headers/meta.hpp/meta_base/fixed_function.hpp +++ b/headers/meta.hpp/meta_base/fixed_function.hpp @@ -78,7 +78,7 @@ namespace meta_hpp::detail struct vtable_t; vtable_t* vtable_{}; private: - using storage_t = std::aligned_storage_t; + using storage_t = std::aligned_storage_t; storage_t storage_{}; }; @@ -142,11 +142,10 @@ namespace meta_hpp::detail static void construct(fixed_function& dst, Functor&& functor) { using Fp = std::decay_t; - static_assert( - sizeof(Fp) <= MaxFunctorSize && - alignof(Fp) <= alignof(storage_t) && - std::is_invocable_r_v && - std::is_nothrow_move_constructible_v); + static_assert(sizeof(Fp) <= MaxFunctorSize); + static_assert(alignof(Fp) <= alignof(storage_t)); + static_assert(std::is_invocable_r_v); + static_assert(std::is_nothrow_move_constructible_v); ::new (&dst.storage_) Fp(std::forward(functor)); dst.vtable_ = vtable_t::get(); diff --git a/headers/meta.hpp/meta_states/ctor.hpp b/headers/meta.hpp/meta_states/ctor.hpp index e278d09..348d036 100644 --- a/headers/meta.hpp/meta_states/ctor.hpp +++ b/headers/meta.hpp/meta_states/ctor.hpp @@ -81,14 +81,12 @@ namespace meta_hpp::detail { template < ctor_policy_kind Policy, class_kind Class, typename... Args > ctor_state::invoke_impl make_ctor_invoke() { - using namespace std::placeholders; - return std::bind(&raw_ctor_invoke, _1); + return &raw_ctor_invoke; } template < class_kind Class, typename... Args > ctor_state::is_invocable_with_impl make_ctor_is_invocable_with() { - using namespace std::placeholders; - return std::bind(&raw_ctor_is_invocable_with, _1); + return &raw_ctor_is_invocable_with; } } diff --git a/headers/meta.hpp/meta_states/dtor.hpp b/headers/meta.hpp/meta_states/dtor.hpp index 06e6d22..a8029da 100644 --- a/headers/meta.hpp/meta_states/dtor.hpp +++ b/headers/meta.hpp/meta_states/dtor.hpp @@ -42,14 +42,12 @@ namespace meta_hpp::detail { template < class_kind Class > dtor_state::invoke_impl make_dtor_invoke() { - using namespace std::placeholders; - return std::bind(&raw_dtor_invoke, _1); + return &raw_dtor_invoke; } template < class_kind Class > dtor_state::is_invocable_with_impl make_dtor_is_invocable_with() { - using namespace std::placeholders; - return std::bind(&raw_dtor_is_invocable_with, _1); + return &raw_dtor_is_invocable_with; } } diff --git a/headers/meta.hpp/meta_states/function.hpp b/headers/meta.hpp/meta_states/function.hpp index a037297..b845980 100644 --- a/headers/meta.hpp/meta_states/function.hpp +++ b/headers/meta.hpp/meta_states/function.hpp @@ -85,14 +85,14 @@ namespace meta_hpp::detail { template < function_policy_kind Policy, function_kind Function > function_state::invoke_impl make_function_invoke(Function function) { - using namespace std::placeholders; - return std::bind(&raw_function_invoke, std::move(function), _1); + return [function = std::move(function)](std::span args){ + return raw_function_invoke(function, args); + }; } template < function_kind Function > function_state::is_invocable_with_impl make_function_is_invocable_with() { - using namespace std::placeholders; - return std::bind(&raw_function_is_invocable_with, _1); + return &raw_function_is_invocable_with; } } diff --git a/headers/meta.hpp/meta_states/member.hpp b/headers/meta.hpp/meta_states/member.hpp index 7cbbb56..ae208a8 100644 --- a/headers/meta.hpp/meta_states/member.hpp +++ b/headers/meta.hpp/meta_states/member.hpp @@ -121,26 +121,26 @@ namespace meta_hpp::detail { template < member_policy_kind Policy, member_kind Member > member_state::getter_impl make_member_getter(Member member) { - using namespace std::placeholders; - return std::bind(&raw_member_getter, std::move(member), _1); + return [member = std::move(member)](const inst& inst){ + return raw_member_getter(member, inst); + }; } template < member_kind Member > member_state::is_gettable_with_impl make_member_is_gettable_with() { - using namespace std::placeholders; - return std::bind(&raw_member_is_gettable_with, _1); + return &raw_member_is_gettable_with; } template < member_kind Member > member_state::setter_impl make_member_setter(Member member) { - using namespace std::placeholders; - return std::bind(&raw_member_setter, std::move(member), _1, _2); + return [member = std::move(member)](const inst& inst, const arg& arg){ + return raw_member_setter(member, inst, arg); + }; } template < member_kind Member > member_state::is_settable_with_impl make_member_is_settable_with() { - using namespace std::placeholders; - return std::bind(&raw_member_is_settable_with, _1, _2); + return &raw_member_is_settable_with; } } diff --git a/headers/meta.hpp/meta_states/method.hpp b/headers/meta.hpp/meta_states/method.hpp index c58da66..96b552e 100644 --- a/headers/meta.hpp/meta_states/method.hpp +++ b/headers/meta.hpp/meta_states/method.hpp @@ -98,14 +98,14 @@ namespace meta_hpp::detail { template < method_policy_kind Policy, method_kind Method > method_state::invoke_impl make_method_invoke(Method method) { - using namespace std::placeholders; - return std::bind(&raw_method_invoke, std::move(method), _1, _2); + return [method = std::move(method)](const inst& inst, std::span args){ + return raw_method_invoke(method, inst, args); + }; } template < method_kind Method > method_state::is_invocable_with_impl make_method_is_invocable_with() { - using namespace std::placeholders; - return std::bind(&raw_method_is_invocable_with, _1, _2); + return &raw_method_is_invocable_with; } } diff --git a/headers/meta.hpp/meta_states/variable.hpp b/headers/meta.hpp/meta_states/variable.hpp index 8e1c188..41f965f 100644 --- a/headers/meta.hpp/meta_states/variable.hpp +++ b/headers/meta.hpp/meta_states/variable.hpp @@ -75,20 +75,21 @@ namespace meta_hpp::detail { 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, std::move(pointer)); + return [pointer = std::move(pointer)](){ + return raw_variable_getter(pointer); + }; } template < pointer_kind Pointer > variable_state::setter_impl make_variable_setter(Pointer pointer) { - using namespace std::placeholders; - return std::bind(&raw_variable_setter, std::move(pointer), _1); + return [pointer = std::move(pointer)](const arg& arg){ + return raw_variable_setter(pointer, arg); + }; } template < pointer_kind Pointer > variable_state::is_settable_with_impl make_variable_is_settable_with() { - using namespace std::placeholders; - return std::bind(&raw_variable_is_settable_with, _1); + return &raw_variable_is_settable_with; } } diff --git a/headers/meta.hpp/meta_value.hpp b/headers/meta.hpp/meta_value.hpp index 0a08d50..9dba8d1 100644 --- a/headers/meta.hpp/meta_value.hpp +++ b/headers/meta.hpp/meta_value.hpp @@ -86,7 +86,7 @@ namespace meta_hpp struct vtable_t; vtable_t* vtable_{}; private: - using buffer_t = std::aligned_storage_t; + using buffer_t = std::aligned_storage_t; using storage_u = std::variant; storage_u storage_{}; }; From 1f06462af402f099b4db9d263869bf4bad74de3b Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Mon, 7 Feb 2022 03:08:30 +0700 Subject: [PATCH 207/233] META_HPP_NO_EXCEPTIONS --- headers/meta.hpp/meta_base.hpp | 26 +++++++++++++++++++ headers/meta.hpp/meta_base/fixed_function.hpp | 6 ++--- .../meta_detail/value_utilities/arg.hpp | 4 +-- .../meta_detail/value_utilities/inst.hpp | 4 +-- headers/meta.hpp/meta_states/ctor.hpp | 4 +-- headers/meta.hpp/meta_states/dtor.hpp | 2 +- headers/meta.hpp/meta_states/function.hpp | 4 +-- headers/meta.hpp/meta_states/member.hpp | 10 +++---- headers/meta.hpp/meta_states/method.hpp | 6 ++--- headers/meta.hpp/meta_states/variable.hpp | 4 +-- headers/meta.hpp/meta_value/value.hpp | 20 +++++++------- 11 files changed, 58 insertions(+), 32 deletions(-) diff --git a/headers/meta.hpp/meta_base.hpp b/headers/meta.hpp/meta_base.hpp index cec6fac..116ad26 100644 --- a/headers/meta.hpp/meta_base.hpp +++ b/headers/meta.hpp/meta_base.hpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -44,6 +45,10 @@ #include "meta_base/type_kinds.hpp" #include "meta_base/type_list.hpp" +#if !defined(__cpp_exceptions) +# define META_HPP_NO_EXCEPTIONS +#endif + namespace meta_hpp { using detail::select_const; @@ -57,6 +62,27 @@ namespace meta_hpp using enum_hpp::bitflags::bitflags; } +namespace meta_hpp +{ + class exception final : public std::runtime_error { + public: + explicit exception(const char* what) + : std::runtime_error(what) {} + }; + + namespace detail + { + inline void throw_exception_with [[noreturn]] (const char* what) { + #ifndef META_HPP_NO_EXCEPTIONS + throw ::meta_hpp::exception(what); + #else + (void)what; + std::abort(); + #endif + } + } +} + namespace meta_hpp { class value; diff --git a/headers/meta.hpp/meta_base/fixed_function.hpp b/headers/meta.hpp/meta_base/fixed_function.hpp index 75f8e32..ee31357 100644 --- a/headers/meta.hpp/meta_base/fixed_function.hpp +++ b/headers/meta.hpp/meta_base/fixed_function.hpp @@ -6,6 +6,7 @@ #pragma once +#include #include #include #include @@ -60,9 +61,8 @@ namespace meta_hpp::detail } R operator()(Args... args) const { - return vtable_ - ? vtable_->call(*this, std::forward(args)...) - : throw std::bad_function_call(); + assert(vtable_ && "bad function call"); + return vtable_->call(*this, std::forward(args)...); } void reset() noexcept { diff --git a/headers/meta.hpp/meta_detail/value_utilities/arg.hpp b/headers/meta.hpp/meta_detail/value_utilities/arg.hpp index efff645..678cf88 100644 --- a/headers/meta.hpp/meta_detail/value_utilities/arg.hpp +++ b/headers/meta.hpp/meta_detail/value_utilities/arg.hpp @@ -250,7 +250,7 @@ namespace meta_hpp::detail // NOLINTNEXTLINE(readability-function-cognitive-complexity) To arg::cast() const { if ( !can_cast_to() ) { - throw std::logic_error("bad argument cast"); + throw_exception_with("bad argument cast"); } using to_raw_type_cv = std::remove_reference_t; @@ -360,6 +360,6 @@ namespace meta_hpp::detail } } - throw std::logic_error("bad argument cast"); + throw_exception_with("bad argument cast"); } } diff --git a/headers/meta.hpp/meta_detail/value_utilities/inst.hpp b/headers/meta.hpp/meta_detail/value_utilities/inst.hpp index e1dc7eb..019ff27 100644 --- a/headers/meta.hpp/meta_detail/value_utilities/inst.hpp +++ b/headers/meta.hpp/meta_detail/value_utilities/inst.hpp @@ -177,7 +177,7 @@ namespace meta_hpp::detail template < inst_class_ref_kind Q > decltype(auto) inst::cast() const { if ( !can_cast_to() ) { - throw std::logic_error("bad instance cast"); + throw_exception_with("bad instance cast"); } using inst_class_cv = std::remove_reference_t; @@ -205,6 +205,6 @@ namespace meta_hpp::detail } } - throw std::logic_error("bad instance cast"); + throw_exception_with("bad instance cast"); } } diff --git a/headers/meta.hpp/meta_states/ctor.hpp b/headers/meta.hpp/meta_states/ctor.hpp index 348d036..02fa66e 100644 --- a/headers/meta.hpp/meta_states/ctor.hpp +++ b/headers/meta.hpp/meta_states/ctor.hpp @@ -33,7 +33,7 @@ namespace meta_hpp::detail 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"); + throw_exception_with("an attempt to call a constructor with an incorrect arity"); } return std::invoke([ @@ -41,7 +41,7 @@ namespace meta_hpp::detail // NOLINTNEXTLINE(readability-named-parameter) ](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"); + throw_exception_with("an attempt to call a constructor with incorrect argument types"); } if constexpr ( as_object ) { diff --git a/headers/meta.hpp/meta_states/dtor.hpp b/headers/meta.hpp/meta_states/dtor.hpp index a8029da..2beda6c 100644 --- a/headers/meta.hpp/meta_states/dtor.hpp +++ b/headers/meta.hpp/meta_states/dtor.hpp @@ -20,7 +20,7 @@ namespace meta_hpp::detail using class_type = typename dt::class_type; if ( !ptr.can_cast_to() ) { - throw std::logic_error("an attempt to call a destructor with an incorrect argument type"); + throw_exception_with("an attempt to call a destructor with an incorrect argument type"); } class_type* raw_ptr = ptr.cast(); diff --git a/headers/meta.hpp/meta_states/function.hpp b/headers/meta.hpp/meta_states/function.hpp index b845980..817ab3f 100644 --- a/headers/meta.hpp/meta_states/function.hpp +++ b/headers/meta.hpp/meta_states/function.hpp @@ -35,7 +35,7 @@ namespace meta_hpp::detail 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"); + throw_exception_with("an attempt to call a function with an incorrect arity"); } return std::invoke([ @@ -43,7 +43,7 @@ namespace meta_hpp::detail // NOLINTNEXTLINE(readability-named-parameter) ](std::index_sequence) -> value { if ( !(... && (args.data() + Is)->can_cast_to>()) ) { - throw std::logic_error("an attempt to call a function with incorrect argument types"); + throw_exception_with("an attempt to call a function with incorrect argument types"); } if constexpr ( as_void ) { diff --git a/headers/meta.hpp/meta_states/member.hpp b/headers/meta.hpp/meta_states/member.hpp index ae208a8..3ea8518 100644 --- a/headers/meta.hpp/meta_states/member.hpp +++ b/headers/meta.hpp/meta_states/member.hpp @@ -34,7 +34,7 @@ namespace meta_hpp::detail 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"); + throw_exception_with("an attempt to get a member with an incorrect instance type"); } if ( inst.is_const() ) { @@ -86,18 +86,18 @@ namespace meta_hpp::detail using value_type = typename mt::value_type; if constexpr ( std::is_const_v ) { - throw std::logic_error("an attempt to set a constant member"); + throw_exception_with("an attempt to set a constant member"); } else { if ( inst.is_const() ) { - throw std::logic_error("an attempt to set a member with an const instance type"); + throw_exception_with("an attempt to set a member with an const instance type"); } if ( !inst.can_cast_to() ) { - throw std::logic_error("an attempt to set a member with an incorrect instance type"); + throw_exception_with("an attempt to set a member with an incorrect instance type"); } if ( !arg.can_cast_to() ) { - throw std::logic_error("an attempt to set a member with an incorrect argument type"); + throw_exception_with("an attempt to set a member with an incorrect argument type"); } std::invoke(member, inst.cast()) = arg.cast(); diff --git a/headers/meta.hpp/meta_states/method.hpp b/headers/meta.hpp/meta_states/method.hpp index 96b552e..69baea2 100644 --- a/headers/meta.hpp/meta_states/method.hpp +++ b/headers/meta.hpp/meta_states/method.hpp @@ -37,11 +37,11 @@ namespace meta_hpp::detail 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"); + throw_exception_with("an attempt to call a method with an incorrect arity"); } if ( !inst.can_cast_to() ) { - throw std::logic_error("an attempt to call a method with an incorrect instance type"); + throw_exception_with("an attempt to call a method with an incorrect instance type"); } return std::invoke([ @@ -49,7 +49,7 @@ namespace meta_hpp::detail // NOLINTNEXTLINE(readability-named-parameter) ](std::index_sequence) -> value { if ( !(... && (args.data() + Is)->can_cast_to>()) ) { - throw std::logic_error("an attempt to call a method with incorrect argument types"); + throw_exception_with("an attempt to call a method with incorrect argument types"); } if constexpr ( as_void ) { diff --git a/headers/meta.hpp/meta_states/variable.hpp b/headers/meta.hpp/meta_states/variable.hpp index 41f965f..54db7b7 100644 --- a/headers/meta.hpp/meta_states/variable.hpp +++ b/headers/meta.hpp/meta_states/variable.hpp @@ -52,10 +52,10 @@ namespace meta_hpp::detail using data_type = typename pt::data_type; if constexpr ( std::is_const_v ) { - throw std::logic_error("an attempt to set a constant variable"); + throw_exception_with("an attempt to set a constant variable"); } else { if ( !arg.can_cast_to() ) { - throw std::logic_error("an attempt to set a variable with an incorrect argument type"); + throw_exception_with("an attempt to set a variable with an incorrect argument type"); } *pointer = arg.cast(); } diff --git a/headers/meta.hpp/meta_value/value.hpp b/headers/meta.hpp/meta_value/value.hpp index fcd7222..b86b1b9 100644 --- a/headers/meta.hpp/meta_value/value.hpp +++ b/headers/meta.hpp/meta_value/value.hpp @@ -188,7 +188,7 @@ namespace meta_hpp if constexpr ( detail::has_deref_traits ) { return detail::deref_traits{}(v.cast()); } else { - throw std::logic_error("value type doesn't have value deref traits"); + detail::throw_exception_with("value type doesn't have value deref traits"); } }, @@ -196,7 +196,7 @@ namespace meta_hpp if constexpr ( detail::has_index_traits ) { return detail::index_traits{}(v.cast(), i); } else { - throw std::logic_error("value type doesn't have value index traits"); + detail::throw_exception_with("value type doesn't have value index traits"); } }, @@ -204,7 +204,7 @@ namespace meta_hpp if constexpr ( detail::has_less_traits ) { return detail::less_traits{}(l.cast(), r.cast()); } else { - throw std::logic_error("value type doesn't have value less traits"); + detail::throw_exception_with("value type doesn't have value less traits"); } }, @@ -212,7 +212,7 @@ namespace meta_hpp if constexpr ( detail::has_equals_traits ) { return detail::equals_traits{}(l.cast(), r.cast()); } else { - throw std::logic_error("value type doesn't have value equals traits"); + detail::throw_exception_with("value type doesn't have value equals traits"); } }, @@ -220,7 +220,7 @@ namespace meta_hpp if constexpr ( detail::has_istream_traits ) { return detail::istream_traits{}(is, v.cast()); } else { - throw std::logic_error("value type doesn't have value istream traits"); + detail::throw_exception_with("value type doesn't have value istream traits"); } }, @@ -228,7 +228,7 @@ namespace meta_hpp if constexpr ( detail::has_ostream_traits ) { return detail::ostream_traits{}(os, v.cast()); } else { - throw std::logic_error("value type doesn't have value ostream traits"); + detail::throw_exception_with("value type doesn't have value ostream traits"); } }, }; @@ -332,7 +332,7 @@ namespace meta_hpp if ( Tp* ptr = try_cast() ) { return *ptr; } - throw std::logic_error("bad value cast"); + detail::throw_exception_with("bad value cast"); } template < typename T > @@ -341,7 +341,7 @@ namespace meta_hpp if ( Tp* ptr = try_cast() ) { return std::move(*ptr); } - throw std::logic_error("bad value cast"); + detail::throw_exception_with("bad value cast"); } template < typename T > @@ -350,7 +350,7 @@ namespace meta_hpp if ( const Tp* ptr = try_cast() ) { return *ptr; } - throw std::logic_error("bad value cast"); + detail::throw_exception_with("bad value cast"); } template < typename T > @@ -359,7 +359,7 @@ namespace meta_hpp if ( const Tp* ptr = try_cast() ) { return std::move(*ptr); } - throw std::logic_error("bad value cast"); + detail::throw_exception_with("bad value cast"); } template < typename T > From 6c156da20d4211fb50aa6f129febbdda767fc50a Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Mon, 7 Feb 2022 03:11:40 +0700 Subject: [PATCH 208/233] META_HPP_NO_RTTI --- headers/meta.hpp/meta_base.hpp | 4 ++++ headers/meta.hpp/meta_detail/type_registry.hpp | 11 +++++++++++ 2 files changed, 15 insertions(+) diff --git a/headers/meta.hpp/meta_base.hpp b/headers/meta.hpp/meta_base.hpp index 116ad26..2f77ccf 100644 --- a/headers/meta.hpp/meta_base.hpp +++ b/headers/meta.hpp/meta_base.hpp @@ -49,6 +49,10 @@ # define META_HPP_NO_EXCEPTIONS #endif +#if !defined(__cpp_rtti) +# define META_HPP_NO_RTTI +#endif + namespace meta_hpp { using detail::select_const; diff --git a/headers/meta.hpp/meta_detail/type_registry.hpp b/headers/meta.hpp/meta_detail/type_registry.hpp index be9fb0d..6e2ba27 100644 --- a/headers/meta.hpp/meta_detail/type_registry.hpp +++ b/headers/meta.hpp/meta_detail/type_registry.hpp @@ -19,6 +19,7 @@ namespace meta_hpp::detail } [[nodiscard]] any_type get_type_by_id(type_id id) const noexcept { + const std::lock_guard lock{mutex_}; if ( auto iter = type_by_id_.find(id); iter != type_by_id_.end() ) { return iter->second; } @@ -26,6 +27,7 @@ namespace meta_hpp::detail } [[nodiscard]] any_type get_type_by_rtti(const std::type_index& index) const noexcept { + const std::lock_guard lock{mutex_}; if ( auto iter = type_by_rtti_.find(index); iter != type_by_rtti_.end() ) { return iter->second; } @@ -200,12 +202,16 @@ namespace meta_hpp::detail TypeData ensure_type(const TypeData& type_data) { static std::once_flag init_flag{}; std::call_once(init_flag, [this, &type_data](){ + const std::lock_guard lock{mutex_}; type_by_id_[type_data->id] = any_type{type_data}; + #ifndef META_HPP_NO_RTTI type_by_rtti_[typeid(Type)] = any_type{type_data}; + #endif }); return type_data; } private: + mutable std::mutex mutex_; std::map> type_by_id_; std::map> type_by_rtti_; }; @@ -259,7 +265,12 @@ namespace meta_hpp::detail { template < typename T > [[nodiscard]] any_type resolve_polymorphic_type(T&& v) noexcept { + #ifndef META_HPP_NO_RTTI type_registry& registry = type_registry::instance(); return registry.get_type_by_rtti(typeid(v)); + #else + (void)v; + return any_type{}; + #endif } } From 58ff96293896f1052b68194ad4752b3bce9f32b0 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Mon, 7 Feb 2022 04:30:31 +0700 Subject: [PATCH 209/233] fix dtor --- TODO.md | 2 +- headers/meta.hpp/meta_states/dtor.hpp | 2 +- untests/meta_states/function_tests.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/TODO.md b/TODO.md index e7e6ecb..2d53ed8 100644 --- a/TODO.md +++ b/TODO.md @@ -1,6 +1,5 @@ # meta.hpp -- exception class - metadata * argument defaults @@ -10,3 +9,4 @@ - (?) enum_type::create, number_type::create, and so on - (?) move-only value type support - (?) type names +- (?) properties diff --git a/headers/meta.hpp/meta_states/dtor.hpp b/headers/meta.hpp/meta_states/dtor.hpp index 2beda6c..08b0d3b 100644 --- a/headers/meta.hpp/meta_states/dtor.hpp +++ b/headers/meta.hpp/meta_states/dtor.hpp @@ -25,7 +25,7 @@ namespace meta_hpp::detail class_type* raw_ptr = ptr.cast(); if ( raw_ptr ) { - raw_ptr->~Class(); + std::unique_ptr{raw_ptr}.reset(); } } diff --git a/untests/meta_states/function_tests.cpp b/untests/meta_states/function_tests.cpp index 880eadf..67a5275 100644 --- a/untests/meta_states/function_tests.cpp +++ b/untests/meta_states/function_tests.cpp @@ -27,7 +27,7 @@ namespace static int arg_unbounded_const_arr(const ivec2 vs[]) { return vs[0].x + vs[0].y + vs[1].x + vs[1].y; } }; - bool operator==(const ivec2& l, const ivec2& r) noexcept { + [[maybe_unused]] bool operator==(const ivec2& l, const ivec2& r) noexcept { return l.x == r.x && l.y == r.y; } } From c80e0c44b6c85da7becf84f53e9b88ca2ed7c0a0 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Mon, 7 Feb 2022 05:44:47 +0700 Subject: [PATCH 210/233] ctad warnings fix --- headers/meta.hpp/meta_detail/type_registry.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/headers/meta.hpp/meta_detail/type_registry.hpp b/headers/meta.hpp/meta_detail/type_registry.hpp index 6e2ba27..763e166 100644 --- a/headers/meta.hpp/meta_detail/type_registry.hpp +++ b/headers/meta.hpp/meta_detail/type_registry.hpp @@ -19,7 +19,7 @@ namespace meta_hpp::detail } [[nodiscard]] any_type get_type_by_id(type_id id) const noexcept { - const std::lock_guard lock{mutex_}; + const std::lock_guard lock{mutex_}; if ( auto iter = type_by_id_.find(id); iter != type_by_id_.end() ) { return iter->second; } @@ -27,7 +27,7 @@ namespace meta_hpp::detail } [[nodiscard]] any_type get_type_by_rtti(const std::type_index& index) const noexcept { - const std::lock_guard lock{mutex_}; + const std::lock_guard lock{mutex_}; if ( auto iter = type_by_rtti_.find(index); iter != type_by_rtti_.end() ) { return iter->second; } @@ -202,7 +202,7 @@ namespace meta_hpp::detail TypeData ensure_type(const TypeData& type_data) { static std::once_flag init_flag{}; std::call_once(init_flag, [this, &type_data](){ - const std::lock_guard lock{mutex_}; + const std::lock_guard lock{mutex_}; type_by_id_[type_data->id] = any_type{type_data}; #ifndef META_HPP_NO_RTTI type_by_rtti_[typeid(Type)] = any_type{type_data}; From f1d9b11b1bf9e3d084ab31ea82e8f1d9743ac4a6 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Mon, 7 Feb 2022 23:51:36 +0700 Subject: [PATCH 211/233] type bitflag aliases --- .../meta_detail/type_traits/array_traits.hpp | 5 +- .../meta_detail/type_traits/class_traits.hpp | 9 +-- .../meta_detail/type_traits/ctor_traits.hpp | 5 +- .../meta_detail/type_traits/dtor_traits.hpp | 5 +- .../meta_detail/type_traits/enum_traits.hpp | 5 +- .../type_traits/function_traits.hpp | 5 +- .../meta_detail/type_traits/member_traits.hpp | 5 +- .../meta_detail/type_traits/method_traits.hpp | 25 +++---- .../meta_detail/type_traits/number_traits.hpp | 5 +- .../type_traits/pointer_traits.hpp | 5 +- .../type_traits/reference_traits.hpp | 5 +- headers/meta.hpp/meta_types.hpp | 65 ++++++++++++------- headers/meta.hpp/meta_types/array_type.hpp | 2 +- headers/meta.hpp/meta_types/class_type.hpp | 2 +- headers/meta.hpp/meta_types/ctor_type.hpp | 2 +- headers/meta.hpp/meta_types/dtor_type.hpp | 2 +- headers/meta.hpp/meta_types/enum_type.hpp | 2 +- headers/meta.hpp/meta_types/function_type.hpp | 2 +- headers/meta.hpp/meta_types/member_type.hpp | 2 +- headers/meta.hpp/meta_types/method_type.hpp | 2 +- headers/meta.hpp/meta_types/number_type.hpp | 2 +- headers/meta.hpp/meta_types/pointer_type.hpp | 2 +- .../meta.hpp/meta_types/reference_type.hpp | 2 +- 23 files changed, 99 insertions(+), 67 deletions(-) diff --git a/headers/meta.hpp/meta_detail/type_traits/array_traits.hpp b/headers/meta.hpp/meta_detail/type_traits/array_traits.hpp index a5439bf..0ff6aa4 100644 --- a/headers/meta.hpp/meta_detail/type_traits/array_traits.hpp +++ b/headers/meta.hpp/meta_detail/type_traits/array_traits.hpp @@ -16,6 +16,7 @@ namespace meta_hpp::detail }; ENUM_HPP_OPERATORS_DECL(array_flags) + using array_bitflags = bitflags; } namespace meta_hpp::detail @@ -26,8 +27,8 @@ namespace meta_hpp::detail using data_type = std::remove_extent_t; - [[nodiscard]] static constexpr bitflags make_flags() noexcept { - bitflags flags; + [[nodiscard]] static constexpr array_bitflags make_flags() noexcept { + array_bitflags flags{}; if constexpr ( std::is_bounded_array_v ) { flags.set(array_flags::is_bounded); diff --git a/headers/meta.hpp/meta_detail/type_traits/class_traits.hpp b/headers/meta.hpp/meta_detail/type_traits/class_traits.hpp index d5e8591..b97a0da 100644 --- a/headers/meta.hpp/meta_detail/type_traits/class_traits.hpp +++ b/headers/meta.hpp/meta_detail/type_traits/class_traits.hpp @@ -19,6 +19,7 @@ namespace meta_hpp::detail }; ENUM_HPP_OPERATORS_DECL(class_flags) + using class_bitflags = bitflags; } namespace meta_hpp::detail @@ -31,7 +32,7 @@ namespace meta_hpp::detail using argument_types = type_list<>; - [[nodiscard]] static constexpr bitflags make_flags() noexcept { + [[nodiscard]] static constexpr class_bitflags make_flags() noexcept { return {}; } }; @@ -42,7 +43,7 @@ namespace meta_hpp::detail using argument_types = type_list; - [[nodiscard]] static constexpr bitflags make_flags() noexcept { + [[nodiscard]] static constexpr class_bitflags make_flags() noexcept { return class_flags::is_template_instantiation; } }; @@ -52,8 +53,8 @@ namespace meta_hpp::detail struct class_traits : impl::class_traits_base { static constexpr std::size_t size{sizeof(Class)}; - [[nodiscard]] static constexpr bitflags make_flags() noexcept { - bitflags flags; + [[nodiscard]] static constexpr class_bitflags make_flags() noexcept { + class_bitflags flags{}; if constexpr ( std::is_empty_v ) { flags.set(class_flags::is_empty); diff --git a/headers/meta.hpp/meta_detail/type_traits/ctor_traits.hpp b/headers/meta.hpp/meta_detail/type_traits/ctor_traits.hpp index e910274..9c8eedd 100644 --- a/headers/meta.hpp/meta_detail/type_traits/ctor_traits.hpp +++ b/headers/meta.hpp/meta_detail/type_traits/ctor_traits.hpp @@ -15,6 +15,7 @@ namespace meta_hpp::detail }; ENUM_HPP_OPERATORS_DECL(ctor_flags) + using ctor_bitflags = bitflags; } namespace meta_hpp::detail @@ -26,8 +27,8 @@ namespace meta_hpp::detail using class_type = Class; using argument_types = type_list; - [[nodiscard]] static constexpr bitflags make_flags() noexcept { - bitflags flags; + [[nodiscard]] static constexpr ctor_bitflags make_flags() noexcept { + ctor_bitflags flags{}; if constexpr ( std::is_nothrow_constructible_v ) { flags.set(ctor_flags::is_noexcept); diff --git a/headers/meta.hpp/meta_detail/type_traits/dtor_traits.hpp b/headers/meta.hpp/meta_detail/type_traits/dtor_traits.hpp index 8037180..759cdd5 100644 --- a/headers/meta.hpp/meta_detail/type_traits/dtor_traits.hpp +++ b/headers/meta.hpp/meta_detail/type_traits/dtor_traits.hpp @@ -15,6 +15,7 @@ namespace meta_hpp::detail }; ENUM_HPP_OPERATORS_DECL(dtor_flags) + using dtor_bitflags = bitflags; } namespace meta_hpp::detail @@ -23,8 +24,8 @@ namespace meta_hpp::detail struct dtor_traits { using class_type = Class; - [[nodiscard]] static constexpr bitflags make_flags() noexcept { - bitflags flags; + [[nodiscard]] static constexpr dtor_bitflags make_flags() noexcept { + dtor_bitflags flags{}; if constexpr ( std::is_nothrow_destructible_v ) { flags.set(dtor_flags::is_noexcept); diff --git a/headers/meta.hpp/meta_detail/type_traits/enum_traits.hpp b/headers/meta.hpp/meta_detail/type_traits/enum_traits.hpp index f347d8f..ed72a6a 100644 --- a/headers/meta.hpp/meta_detail/type_traits/enum_traits.hpp +++ b/headers/meta.hpp/meta_detail/type_traits/enum_traits.hpp @@ -15,6 +15,7 @@ namespace meta_hpp::detail }; ENUM_HPP_OPERATORS_DECL(enum_flags) + using enum_bitflags = bitflags; } namespace meta_hpp::detail @@ -23,8 +24,8 @@ namespace meta_hpp::detail struct enum_traits { using underlying_type = std::underlying_type_t; - [[nodiscard]] static constexpr bitflags make_flags() noexcept { - bitflags flags; + [[nodiscard]] static constexpr enum_bitflags make_flags() noexcept { + enum_bitflags flags{}; if constexpr ( !std::is_convertible_v ) { flags.set(enum_flags::is_scoped); diff --git a/headers/meta.hpp/meta_detail/type_traits/function_traits.hpp b/headers/meta.hpp/meta_detail/type_traits/function_traits.hpp index e82fb71..15b3046 100644 --- a/headers/meta.hpp/meta_detail/type_traits/function_traits.hpp +++ b/headers/meta.hpp/meta_detail/type_traits/function_traits.hpp @@ -15,6 +15,7 @@ namespace meta_hpp::detail }; ENUM_HPP_OPERATORS_DECL(function_flags) + using function_bitflags = bitflags; } namespace meta_hpp::detail @@ -29,14 +30,14 @@ namespace meta_hpp::detail using return_type = R; using argument_types = type_list; - [[nodiscard]] static constexpr bitflags make_flags() noexcept { + [[nodiscard]] static constexpr function_bitflags make_flags() noexcept { return {}; } }; template < typename R, typename... Args > struct function_traits : function_traits { - [[nodiscard]] static constexpr bitflags make_flags() noexcept { + [[nodiscard]] static constexpr function_bitflags make_flags() noexcept { return function_flags::is_noexcept; } }; diff --git a/headers/meta.hpp/meta_detail/type_traits/member_traits.hpp b/headers/meta.hpp/meta_detail/type_traits/member_traits.hpp index adaf932..e3bac94 100644 --- a/headers/meta.hpp/meta_detail/type_traits/member_traits.hpp +++ b/headers/meta.hpp/meta_detail/type_traits/member_traits.hpp @@ -15,6 +15,7 @@ namespace meta_hpp::detail }; ENUM_HPP_OPERATORS_DECL(member_flags) + using member_bitflags = bitflags; } namespace meta_hpp::detail @@ -27,8 +28,8 @@ namespace meta_hpp::detail using class_type = C; using value_type = V; - [[nodiscard]] static constexpr bitflags make_flags() noexcept { - bitflags flags; + [[nodiscard]] static constexpr member_bitflags make_flags() noexcept { + member_bitflags flags{}; if constexpr ( std::is_const_v ) { flags.set(member_flags::is_readonly); diff --git a/headers/meta.hpp/meta_detail/type_traits/method_traits.hpp b/headers/meta.hpp/meta_detail/type_traits/method_traits.hpp index 75384d5..b434fba 100644 --- a/headers/meta.hpp/meta_detail/type_traits/method_traits.hpp +++ b/headers/meta.hpp/meta_detail/type_traits/method_traits.hpp @@ -18,6 +18,7 @@ namespace meta_hpp::detail }; ENUM_HPP_OPERATORS_DECL(method_flags) + using method_bitflags = bitflags; } namespace meta_hpp::detail @@ -34,7 +35,7 @@ namespace meta_hpp::detail using qualified_type = C; using argument_types = type_list; - [[nodiscard]] static constexpr bitflags make_flags() noexcept { + [[nodiscard]] static constexpr method_bitflags make_flags() noexcept { return {}; } }; @@ -43,7 +44,7 @@ namespace meta_hpp::detail struct method_traits : method_traits { using qualified_type = const C; - [[nodiscard]] static constexpr bitflags make_flags() noexcept { + [[nodiscard]] static constexpr method_bitflags make_flags() noexcept { return method_flags::is_const; } }; @@ -52,7 +53,7 @@ namespace meta_hpp::detail struct method_traits : method_traits { using qualified_type = C; - [[nodiscard]] static constexpr bitflags make_flags() noexcept { + [[nodiscard]] static constexpr method_bitflags make_flags() noexcept { return method_flags::is_noexcept; } }; @@ -61,7 +62,7 @@ namespace meta_hpp::detail struct method_traits : method_traits { using qualified_type = const C; - [[nodiscard]] static constexpr bitflags make_flags() noexcept { + [[nodiscard]] static constexpr method_bitflags make_flags() noexcept { return method_flags::is_const | method_flags::is_noexcept; } }; @@ -70,7 +71,7 @@ namespace meta_hpp::detail struct method_traits : method_traits { using qualified_type = C&; - [[nodiscard]] static constexpr bitflags make_flags() noexcept { + [[nodiscard]] static constexpr method_bitflags make_flags() noexcept { return method_flags::is_lvalue_qualified; } }; @@ -79,7 +80,7 @@ namespace meta_hpp::detail struct method_traits : method_traits { using qualified_type = C&; - [[nodiscard]] static constexpr bitflags make_flags() noexcept { + [[nodiscard]] static constexpr method_bitflags make_flags() noexcept { return method_flags::is_noexcept | method_flags::is_lvalue_qualified; } }; @@ -88,7 +89,7 @@ namespace meta_hpp::detail struct method_traits : method_traits { using qualified_type = const C&; - [[nodiscard]] static constexpr bitflags make_flags() noexcept { + [[nodiscard]] static constexpr method_bitflags make_flags() noexcept { return method_flags::is_const | method_flags::is_lvalue_qualified; } }; @@ -97,7 +98,7 @@ namespace meta_hpp::detail struct method_traits : method_traits { using qualified_type = const C&; - [[nodiscard]] static constexpr bitflags make_flags() noexcept { + [[nodiscard]] static constexpr method_bitflags make_flags() noexcept { return method_flags::is_const | method_flags::is_noexcept | method_flags::is_lvalue_qualified; } }; @@ -106,7 +107,7 @@ namespace meta_hpp::detail struct method_traits : method_traits { using qualified_type = C&&; - [[nodiscard]] static constexpr bitflags make_flags() noexcept { + [[nodiscard]] static constexpr method_bitflags make_flags() noexcept { return method_flags::is_rvalue_qualified; } }; @@ -115,7 +116,7 @@ namespace meta_hpp::detail struct method_traits : method_traits { using qualified_type = C&&; - [[nodiscard]] static constexpr bitflags make_flags() noexcept { + [[nodiscard]] static constexpr method_bitflags make_flags() noexcept { return method_flags::is_noexcept | method_flags::is_rvalue_qualified; } }; @@ -124,7 +125,7 @@ namespace meta_hpp::detail struct method_traits : method_traits { using qualified_type = const C&&; - [[nodiscard]] static constexpr bitflags make_flags() noexcept { + [[nodiscard]] static constexpr method_bitflags make_flags() noexcept { return method_flags::is_const | method_flags::is_rvalue_qualified; } }; @@ -133,7 +134,7 @@ namespace meta_hpp::detail struct method_traits : method_traits { using qualified_type = const C&&; - [[nodiscard]] static constexpr bitflags make_flags() noexcept { + [[nodiscard]] static constexpr method_bitflags make_flags() noexcept { return method_flags::is_const | method_flags::is_noexcept | method_flags::is_rvalue_qualified; } }; diff --git a/headers/meta.hpp/meta_detail/type_traits/number_traits.hpp b/headers/meta.hpp/meta_detail/type_traits/number_traits.hpp index c438770..4126161 100644 --- a/headers/meta.hpp/meta_detail/type_traits/number_traits.hpp +++ b/headers/meta.hpp/meta_detail/type_traits/number_traits.hpp @@ -18,6 +18,7 @@ namespace meta_hpp::detail }; ENUM_HPP_OPERATORS_DECL(number_flags) + using number_bitflags = bitflags; } namespace meta_hpp::detail @@ -26,8 +27,8 @@ namespace meta_hpp::detail struct number_traits { static constexpr std::size_t size{sizeof(Number)}; - [[nodiscard]] static constexpr bitflags make_flags() noexcept { - bitflags flags; + [[nodiscard]] static constexpr number_bitflags make_flags() noexcept { + number_bitflags flags{}; if constexpr ( std::is_signed_v ) { flags.set(number_flags::is_signed); diff --git a/headers/meta.hpp/meta_detail/type_traits/pointer_traits.hpp b/headers/meta.hpp/meta_detail/type_traits/pointer_traits.hpp index beebc8a..43be453 100644 --- a/headers/meta.hpp/meta_detail/type_traits/pointer_traits.hpp +++ b/headers/meta.hpp/meta_detail/type_traits/pointer_traits.hpp @@ -15,6 +15,7 @@ namespace meta_hpp::detail }; ENUM_HPP_OPERATORS_DECL(pointer_flags) + using pointer_bitflags = bitflags; } namespace meta_hpp::detail @@ -23,8 +24,8 @@ namespace meta_hpp::detail struct pointer_traits { using data_type = std::remove_pointer_t; - [[nodiscard]] static constexpr bitflags make_flags() noexcept { - bitflags flags; + [[nodiscard]] static constexpr pointer_bitflags make_flags() noexcept { + pointer_bitflags flags{}; if constexpr ( std::is_const_v ) { flags.set(pointer_flags::is_readonly); diff --git a/headers/meta.hpp/meta_detail/type_traits/reference_traits.hpp b/headers/meta.hpp/meta_detail/type_traits/reference_traits.hpp index efd179e..4acf314 100644 --- a/headers/meta.hpp/meta_detail/type_traits/reference_traits.hpp +++ b/headers/meta.hpp/meta_detail/type_traits/reference_traits.hpp @@ -17,6 +17,7 @@ namespace meta_hpp::detail }; ENUM_HPP_OPERATORS_DECL(reference_flags) + using reference_bitflags = bitflags; } namespace meta_hpp::detail @@ -25,8 +26,8 @@ namespace meta_hpp::detail struct reference_traits { using data_type = std::remove_reference_t; - [[nodiscard]] static constexpr bitflags make_flags() noexcept { - bitflags flags; + [[nodiscard]] static constexpr reference_bitflags make_flags() noexcept { + reference_bitflags flags{}; if constexpr ( std::is_const_v ) { flags.set(reference_flags::is_readonly); diff --git a/headers/meta.hpp/meta_types.hpp b/headers/meta.hpp/meta_types.hpp index c1e38b0..675bfaf 100644 --- a/headers/meta.hpp/meta_types.hpp +++ b/headers/meta.hpp/meta_types.hpp @@ -25,16 +25,37 @@ namespace meta_hpp { using array_flags = detail::array_flags; + using array_bitflags = detail::array_bitflags; + using class_flags = detail::class_flags; + using class_bitflags = detail::class_bitflags; + using ctor_flags = detail::ctor_flags; + using ctor_bitflags = detail::ctor_bitflags; + using dtor_flags = detail::dtor_flags; + using dtor_bitflags = detail::dtor_bitflags; + using enum_flags = detail::enum_flags; + using enum_bitflags = detail::enum_bitflags; + using function_flags = detail::function_flags; + using function_bitflags = detail::function_bitflags; + using member_flags = detail::member_flags; + using member_bitflags = detail::member_bitflags; + using method_flags = detail::method_flags; + using method_bitflags = detail::method_bitflags; + using number_flags = detail::number_flags; + using number_bitflags = detail::number_bitflags; + using pointer_flags = detail::pointer_flags; + using pointer_bitflags = detail::pointer_bitflags; + using reference_flags = detail::reference_flags; + using reference_bitflags = detail::reference_bitflags; } namespace meta_hpp @@ -104,7 +125,7 @@ namespace meta_hpp [[nodiscard]] explicit operator bool() const noexcept; [[nodiscard]] type_id get_id() const noexcept; - [[nodiscard]] bitflags get_flags() const noexcept; + [[nodiscard]] array_bitflags get_flags() const noexcept; [[nodiscard]] std::size_t get_extent() const noexcept; [[nodiscard]] any_type get_data_type() const noexcept; @@ -122,7 +143,7 @@ namespace meta_hpp [[nodiscard]] explicit operator bool() const noexcept; [[nodiscard]] type_id get_id() const noexcept; - [[nodiscard]] bitflags get_flags() const noexcept; + [[nodiscard]] class_bitflags get_flags() const noexcept; [[nodiscard]] std::size_t get_size() const noexcept; @@ -188,7 +209,7 @@ namespace meta_hpp [[nodiscard]] explicit operator bool() const noexcept; [[nodiscard]] type_id get_id() const noexcept; - [[nodiscard]] bitflags get_flags() const noexcept; + [[nodiscard]] ctor_bitflags get_flags() const noexcept; [[nodiscard]] std::size_t get_arity() const noexcept; [[nodiscard]] any_type get_class_type() const noexcept; @@ -208,7 +229,7 @@ namespace meta_hpp [[nodiscard]] explicit operator bool() const noexcept; [[nodiscard]] type_id get_id() const noexcept; - [[nodiscard]] bitflags get_flags() const noexcept; + [[nodiscard]] dtor_bitflags get_flags() const noexcept; [[nodiscard]] any_type get_class_type() const noexcept; private: @@ -225,7 +246,7 @@ namespace meta_hpp [[nodiscard]] explicit operator bool() const noexcept; [[nodiscard]] type_id get_id() const noexcept; - [[nodiscard]] bitflags get_flags() const noexcept; + [[nodiscard]] enum_bitflags get_flags() const noexcept; [[nodiscard]] number_type get_underlying_type() const noexcept; @@ -250,7 +271,7 @@ namespace meta_hpp [[nodiscard]] explicit operator bool() const noexcept; [[nodiscard]] type_id get_id() const noexcept; - [[nodiscard]] bitflags get_flags() const noexcept; + [[nodiscard]] function_bitflags get_flags() const noexcept; [[nodiscard]] std::size_t get_arity() const noexcept; [[nodiscard]] any_type get_return_type() const noexcept; @@ -270,7 +291,7 @@ namespace meta_hpp [[nodiscard]] explicit operator bool() const noexcept; [[nodiscard]] type_id get_id() const noexcept; - [[nodiscard]] bitflags get_flags() const noexcept; + [[nodiscard]] member_bitflags get_flags() const noexcept; [[nodiscard]] class_type get_owner_type() const noexcept; [[nodiscard]] any_type get_value_type() const noexcept; @@ -288,7 +309,7 @@ namespace meta_hpp [[nodiscard]] explicit operator bool() const noexcept; [[nodiscard]] type_id get_id() const noexcept; - [[nodiscard]] bitflags get_flags() const noexcept; + [[nodiscard]] method_bitflags get_flags() const noexcept; [[nodiscard]] std::size_t get_arity() const noexcept; [[nodiscard]] class_type get_owner_type() const noexcept; @@ -323,7 +344,7 @@ namespace meta_hpp [[nodiscard]] explicit operator bool() const noexcept; [[nodiscard]] type_id get_id() const noexcept; - [[nodiscard]] bitflags get_flags() const noexcept; + [[nodiscard]] number_bitflags get_flags() const noexcept; [[nodiscard]] std::size_t get_size() const noexcept; private: @@ -340,7 +361,7 @@ namespace meta_hpp [[nodiscard]] explicit operator bool() const noexcept; [[nodiscard]] type_id get_id() const noexcept; - [[nodiscard]] bitflags get_flags() const noexcept; + [[nodiscard]] pointer_bitflags get_flags() const noexcept; [[nodiscard]] any_type get_data_type() const noexcept; private: @@ -357,7 +378,7 @@ namespace meta_hpp [[nodiscard]] explicit operator bool() const noexcept; [[nodiscard]] type_id get_id() const noexcept; - [[nodiscard]] bitflags get_flags() const noexcept; + [[nodiscard]] reference_bitflags get_flags() const noexcept; [[nodiscard]] any_type get_data_type() const noexcept; private: @@ -426,7 +447,7 @@ namespace meta_hpp::detail }; struct array_type_data final : type_data_base { - const bitflags flags; + const array_bitflags flags; const std::size_t extent; const any_type data_type; @@ -435,7 +456,7 @@ namespace meta_hpp::detail }; struct class_type_data final : type_data_base { - const bitflags flags; + const class_bitflags flags; const std::size_t size; const std::vector argument_types; @@ -460,7 +481,7 @@ namespace meta_hpp::detail }; struct ctor_type_data final : type_data_base { - const bitflags flags; + const ctor_bitflags flags; const any_type class_type; const std::vector argument_types; @@ -469,7 +490,7 @@ namespace meta_hpp::detail }; struct dtor_type_data final : type_data_base { - const bitflags flags; + const dtor_bitflags flags; const any_type class_type; template < class_kind Class > @@ -477,7 +498,7 @@ namespace meta_hpp::detail }; struct enum_type_data final : type_data_base { - const bitflags flags; + const enum_bitflags flags; const number_type underlying_type; evalue_map evalues; @@ -487,7 +508,7 @@ namespace meta_hpp::detail }; struct function_type_data final : type_data_base { - const bitflags flags; + const function_bitflags flags; const any_type return_type; const std::vector argument_types; @@ -496,7 +517,7 @@ namespace meta_hpp::detail }; struct member_type_data final : type_data_base { - const bitflags flags; + const member_bitflags flags; const class_type owner_type; const any_type value_type; @@ -505,7 +526,7 @@ namespace meta_hpp::detail }; struct method_type_data final : type_data_base { - const bitflags flags; + const method_bitflags flags; const class_type owner_type; const any_type return_type; const std::vector argument_types; @@ -520,7 +541,7 @@ namespace meta_hpp::detail }; struct number_type_data final : type_data_base { - const bitflags flags; + const number_bitflags flags; const std::size_t size; template < number_kind Number > @@ -528,7 +549,7 @@ namespace meta_hpp::detail }; struct pointer_type_data final : type_data_base { - const bitflags flags; + const pointer_bitflags flags; const any_type data_type; template < pointer_kind Pointer > @@ -536,7 +557,7 @@ namespace meta_hpp::detail }; struct reference_type_data final : type_data_base { - const bitflags flags; + const reference_bitflags flags; const any_type data_type; template < reference_kind Reference > diff --git a/headers/meta.hpp/meta_types/array_type.hpp b/headers/meta.hpp/meta_types/array_type.hpp index 0fa628c..dbf0836 100644 --- a/headers/meta.hpp/meta_types/array_type.hpp +++ b/headers/meta.hpp/meta_types/array_type.hpp @@ -43,7 +43,7 @@ namespace meta_hpp return data_->id; } - inline bitflags array_type::get_flags() const noexcept { + inline array_bitflags array_type::get_flags() const noexcept { return data_->flags; } diff --git a/headers/meta.hpp/meta_types/class_type.hpp b/headers/meta.hpp/meta_types/class_type.hpp index f9a0f12..d9c5740 100644 --- a/headers/meta.hpp/meta_types/class_type.hpp +++ b/headers/meta.hpp/meta_types/class_type.hpp @@ -49,7 +49,7 @@ namespace meta_hpp return data_->id; } - inline bitflags class_type::get_flags() const noexcept { + inline class_bitflags class_type::get_flags() const noexcept { return data_->flags; } diff --git a/headers/meta.hpp/meta_types/ctor_type.hpp b/headers/meta.hpp/meta_types/ctor_type.hpp index b719b58..c08ea0a 100644 --- a/headers/meta.hpp/meta_types/ctor_type.hpp +++ b/headers/meta.hpp/meta_types/ctor_type.hpp @@ -43,7 +43,7 @@ namespace meta_hpp return data_->id; } - inline bitflags ctor_type::get_flags() const noexcept { + inline ctor_bitflags ctor_type::get_flags() const noexcept { return data_->flags; } diff --git a/headers/meta.hpp/meta_types/dtor_type.hpp b/headers/meta.hpp/meta_types/dtor_type.hpp index f24413c..d0dbc02 100644 --- a/headers/meta.hpp/meta_types/dtor_type.hpp +++ b/headers/meta.hpp/meta_types/dtor_type.hpp @@ -42,7 +42,7 @@ namespace meta_hpp return data_->id; } - inline bitflags dtor_type::get_flags() const noexcept { + inline dtor_bitflags dtor_type::get_flags() const noexcept { return data_->flags; } diff --git a/headers/meta.hpp/meta_types/enum_type.hpp b/headers/meta.hpp/meta_types/enum_type.hpp index db20134..d515d9f 100644 --- a/headers/meta.hpp/meta_types/enum_type.hpp +++ b/headers/meta.hpp/meta_types/enum_type.hpp @@ -45,7 +45,7 @@ namespace meta_hpp return data_->id; } - inline bitflags enum_type::get_flags() const noexcept { + inline enum_bitflags enum_type::get_flags() const noexcept { return data_->flags; } diff --git a/headers/meta.hpp/meta_types/function_type.hpp b/headers/meta.hpp/meta_types/function_type.hpp index 551c4a4..52fb118 100644 --- a/headers/meta.hpp/meta_types/function_type.hpp +++ b/headers/meta.hpp/meta_types/function_type.hpp @@ -43,7 +43,7 @@ namespace meta_hpp return data_->id; } - inline bitflags function_type::get_flags() const noexcept { + inline function_bitflags function_type::get_flags() const noexcept { return data_->flags; } diff --git a/headers/meta.hpp/meta_types/member_type.hpp b/headers/meta.hpp/meta_types/member_type.hpp index 60964fb..2ca258d 100644 --- a/headers/meta.hpp/meta_types/member_type.hpp +++ b/headers/meta.hpp/meta_types/member_type.hpp @@ -43,7 +43,7 @@ namespace meta_hpp return data_->id; } - inline bitflags member_type::get_flags() const noexcept { + inline member_bitflags member_type::get_flags() const noexcept { return data_->flags; } diff --git a/headers/meta.hpp/meta_types/method_type.hpp b/headers/meta.hpp/meta_types/method_type.hpp index 8e97769..2e8e193 100644 --- a/headers/meta.hpp/meta_types/method_type.hpp +++ b/headers/meta.hpp/meta_types/method_type.hpp @@ -44,7 +44,7 @@ namespace meta_hpp return data_->id; } - inline bitflags method_type::get_flags() const noexcept { + inline method_bitflags method_type::get_flags() const noexcept { return data_->flags; } diff --git a/headers/meta.hpp/meta_types/number_type.hpp b/headers/meta.hpp/meta_types/number_type.hpp index cbf65b2..463f3ef 100644 --- a/headers/meta.hpp/meta_types/number_type.hpp +++ b/headers/meta.hpp/meta_types/number_type.hpp @@ -41,7 +41,7 @@ namespace meta_hpp return data_->id; } - inline bitflags number_type::get_flags() const noexcept { + inline number_bitflags number_type::get_flags() const noexcept { return data_->flags; } diff --git a/headers/meta.hpp/meta_types/pointer_type.hpp b/headers/meta.hpp/meta_types/pointer_type.hpp index 485f227..e6c178d 100644 --- a/headers/meta.hpp/meta_types/pointer_type.hpp +++ b/headers/meta.hpp/meta_types/pointer_type.hpp @@ -42,7 +42,7 @@ namespace meta_hpp return data_->id; } - inline bitflags pointer_type::get_flags() const noexcept { + inline pointer_bitflags pointer_type::get_flags() const noexcept { return data_->flags; } diff --git a/headers/meta.hpp/meta_types/reference_type.hpp b/headers/meta.hpp/meta_types/reference_type.hpp index aed33d1..e4e3cde 100644 --- a/headers/meta.hpp/meta_types/reference_type.hpp +++ b/headers/meta.hpp/meta_types/reference_type.hpp @@ -42,7 +42,7 @@ namespace meta_hpp return data_->id; } - inline bitflags reference_type::get_flags() const noexcept { + inline reference_bitflags reference_type::get_flags() const noexcept { return data_->flags; } From 54526bdd84a9442866bfe3ec506a9f8d3dd4a7d9 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Mon, 7 Feb 2022 23:58:32 +0700 Subject: [PATCH 212/233] parameter_index --- headers/meta.hpp/meta_all.hpp | 1 + headers/meta.hpp/meta_base.hpp | 1 + headers/meta.hpp/meta_indices.hpp | 18 ++++++++ .../meta.hpp/meta_indices/parameter_index.hpp | 41 +++++++++++++++++++ 4 files changed, 61 insertions(+) create mode 100644 headers/meta.hpp/meta_indices/parameter_index.hpp diff --git a/headers/meta.hpp/meta_all.hpp b/headers/meta.hpp/meta_all.hpp index 0a44744..d903251 100644 --- a/headers/meta.hpp/meta_all.hpp +++ b/headers/meta.hpp/meta_all.hpp @@ -20,6 +20,7 @@ #include "meta_indices/function_index.hpp" #include "meta_indices/member_index.hpp" #include "meta_indices/method_index.hpp" +#include "meta_indices/parameter_index.hpp" #include "meta_indices/scope_index.hpp" #include "meta_indices/variable_index.hpp" diff --git a/headers/meta.hpp/meta_base.hpp b/headers/meta.hpp/meta_base.hpp index 2f77ccf..8591464 100644 --- a/headers/meta.hpp/meta_base.hpp +++ b/headers/meta.hpp/meta_base.hpp @@ -193,6 +193,7 @@ namespace meta_hpp class function_index; class member_index; class method_index; + class parameter_index; class scope_index; class variable_index; diff --git a/headers/meta.hpp/meta_indices.hpp b/headers/meta.hpp/meta_indices.hpp index 5be5774..74f18b8 100644 --- a/headers/meta.hpp/meta_indices.hpp +++ b/headers/meta.hpp/meta_indices.hpp @@ -115,6 +115,24 @@ namespace meta_hpp std::string name_; }; + class parameter_index final { + public: + parameter_index() = delete; + [[nodiscard]] const any_type& get_type() const noexcept; + [[nodiscard]] const std::string& get_name() const noexcept; + private: + friend detail::parameter_state; + template < typename Parameter > + [[nodiscard]] static parameter_index make(std::string name); + private: + explicit parameter_index(any_type type, std::string name); + friend bool operator<(const parameter_index& l, const parameter_index& r) noexcept; + friend bool operator==(const parameter_index& l, const parameter_index& r) noexcept; + private: + any_type type_; + std::string name_; + }; + class scope_index final { public: scope_index() = delete; diff --git a/headers/meta.hpp/meta_indices/parameter_index.hpp b/headers/meta.hpp/meta_indices/parameter_index.hpp new file mode 100644 index 0000000..d44bfc6 --- /dev/null +++ b/headers/meta.hpp/meta_indices/parameter_index.hpp @@ -0,0 +1,41 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_indices.hpp" +#include "../meta_types.hpp" + +#include "../meta_detail/type_registry.hpp" + +namespace meta_hpp +{ + inline parameter_index::parameter_index(any_type type, std::string name) + : type_{std::move(type)} + , name_{std::move(name)} {} + + template < typename Parameter > + inline parameter_index parameter_index::make(std::string name) { + return parameter_index{detail::resolve_type(), std::move(name)}; + } + + inline const any_type& parameter_index::get_type() const noexcept { + return type_; + } + + inline const std::string& parameter_index::get_name() const noexcept { + return name_; + } + + inline bool operator<(const parameter_index& l, const parameter_index& r) noexcept { + return l.type_ < r.type_ || (l.type_ == r.type_ && std::less<>{}(l.name_, r.name_)); + } + + inline bool operator==(const parameter_index& l, const parameter_index& r) noexcept { + return l.type_ == r.type_ && std::equal_to<>{}(l.name_, r.name_); + } +} From 9a7808939b09cd11da60fada286bb88eb28b9410 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Tue, 8 Feb 2022 01:36:58 +0700 Subject: [PATCH 213/233] style fixes --- .clang-tidy | 1 + TODO.md | 2 ++ .../meta.hpp/meta_detail/value_traits/index_traits.hpp | 4 ++-- headers/meta.hpp/meta_states/ctor.hpp | 10 +++++----- headers/meta.hpp/meta_states/function.hpp | 8 ++++---- headers/meta.hpp/meta_states/method.hpp | 8 ++++---- 6 files changed, 18 insertions(+), 15 deletions(-) diff --git a/.clang-tidy b/.clang-tidy index 3def598..d4c66b5 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -7,6 +7,7 @@ Checks: '-*, cppcoreguidelines-*, -cppcoreguidelines-macro-usage, + -cppcoreguidelines-pro-bounds-pointer-arithmetic, modernize-*, -modernize-use-trailing-return-type, diff --git a/TODO.md b/TODO.md index 2d53ed8..a98a338 100644 --- a/TODO.md +++ b/TODO.md @@ -1,6 +1,8 @@ # meta.hpp - metadata +- add policy tests +- rebind types support * argument defaults * argument names diff --git a/headers/meta.hpp/meta_detail/value_traits/index_traits.hpp b/headers/meta.hpp/meta_detail/value_traits/index_traits.hpp index 22c5cce..53e6f14 100644 --- a/headers/meta.hpp/meta_detail/value_traits/index_traits.hpp +++ b/headers/meta.hpp/meta_detail/value_traits/index_traits.hpp @@ -25,14 +25,14 @@ namespace meta_hpp::detail template < stdex::copy_constructible T > struct index_traits { value operator()(T* v, std::size_t i) const { - return value{*(v + i)}; + return value{v[i]}; } }; template < stdex::copy_constructible T > struct index_traits { value operator()(const T* v, std::size_t i) const { - return value{*(v + i)}; + return value{v[i]}; } }; diff --git a/headers/meta.hpp/meta_states/ctor.hpp b/headers/meta.hpp/meta_states/ctor.hpp index 02fa66e..b4da195 100644 --- a/headers/meta.hpp/meta_states/ctor.hpp +++ b/headers/meta.hpp/meta_states/ctor.hpp @@ -40,22 +40,22 @@ namespace meta_hpp::detail args // NOLINTNEXTLINE(readability-named-parameter) ](std::index_sequence) -> value { - if ( !(... && (args.data() + Is)->can_cast_to>()) ) { + if ( !(... && args[Is].can_cast_to>()) ) { throw_exception_with("an attempt to call a constructor with incorrect argument types"); } if constexpr ( as_object ) { - class_type return_value{(args.data() + Is)->cast>()...}; + class_type return_value{args[Is].cast>()...}; return value{std::move(return_value)}; } if constexpr ( as_raw_ptr ) { - auto return_value{std::make_unique((args.data() + Is)->cast>()...)}; + auto return_value{std::make_unique(args[Is].cast>()...)}; return value{return_value.release()}; } if constexpr ( as_shared_ptr ) { - auto return_value{std::make_shared((args.data() + Is)->cast>()...)}; + auto return_value{std::make_shared(args[Is].cast>()...)}; return value{std::move(return_value)}; } }, std::make_index_sequence()); @@ -72,7 +72,7 @@ namespace meta_hpp::detail // NOLINTNEXTLINE(readability-named-parameter) return std::invoke([args](std::index_sequence){ - return (... && (args.data() + Is)->can_cast_to>()); + return (... && args[Is].can_cast_to>()); }, std::make_index_sequence()); } } diff --git a/headers/meta.hpp/meta_states/function.hpp b/headers/meta.hpp/meta_states/function.hpp index 817ab3f..27d63ac 100644 --- a/headers/meta.hpp/meta_states/function.hpp +++ b/headers/meta.hpp/meta_states/function.hpp @@ -42,19 +42,19 @@ namespace meta_hpp::detail &function, args // NOLINTNEXTLINE(readability-named-parameter) ](std::index_sequence) -> value { - if ( !(... && (args.data() + Is)->can_cast_to>()) ) { + if ( !(... && args[Is].can_cast_to>()) ) { throw_exception_with("an attempt to call a function with incorrect argument types"); } if constexpr ( as_void ) { std::ignore = std::invoke( function, - (args.data() + Is)->cast>()...); + args[Is].cast>()...); return value{}; } else { return_type&& return_value = std::invoke( function, - (args.data() + Is)->cast>()...); + args[Is].cast>()...); if constexpr ( ref_as_ptr ) { return value{std::addressof(return_value)}; @@ -76,7 +76,7 @@ namespace meta_hpp::detail // NOLINTNEXTLINE(readability-named-parameter) return std::invoke([args](std::index_sequence){ - return (... && (args.data() + Is)->can_cast_to>()); + return (... && args[Is].can_cast_to>()); }, std::make_index_sequence()); } } diff --git a/headers/meta.hpp/meta_states/method.hpp b/headers/meta.hpp/meta_states/method.hpp index 69baea2..bed9b9c 100644 --- a/headers/meta.hpp/meta_states/method.hpp +++ b/headers/meta.hpp/meta_states/method.hpp @@ -48,7 +48,7 @@ namespace meta_hpp::detail &method, &inst, args // NOLINTNEXTLINE(readability-named-parameter) ](std::index_sequence) -> value { - if ( !(... && (args.data() + Is)->can_cast_to>()) ) { + if ( !(... && args[Is].can_cast_to>()) ) { throw_exception_with("an attempt to call a method with incorrect argument types"); } @@ -56,13 +56,13 @@ namespace meta_hpp::detail std::ignore = std::invoke( method, inst.cast(), - (args.data() + Is)->cast>()...); + args[Is].cast>()...); return value{}; } else { return_type&& return_value = std::invoke( method, inst.cast(), - (args.data() + Is)->cast>()...); + args[Is].cast>()...); if constexpr ( ref_as_ptr ) { return value{std::addressof(return_value)}; @@ -89,7 +89,7 @@ namespace meta_hpp::detail // NOLINTNEXTLINE(readability-named-parameter) return std::invoke([args](std::index_sequence){ - return (... && (args.data() + Is)->can_cast_to>()); + return (... && args[Is].can_cast_to>()); }, std::make_index_sequence()); } } From a30d8075e8062617d8f33eace37795c3bb0ece36 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Tue, 8 Feb 2022 01:38:49 +0700 Subject: [PATCH 214/233] parameter state --- headers/meta.hpp/meta_all.hpp | 1 + headers/meta.hpp/meta_base.hpp | 3 ++ headers/meta.hpp/meta_detail/state_family.hpp | 1 + headers/meta.hpp/meta_states.hpp | 23 +++++++++ headers/meta.hpp/meta_states/parameter.hpp | 47 +++++++++++++++++++ 5 files changed, 75 insertions(+) create mode 100644 headers/meta.hpp/meta_states/parameter.hpp diff --git a/headers/meta.hpp/meta_all.hpp b/headers/meta.hpp/meta_all.hpp index d903251..45fe3a7 100644 --- a/headers/meta.hpp/meta_all.hpp +++ b/headers/meta.hpp/meta_all.hpp @@ -31,6 +31,7 @@ #include "meta_states/function.hpp" #include "meta_states/member.hpp" #include "meta_states/method.hpp" +#include "meta_states/parameter.hpp" #include "meta_states/scope.hpp" #include "meta_states/variable.hpp" diff --git a/headers/meta.hpp/meta_base.hpp b/headers/meta.hpp/meta_base.hpp index 8591464..868a172 100644 --- a/headers/meta.hpp/meta_base.hpp +++ b/headers/meta.hpp/meta_base.hpp @@ -109,6 +109,7 @@ namespace meta_hpp class function; class member; class method; + class parameter; class scope; class variable; @@ -120,6 +121,7 @@ namespace meta_hpp struct function_state; struct member_state; struct method_state; + struct parameter_state; struct scope_state; struct variable_state; @@ -129,6 +131,7 @@ namespace meta_hpp using function_state_ptr = std::shared_ptr; using member_state_ptr = std::shared_ptr; using method_state_ptr = std::shared_ptr; + using parameter_state_ptr = std::shared_ptr; using scope_state_ptr = std::shared_ptr; using variable_state_ptr = std::shared_ptr; } diff --git a/headers/meta.hpp/meta_detail/state_family.hpp b/headers/meta.hpp/meta_detail/state_family.hpp index a580340..18c4865 100644 --- a/headers/meta.hpp/meta_detail/state_family.hpp +++ b/headers/meta.hpp/meta_detail/state_family.hpp @@ -18,6 +18,7 @@ namespace meta_hpp::detail std::is_same_v || std::is_same_v || std::is_same_v || + std::is_same_v || std::is_same_v || std::is_same_v; diff --git a/headers/meta.hpp/meta_states.hpp b/headers/meta.hpp/meta_states.hpp index 3f590cd..589bafe 100644 --- a/headers/meta.hpp/meta_states.hpp +++ b/headers/meta.hpp/meta_states.hpp @@ -267,6 +267,22 @@ namespace meta_hpp friend auto detail::state_access(const method&); }; + class parameter final { + public: + explicit parameter() = default; + explicit parameter(detail::parameter_state_ptr state); + + [[nodiscard]] bool is_valid() const noexcept; + [[nodiscard]] explicit operator bool() const noexcept; + + [[nodiscard]] const parameter_index& get_index() const noexcept; + [[nodiscard]] const any_type& get_type() const noexcept; + [[nodiscard]] const std::string& get_name() const noexcept; + private: + detail::parameter_state_ptr state_; + friend auto detail::state_access(const parameter&); + }; + class scope final { public: explicit scope() = default; @@ -440,6 +456,13 @@ namespace meta_hpp::detail [[nodiscard]] static method_state_ptr make(std::string name, Method method); }; + struct parameter_state final { + parameter_index index; + + template < typename Parameter > + [[nodiscard]] static parameter_state_ptr make(std::string name); + }; + struct scope_state final { scope_index index; diff --git a/headers/meta.hpp/meta_states/parameter.hpp b/headers/meta.hpp/meta_states/parameter.hpp new file mode 100644 index 0000000..4060458 --- /dev/null +++ b/headers/meta.hpp/meta_states/parameter.hpp @@ -0,0 +1,47 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_states.hpp" + +namespace meta_hpp::detail +{ + template < typename Parameter > + inline parameter_state_ptr parameter_state::make(std::string name) { + return std::make_shared(parameter_state{ + .index{parameter_index::make(std::move(name))}, + }); + } +} + +namespace meta_hpp +{ + + inline parameter::parameter(detail::parameter_state_ptr state) + : state_{std::move(state)} {} + + inline bool parameter::is_valid() const noexcept { + return !!state_; + } + + inline parameter::operator bool() const noexcept { + return is_valid(); + } + + inline const parameter_index& parameter::get_index() const noexcept { + return state_->index; + } + + inline const any_type& parameter::get_type() const noexcept { + return state_->index.get_type(); + } + + inline const std::string& parameter::get_name() const noexcept { + return state_->index.get_name(); + } +} From 5a20a1c7b225e60ad1a627d6cbe9555ea9520c85 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Tue, 8 Feb 2022 06:21:29 +0700 Subject: [PATCH 215/233] little copy/paste refactoring --- TODO.md | 1 + headers/meta.hpp/meta_states.hpp | 2 + headers/meta.hpp/meta_states/scope.hpp | 31 ++---- headers/meta.hpp/meta_types.hpp | 6 ++ headers/meta.hpp/meta_types/class_type.hpp | 109 ++++++--------------- 5 files changed, 47 insertions(+), 102 deletions(-) diff --git a/TODO.md b/TODO.md index a98a338..75a811d 100644 --- a/TODO.md +++ b/TODO.md @@ -3,6 +3,7 @@ - metadata - add policy tests - rebind types support +- rewrite ctor/dtor system * argument defaults * argument names diff --git a/headers/meta.hpp/meta_states.hpp b/headers/meta.hpp/meta_states.hpp index 589bafe..1fb5005 100644 --- a/headers/meta.hpp/meta_states.hpp +++ b/headers/meta.hpp/meta_states.hpp @@ -306,6 +306,8 @@ namespace meta_hpp template < typename... Args > [[nodiscard]] function get_function_with(std::string_view name) const noexcept; + template < typename Iter > + [[nodiscard]] function get_function_with(std::string_view name, Iter first, Iter last) const noexcept; [[nodiscard]] function get_function_with(std::string_view name, const std::vector& args) const noexcept; [[nodiscard]] function get_function_with(std::string_view name, std::initializer_list args) const noexcept; private: diff --git a/headers/meta.hpp/meta_states/scope.hpp b/headers/meta.hpp/meta_states/scope.hpp index 81b56d9..f4c3334 100644 --- a/headers/meta.hpp/meta_states/scope.hpp +++ b/headers/meta.hpp/meta_states/scope.hpp @@ -101,39 +101,26 @@ namespace meta_hpp return get_function_with(name, {detail::resolve_type()...}); } - inline function scope::get_function_with(std::string_view name, const std::vector& args) const noexcept { + template < typename Iter > + function scope::get_function_with(std::string_view name, Iter first, Iter last) const noexcept { for ( auto&& [index, function] : state_->functions ) { if ( index.get_name() != name ) { continue; } - if ( function.get_type().get_arity() != args.size() ) { - continue; - } - - const std::vector& function_args = function.get_type().get_argument_types(); - if ( std::equal(args.begin(), args.end(), function_args.begin(), function_args.end()) ) { + const std::vector& args = function.get_type().get_argument_types(); + if ( std::equal(first, last, args.begin(), args.end()) ) { return function; } } return function{}; } + inline function scope::get_function_with(std::string_view name, const std::vector& args) const noexcept { + return get_function_with(name, args.begin(), args.end()); + } + inline function scope::get_function_with(std::string_view name, std::initializer_list args) const noexcept { - for ( auto&& [index, function] : state_->functions ) { - if ( index.get_name() != name ) { - continue; - } - - if ( function.get_type().get_arity() != args.size() ) { - continue; - } - - const std::vector& function_args = function.get_type().get_argument_types(); - if ( std::equal(args.begin(), args.end(), function_args.begin(), function_args.end()) ) { - return function; - } - } - return function{}; + return get_function_with(name, args.begin(), args.end()); } } diff --git a/headers/meta.hpp/meta_types.hpp b/headers/meta.hpp/meta_types.hpp index 675bfaf..c9105dd 100644 --- a/headers/meta.hpp/meta_types.hpp +++ b/headers/meta.hpp/meta_types.hpp @@ -183,16 +183,22 @@ namespace meta_hpp template < typename... Args > [[nodiscard]] ctor get_ctor_with() const noexcept; + template < typename Iter > + [[nodiscard]] ctor get_ctor_with(Iter first, Iter last) const noexcept; [[nodiscard]] ctor get_ctor_with(const std::vector& args) const noexcept; [[nodiscard]] ctor get_ctor_with(std::initializer_list args) const noexcept; template < typename... Args > [[nodiscard]] function get_function_with(std::string_view name) const noexcept; + template < typename Iter > + [[nodiscard]] function get_function_with(std::string_view name, Iter first, Iter last) const noexcept; [[nodiscard]] function get_function_with(std::string_view name, const std::vector& args) const noexcept; [[nodiscard]] function get_function_with(std::string_view name, std::initializer_list args) const noexcept; template < typename... Args > [[nodiscard]] method get_method_with(std::string_view name) const noexcept; + template < typename Iter > + [[nodiscard]] method get_method_with(std::string_view name, Iter first, Iter last) const noexcept; [[nodiscard]] method get_method_with(std::string_view name, const std::vector& args) const noexcept; [[nodiscard]] method get_method_with(std::string_view name, std::initializer_list args) const noexcept; private: diff --git a/headers/meta.hpp/meta_types/class_type.hpp b/headers/meta.hpp/meta_types/class_type.hpp index d9c5740..542d71c 100644 --- a/headers/meta.hpp/meta_types/class_type.hpp +++ b/headers/meta.hpp/meta_types/class_type.hpp @@ -242,34 +242,23 @@ namespace meta_hpp return get_ctor_with({detail::resolve_type()...}); } - inline ctor class_type::get_ctor_with(const std::vector& args) const noexcept { + template < typename Iter > + ctor class_type::get_ctor_with(Iter first, Iter last) const noexcept { for ( auto&& [index, ctor] : data_->ctors ) { - if ( ctor.get_type().get_arity() != args.size() ) { - continue; - } - - const std::vector& ctor_args = ctor.get_type().get_argument_types(); - if ( std::equal(args.begin(), args.end(), ctor_args.begin(), ctor_args.end()) ) { + const std::vector& args = ctor.get_type().get_argument_types(); + if ( std::equal(first, last, args.begin(), args.end()) ) { return ctor; } } - return ctor{}; } + inline ctor class_type::get_ctor_with(const std::vector& args) const noexcept { + return get_ctor_with(args.begin(), args.end()); + } + inline ctor class_type::get_ctor_with(std::initializer_list args) const noexcept { - for ( auto&& [index, ctor] : data_->ctors ) { - if ( ctor.get_type().get_arity() != args.size() ) { - continue; - } - - const std::vector& ctor_args = ctor.get_type().get_argument_types(); - if ( std::equal(args.begin(), args.end(), ctor_args.begin(), ctor_args.end()) ) { - return ctor; - } - } - - return ctor{}; + return get_ctor_with(args.begin(), args.end()); } // @@ -281,24 +270,21 @@ namespace meta_hpp return get_function_with(name, {detail::resolve_type()...}); } - inline function class_type::get_function_with(std::string_view name, const std::vector& args) const noexcept { + template < typename Iter > + function class_type::get_function_with(std::string_view name, Iter first, Iter last) const noexcept { for ( auto&& [index, function] : data_->functions ) { if ( index.get_name() != name ) { continue; } - if ( function.get_type().get_arity() != args.size() ) { - continue; - } - - const std::vector& function_args = function.get_type().get_argument_types(); - if ( std::equal(args.begin(), args.end(), function_args.begin(), function_args.end()) ) { + const std::vector& args = function.get_type().get_argument_types(); + if ( std::equal(first, last, args.begin(), args.end()) ) { return function; } } for ( auto&& base : data_->bases ) { - if ( function function = base.get_function_with(name, args); function ) { + if ( function function = base.get_function_with(name, first, last); function ) { return function; } } @@ -306,29 +292,12 @@ namespace meta_hpp return function{}; } + inline function class_type::get_function_with(std::string_view name, const std::vector& args) const noexcept { + return get_function_with(name, args.begin(), args.end()); + } + inline function class_type::get_function_with(std::string_view name, std::initializer_list args) const noexcept { - for ( auto&& [index, function] : data_->functions ) { - if ( index.get_name() != name ) { - continue; - } - - if ( function.get_type().get_arity() != args.size() ) { - continue; - } - - const std::vector& function_args = function.get_type().get_argument_types(); - if ( std::equal(args.begin(), args.end(), function_args.begin(), function_args.end()) ) { - return function; - } - } - - for ( auto&& base : data_->bases ) { - if ( function function = base.get_function_with(name, args); function ) { - return function; - } - } - - return function{}; + return get_function_with(name, args.begin(), args.end()); } // @@ -340,24 +309,21 @@ namespace meta_hpp return get_method_with(name, {detail::resolve_type()...}); } - inline method class_type::get_method_with(std::string_view name, const std::vector& args) const noexcept { + template < typename Iter > + method class_type::get_method_with(std::string_view name, Iter first, Iter last) const noexcept { for ( auto&& [index, method] : data_->methods ) { if ( index.get_name() != name ) { continue; } - if ( method.get_type().get_arity() != args.size() ) { - continue; - } - - const std::vector& method_args = method.get_type().get_argument_types(); - if ( std::equal(args.begin(), args.end(), method_args.begin(), method_args.end()) ) { + const std::vector& args = method.get_type().get_argument_types(); + if ( std::equal(first, last, args.begin(), args.end()) ) { return method; } } for ( auto&& base : data_->bases ) { - if ( method method = base.get_method_with(name, args); method ) { + if ( method method = base.get_method_with(name, first, last); method ) { return method; } } @@ -365,28 +331,11 @@ namespace meta_hpp return method{}; } + inline method class_type::get_method_with(std::string_view name, const std::vector& args) const noexcept { + return get_method_with(name, args.begin(), args.end()); + } + inline method class_type::get_method_with(std::string_view name, std::initializer_list args) const noexcept { - for ( auto&& [index, method] : data_->methods ) { - if ( index.get_name() != name ) { - continue; - } - - if ( method.get_type().get_arity() != args.size() ) { - continue; - } - - const std::vector& method_args = method.get_type().get_argument_types(); - if ( std::equal(args.begin(), args.end(), method_args.begin(), method_args.end()) ) { - return method; - } - } - - for ( auto&& base : data_->bases ) { - if ( method method = base.get_method_with(name, args); method ) { - return method; - } - } - - return method{}; + return get_method_with(name, args.begin(), args.end()); } } From 9afb3920fc995c544cc2fce05caaff608cef0251 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Tue, 8 Feb 2022 07:16:16 +0700 Subject: [PATCH 216/233] parameter_index without name --- headers/meta.hpp/meta_indices.hpp | 8 ++++---- .../meta.hpp/meta_indices/parameter_index.hpp | 16 ++++++++-------- headers/meta.hpp/meta_states.hpp | 4 +++- headers/meta.hpp/meta_states/parameter.hpp | 10 +++++++--- 4 files changed, 22 insertions(+), 16 deletions(-) diff --git a/headers/meta.hpp/meta_indices.hpp b/headers/meta.hpp/meta_indices.hpp index 74f18b8..7033a92 100644 --- a/headers/meta.hpp/meta_indices.hpp +++ b/headers/meta.hpp/meta_indices.hpp @@ -119,18 +119,18 @@ namespace meta_hpp public: parameter_index() = delete; [[nodiscard]] const any_type& get_type() const noexcept; - [[nodiscard]] const std::string& get_name() const noexcept; + [[nodiscard]] std::size_t get_position() const noexcept; private: friend detail::parameter_state; template < typename Parameter > - [[nodiscard]] static parameter_index make(std::string name); + [[nodiscard]] static parameter_index make(std::size_t position); private: - explicit parameter_index(any_type type, std::string name); + explicit parameter_index(any_type type, std::size_t position); friend bool operator<(const parameter_index& l, const parameter_index& r) noexcept; friend bool operator==(const parameter_index& l, const parameter_index& r) noexcept; private: any_type type_; - std::string name_; + std::size_t position_{}; }; class scope_index final { diff --git a/headers/meta.hpp/meta_indices/parameter_index.hpp b/headers/meta.hpp/meta_indices/parameter_index.hpp index d44bfc6..00b9d48 100644 --- a/headers/meta.hpp/meta_indices/parameter_index.hpp +++ b/headers/meta.hpp/meta_indices/parameter_index.hpp @@ -14,28 +14,28 @@ namespace meta_hpp { - inline parameter_index::parameter_index(any_type type, std::string name) + inline parameter_index::parameter_index(any_type type, std::size_t position) : type_{std::move(type)} - , name_{std::move(name)} {} + , position_{position} {} template < typename Parameter > - inline parameter_index parameter_index::make(std::string name) { - return parameter_index{detail::resolve_type(), std::move(name)}; + inline parameter_index parameter_index::make(std::size_t position) { + return parameter_index{detail::resolve_type(), position}; } inline const any_type& parameter_index::get_type() const noexcept { return type_; } - inline const std::string& parameter_index::get_name() const noexcept { - return name_; + inline std::size_t parameter_index::get_position() const noexcept { + return position_; } inline bool operator<(const parameter_index& l, const parameter_index& r) noexcept { - return l.type_ < r.type_ || (l.type_ == r.type_ && std::less<>{}(l.name_, r.name_)); + return l.type_ < r.type_ || (l.type_ == r.type_ && l.position_ < r.position_); } inline bool operator==(const parameter_index& l, const parameter_index& r) noexcept { - return l.type_ == r.type_ && std::equal_to<>{}(l.name_, r.name_); + return l.type_ == r.type_ && l.position_ == r.position_; } } diff --git a/headers/meta.hpp/meta_states.hpp b/headers/meta.hpp/meta_states.hpp index 1fb5005..71bf54f 100644 --- a/headers/meta.hpp/meta_states.hpp +++ b/headers/meta.hpp/meta_states.hpp @@ -461,8 +461,10 @@ namespace meta_hpp::detail struct parameter_state final { parameter_index index; + std::string name{}; + template < typename Parameter > - [[nodiscard]] static parameter_state_ptr make(std::string name); + [[nodiscard]] static parameter_state_ptr make(std::size_t position); }; struct scope_state final { diff --git a/headers/meta.hpp/meta_states/parameter.hpp b/headers/meta.hpp/meta_states/parameter.hpp index 4060458..e0cad8d 100644 --- a/headers/meta.hpp/meta_states/parameter.hpp +++ b/headers/meta.hpp/meta_states/parameter.hpp @@ -12,9 +12,9 @@ namespace meta_hpp::detail { template < typename Parameter > - inline parameter_state_ptr parameter_state::make(std::string name) { + inline parameter_state_ptr parameter_state::make(std::size_t position) { return std::make_shared(parameter_state{ - .index{parameter_index::make(std::move(name))}, + .index{parameter_index::make(position)}, }); } } @@ -41,7 +41,11 @@ namespace meta_hpp return state_->index.get_type(); } + inline std::size_t parameter::get_position() const noexcept { + return state_->index.get_position(); + } + inline const std::string& parameter::get_name() const noexcept { - return state_->index.get_name(); + return state_->name; } } From 40b76839d8aa30f92abac5b990e3165961deb271 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Tue, 8 Feb 2022 07:30:21 +0700 Subject: [PATCH 217/233] parameter states for function, method and ctor --- headers/meta.hpp/meta_base.hpp | 5 ++ headers/meta.hpp/meta_binds.hpp | 32 ++++++++ headers/meta.hpp/meta_binds/class_bind.hpp | 78 ++++++++++++++++--- headers/meta.hpp/meta_binds/scope_bind.hpp | 26 ++++++- headers/meta.hpp/meta_states.hpp | 16 ++++ headers/meta.hpp/meta_states/ctor.hpp | 27 +++++++ headers/meta.hpp/meta_states/function.hpp | 27 +++++++ headers/meta.hpp/meta_states/method.hpp | 27 +++++++ headers/meta.hpp/meta_types.hpp | 8 +- headers/meta.hpp/meta_types/class_type.hpp | 4 +- headers/meta.hpp/meta_types/ctor_type.hpp | 4 +- headers/meta.hpp/meta_types/function_type.hpp | 4 +- headers/meta.hpp/meta_types/method_type.hpp | 4 +- untests/meta_states/function2_tests.cpp | 72 +++++++++++++++++ untests/meta_states/method2_tests.cpp | 45 +++++++++++ untests/meta_states/scope_tests.cpp | 36 ++++++++- 16 files changed, 387 insertions(+), 28 deletions(-) create mode 100644 untests/meta_states/function2_tests.cpp create mode 100644 untests/meta_states/method2_tests.cpp diff --git a/headers/meta.hpp/meta_base.hpp b/headers/meta.hpp/meta_base.hpp index 868a172..5a1996a 100644 --- a/headers/meta.hpp/meta_base.hpp +++ b/headers/meta.hpp/meta_base.hpp @@ -199,7 +199,10 @@ namespace meta_hpp class parameter_index; class scope_index; class variable_index; +} +namespace meta_hpp +{ using class_set = std::set>; using class_map = std::map>; @@ -214,4 +217,6 @@ namespace meta_hpp using method_map = std::map>; using scope_map = std::map>; using variable_map = std::map>; + + using parameter_list = std::vector; } diff --git a/headers/meta.hpp/meta_binds.hpp b/headers/meta.hpp/meta_binds.hpp index 958013b..272e08b 100644 --- a/headers/meta.hpp/meta_binds.hpp +++ b/headers/meta.hpp/meta_binds.hpp @@ -50,6 +50,13 @@ namespace meta_hpp class_bind& ctor_(Policy = Policy{}) requires detail::class_bind_ctor_kind; + template < typename... Args + , ctor_policy_kind Policy = ctor_policy::as_object > + class_bind& ctor_( + std::initializer_list pnames, + Policy = Policy{}) + requires detail::class_bind_ctor_kind; + class_bind& dtor_() requires detail::class_bind_dtor_kind; @@ -61,6 +68,14 @@ namespace meta_hpp , function_policy_kind Policy = function_policy::as_copy > class_bind& function_(std::string name, Function function, Policy = Policy{}); + template < detail::function_kind Function + , function_policy_kind Policy = function_policy::as_copy > + class_bind& function_( + std::string name, + Function function, + std::initializer_list pnames, + Policy = Policy{}); + template < detail::member_kind Member , member_policy_kind Policy = member_policy::as_copy > class_bind& member_(std::string name, Member member, Policy = Policy{}) @@ -71,6 +86,15 @@ namespace meta_hpp class_bind& method_(std::string name, Method method, Policy = Policy{}) requires detail::class_bind_method_kind; + template < detail::method_kind Method + , method_policy_kind Policy = method_policy::as_copy > + class_bind& method_( + std::string name, + Method method, + std::initializer_list pnames, + Policy = Policy{}) + requires detail::class_bind_method_kind; + template < detail::pointer_kind Pointer , variable_policy_kind Policy = variable_policy::as_copy > class_bind& variable_(std::string name, Pointer pointer, Policy = Policy{}); @@ -114,6 +138,14 @@ namespace meta_hpp , function_policy_kind Policy = function_policy::as_copy > scope_bind& function_(std::string name, Function function, Policy = Policy{}); + template < detail::function_kind Function + , function_policy_kind Policy = function_policy::as_copy > + scope_bind& function_( + std::string name, + Function function, + std::initializer_list pnames, + Policy = Policy{}); + template < detail::pointer_kind Pointer , variable_policy_kind Policy = variable_policy::as_copy > scope_bind& variable_(std::string name, Pointer pointer, Policy = Policy{}); diff --git a/headers/meta.hpp/meta_binds/class_bind.hpp b/headers/meta.hpp/meta_binds/class_bind.hpp index ea00403..b6254c4 100644 --- a/headers/meta.hpp/meta_binds/class_bind.hpp +++ b/headers/meta.hpp/meta_binds/class_bind.hpp @@ -24,11 +24,30 @@ namespace meta_hpp template < detail::class_kind Class > template < typename... Args, ctor_policy_kind Policy > - // NOLINTNEXTLINE(readability-named-parameter) - class_bind& class_bind::ctor_(Policy) + class_bind& class_bind::ctor_(Policy policy) + requires detail::class_bind_ctor_kind + { + return ctor_({}, policy); + } + + template < detail::class_kind Class > + template < typename... Args, ctor_policy_kind Policy > + class_bind& class_bind::ctor_( + std::initializer_list pnames, + [[maybe_unused]] Policy policy) requires detail::class_bind_ctor_kind { auto ctor_state = detail::ctor_state::make(); + + if ( pnames.size() > ctor_state->parameters.size() ) { + detail::throw_exception_with("provided parameter names don't match constructor argument count"); + } + + for ( std::size_t i = 0; i < pnames.size(); ++i ) { + parameter& param = ctor_state->parameters[i]; + detail::state_access(param)->name = std::string{std::data(pnames)[i]}; + } + data_->ctors.emplace(ctor_state->index, std::move(ctor_state)); return *this; } @@ -58,17 +77,36 @@ namespace meta_hpp template < detail::class_kind Class > template < detail::function_kind Function, function_policy_kind Policy > - // NOLINTNEXTLINE(readability-named-parameter) - class_bind& class_bind::function_(std::string name, Function function, Policy) { + class_bind& class_bind::function_(std::string name, Function function, Policy policy) { + return function_(std::move(name), std::move(function), {}, policy); + } + + template < detail::class_kind Class > + template < detail::function_kind Function, function_policy_kind Policy > + class_bind& class_bind::function_( + std::string name, + Function function, + std::initializer_list pnames, + [[maybe_unused]] Policy policy) + { auto function_state = detail::function_state::make(std::move(name), std::move(function)); + + if ( pnames.size() > function_state->parameters.size() ) { + detail::throw_exception_with("provided parameter names don't match function argument count"); + } + + for ( std::size_t i = 0; i < pnames.size(); ++i ) { + parameter& param = function_state->parameters[i]; + detail::state_access(param)->name = std::string{std::data(pnames)[i]}; + } + data_->functions.emplace(function_state->index, std::move(function_state)); return *this; } template < detail::class_kind Class > template < detail::member_kind Member, member_policy_kind Policy > - // NOLINTNEXTLINE(readability-named-parameter) - class_bind& class_bind::member_(std::string name, Member member, Policy) + class_bind& class_bind::member_(std::string name, Member member, [[maybe_unused]] Policy policy) requires detail::class_bind_member_kind { auto member_state = detail::member_state::make(std::move(name), std::move(member)); @@ -78,19 +116,39 @@ namespace meta_hpp template < detail::class_kind Class > template < detail::method_kind Method, method_policy_kind Policy > - // NOLINTNEXTLINE(readability-named-parameter) - class_bind& class_bind::method_(std::string name, Method method, Policy) + class_bind& class_bind::method_(std::string name, Method method, Policy policy) + requires detail::class_bind_method_kind + { + return method_(std::move(name), std::move(method), {}, policy); + } + + template < detail::class_kind Class > + template < detail::method_kind Method, method_policy_kind Policy > + class_bind& class_bind::method_( + std::string name, + Method method, + std::initializer_list pnames, + [[maybe_unused]] Policy policy) requires detail::class_bind_method_kind { auto method_state = detail::method_state::make(std::move(name), std::move(method)); + + if ( pnames.size() > method_state->parameters.size() ) { + detail::throw_exception_with("provided parameter names don't match method argument count"); + } + + for ( std::size_t i = 0; i < pnames.size(); ++i ) { + parameter& param = method_state->parameters[i]; + detail::state_access(param)->name = std::string{std::data(pnames)[i]}; + } + data_->methods.emplace(method_state->index, std::move(method_state)); return *this; } template < detail::class_kind Class > template < detail::pointer_kind Pointer, variable_policy_kind Policy > - // NOLINTNEXTLINE(readability-named-parameter) - class_bind& class_bind::variable_(std::string name, Pointer pointer, Policy) { + class_bind& class_bind::variable_( std::string name, Pointer pointer, [[maybe_unused]] Policy 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_binds/scope_bind.hpp b/headers/meta.hpp/meta_binds/scope_bind.hpp index 9e3648a..1f00cd9 100644 --- a/headers/meta.hpp/meta_binds/scope_bind.hpp +++ b/headers/meta.hpp/meta_binds/scope_bind.hpp @@ -39,16 +39,34 @@ namespace meta_hpp } template < detail::function_kind Function, function_policy_kind Policy > - // NOLINTNEXTLINE(readability-named-parameter) - scope_bind& scope_bind::function_(std::string name, Function function, Policy) { + scope_bind& scope_bind::function_(std::string name, Function function, Policy policy) { + return function_(std::move(name), std::move(function), {}, policy); + } + + template < detail::function_kind Function, function_policy_kind Policy > + scope_bind& scope_bind::function_( + std::string name, + Function function, + std::initializer_list pnames, + [[maybe_unused]] Policy policy) + { auto function_state = detail::function_state::make(std::move(name), std::move(function)); + + if ( pnames.size() > function_state->parameters.size() ) { + detail::throw_exception_with("provided parameter names don't match function argument count"); + } + + for ( std::size_t i = 0; i < pnames.size(); ++i ) { + parameter& param = function_state->parameters[i]; + detail::state_access(param)->name = std::string{std::data(pnames)[i]}; + } + state_->functions.emplace(function_state->index, std::move(function_state)); return *this; } template < detail::pointer_kind Pointer, variable_policy_kind Policy > - // NOLINTNEXTLINE(readability-named-parameter) - scope_bind& scope_bind::variable_(std::string name, Pointer pointer, Policy) { + scope_bind& scope_bind::variable_(std::string name, Pointer pointer, [[maybe_unused]] Policy 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 71bf54f..9546758 100644 --- a/headers/meta.hpp/meta_states.hpp +++ b/headers/meta.hpp/meta_states.hpp @@ -120,6 +120,9 @@ namespace meta_hpp template < typename... Args > [[nodiscard]] bool is_invocable_with(Args&&... args) const noexcept; + + [[nodiscard]] parameter get_parameter(std::size_t position) const noexcept; + [[nodiscard]] const parameter_list& get_parameters() const noexcept; private: detail::ctor_state_ptr state_; friend auto detail::state_access(const ctor&); @@ -194,6 +197,9 @@ namespace meta_hpp template < typename... Args > [[nodiscard]] bool is_invocable_with(Args&&... args) const noexcept; + + [[nodiscard]] parameter get_parameter(std::size_t position) const noexcept; + [[nodiscard]] const parameter_list& get_parameters() const noexcept; private: detail::function_state_ptr state_; friend auto detail::state_access(const function&); @@ -262,6 +268,9 @@ namespace meta_hpp template < typename Instance, typename... Args > [[nodiscard]] bool is_invocable_with(Instance&& instance, Args&&... args) const noexcept; + + [[nodiscard]] parameter get_parameter(std::size_t position) const noexcept; + [[nodiscard]] const parameter_list& get_parameters() const noexcept; private: detail::method_state_ptr state_; friend auto detail::state_access(const method&); @@ -277,6 +286,7 @@ namespace meta_hpp [[nodiscard]] const parameter_index& get_index() const noexcept; [[nodiscard]] const any_type& get_type() const noexcept; + [[nodiscard]] std::size_t get_position() const noexcept; [[nodiscard]] const std::string& get_name() const noexcept; private: detail::parameter_state_ptr state_; @@ -392,6 +402,8 @@ namespace meta_hpp::detail invoke_impl invoke; is_invocable_with_impl is_invocable_with; + parameter_list parameters; + template < ctor_policy_kind Policy, class_kind Class, typename... Args > [[nodiscard]] static ctor_state_ptr make(); }; @@ -425,6 +437,8 @@ namespace meta_hpp::detail invoke_impl invoke; is_invocable_with_impl is_invocable_with; + parameter_list parameters; + template < function_policy_kind Policy, function_kind Function > [[nodiscard]] static function_state_ptr make(std::string name, Function function); }; @@ -454,6 +468,8 @@ namespace meta_hpp::detail invoke_impl invoke; is_invocable_with_impl is_invocable_with; + parameter_list parameters; + template < method_policy_kind Policy, method_kind Method > [[nodiscard]] static method_state_ptr make(std::string name, Method method); }; diff --git a/headers/meta.hpp/meta_states/ctor.hpp b/headers/meta.hpp/meta_states/ctor.hpp index b4da195..509064d 100644 --- a/headers/meta.hpp/meta_states/ctor.hpp +++ b/headers/meta.hpp/meta_states/ctor.hpp @@ -88,6 +88,24 @@ namespace meta_hpp::detail ctor_state::is_invocable_with_impl make_ctor_is_invocable_with() { return &raw_ctor_is_invocable_with; } + + template < class_kind Class, typename... Args > + parameter_list make_ctor_parameters() { + using ct = detail::ctor_traits; + + parameter_list parameters; + parameters.reserve(ct::arity); + + // NOLINTNEXTLINE(readability-named-parameter) + [¶meters](std::index_sequence) mutable { + (parameters.push_back([](){ + using P = detail::type_list_at_t; + return parameter{detail::parameter_state::make

(I)}; + }.template operator()()), ...); + }(std::make_index_sequence()); + + return parameters; + } } namespace meta_hpp::detail @@ -98,6 +116,7 @@ namespace meta_hpp::detail .index{ctor_index::make()}, .invoke{make_ctor_invoke()}, .is_invocable_with{make_ctor_is_invocable_with()}, + .parameters{make_ctor_parameters()}, }); } } @@ -160,4 +179,12 @@ namespace meta_hpp return state_->is_invocable_with({}); } } + + inline parameter ctor::get_parameter(std::size_t position) const noexcept { + return position < state_->parameters.size() ? state_->parameters[position] : parameter{}; + } + + inline const parameter_list& ctor::get_parameters() const noexcept { + return state_->parameters; + } } diff --git a/headers/meta.hpp/meta_states/function.hpp b/headers/meta.hpp/meta_states/function.hpp index 27d63ac..0d3da8c 100644 --- a/headers/meta.hpp/meta_states/function.hpp +++ b/headers/meta.hpp/meta_states/function.hpp @@ -94,6 +94,24 @@ namespace meta_hpp::detail function_state::is_invocable_with_impl make_function_is_invocable_with() { return &raw_function_is_invocable_with; } + + template < function_kind Function > + parameter_list make_function_parameters() { + using ft = detail::function_traits; + + parameter_list parameters; + parameters.reserve(ft::arity); + + // NOLINTNEXTLINE(readability-named-parameter) + [¶meters](std::index_sequence) mutable { + (parameters.push_back([](){ + using P = detail::type_list_at_t; + return parameter{detail::parameter_state::make

(I)}; + }.template operator()()), ...); + }(std::make_index_sequence()); + + return parameters; + } } namespace meta_hpp::detail @@ -104,6 +122,7 @@ namespace meta_hpp::detail .index{function_index::make(std::move(name))}, .invoke{make_function_invoke(std::move(function))}, .is_invocable_with{make_function_is_invocable_with()}, + .parameters{make_function_parameters()}, }); } } @@ -170,4 +189,12 @@ namespace meta_hpp return state_->is_invocable_with({}); } } + + inline parameter function::get_parameter(std::size_t position) const noexcept { + return position < state_->parameters.size() ? state_->parameters[position] : parameter{}; + } + + inline const parameter_list& function::get_parameters() const noexcept { + return state_->parameters; + } } diff --git a/headers/meta.hpp/meta_states/method.hpp b/headers/meta.hpp/meta_states/method.hpp index bed9b9c..efd2c9c 100644 --- a/headers/meta.hpp/meta_states/method.hpp +++ b/headers/meta.hpp/meta_states/method.hpp @@ -107,6 +107,24 @@ namespace meta_hpp::detail method_state::is_invocable_with_impl make_method_is_invocable_with() { return &raw_method_is_invocable_with; } + + template < method_kind Method > + parameter_list make_method_parameters() { + using mt = detail::method_traits; + + parameter_list parameters; + parameters.reserve(mt::arity); + + // NOLINTNEXTLINE(readability-named-parameter) + [¶meters](std::index_sequence) mutable { + (parameters.push_back([](){ + using P = detail::type_list_at_t; + return parameter{detail::parameter_state::make

(I)}; + return argument{detail::argument_state::make

(I)}; }.template operator()()), ...); }(std::make_index_sequence()); - return parameters; + return arguments; } } namespace meta_hpp::detail { - template < ctor_policy_kind Policy, class_kind Class, typename... Args > - ctor_state_ptr ctor_state::make() { - return std::make_shared(ctor_state{ - .index{ctor_index::make()}, - .invoke{make_ctor_invoke()}, - .is_invocable_with{make_ctor_is_invocable_with()}, - .parameters{make_ctor_parameters()}, + template < constructor_policy_kind Policy, class_kind Class, typename... Args > + constructor_state_ptr constructor_state::make() { + return std::make_shared(constructor_state{ + .index{constructor_index::make()}, + .invoke{make_constructor_invoke()}, + .is_invocable_with{make_constructor_is_invocable_with()}, + .arguments{make_constructor_arguments()}, }); } } namespace meta_hpp { - inline ctor::ctor(detail::ctor_state_ptr state) + inline constructor::constructor(detail::constructor_state_ptr state) : state_{std::move(state)} {} - inline bool ctor::is_valid() const noexcept { + inline bool constructor::is_valid() const noexcept { return !!state_; } - inline ctor::operator bool() const noexcept { + inline constructor::operator bool() const noexcept { return is_valid(); } - inline const ctor_index& ctor::get_index() const noexcept { + inline const constructor_index& constructor::get_index() const noexcept { return state_->index; } - inline const ctor_type& ctor::get_type() const noexcept { + inline const constructor_type& constructor::get_type() const noexcept { return state_->index.get_type(); } template < typename... Args > - uvalue ctor::invoke(Args&&... args) const { + uvalue constructor::invoke(Args&&... args) const { if constexpr ( sizeof...(Args) > 0 ) { using namespace detail; const std::array vargs{uarg{std::forward(args)}...}; @@ -154,12 +154,12 @@ namespace meta_hpp } template < typename... Args > - uvalue ctor::operator()(Args&&... args) const { + uvalue constructor::operator()(Args&&... args) const { return invoke(std::forward(args)...); } template < typename... Args > - bool ctor::is_invocable_with() const noexcept { + bool constructor::is_invocable_with() const noexcept { if constexpr ( sizeof...(Args) > 0 ) { using namespace detail; const std::array vargs{uarg_base{type_list{}}...}; @@ -170,7 +170,7 @@ namespace meta_hpp } template < typename... Args > - bool ctor::is_invocable_with(Args&&... args) const noexcept { + bool constructor::is_invocable_with(Args&&... args) const noexcept { if constexpr ( sizeof...(Args) > 0 ) { using namespace detail; const std::array vargs{uarg_base{std::forward(args)}...}; @@ -180,11 +180,11 @@ namespace meta_hpp } } - inline parameter ctor::get_parameter(std::size_t position) const noexcept { - return position < state_->parameters.size() ? state_->parameters[position] : parameter{}; + inline argument constructor::get_argument(std::size_t position) const noexcept { + return position < state_->arguments.size() ? state_->arguments[position] : argument{}; } - inline const parameter_list& ctor::get_parameters() const noexcept { - return state_->parameters; + inline const argument_list& constructor::get_arguments() const noexcept { + return state_->arguments; } } diff --git a/headers/meta.hpp/meta_states/dtor.hpp b/headers/meta.hpp/meta_states/destructor.hpp similarity index 60% rename from headers/meta.hpp/meta_states/dtor.hpp rename to headers/meta.hpp/meta_states/destructor.hpp index 079c563..d408b1b 100644 --- a/headers/meta.hpp/meta_states/dtor.hpp +++ b/headers/meta.hpp/meta_states/destructor.hpp @@ -9,14 +9,14 @@ #include "../meta_base.hpp" #include "../meta_states.hpp" -#include "../meta_types/dtor_type.hpp" +#include "../meta_types/destructor_type.hpp" #include "../meta_detail/value_utilities/uarg.hpp" namespace meta_hpp::detail { template < class_kind Class > - void raw_dtor_invoke(const uarg& ptr) { - using dt = dtor_traits; + void raw_destructor_invoke(const uarg& ptr) { + using dt = destructor_traits; using class_type = typename dt::class_type; if ( !ptr.can_cast_to() ) { @@ -30,8 +30,8 @@ namespace meta_hpp::detail } template < class_kind Class > - bool raw_dtor_is_invocable_with(const uarg_base& ptr) { - using dt = dtor_traits; + bool raw_destructor_is_invocable_with(const uarg_base& ptr) { + using dt = destructor_traits; using class_type = typename dt::class_type; return ptr.can_cast_to(); @@ -41,70 +41,70 @@ namespace meta_hpp::detail namespace meta_hpp::detail { template < class_kind Class > - dtor_state::invoke_impl make_dtor_invoke() { - return &raw_dtor_invoke; + destructor_state::invoke_impl make_destructor_invoke() { + return &raw_destructor_invoke; } template < class_kind Class > - dtor_state::is_invocable_with_impl make_dtor_is_invocable_with() { - return &raw_dtor_is_invocable_with; + destructor_state::is_invocable_with_impl make_destructor_is_invocable_with() { + return &raw_destructor_is_invocable_with; } } namespace meta_hpp::detail { template < class_kind Class > - dtor_state_ptr dtor_state::make() { - return std::make_shared(dtor_state{ - .index{dtor_index::make()}, - .invoke{make_dtor_invoke()}, - .is_invocable_with{make_dtor_is_invocable_with()}, + destructor_state_ptr destructor_state::make() { + return std::make_shared(destructor_state{ + .index{destructor_index::make()}, + .invoke{make_destructor_invoke()}, + .is_invocable_with{make_destructor_is_invocable_with()}, }); } } namespace meta_hpp { - inline dtor::dtor(detail::dtor_state_ptr state) + inline destructor::destructor(detail::destructor_state_ptr state) : state_{std::move(state)} {} - inline bool dtor::is_valid() const noexcept { + inline bool destructor::is_valid() const noexcept { return !!state_; } - inline dtor::operator bool() const noexcept { + inline destructor::operator bool() const noexcept { return is_valid(); } - inline const dtor_index& dtor::get_index() const noexcept { + inline const destructor_index& destructor::get_index() const noexcept { return state_->index; } - inline const dtor_type& dtor::get_type() const noexcept { + inline const destructor_type& destructor::get_type() const noexcept { return state_->index.get_type(); } template < typename Arg > - void dtor::invoke(Arg&& ptr) const { + void destructor::invoke(Arg&& ptr) const { using namespace detail; const uarg varg{std::forward(ptr)}; state_->invoke(varg); } template < typename Arg > - void dtor::operator()(Arg&& ptr) const { + void destructor::operator()(Arg&& ptr) const { invoke(std::forward(ptr)); } template < typename Arg > - bool dtor::is_invocable_with() const noexcept { + bool destructor::is_invocable_with() const noexcept { using namespace detail; const uarg_base varg{type_list{}}; return state_->is_invocable_with(varg); } template < typename Arg > - bool dtor::is_invocable_with(Arg&& ptr) const noexcept { + bool destructor::is_invocable_with(Arg&& ptr) const noexcept { using namespace detail; const uarg_base varg{std::forward(ptr)}; return state_->is_invocable_with(varg); diff --git a/headers/meta.hpp/meta_states/function.hpp b/headers/meta.hpp/meta_states/function.hpp index f219171..6933a73 100644 --- a/headers/meta.hpp/meta_states/function.hpp +++ b/headers/meta.hpp/meta_states/function.hpp @@ -96,21 +96,21 @@ namespace meta_hpp::detail } template < function_kind Function > - parameter_list make_function_parameters() { + argument_list make_function_arguments() { using ft = detail::function_traits; - parameter_list parameters; - parameters.reserve(ft::arity); + argument_list arguments; + arguments.reserve(ft::arity); // NOLINTNEXTLINE(readability-named-parameter) - [¶meters](std::index_sequence) mutable { - (parameters.push_back([](){ + [&arguments](std::index_sequence) mutable { + (arguments.push_back([](){ using P = detail::type_list_at_t; - return parameter{detail::parameter_state::make

(I)}; + return argument{detail::argument_state::make

(I)}; }.template operator()()), ...); }(std::make_index_sequence()); - return parameters; + return arguments; } } @@ -122,7 +122,7 @@ namespace meta_hpp::detail .index{function_index::make(std::move(name))}, .invoke{make_function_invoke(std::move(function))}, .is_invocable_with{make_function_is_invocable_with()}, - .parameters{make_function_parameters()}, + .arguments{make_function_arguments()}, }); } } @@ -190,11 +190,11 @@ namespace meta_hpp } } - inline parameter function::get_parameter(std::size_t position) const noexcept { - return position < state_->parameters.size() ? state_->parameters[position] : parameter{}; + inline argument function::get_argument(std::size_t position) const noexcept { + return position < state_->arguments.size() ? state_->arguments[position] : argument{}; } - inline const parameter_list& function::get_parameters() const noexcept { - return state_->parameters; + inline const argument_list& function::get_arguments() const noexcept { + return state_->arguments; } } diff --git a/headers/meta.hpp/meta_states/method.hpp b/headers/meta.hpp/meta_states/method.hpp index db02f03..28b8d82 100644 --- a/headers/meta.hpp/meta_states/method.hpp +++ b/headers/meta.hpp/meta_states/method.hpp @@ -109,21 +109,21 @@ namespace meta_hpp::detail } template < method_kind Method > - parameter_list make_method_parameters() { + argument_list make_method_arguments() { using mt = detail::method_traits; - parameter_list parameters; - parameters.reserve(mt::arity); + argument_list arguments; + arguments.reserve(mt::arity); // NOLINTNEXTLINE(readability-named-parameter) - [¶meters](std::index_sequence) mutable { - (parameters.push_back([](){ + [&arguments](std::index_sequence) mutable { + (arguments.push_back([](){ using P = detail::type_list_at_t; - return parameter{detail::parameter_state::make

(I)}; + return argument{detail::argument_state::make

(I)}; }.template operator()()), ...); }(std::make_index_sequence()); - return parameters; + return arguments; } } @@ -135,7 +135,7 @@ namespace meta_hpp::detail .index{method_index::make(std::move(name))}, .invoke{make_method_invoke(std::move(method))}, .is_invocable_with{make_method_is_invocable_with()}, - .parameters{make_method_parameters()}, + .arguments{make_method_arguments()}, }); } } @@ -206,11 +206,11 @@ namespace meta_hpp } } - inline parameter method::get_parameter(std::size_t position) const noexcept { - return position < state_->parameters.size() ? state_->parameters[position] : parameter{}; + inline argument method::get_argument(std::size_t position) const noexcept { + return position < state_->arguments.size() ? state_->arguments[position] : argument{}; } - inline const parameter_list& method::get_parameters() const noexcept { - return state_->parameters; + inline const argument_list& method::get_arguments() const noexcept { + return state_->arguments; } } diff --git a/headers/meta.hpp/meta_types.hpp b/headers/meta.hpp/meta_types.hpp index 7cb9bbb..0dd3579 100644 --- a/headers/meta.hpp/meta_types.hpp +++ b/headers/meta.hpp/meta_types.hpp @@ -12,8 +12,8 @@ #include "meta_detail/type_traits/array_traits.hpp" #include "meta_detail/type_traits/class_traits.hpp" -#include "meta_detail/type_traits/ctor_traits.hpp" -#include "meta_detail/type_traits/dtor_traits.hpp" +#include "meta_detail/type_traits/constructor_traits.hpp" +#include "meta_detail/type_traits/destructor_traits.hpp" #include "meta_detail/type_traits/enum_traits.hpp" #include "meta_detail/type_traits/function_traits.hpp" #include "meta_detail/type_traits/member_traits.hpp" @@ -30,11 +30,11 @@ namespace meta_hpp using class_flags = detail::class_flags; using class_bitflags = detail::class_bitflags; - using ctor_flags = detail::ctor_flags; - using ctor_bitflags = detail::ctor_bitflags; + using constructor_flags = detail::constructor_flags; + using constructor_bitflags = detail::constructor_bitflags; - using dtor_flags = detail::dtor_flags; - using dtor_bitflags = detail::dtor_bitflags; + using destructor_flags = detail::destructor_flags; + using destructor_bitflags = detail::destructor_bitflags; using enum_flags = detail::enum_flags; using enum_bitflags = detail::enum_bitflags; @@ -72,8 +72,8 @@ namespace meta_hpp any_type(const array_type& other) noexcept; any_type(const class_type& other) noexcept; - any_type(const ctor_type& other) noexcept; - any_type(const dtor_type& other) noexcept; + any_type(const constructor_type& other) noexcept; + any_type(const destructor_type& other) noexcept; any_type(const enum_type& other) noexcept; any_type(const function_type& other) noexcept; any_type(const member_type& other) noexcept; @@ -86,8 +86,8 @@ namespace meta_hpp [[nodiscard]] bool is_array() const noexcept; [[nodiscard]] bool is_class() const noexcept; - [[nodiscard]] bool is_ctor() const noexcept; - [[nodiscard]] bool is_dtor() const noexcept; + [[nodiscard]] bool is_constructor() const noexcept; + [[nodiscard]] bool is_destructor() const noexcept; [[nodiscard]] bool is_enum() const noexcept; [[nodiscard]] bool is_function() const noexcept; [[nodiscard]] bool is_member() const noexcept; @@ -100,8 +100,8 @@ namespace meta_hpp [[nodiscard]] array_type as_array() const noexcept; [[nodiscard]] class_type as_class() const noexcept; - [[nodiscard]] ctor_type as_ctor() const noexcept; - [[nodiscard]] dtor_type as_dtor() const noexcept; + [[nodiscard]] constructor_type as_constructor() const noexcept; + [[nodiscard]] destructor_type as_destructor() const noexcept; [[nodiscard]] enum_type as_enum() const noexcept; [[nodiscard]] function_type as_function() const noexcept; [[nodiscard]] member_type as_member() const noexcept; @@ -151,8 +151,8 @@ namespace meta_hpp [[nodiscard]] any_type get_argument_type(std::size_t position) const noexcept; [[nodiscard]] const std::vector& get_argument_types() const noexcept; - [[nodiscard]] const ctor_map& get_ctors() const noexcept; - [[nodiscard]] const dtor_map& get_dtors() const noexcept; + [[nodiscard]] const constructor_map& get_ctors() const noexcept; + [[nodiscard]] const destructor_map& get_dtors() const noexcept; [[nodiscard]] const class_set& get_bases() const noexcept; [[nodiscard]] const function_map& get_functions() const noexcept; [[nodiscard]] const member_map& get_members() const noexcept; @@ -182,11 +182,11 @@ namespace meta_hpp [[nodiscard]] variable get_variable(std::string_view name) const noexcept; template < typename... Args > - [[nodiscard]] ctor get_ctor_with() const noexcept; + [[nodiscard]] constructor get_constructor_with() const noexcept; template < typename Iter > - [[nodiscard]] ctor get_ctor_with(Iter first, Iter last) const noexcept; - [[nodiscard]] ctor get_ctor_with(const std::vector& args) const noexcept; - [[nodiscard]] ctor get_ctor_with(std::initializer_list args) const noexcept; + [[nodiscard]] constructor get_constructor_with(Iter first, Iter last) const noexcept; + [[nodiscard]] constructor get_constructor_with(const std::vector& args) const noexcept; + [[nodiscard]] constructor get_constructor_with(std::initializer_list args) const noexcept; template < typename... Args > [[nodiscard]] function get_function_with(std::string_view name) const noexcept; @@ -206,41 +206,41 @@ namespace meta_hpp friend auto detail::type_access(const class_type&); }; - class ctor_type final { + class constructor_type final { public: - ctor_type() = default; - ctor_type(detail::ctor_type_data_ptr data); + constructor_type() = default; + constructor_type(detail::constructor_type_data_ptr data); [[nodiscard]] bool is_valid() const noexcept; [[nodiscard]] explicit operator bool() const noexcept; [[nodiscard]] type_id get_id() const noexcept; - [[nodiscard]] ctor_bitflags get_flags() const noexcept; + [[nodiscard]] constructor_bitflags get_flags() const noexcept; [[nodiscard]] std::size_t get_arity() const noexcept; [[nodiscard]] any_type get_class_type() const noexcept; [[nodiscard]] any_type get_argument_type(std::size_t position) const noexcept; [[nodiscard]] const std::vector& get_argument_types() const noexcept; private: - detail::ctor_type_data_ptr data_; - friend auto detail::type_access(const ctor_type&); + detail::constructor_type_data_ptr data_; + friend auto detail::type_access(const constructor_type&); }; - class dtor_type final { + class destructor_type final { public: - dtor_type() = default; - dtor_type(detail::dtor_type_data_ptr data); + destructor_type() = default; + destructor_type(detail::destructor_type_data_ptr data); [[nodiscard]] bool is_valid() const noexcept; [[nodiscard]] explicit operator bool() const noexcept; [[nodiscard]] type_id get_id() const noexcept; - [[nodiscard]] dtor_bitflags get_flags() const noexcept; + [[nodiscard]] destructor_bitflags get_flags() const noexcept; [[nodiscard]] any_type get_class_type() const noexcept; private: - detail::dtor_type_data_ptr data_; - friend auto detail::type_access(const dtor_type&); + detail::destructor_type_data_ptr data_; + friend auto detail::type_access(const destructor_type&); }; class enum_type final { @@ -466,8 +466,8 @@ namespace meta_hpp::detail const std::size_t size; const std::vector argument_types; - ctor_map ctors; - dtor_map dtors; + constructor_map constructors; + destructor_map destructors; class_set bases; function_map functions; member_map members; @@ -486,21 +486,21 @@ namespace meta_hpp::detail explicit class_type_data(type_list); }; - struct ctor_type_data final : type_data_base { - const ctor_bitflags flags; + struct constructor_type_data final : type_data_base { + const constructor_bitflags flags; const any_type class_type; const std::vector argument_types; template < class_kind Class, typename... Args > - explicit ctor_type_data(type_list, type_list); + explicit constructor_type_data(type_list, type_list); }; - struct dtor_type_data final : type_data_base { - const dtor_bitflags flags; + struct destructor_type_data final : type_data_base { + const destructor_bitflags flags; const any_type class_type; template < class_kind Class > - explicit dtor_type_data(type_list); + explicit destructor_type_data(type_list); }; struct enum_type_data final : type_data_base { diff --git a/headers/meta.hpp/meta_types/any_type.hpp b/headers/meta.hpp/meta_types/any_type.hpp index b94a4cf..ff42971 100644 --- a/headers/meta.hpp/meta_types/any_type.hpp +++ b/headers/meta.hpp/meta_types/any_type.hpp @@ -33,10 +33,10 @@ namespace meta_hpp inline any_type::any_type(const class_type& other) noexcept : data_{detail::type_access(other)} {} - inline any_type::any_type(const ctor_type& other) noexcept + inline any_type::any_type(const constructor_type& other) noexcept : data_{detail::type_access(other)} {} - inline any_type::any_type(const dtor_type& other) noexcept + inline any_type::any_type(const destructor_type& other) noexcept : data_{detail::type_access(other)} {} inline any_type::any_type(const enum_type& other) noexcept @@ -74,12 +74,12 @@ namespace meta_hpp return data_ && data_->kind == type_kind::class_; } - inline bool any_type::is_ctor() const noexcept { - return data_ && data_->kind == type_kind::ctor_; + inline bool any_type::is_constructor() const noexcept { + return data_ && data_->kind == type_kind::constructor_; } - inline bool any_type::is_dtor() const noexcept { - return data_ && data_->kind == type_kind::dtor_; + inline bool any_type::is_destructor() const noexcept { + return data_ && data_->kind == type_kind::destructor_; } inline bool any_type::is_enum() const noexcept { @@ -130,16 +130,16 @@ namespace meta_hpp : class_type{}; } - inline ctor_type any_type::as_ctor() const noexcept { - return is_ctor() - ? ctor_type{std::static_pointer_cast(data_)} - : ctor_type{}; + inline constructor_type any_type::as_constructor() const noexcept { + return is_constructor() + ? constructor_type{std::static_pointer_cast(data_)} + : constructor_type{}; } - inline dtor_type any_type::as_dtor() const noexcept { - return is_dtor() - ? dtor_type{std::static_pointer_cast(data_)} - : dtor_type{}; + inline destructor_type any_type::as_destructor() const noexcept { + return is_destructor() + ? destructor_type{std::static_pointer_cast(data_)} + : destructor_type{}; } inline enum_type any_type::as_enum() const noexcept { diff --git a/headers/meta.hpp/meta_types/class_type.hpp b/headers/meta.hpp/meta_types/class_type.hpp index 64e3dfc..9677349 100644 --- a/headers/meta.hpp/meta_types/class_type.hpp +++ b/headers/meta.hpp/meta_types/class_type.hpp @@ -9,7 +9,7 @@ #include "../meta_base.hpp" #include "../meta_types.hpp" -#include "../meta_states/ctor.hpp" +#include "../meta_states/constructor.hpp" #include "../meta_states/function.hpp" #include "../meta_states/member.hpp" #include "../meta_states/method.hpp" @@ -69,12 +69,12 @@ namespace meta_hpp return data_->argument_types; } - inline const ctor_map& class_type::get_ctors() const noexcept { - return data_->ctors; + inline const constructor_map& class_type::get_ctors() const noexcept { + return data_->constructors; } - inline const dtor_map& class_type::get_dtors() const noexcept { - return data_->dtors; + inline const destructor_map& class_type::get_dtors() const noexcept { + return data_->destructors; } inline const class_set& class_type::get_bases() const noexcept { @@ -99,7 +99,7 @@ namespace meta_hpp template < typename... Args > uvalue class_type::create(Args&&... args) const { - for ( auto&& ctor : data_->ctors ) { + for ( auto&& ctor : data_->constructors ) { if ( ctor.second.is_invocable_with(std::forward(args)...) ) { return ctor.second.invoke(std::forward(args)...); } @@ -114,7 +114,7 @@ namespace meta_hpp template < typename Arg > bool class_type::destroy(Arg&& ptr) const { - for ( auto&& dtor : data_->dtors ) { + for ( auto&& dtor : data_->destructors ) { if ( dtor.second.is_invocable_with(std::forward(ptr)) ) { dtor.second.invoke(std::forward(ptr)); return true; @@ -234,31 +234,31 @@ namespace meta_hpp } // - // get_ctor_with + // get_constructor_with // template < typename... Args > - ctor class_type::get_ctor_with() const noexcept { - return get_ctor_with({detail::resolve_type()...}); + constructor class_type::get_constructor_with() const noexcept { + return get_constructor_with({detail::resolve_type()...}); } template < typename Iter > - ctor class_type::get_ctor_with(Iter first, Iter last) const noexcept { - for ( auto&& [index, ctor] : data_->ctors ) { + constructor class_type::get_constructor_with(Iter first, Iter last) const noexcept { + for ( auto&& [index, ctor] : data_->constructors ) { const std::vector& args = ctor.get_type().get_argument_types(); if ( std::equal(first, last, args.begin(), args.end()) ) { return ctor; } } - return ctor{}; + return constructor{}; } - inline ctor class_type::get_ctor_with(const std::vector& args) const noexcept { - return get_ctor_with(args.begin(), args.end()); + inline constructor class_type::get_constructor_with(const std::vector& args) const noexcept { + return get_constructor_with(args.begin(), args.end()); } - inline ctor class_type::get_ctor_with(std::initializer_list args) const noexcept { - return get_ctor_with(args.begin(), args.end()); + inline constructor class_type::get_constructor_with(std::initializer_list args) const noexcept { + return get_constructor_with(args.begin(), args.end()); } // diff --git a/headers/meta.hpp/meta_types/constructor_type.hpp b/headers/meta.hpp/meta_types/constructor_type.hpp new file mode 100644 index 0000000..8baacf3 --- /dev/null +++ b/headers/meta.hpp/meta_types/constructor_type.hpp @@ -0,0 +1,65 @@ +/******************************************************************************* + * 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) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_types.hpp" + +#include "../meta_detail/type_registry.hpp" +#include "../meta_detail/type_traits/constructor_traits.hpp" + +namespace meta_hpp::detail +{ + template < class_kind Class, typename... Args > + struct constructor_tag {}; + + template < class_kind Class, typename... Args > + // NOLINTNEXTLINE(readability-named-parameter) + constructor_type_data::constructor_type_data(type_list, type_list) + : type_data_base{type_id{type_list>{}}, type_kind::constructor_} + , flags{constructor_traits::make_flags()} + , class_type{resolve_type::class_type>()} + , argument_types{resolve_types(typename constructor_traits::argument_types{})} {} +} + +namespace meta_hpp +{ + inline constructor_type::constructor_type(detail::constructor_type_data_ptr data) + : data_{std::move(data)} {} + + inline bool constructor_type::is_valid() const noexcept { + return !!data_; + } + + inline constructor_type::operator bool() const noexcept { + return is_valid(); + } + + inline type_id constructor_type::get_id() const noexcept { + return data_->id; + } + + inline constructor_bitflags constructor_type::get_flags() const noexcept { + return data_->flags; + } + + inline std::size_t constructor_type::get_arity() const noexcept { + return data_->argument_types.size(); + } + + inline any_type constructor_type::get_class_type() const noexcept { + return data_->class_type; + } + + inline any_type constructor_type::get_argument_type(std::size_t position) const noexcept { + return position < data_->argument_types.size() ? data_->argument_types[position] : any_type{}; + } + + inline const std::vector& constructor_type::get_argument_types() const noexcept { + return data_->argument_types; + } +} diff --git a/headers/meta.hpp/meta_types/ctor_type.hpp b/headers/meta.hpp/meta_types/ctor_type.hpp deleted file mode 100644 index c525f2e..0000000 --- a/headers/meta.hpp/meta_types/ctor_type.hpp +++ /dev/null @@ -1,65 +0,0 @@ -/******************************************************************************* - * 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) - ******************************************************************************/ - -#pragma once - -#include "../meta_base.hpp" -#include "../meta_types.hpp" - -#include "../meta_detail/type_registry.hpp" -#include "../meta_detail/type_traits/ctor_traits.hpp" - -namespace meta_hpp::detail -{ - template < class_kind Class, typename... Args > - struct ctor_tag {}; - - template < class_kind Class, typename... Args > - // NOLINTNEXTLINE(readability-named-parameter) - ctor_type_data::ctor_type_data(type_list, type_list) - : type_data_base{type_id{type_list>{}}, type_kind::ctor_} - , flags{ctor_traits::make_flags()} - , class_type{resolve_type::class_type>()} - , argument_types{resolve_types(typename ctor_traits::argument_types{})} {} -} - -namespace meta_hpp -{ - inline ctor_type::ctor_type(detail::ctor_type_data_ptr data) - : data_{std::move(data)} {} - - inline bool ctor_type::is_valid() const noexcept { - return !!data_; - } - - inline ctor_type::operator bool() const noexcept { - return is_valid(); - } - - inline type_id ctor_type::get_id() const noexcept { - return data_->id; - } - - inline ctor_bitflags ctor_type::get_flags() const noexcept { - return data_->flags; - } - - inline std::size_t ctor_type::get_arity() const noexcept { - return data_->argument_types.size(); - } - - inline any_type ctor_type::get_class_type() const noexcept { - return data_->class_type; - } - - inline any_type ctor_type::get_argument_type(std::size_t position) const noexcept { - return position < data_->argument_types.size() ? data_->argument_types[position] : any_type{}; - } - - inline const std::vector& ctor_type::get_argument_types() const noexcept { - return data_->argument_types; - } -} diff --git a/headers/meta.hpp/meta_types/dtor_type.hpp b/headers/meta.hpp/meta_types/destructor_type.hpp similarity index 52% rename from headers/meta.hpp/meta_types/dtor_type.hpp rename to headers/meta.hpp/meta_types/destructor_type.hpp index d0dbc02..3517003 100644 --- a/headers/meta.hpp/meta_types/dtor_type.hpp +++ b/headers/meta.hpp/meta_types/destructor_type.hpp @@ -10,43 +10,43 @@ #include "../meta_types.hpp" #include "../meta_detail/type_registry.hpp" -#include "../meta_detail/type_traits/dtor_traits.hpp" +#include "../meta_detail/type_traits/destructor_traits.hpp" namespace meta_hpp::detail { template < class_kind Class > - struct dtor_tag {}; + struct destructor_tag {}; template < class_kind Class > // NOLINTNEXTLINE(readability-named-parameter) - dtor_type_data::dtor_type_data(type_list) - : type_data_base{type_id{type_list>{}}, type_kind::dtor_} - , flags{dtor_traits::make_flags()} - , class_type{resolve_type::class_type>()} {} + destructor_type_data::destructor_type_data(type_list) + : type_data_base{type_id{type_list>{}}, type_kind::destructor_} + , flags{destructor_traits::make_flags()} + , class_type{resolve_type::class_type>()} {} } namespace meta_hpp { - inline dtor_type::dtor_type(detail::dtor_type_data_ptr data) + inline destructor_type::destructor_type(detail::destructor_type_data_ptr data) : data_{std::move(data)} {} - inline bool dtor_type::is_valid() const noexcept { + inline bool destructor_type::is_valid() const noexcept { return !!data_; } - inline dtor_type::operator bool() const noexcept { + inline destructor_type::operator bool() const noexcept { return is_valid(); } - inline type_id dtor_type::get_id() const noexcept { + inline type_id destructor_type::get_id() const noexcept { return data_->id; } - inline dtor_bitflags dtor_type::get_flags() const noexcept { + inline destructor_bitflags destructor_type::get_flags() const noexcept { return data_->flags; } - inline any_type dtor_type::get_class_type() const noexcept { + inline any_type destructor_type::get_class_type() const noexcept { return data_->class_type; } } diff --git a/manuals/meta_examples/classes_example.cpp b/manuals/meta_examples/classes_example.cpp index a969a21..83395d5 100644 --- a/manuals/meta_examples/classes_example.cpp +++ b/manuals/meta_examples/classes_example.cpp @@ -47,7 +47,7 @@ TEST_CASE("meta/meta_examples/classes/type") { // 'rectangle' class type registration meta::class_() .base_() - .ctor_() + .constructor_() .method_("get_width", &rectangle::get_width) .method_("get_height", &rectangle::get_height); diff --git a/manuals/meta_examples/functions_example.cpp b/manuals/meta_examples/functions_example.cpp index 0008a3c..c4c6dd0 100644 --- a/manuals/meta_examples/functions_example.cpp +++ b/manuals/meta_examples/functions_example.cpp @@ -54,7 +54,7 @@ TEST_CASE("meta/meta_examples/functions/usage") { // checks a type of the founded function CHECK(sub_function.get_type() == meta::resolve_type()); - // checks the ability to call the function with specific parameters + // checks the ability to call the function with specific arguments CHECK(sub_function.is_invocable_with(60, 18)); CHECK(sub_function.is_invocable_with()); diff --git a/manuals/meta_examples/methods_example.cpp b/manuals/meta_examples/methods_example.cpp index a9957ec..be68952 100644 --- a/manuals/meta_examples/methods_example.cpp +++ b/manuals/meta_examples/methods_example.cpp @@ -64,7 +64,7 @@ TEST_CASE("meta/meta_examples/methods/usage") { // checks the type of the method 'add' CHECK(ivec2_add.get_type() == meta::resolve_type()); - // checks the ability to call the method with specific parameters + // checks the ability to call the method with specific arguments CHECK(ivec2_add.is_invocable_with(v, ivec2{22, 11})); CHECK(ivec2_add.is_invocable_with()); diff --git a/untests/meta_states/ctor_tests.cpp b/untests/meta_states/ctor_tests.cpp index f5a223f..2f0d9a1 100644 --- a/untests/meta_states/ctor_tests.cpp +++ b/untests/meta_states/ctor_tests.cpp @@ -14,75 +14,75 @@ namespace clazz(int i) : i{i} { - ++ctor_counter; + ++constructor_counter; } clazz(clazz&& other) : i{other.i} { other.i = 0; - ++move_ctor_counter; + ++move_constructor_counter; } clazz(const clazz& other) : i{other.i} { - ++copy_ctor_counter; + ++copy_constructor_counter; } clazz& operator=(clazz&& other) = delete; clazz& operator=(const clazz& other) = delete; ~clazz() { - ++dtor_counter; + ++destructor_counter; } public: - static int ctor_counter; - static int dtor_counter; - static int move_ctor_counter; - static int copy_ctor_counter; + static int constructor_counter; + static int destructor_counter; + static int move_constructor_counter; + static int copy_constructor_counter; }; template < std::size_t N > - int clazz::ctor_counter{0}; + int clazz::constructor_counter{0}; template < std::size_t N > - int clazz::dtor_counter{0}; + int clazz::destructor_counter{0}; template < std::size_t N > - int clazz::move_ctor_counter{0}; + int clazz::move_constructor_counter{0}; template < std::size_t N > - int clazz::copy_ctor_counter{0}; + int clazz::copy_constructor_counter{0}; } TEST_CASE("meta/meta_states/ctor") { namespace meta = meta_hpp; meta::class_>() - .ctor_(meta::ctor_policy::as_object{}) - .dtor_(); + .constructor_(meta::constructor_policy::as_object{}) + .destructor_(); meta::class_>() - .ctor_(meta::ctor_policy::as_raw_pointer{}) - .dtor_(); + .constructor_(meta::constructor_policy::as_raw_pointer{}) + .destructor_(); meta::class_>() - .ctor_(meta::ctor_policy::as_shared_pointer{}) - .dtor_(); + .constructor_(meta::constructor_policy::as_shared_pointer{}) + .destructor_(); - clazz<1>::ctor_counter = 0; - clazz<1>::dtor_counter = 0; - clazz<1>::move_ctor_counter = 0; - clazz<1>::copy_ctor_counter = 0; + clazz<1>::constructor_counter = 0; + clazz<1>::destructor_counter = 0; + clazz<1>::move_constructor_counter = 0; + clazz<1>::copy_constructor_counter = 0; - clazz<2>::ctor_counter = 0; - clazz<2>::dtor_counter = 0; - clazz<2>::move_ctor_counter = 0; - clazz<2>::copy_ctor_counter = 0; + clazz<2>::constructor_counter = 0; + clazz<2>::destructor_counter = 0; + clazz<2>::move_constructor_counter = 0; + clazz<2>::copy_constructor_counter = 0; - clazz<3>::ctor_counter = 0; - clazz<3>::dtor_counter = 0; - clazz<3>::move_ctor_counter = 0; - clazz<3>::copy_ctor_counter = 0; + clazz<3>::constructor_counter = 0; + clazz<3>::destructor_counter = 0; + clazz<3>::move_constructor_counter = 0; + clazz<3>::copy_constructor_counter = 0; SUBCASE("clazz<1>") { const meta::class_type clazz_type = meta::resolve_type>(); @@ -98,10 +98,10 @@ TEST_CASE("meta/meta_states/ctor") { CHECK(clazz_type.destroy(meta::uvalue{nullptr})); } - CHECK(clazz<1>::ctor_counter == 1); - CHECK(clazz<1>::dtor_counter == 2); - CHECK(clazz<1>::move_ctor_counter == 1); - CHECK(clazz<1>::copy_ctor_counter == 0); + CHECK(clazz<1>::constructor_counter == 1); + CHECK(clazz<1>::destructor_counter == 2); + CHECK(clazz<1>::move_constructor_counter == 1); + CHECK(clazz<1>::copy_constructor_counter == 0); } SUBCASE("clazz<2>") { @@ -119,10 +119,10 @@ TEST_CASE("meta/meta_states/ctor") { CHECK(clazz_type.destroy(meta::uvalue{nullptr})); } - CHECK(clazz<2>::ctor_counter == 1); - CHECK(clazz<2>::dtor_counter == 1); - CHECK(clazz<2>::move_ctor_counter == 0); - CHECK(clazz<2>::copy_ctor_counter == 0); + CHECK(clazz<2>::constructor_counter == 1); + CHECK(clazz<2>::destructor_counter == 1); + CHECK(clazz<2>::move_constructor_counter == 0); + CHECK(clazz<2>::copy_constructor_counter == 0); } SUBCASE("clazz<3>") { @@ -139,9 +139,9 @@ TEST_CASE("meta/meta_states/ctor") { CHECK(clazz_type.destroy(meta::uvalue{nullptr})); } - CHECK(clazz<3>::ctor_counter == 1); - CHECK(clazz<3>::dtor_counter == 1); - CHECK(clazz<3>::move_ctor_counter == 0); - CHECK(clazz<3>::copy_ctor_counter == 0); + CHECK(clazz<3>::constructor_counter == 1); + CHECK(clazz<3>::destructor_counter == 1); + CHECK(clazz<3>::move_constructor_counter == 0); + CHECK(clazz<3>::copy_constructor_counter == 0); } } diff --git a/untests/meta_states/function2_tests.cpp b/untests/meta_states/function2_tests.cpp index ab76043..af4f62c 100644 --- a/untests/meta_states/function2_tests.cpp +++ b/untests/meta_states/function2_tests.cpp @@ -36,37 +36,37 @@ TEST_CASE("meta/meta_states/function2") { const meta::function func = ivec2_type.get_function("iadd"); REQUIRE(func); - CHECK(func.get_parameters().size() == 2); + CHECK(func.get_arguments().size() == 2); - REQUIRE(func.get_parameter(0)); - CHECK(func.get_parameter(0).get_type() == meta::resolve_type()); - CHECK(func.get_parameter(0).get_position() == 0); - CHECK(func.get_parameter(0).get_name() == "l"); + REQUIRE(func.get_argument(0)); + CHECK(func.get_argument(0).get_type() == meta::resolve_type()); + CHECK(func.get_argument(0).get_position() == 0); + CHECK(func.get_argument(0).get_name() == "l"); - REQUIRE(func.get_parameter(1)); - CHECK(func.get_parameter(1).get_type() == meta::resolve_type()); - CHECK(func.get_parameter(1).get_position() == 1); - CHECK(func.get_parameter(1).get_name() == ""); + REQUIRE(func.get_argument(1)); + CHECK(func.get_argument(1).get_type() == meta::resolve_type()); + CHECK(func.get_argument(1).get_position() == 1); + CHECK(func.get_argument(1).get_name() == ""); - CHECK_FALSE(func.get_parameter(2)); + CHECK_FALSE(func.get_argument(2)); } SUBCASE("isub2") { const meta::function func = ivec2_type.get_function("isub"); REQUIRE(func); - REQUIRE(func.get_parameters().size() == 2); + REQUIRE(func.get_arguments().size() == 2); - REQUIRE(func.get_parameter(0)); - CHECK(func.get_parameter(0).get_type() == meta::resolve_type()); - CHECK(func.get_parameter(0).get_position() == 0); - CHECK(func.get_parameter(0).get_name() == "l"); + REQUIRE(func.get_argument(0)); + CHECK(func.get_argument(0).get_type() == meta::resolve_type()); + CHECK(func.get_argument(0).get_position() == 0); + CHECK(func.get_argument(0).get_name() == "l"); - REQUIRE(func.get_parameter(1)); - CHECK(func.get_parameter(1).get_type() == meta::resolve_type()); - CHECK(func.get_parameter(1).get_position() == 1); - CHECK(func.get_parameter(1).get_name() == "r"); + REQUIRE(func.get_argument(1)); + CHECK(func.get_argument(1).get_type() == meta::resolve_type()); + CHECK(func.get_argument(1).get_position() == 1); + CHECK(func.get_argument(1).get_name() == "r"); - CHECK_FALSE(func.get_parameter(2)); + CHECK_FALSE(func.get_argument(2)); } } diff --git a/untests/meta_states/method2_tests.cpp b/untests/meta_states/method2_tests.cpp index a5ffbad..d7216b6 100644 --- a/untests/meta_states/method2_tests.cpp +++ b/untests/meta_states/method2_tests.cpp @@ -33,13 +33,13 @@ TEST_CASE("meta/meta_states/method2") { const meta::method add_m = ivec2_type.get_method("add"); REQUIRE(add_m); - CHECK(add_m.get_parameters().size() == 1); + CHECK(add_m.get_arguments().size() == 1); - REQUIRE(add_m.get_parameter(0)); - CHECK(add_m.get_parameter(0).get_type() == meta::resolve_type()); - CHECK(add_m.get_parameter(0).get_position() == 0); - CHECK(add_m.get_parameter(0).get_name() == "other"); + REQUIRE(add_m.get_argument(0)); + CHECK(add_m.get_argument(0).get_type() == meta::resolve_type()); + CHECK(add_m.get_argument(0).get_position() == 0); + CHECK(add_m.get_argument(0).get_name() == "other"); - CHECK_FALSE(add_m.get_parameter(1)); + CHECK_FALSE(add_m.get_argument(1)); } } diff --git a/untests/meta_states/scope_tests.cpp b/untests/meta_states/scope_tests.cpp index da8be1b..7664c6b 100644 --- a/untests/meta_states/scope_tests.cpp +++ b/untests/meta_states/scope_tests.cpp @@ -97,38 +97,38 @@ TEST_CASE("meta/meta_states/scope") { REQUIRE(iadd2_func); { - CHECK(iadd2_func.get_parameters().size() == 2); + CHECK(iadd2_func.get_arguments().size() == 2); - REQUIRE(iadd2_func.get_parameter(0)); - CHECK(iadd2_func.get_parameter(0).get_type() == meta::resolve_type()); - CHECK(iadd2_func.get_parameter(0).get_position() == 0); - CHECK(iadd2_func.get_parameter(0).get_name() == "l"); + REQUIRE(iadd2_func.get_argument(0)); + CHECK(iadd2_func.get_argument(0).get_type() == meta::resolve_type()); + CHECK(iadd2_func.get_argument(0).get_position() == 0); + CHECK(iadd2_func.get_argument(0).get_name() == "l"); - REQUIRE(iadd2_func.get_parameter(1)); - CHECK(iadd2_func.get_parameter(1).get_type() == meta::resolve_type()); - CHECK(iadd2_func.get_parameter(1).get_position() == 1); - CHECK(iadd2_func.get_parameter(1).get_name() == "r"); + REQUIRE(iadd2_func.get_argument(1)); + CHECK(iadd2_func.get_argument(1).get_type() == meta::resolve_type()); + CHECK(iadd2_func.get_argument(1).get_position() == 1); + CHECK(iadd2_func.get_argument(1).get_name() == "r"); - CHECK_FALSE(iadd2_func.get_parameter(2)); + CHECK_FALSE(iadd2_func.get_argument(2)); } const meta::function iadd3_func = math_scope.get_function("iadd3"); REQUIRE(iadd3_func); { - CHECK(iadd3_func.get_parameters().size() == 2); + CHECK(iadd3_func.get_arguments().size() == 2); - REQUIRE(iadd3_func.get_parameter(0)); - CHECK(iadd3_func.get_parameter(0).get_type() == meta::resolve_type()); - CHECK(iadd3_func.get_parameter(0).get_position() == 0); - CHECK(iadd3_func.get_parameter(0).get_name() == "l"); + REQUIRE(iadd3_func.get_argument(0)); + CHECK(iadd3_func.get_argument(0).get_type() == meta::resolve_type()); + CHECK(iadd3_func.get_argument(0).get_position() == 0); + CHECK(iadd3_func.get_argument(0).get_name() == "l"); - REQUIRE(iadd3_func.get_parameter(1)); - CHECK(iadd3_func.get_parameter(1).get_type() == meta::resolve_type()); - CHECK(iadd3_func.get_parameter(1).get_position() == 1); - CHECK(iadd3_func.get_parameter(1).get_name() == ""); + REQUIRE(iadd3_func.get_argument(1)); + CHECK(iadd3_func.get_argument(1).get_type() == meta::resolve_type()); + CHECK(iadd3_func.get_argument(1).get_position() == 1); + CHECK(iadd3_func.get_argument(1).get_name() == ""); - CHECK_FALSE(iadd3_func.get_parameter(2)); + CHECK_FALSE(iadd3_func.get_argument(2)); } } diff --git a/untests/meta_types/any_type_tests.cpp b/untests/meta_types/any_type_tests.cpp index 2bf6c88..256107d 100644 --- a/untests/meta_types/any_type_tests.cpp +++ b/untests/meta_types/any_type_tests.cpp @@ -32,8 +32,8 @@ TEST_CASE("meta/meta_types/any_type") { namespace meta = meta_hpp; meta::class_() - .ctor_<>() - .ctor_(); + .constructor_<>() + .constructor_(); SUBCASE("") { const meta::any_type type{}; @@ -72,8 +72,8 @@ TEST_CASE("meta/meta_types/any_type") { CHECK(type.is_class()); CHECK(type.get_kind() == meta::type_kind::class_); - CHECK_FALSE(type.is_ctor()); - CHECK_FALSE(type.as_ctor()); + CHECK_FALSE(type.is_constructor()); + CHECK_FALSE(type.as_constructor()); const meta::class_type& specific_type = type.as_class(); REQUIRE(specific_type); @@ -82,18 +82,18 @@ TEST_CASE("meta/meta_types/any_type") { SUBCASE("ctor") { const meta::any_type& type = meta::resolve_type() - .get_ctor_with<>() + .get_constructor_with<>() .get_type(); REQUIRE(type); - CHECK(type.is_ctor()); - CHECK(type.get_kind() == meta::type_kind::ctor_); + CHECK(type.is_constructor()); + CHECK(type.get_kind() == meta::type_kind::constructor_); CHECK_FALSE(type.is_enum()); CHECK_FALSE(type.as_enum()); - const meta::ctor_type& specific_type = type.as_ctor(); + const meta::constructor_type& specific_type = type.as_constructor(); REQUIRE(specific_type); CHECK(specific_type.get_id() == type.get_id()); } diff --git a/untests/meta_types/class_type_tests.cpp b/untests/meta_types/class_type_tests.cpp index f09cf03..aac9d81 100644 --- a/untests/meta_types/class_type_tests.cpp +++ b/untests/meta_types/class_type_tests.cpp @@ -62,7 +62,7 @@ TEST_CASE("meta/meta_types/class_type") { namespace meta = meta_hpp; meta::class_() - .ctor_() + .constructor_() .member_("base_member_1", &base_clazz_1::base_member_1) .method_("base_method_1", &base_clazz_1::base_method_1) .function_("base_function_1", &base_clazz_1::base_function_1) @@ -73,14 +73,14 @@ TEST_CASE("meta/meta_types/class_type") { .variable_("base_variable_1", &base_clazz_1::base_variable_1); meta::class_() - .ctor_() + .constructor_() .member_("base_member_2", &base_clazz_2::base_member_2) .method_("base_method_2", &base_clazz_2::base_method_2) .function_("base_function_2", &base_clazz_2::base_function_2) .variable_("base_variable_2", &base_clazz_2::base_variable_2); meta::class_() - .ctor_() + .constructor_() .base_() .base_() .member_("derived_member", &derived_clazz::derived_member) @@ -89,7 +89,7 @@ TEST_CASE("meta/meta_types/class_type") { .variable_("derived_variable", &derived_clazz::derived_variable); meta::class_() - .ctor_() + .constructor_() .base_(); const meta::class_type base_clazz_1_type = meta::resolve_type(); @@ -368,23 +368,23 @@ TEST_CASE("meta/meta_types/class_type") { CHECK(derived_clazz_type.get_variable("derived_variable")); } - SUBCASE("get_ctor_with") { + SUBCASE("get_constructor_with") { { - CHECK_FALSE(base_clazz_1_type.get_ctor_with<>()); - CHECK(base_clazz_1_type.get_ctor_with()); - CHECK_FALSE(base_clazz_1_type.get_ctor_with()); + CHECK_FALSE(base_clazz_1_type.get_constructor_with<>()); + CHECK(base_clazz_1_type.get_constructor_with()); + CHECK_FALSE(base_clazz_1_type.get_constructor_with()); } { - CHECK_FALSE(base_clazz_2_type.get_ctor_with<>()); - CHECK_FALSE(base_clazz_2_type.get_ctor_with()); - CHECK(base_clazz_2_type.get_ctor_with()); + CHECK_FALSE(base_clazz_2_type.get_constructor_with<>()); + CHECK_FALSE(base_clazz_2_type.get_constructor_with()); + CHECK(base_clazz_2_type.get_constructor_with()); } { - CHECK_FALSE(derived_clazz_type.get_ctor_with<>()); - CHECK_FALSE(derived_clazz_type.get_ctor_with()); - CHECK_FALSE(derived_clazz_type.get_ctor_with()); - CHECK(derived_clazz_type.get_ctor_with()); - CHECK_FALSE(derived_clazz_type.get_ctor_with()); + CHECK_FALSE(derived_clazz_type.get_constructor_with<>()); + CHECK_FALSE(derived_clazz_type.get_constructor_with()); + CHECK_FALSE(derived_clazz_type.get_constructor_with()); + CHECK(derived_clazz_type.get_constructor_with()); + CHECK_FALSE(derived_clazz_type.get_constructor_with()); } } diff --git a/untests/meta_utilities/value2_tests.cpp b/untests/meta_utilities/value2_tests.cpp index d98d9dc..8f08c37 100644 --- a/untests/meta_utilities/value2_tests.cpp +++ b/untests/meta_utilities/value2_tests.cpp @@ -21,25 +21,25 @@ namespace , y{other.y} { other.x = 0; other.y = 0; - ++move_ctor_counter; + ++move_constructor_counter; } ivec2(const ivec2& other) noexcept : x{other.x} , y{other.y} { - ++copy_ctor_counter; + ++copy_constructor_counter; } ~ivec2() noexcept { - ++dtor_counter; + ++destructor_counter; } ivec2& operator=(ivec2&& other) = delete; ivec2& operator=(const ivec2& other) = delete; - static int dtor_counter; - static int move_ctor_counter; - static int copy_ctor_counter; + static int destructor_counter; + static int move_constructor_counter; + static int copy_constructor_counter; }; struct ivec2_big final { @@ -57,25 +57,25 @@ namespace , y{other.y} { other.x = 0; other.y = 0; - ++move_ctor_counter; + ++move_constructor_counter; } ivec2_big(const ivec2_big& other) noexcept : x{other.x} , y{other.y} { - ++copy_ctor_counter; + ++copy_constructor_counter; } ~ivec2_big() noexcept { - ++dtor_counter; + ++destructor_counter; } ivec2_big& operator=(ivec2_big&& other) = delete; ivec2_big& operator=(const ivec2_big& other) = delete; - static int dtor_counter; - static int move_ctor_counter; - static int copy_ctor_counter; + static int destructor_counter; + static int move_constructor_counter; + static int copy_constructor_counter; }; [[maybe_unused]] bool operator==(const ivec2& l, const ivec2& r) noexcept { @@ -86,31 +86,31 @@ namespace return l.x == r.x && l.y == r.y; } - int ivec2::dtor_counter{0}; - int ivec2::move_ctor_counter{0}; - int ivec2::copy_ctor_counter{0}; + int ivec2::destructor_counter{0}; + int ivec2::move_constructor_counter{0}; + int ivec2::copy_constructor_counter{0}; - int ivec2_big::dtor_counter{0}; - int ivec2_big::move_ctor_counter{0}; - int ivec2_big::copy_ctor_counter{0}; + int ivec2_big::destructor_counter{0}; + int ivec2_big::move_constructor_counter{0}; + int ivec2_big::copy_constructor_counter{0}; } TEST_CASE("meta/meta_utilities/value2") { namespace meta = meta_hpp; meta::class_() - .ctor_() - .ctor_() - .ctor_() - .ctor_() + .constructor_() + .constructor_() + .constructor_() + .constructor_() .member_("x", &ivec2::x) .member_("y", &ivec2::y); meta::class_() - .ctor_() - .ctor_() - .ctor_() - .ctor_() + .constructor_() + .constructor_() + .constructor_() + .constructor_() .member_("x", &ivec2_big::x) .member_("y", &ivec2_big::y); } @@ -118,32 +118,32 @@ TEST_CASE("meta/meta_utilities/value2") { TEST_CASE("meta/meta_utilities/value2/counters/small") { namespace meta = meta_hpp; - ivec2::dtor_counter = 0; - ivec2::move_ctor_counter = 0; - ivec2::copy_ctor_counter = 0; + ivec2::destructor_counter = 0; + ivec2::move_constructor_counter = 0; + ivec2::copy_constructor_counter = 0; SUBCASE("def ctor") { { meta::uvalue v{}; - CHECK(ivec2::dtor_counter == 0); - CHECK(ivec2::move_ctor_counter == 0); - CHECK(ivec2::copy_ctor_counter == 0); + CHECK(ivec2::destructor_counter == 0); + CHECK(ivec2::move_constructor_counter == 0); + CHECK(ivec2::copy_constructor_counter == 0); } - CHECK(ivec2::dtor_counter == 0); - CHECK(ivec2::move_ctor_counter == 0); - CHECK(ivec2::copy_ctor_counter == 0); + CHECK(ivec2::destructor_counter == 0); + CHECK(ivec2::move_constructor_counter == 0); + CHECK(ivec2::copy_constructor_counter == 0); } SUBCASE("val ctor") { { meta::uvalue v{ivec2{1,2}}; - CHECK(ivec2::dtor_counter == 1); - CHECK(ivec2::move_ctor_counter == 1); - CHECK(ivec2::copy_ctor_counter == 0); + CHECK(ivec2::destructor_counter == 1); + CHECK(ivec2::move_constructor_counter == 1); + CHECK(ivec2::copy_constructor_counter == 0); } - CHECK(ivec2::dtor_counter == 2); - CHECK(ivec2::move_ctor_counter == 1); - CHECK(ivec2::copy_ctor_counter == 0); + CHECK(ivec2::destructor_counter == 2); + CHECK(ivec2::move_constructor_counter == 1); + CHECK(ivec2::copy_constructor_counter == 0); } SUBCASE("move ctor") { @@ -154,13 +154,13 @@ TEST_CASE("meta/meta_utilities/value2/counters/small") { CHECK_FALSE(v1); CHECK(v2.cast().x == 1); - CHECK(ivec2::dtor_counter == 2); - CHECK(ivec2::move_ctor_counter == 2); - CHECK(ivec2::copy_ctor_counter == 0); + CHECK(ivec2::destructor_counter == 2); + CHECK(ivec2::move_constructor_counter == 2); + CHECK(ivec2::copy_constructor_counter == 0); } - CHECK(ivec2::dtor_counter == 3); - CHECK(ivec2::move_ctor_counter == 2); - CHECK(ivec2::copy_ctor_counter == 0); + CHECK(ivec2::destructor_counter == 3); + CHECK(ivec2::move_constructor_counter == 2); + CHECK(ivec2::copy_constructor_counter == 0); } SUBCASE("copy ctor") { @@ -171,66 +171,66 @@ TEST_CASE("meta/meta_utilities/value2/counters/small") { CHECK(v1.cast().x == 1); CHECK(v2.cast().y == 2); - CHECK(ivec2::dtor_counter == 1); - CHECK(ivec2::move_ctor_counter == 1); - CHECK(ivec2::copy_ctor_counter == 1); + CHECK(ivec2::destructor_counter == 1); + CHECK(ivec2::move_constructor_counter == 1); + CHECK(ivec2::copy_constructor_counter == 1); } - CHECK(ivec2::dtor_counter == 3); - CHECK(ivec2::move_ctor_counter == 1); - CHECK(ivec2::copy_ctor_counter == 1); + CHECK(ivec2::destructor_counter == 3); + CHECK(ivec2::move_constructor_counter == 1); + CHECK(ivec2::copy_constructor_counter == 1); } SUBCASE("swap") { { meta::uvalue v1{ivec2{1,2}}; meta::uvalue v2{ivec2{3,4}}; - CHECK(ivec2::dtor_counter == 2); - CHECK(ivec2::move_ctor_counter == 2); - CHECK(ivec2::copy_ctor_counter == 0); + CHECK(ivec2::destructor_counter == 2); + CHECK(ivec2::move_constructor_counter == 2); + CHECK(ivec2::copy_constructor_counter == 0); v1.swap(v2); CHECK(v1.cast().x == 3); CHECK(v2.cast().x == 1); - CHECK(ivec2::dtor_counter == 5); - CHECK(ivec2::move_ctor_counter == 5); - CHECK(ivec2::copy_ctor_counter == 0); + CHECK(ivec2::destructor_counter == 5); + CHECK(ivec2::move_constructor_counter == 5); + CHECK(ivec2::copy_constructor_counter == 0); } - CHECK(ivec2::dtor_counter == 7); - CHECK(ivec2::move_ctor_counter == 5); - CHECK(ivec2::copy_ctor_counter == 0); + CHECK(ivec2::destructor_counter == 7); + CHECK(ivec2::move_constructor_counter == 5); + CHECK(ivec2::copy_constructor_counter == 0); } } TEST_CASE("meta/meta_utilities/value2/counters/big") { namespace meta = meta_hpp; - ivec2_big::dtor_counter = 0; - ivec2_big::move_ctor_counter = 0; - ivec2_big::copy_ctor_counter = 0; + ivec2_big::destructor_counter = 0; + ivec2_big::move_constructor_counter = 0; + ivec2_big::copy_constructor_counter = 0; SUBCASE("def ctor") { { meta::uvalue v{}; - CHECK(ivec2_big::dtor_counter == 0); - CHECK(ivec2_big::move_ctor_counter == 0); - CHECK(ivec2_big::copy_ctor_counter == 0); + CHECK(ivec2_big::destructor_counter == 0); + CHECK(ivec2_big::move_constructor_counter == 0); + CHECK(ivec2_big::copy_constructor_counter == 0); } - CHECK(ivec2_big::dtor_counter == 0); - CHECK(ivec2_big::move_ctor_counter == 0); - CHECK(ivec2_big::copy_ctor_counter == 0); + CHECK(ivec2_big::destructor_counter == 0); + CHECK(ivec2_big::move_constructor_counter == 0); + CHECK(ivec2_big::copy_constructor_counter == 0); } SUBCASE("val ctor") { { meta::uvalue v{ivec2_big{1,2}}; - CHECK(ivec2_big::dtor_counter == 1); - CHECK(ivec2_big::move_ctor_counter == 1); - CHECK(ivec2_big::copy_ctor_counter == 0); + CHECK(ivec2_big::destructor_counter == 1); + CHECK(ivec2_big::move_constructor_counter == 1); + CHECK(ivec2_big::copy_constructor_counter == 0); } - CHECK(ivec2_big::dtor_counter == 2); - CHECK(ivec2_big::move_ctor_counter == 1); - CHECK(ivec2_big::copy_ctor_counter == 0); + CHECK(ivec2_big::destructor_counter == 2); + CHECK(ivec2_big::move_constructor_counter == 1); + CHECK(ivec2_big::copy_constructor_counter == 0); } SUBCASE("move ctor") { @@ -241,13 +241,13 @@ TEST_CASE("meta/meta_utilities/value2/counters/big") { CHECK_FALSE(v1); CHECK(v2.cast().x == 1); - CHECK(ivec2_big::dtor_counter == 1); - CHECK(ivec2_big::move_ctor_counter == 1); - CHECK(ivec2_big::copy_ctor_counter == 0); + CHECK(ivec2_big::destructor_counter == 1); + CHECK(ivec2_big::move_constructor_counter == 1); + CHECK(ivec2_big::copy_constructor_counter == 0); } - CHECK(ivec2_big::dtor_counter == 2); - CHECK(ivec2_big::move_ctor_counter == 1); - CHECK(ivec2_big::copy_ctor_counter == 0); + CHECK(ivec2_big::destructor_counter == 2); + CHECK(ivec2_big::move_constructor_counter == 1); + CHECK(ivec2_big::copy_constructor_counter == 0); } SUBCASE("copy ctor") { @@ -258,77 +258,77 @@ TEST_CASE("meta/meta_utilities/value2/counters/big") { CHECK(v1.cast().x == 1); CHECK(v2.cast().y == 2); - CHECK(ivec2_big::dtor_counter == 1); - CHECK(ivec2_big::move_ctor_counter == 1); - CHECK(ivec2_big::copy_ctor_counter == 1); + CHECK(ivec2_big::destructor_counter == 1); + CHECK(ivec2_big::move_constructor_counter == 1); + CHECK(ivec2_big::copy_constructor_counter == 1); } - CHECK(ivec2_big::dtor_counter == 3); - CHECK(ivec2_big::move_ctor_counter == 1); - CHECK(ivec2_big::copy_ctor_counter == 1); + CHECK(ivec2_big::destructor_counter == 3); + CHECK(ivec2_big::move_constructor_counter == 1); + CHECK(ivec2_big::copy_constructor_counter == 1); } SUBCASE("swap") { { meta::uvalue v1{ivec2_big{1,2}}; meta::uvalue v2{ivec2_big{3,4}}; - CHECK(ivec2_big::dtor_counter == 2); - CHECK(ivec2_big::move_ctor_counter == 2); - CHECK(ivec2_big::copy_ctor_counter == 0); + CHECK(ivec2_big::destructor_counter == 2); + CHECK(ivec2_big::move_constructor_counter == 2); + CHECK(ivec2_big::copy_constructor_counter == 0); v1.swap(v2); CHECK(v1.cast().x == 3); CHECK(v2.cast().x == 1); - CHECK(ivec2_big::dtor_counter == 2); - CHECK(ivec2_big::move_ctor_counter == 2); - CHECK(ivec2_big::copy_ctor_counter == 0); + CHECK(ivec2_big::destructor_counter == 2); + CHECK(ivec2_big::move_constructor_counter == 2); + CHECK(ivec2_big::copy_constructor_counter == 0); } - CHECK(ivec2_big::dtor_counter == 4); - CHECK(ivec2_big::move_ctor_counter == 2); - CHECK(ivec2_big::copy_ctor_counter == 0); + CHECK(ivec2_big::destructor_counter == 4); + CHECK(ivec2_big::move_constructor_counter == 2); + CHECK(ivec2_big::copy_constructor_counter == 0); } } TEST_CASE("meta/meta_utilities/value2/counters/swap") { namespace meta = meta_hpp; - ivec2::dtor_counter = 0; - ivec2::move_ctor_counter = 0; - ivec2::copy_ctor_counter = 0; + ivec2::destructor_counter = 0; + ivec2::move_constructor_counter = 0; + ivec2::copy_constructor_counter = 0; - ivec2_big::dtor_counter = 0; - ivec2_big::move_ctor_counter = 0; - ivec2_big::copy_ctor_counter = 0; + ivec2_big::destructor_counter = 0; + ivec2_big::move_constructor_counter = 0; + ivec2_big::copy_constructor_counter = 0; SUBCASE("empty/small") { { meta::uvalue v1{}; meta::uvalue v2{ivec2{1,2}}; - CHECK(ivec2::dtor_counter == 1); - CHECK(ivec2::move_ctor_counter == 1); - CHECK(ivec2::copy_ctor_counter == 0); + CHECK(ivec2::destructor_counter == 1); + CHECK(ivec2::move_constructor_counter == 1); + CHECK(ivec2::copy_constructor_counter == 0); v1.swap(v2); CHECK(v1.cast().x == 1); CHECK_FALSE(v2); - CHECK(ivec2::dtor_counter == 2); - CHECK(ivec2::move_ctor_counter == 2); - CHECK(ivec2::copy_ctor_counter == 0); + CHECK(ivec2::destructor_counter == 2); + CHECK(ivec2::move_constructor_counter == 2); + CHECK(ivec2::copy_constructor_counter == 0); v1.swap(v2); CHECK_FALSE(v1); CHECK(v2.cast().y == 2); - CHECK(ivec2::dtor_counter == 3); - CHECK(ivec2::move_ctor_counter == 3); - CHECK(ivec2::copy_ctor_counter == 0); + CHECK(ivec2::destructor_counter == 3); + CHECK(ivec2::move_constructor_counter == 3); + CHECK(ivec2::copy_constructor_counter == 0); } - CHECK(ivec2::dtor_counter == 4); - CHECK(ivec2::move_ctor_counter == 3); - CHECK(ivec2::copy_ctor_counter == 0); + CHECK(ivec2::destructor_counter == 4); + CHECK(ivec2::move_constructor_counter == 3); + CHECK(ivec2::copy_constructor_counter == 0); } SUBCASE("empty/big") { @@ -336,30 +336,30 @@ TEST_CASE("meta/meta_utilities/value2/counters/swap") { meta::uvalue v1{}; meta::uvalue v2{ivec2_big{3,4}}; - CHECK(ivec2_big::dtor_counter == 1); - CHECK(ivec2_big::move_ctor_counter == 1); - CHECK(ivec2_big::copy_ctor_counter == 0); + CHECK(ivec2_big::destructor_counter == 1); + CHECK(ivec2_big::move_constructor_counter == 1); + CHECK(ivec2_big::copy_constructor_counter == 0); v1.swap(v2); CHECK(v1.cast().x == 3); CHECK_FALSE(v2); - CHECK(ivec2_big::dtor_counter == 1); - CHECK(ivec2_big::move_ctor_counter == 1); - CHECK(ivec2_big::copy_ctor_counter == 0); + CHECK(ivec2_big::destructor_counter == 1); + CHECK(ivec2_big::move_constructor_counter == 1); + CHECK(ivec2_big::copy_constructor_counter == 0); v1.swap(v2); CHECK_FALSE(v1); CHECK(v2.cast().y == 4); - CHECK(ivec2_big::dtor_counter == 1); - CHECK(ivec2_big::move_ctor_counter == 1); - CHECK(ivec2_big::copy_ctor_counter == 0); + CHECK(ivec2_big::destructor_counter == 1); + CHECK(ivec2_big::move_constructor_counter == 1); + CHECK(ivec2_big::copy_constructor_counter == 0); } - CHECK(ivec2_big::dtor_counter == 2); - CHECK(ivec2_big::move_ctor_counter == 1); - CHECK(ivec2_big::copy_ctor_counter == 0); + CHECK(ivec2_big::destructor_counter == 2); + CHECK(ivec2_big::move_constructor_counter == 1); + CHECK(ivec2_big::copy_constructor_counter == 0); } SUBCASE("small/big") { @@ -367,45 +367,45 @@ TEST_CASE("meta/meta_utilities/value2/counters/swap") { meta::uvalue v1{ivec2{1,2}}; meta::uvalue v2{ivec2_big{3,4}}; - CHECK(ivec2::dtor_counter == 1); - CHECK(ivec2::move_ctor_counter == 1); - CHECK(ivec2::copy_ctor_counter == 0); + CHECK(ivec2::destructor_counter == 1); + CHECK(ivec2::move_constructor_counter == 1); + CHECK(ivec2::copy_constructor_counter == 0); - CHECK(ivec2_big::dtor_counter == 1); - CHECK(ivec2_big::move_ctor_counter == 1); - CHECK(ivec2_big::copy_ctor_counter == 0); + CHECK(ivec2_big::destructor_counter == 1); + CHECK(ivec2_big::move_constructor_counter == 1); + CHECK(ivec2_big::copy_constructor_counter == 0); v1.swap(v2); CHECK(v1.cast().x == 3); CHECK(v2.cast().x == 1); - CHECK(ivec2::dtor_counter == 2); - CHECK(ivec2::move_ctor_counter == 2); - CHECK(ivec2::copy_ctor_counter == 0); + CHECK(ivec2::destructor_counter == 2); + CHECK(ivec2::move_constructor_counter == 2); + CHECK(ivec2::copy_constructor_counter == 0); - CHECK(ivec2_big::dtor_counter == 1); - CHECK(ivec2_big::move_ctor_counter == 1); - CHECK(ivec2_big::copy_ctor_counter == 0); + CHECK(ivec2_big::destructor_counter == 1); + CHECK(ivec2_big::move_constructor_counter == 1); + CHECK(ivec2_big::copy_constructor_counter == 0); v1.swap(v2); CHECK(v1.cast().y == 2); CHECK(v2.cast().y == 4); - CHECK(ivec2::dtor_counter == 3); - CHECK(ivec2::move_ctor_counter == 3); - CHECK(ivec2::copy_ctor_counter == 0); + CHECK(ivec2::destructor_counter == 3); + CHECK(ivec2::move_constructor_counter == 3); + CHECK(ivec2::copy_constructor_counter == 0); - CHECK(ivec2_big::dtor_counter == 1); - CHECK(ivec2_big::move_ctor_counter == 1); - CHECK(ivec2_big::copy_ctor_counter == 0); + CHECK(ivec2_big::destructor_counter == 1); + CHECK(ivec2_big::move_constructor_counter == 1); + CHECK(ivec2_big::copy_constructor_counter == 0); } - CHECK(ivec2::dtor_counter == 4); - CHECK(ivec2::move_ctor_counter == 3); - CHECK(ivec2::copy_ctor_counter == 0); + CHECK(ivec2::destructor_counter == 4); + CHECK(ivec2::move_constructor_counter == 3); + CHECK(ivec2::copy_constructor_counter == 0); - CHECK(ivec2_big::dtor_counter == 2); - CHECK(ivec2_big::move_ctor_counter == 1); - CHECK(ivec2_big::copy_ctor_counter == 0); + CHECK(ivec2_big::destructor_counter == 2); + CHECK(ivec2_big::move_constructor_counter == 1); + CHECK(ivec2_big::copy_constructor_counter == 0); } } diff --git a/untests/meta_utilities/value_tests.cpp b/untests/meta_utilities/value_tests.cpp index 920e894..20b8321 100644 --- a/untests/meta_utilities/value_tests.cpp +++ b/untests/meta_utilities/value_tests.cpp @@ -21,13 +21,13 @@ namespace , y{other.y} { other.x = 0; other.y = 0; - ++move_ctor_counter; + ++move_constructor_counter; } ivec2(const ivec2& other) noexcept : x{other.x} , y{other.y} { - ++copy_ctor_counter; + ++copy_constructor_counter; } ivec2& add(const ivec2& other) { @@ -39,8 +39,8 @@ namespace ivec2& operator=(ivec2&& other) = delete; ivec2& operator=(const ivec2& other) = delete; public: - static int move_ctor_counter; - static int copy_ctor_counter; + static int move_constructor_counter; + static int copy_constructor_counter; }; struct ivec3 { @@ -53,8 +53,8 @@ namespace ivec3(int x, int y, int z): x{x}, y{y}, z{z} {} }; - int ivec2::move_ctor_counter{0}; - int ivec2::copy_ctor_counter{0}; + int ivec2::move_constructor_counter{0}; + int ivec2::copy_constructor_counter{0}; ivec2 iadd2(ivec2 l, ivec2 r) { return {l.x + r.x, l.y + r.y}; @@ -73,10 +73,10 @@ TEST_CASE("meta/meta_utilities/value/ivec2") { namespace meta = meta_hpp; meta::class_() - .ctor_() - .ctor_() - .ctor_() - .ctor_() + .constructor_() + .constructor_() + .constructor_() + .constructor_() .member_("x", &ivec2::x) .member_("y", &ivec2::y); } @@ -85,10 +85,10 @@ TEST_CASE("meta/meta_utilities/value/ivec3") { namespace meta = meta_hpp; meta::class_() - .ctor_() - .ctor_() - .ctor_() - .ctor_() + .constructor_() + .constructor_() + .constructor_() + .constructor_() .member_("x", &ivec3::x) .member_("y", &ivec3::y) .member_("z", &ivec3::z); @@ -98,8 +98,8 @@ TEST_CASE("meta/meta_utilities/value") { namespace meta = meta_hpp; using namespace std::string_literals; - ivec2::move_ctor_counter = 0; - ivec2::copy_ctor_counter = 0; + ivec2::move_constructor_counter = 0; + ivec2::copy_constructor_counter = 0; SUBCASE("cast types") { static_assert(std::is_same_v< @@ -189,8 +189,8 @@ TEST_CASE("meta/meta_utilities/value") { ivec2& vr = v; meta::uvalue val{vr}; - CHECK(ivec2::move_ctor_counter == 0); - CHECK(ivec2::copy_ctor_counter == 1); + CHECK(ivec2::move_constructor_counter == 0); + CHECK(ivec2::copy_constructor_counter == 1); CHECK(val.get_type() == meta::resolve_type()); @@ -223,8 +223,8 @@ TEST_CASE("meta/meta_utilities/value") { const ivec2& vr = v; meta::uvalue val{vr}; - CHECK(ivec2::move_ctor_counter == 0); - CHECK(ivec2::copy_ctor_counter == 1); + CHECK(ivec2::move_constructor_counter == 0); + CHECK(ivec2::copy_constructor_counter == 1); CHECK(val.get_type() == meta::resolve_type()); @@ -256,8 +256,8 @@ TEST_CASE("meta/meta_utilities/value") { ivec2 v{1,2}; meta::uvalue val{std::move(v)}; - CHECK(ivec2::move_ctor_counter == 1); - CHECK(ivec2::copy_ctor_counter == 0); + CHECK(ivec2::move_constructor_counter == 1); + CHECK(ivec2::copy_constructor_counter == 0); CHECK(val.get_type() == meta::resolve_type()); @@ -284,8 +284,8 @@ TEST_CASE("meta/meta_utilities/value") { const ivec2 v{1,2}; meta::uvalue val{std::move(v)}; - CHECK(ivec2::move_ctor_counter == 0); - CHECK(ivec2::copy_ctor_counter == 1); + CHECK(ivec2::move_constructor_counter == 0); + CHECK(ivec2::copy_constructor_counter == 1); CHECK(val.get_type() == meta::resolve_type()); @@ -311,25 +311,25 @@ TEST_CASE("meta/meta_utilities/value") { SUBCASE("value(value&&)") { ivec2 v{1,2}; meta::uvalue val_src{std::move(v)}; - CHECK(ivec2::move_ctor_counter == 1); - CHECK(ivec2::copy_ctor_counter == 0); + CHECK(ivec2::move_constructor_counter == 1); + CHECK(ivec2::copy_constructor_counter == 0); meta::uvalue val_dst{std::move(val_src)}; CHECK(val_dst == ivec2{1,2}); - CHECK(ivec2::move_ctor_counter == 2); - CHECK(ivec2::copy_ctor_counter == 0); + CHECK(ivec2::move_constructor_counter == 2); + CHECK(ivec2::copy_constructor_counter == 0); } SUBCASE("value(const meta::value&)") { const ivec2 v{1,2}; meta::uvalue val_src{v}; - CHECK(ivec2::move_ctor_counter == 0); - CHECK(ivec2::copy_ctor_counter == 1); + CHECK(ivec2::move_constructor_counter == 0); + CHECK(ivec2::copy_constructor_counter == 1); meta::uvalue val_dst{val_src}; CHECK(val_dst == ivec2{1,2}); - CHECK(ivec2::move_ctor_counter == 0); - CHECK(ivec2::copy_ctor_counter == 2); + CHECK(ivec2::move_constructor_counter == 0); + CHECK(ivec2::copy_constructor_counter == 2); CHECK(val_src == ivec2{1,2}); CHECK(val_src.data() != val_dst.data()); @@ -348,39 +348,39 @@ TEST_CASE("meta/meta_utilities/value") { SUBCASE("value& operator=(value&&)") { meta::uvalue val_src1{"world"s}; meta::uvalue val_src2{ivec2{1,2}}; - CHECK(ivec2::move_ctor_counter == 1); - CHECK(ivec2::copy_ctor_counter == 0); + CHECK(ivec2::move_constructor_counter == 1); + CHECK(ivec2::copy_constructor_counter == 0); meta::uvalue val_dst{"hello"s}; val_dst = std::move(val_src1); CHECK(val_dst == "world"s); - CHECK(ivec2::move_ctor_counter == 1); - CHECK(ivec2::copy_ctor_counter == 0); + CHECK(ivec2::move_constructor_counter == 1); + CHECK(ivec2::copy_constructor_counter == 0); val_dst = std::move(val_src2); CHECK(val_dst == ivec2{1,2}); - CHECK(ivec2::move_ctor_counter == 3); - CHECK(ivec2::copy_ctor_counter == 0); + CHECK(ivec2::move_constructor_counter == 3); + CHECK(ivec2::copy_constructor_counter == 0); } SUBCASE("value& operator=(const meta::value&)") { meta::uvalue val_src1{"world"s}; meta::uvalue val_src2{ivec2{1,2}}; - CHECK(ivec2::move_ctor_counter == 1); - CHECK(ivec2::copy_ctor_counter == 0); + CHECK(ivec2::move_constructor_counter == 1); + CHECK(ivec2::copy_constructor_counter == 0); meta::uvalue val_dst{"hello"s}; val_dst = val_src1; CHECK(val_dst == "world"s); - CHECK(ivec2::move_ctor_counter == 1); - CHECK(ivec2::copy_ctor_counter == 0); + CHECK(ivec2::move_constructor_counter == 1); + CHECK(ivec2::copy_constructor_counter == 0); val_dst = val_src2; CHECK(val_dst == ivec2{1,2}); - CHECK(ivec2::move_ctor_counter == 2); - CHECK(ivec2::copy_ctor_counter == 1); + CHECK(ivec2::move_constructor_counter == 2); + CHECK(ivec2::copy_constructor_counter == 1); CHECK(val_src2 == ivec2{1,2}); CHECK(val_src2.data() != val_dst.data()); @@ -389,14 +389,14 @@ TEST_CASE("meta/meta_utilities/value") { SUBCASE("swap") { meta::uvalue val1{"world"s}; meta::uvalue val2{ivec2{1,2}}; - CHECK(ivec2::move_ctor_counter == 1); - CHECK(ivec2::copy_ctor_counter == 0); + CHECK(ivec2::move_constructor_counter == 1); + CHECK(ivec2::copy_constructor_counter == 0); val1.swap(val2); CHECK(val1 == ivec2{1,2}); CHECK(val2 == "world"s); - CHECK(ivec2::move_ctor_counter == 2); - CHECK(ivec2::copy_ctor_counter == 0); + CHECK(ivec2::move_constructor_counter == 2); + CHECK(ivec2::copy_constructor_counter == 0); swap(val1, val2); CHECK(val1 == "world"s); @@ -498,20 +498,20 @@ TEST_CASE("meta/meta_utilities/value") { { ivec2 v{1,2}; meta::uvalue vp{&v}; - CHECK(ivec2::move_ctor_counter == 0); - CHECK(ivec2::copy_ctor_counter == 0); + CHECK(ivec2::move_constructor_counter == 0); + CHECK(ivec2::copy_constructor_counter == 0); [[maybe_unused]] meta::uvalue vv1{*vp}; - CHECK((ivec2::move_ctor_counter == 0 || ivec2::move_ctor_counter == 2)); - CHECK(ivec2::copy_ctor_counter == 1); + CHECK((ivec2::move_constructor_counter == 0 || ivec2::move_constructor_counter == 2)); + CHECK(ivec2::copy_constructor_counter == 1); [[maybe_unused]] meta::uvalue vv2{*std::move(vp)}; - CHECK((ivec2::move_ctor_counter == 0 || ivec2::move_ctor_counter == 4)); - CHECK(ivec2::copy_ctor_counter == 2); + CHECK((ivec2::move_constructor_counter == 0 || ivec2::move_constructor_counter == 4)); + CHECK(ivec2::copy_constructor_counter == 2); [[maybe_unused]] meta::uvalue vv3{*std::as_const(vp)}; - CHECK((ivec2::move_ctor_counter == 0 || ivec2::move_ctor_counter == 6)); - CHECK(ivec2::copy_ctor_counter == 3); + CHECK((ivec2::move_constructor_counter == 0 || ivec2::move_constructor_counter == 6)); + CHECK(ivec2::copy_constructor_counter == 3); } { meta::uvalue v{std::make_shared(42)}; From 380aacc4f58ecdf58738505cea6e51d993981eca Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Tue, 8 Feb 2022 23:48:56 +0700 Subject: [PATCH 220/233] copyrights update --- LICENSE.md | 2 +- headers/meta.hpp/meta_all.hpp | 2 +- headers/meta.hpp/meta_base.hpp | 2 +- headers/meta.hpp/meta_base/cvref_traits.hpp | 2 +- headers/meta.hpp/meta_base/fixed_function.hpp | 2 +- headers/meta.hpp/meta_base/noncopyable.hpp | 2 +- headers/meta.hpp/meta_base/overloaded.hpp | 2 +- headers/meta.hpp/meta_base/select_overload.hpp | 2 +- headers/meta.hpp/meta_base/stdex.hpp | 2 +- headers/meta.hpp/meta_base/type_id.hpp | 2 +- headers/meta.hpp/meta_base/type_kinds.hpp | 2 +- headers/meta.hpp/meta_base/type_list.hpp | 2 +- headers/meta.hpp/meta_binds.hpp | 2 +- headers/meta.hpp/meta_binds/class_bind.hpp | 2 +- headers/meta.hpp/meta_binds/enum_bind.hpp | 2 +- headers/meta.hpp/meta_binds/scope_bind.hpp | 2 +- headers/meta.hpp/meta_detail/state_family.hpp | 2 +- headers/meta.hpp/meta_detail/state_registry.hpp | 2 +- headers/meta.hpp/meta_detail/type_family.hpp | 2 +- headers/meta.hpp/meta_detail/type_registry.hpp | 2 +- headers/meta.hpp/meta_detail/type_traits/array_traits.hpp | 2 +- headers/meta.hpp/meta_detail/type_traits/class_traits.hpp | 2 +- headers/meta.hpp/meta_detail/type_traits/constructor_traits.hpp | 2 +- headers/meta.hpp/meta_detail/type_traits/destructor_traits.hpp | 2 +- headers/meta.hpp/meta_detail/type_traits/enum_traits.hpp | 2 +- headers/meta.hpp/meta_detail/type_traits/function_traits.hpp | 2 +- headers/meta.hpp/meta_detail/type_traits/member_traits.hpp | 2 +- headers/meta.hpp/meta_detail/type_traits/method_traits.hpp | 2 +- headers/meta.hpp/meta_detail/type_traits/number_traits.hpp | 2 +- headers/meta.hpp/meta_detail/type_traits/pointer_traits.hpp | 2 +- headers/meta.hpp/meta_detail/type_traits/reference_traits.hpp | 2 +- headers/meta.hpp/meta_detail/value_traits/deref_traits.hpp | 2 +- headers/meta.hpp/meta_detail/value_traits/equals_traits.hpp | 2 +- headers/meta.hpp/meta_detail/value_traits/index_traits.hpp | 2 +- headers/meta.hpp/meta_detail/value_traits/istream_traits.hpp | 2 +- headers/meta.hpp/meta_detail/value_traits/less_traits.hpp | 2 +- headers/meta.hpp/meta_detail/value_traits/ostream_traits.hpp | 2 +- headers/meta.hpp/meta_detail/value_utilities/uarg.hpp | 2 +- headers/meta.hpp/meta_detail/value_utilities/uinst.hpp | 2 +- headers/meta.hpp/meta_detail/value_utilities/utraits.hpp | 2 +- headers/meta.hpp/meta_indices.hpp | 2 +- headers/meta.hpp/meta_indices/argument_index.hpp | 2 +- headers/meta.hpp/meta_indices/constructor_index.hpp | 2 +- headers/meta.hpp/meta_indices/destructor_index.hpp | 2 +- headers/meta.hpp/meta_indices/evalue_index.hpp | 2 +- headers/meta.hpp/meta_indices/function_index.hpp | 2 +- headers/meta.hpp/meta_indices/member_index.hpp | 2 +- headers/meta.hpp/meta_indices/method_index.hpp | 2 +- headers/meta.hpp/meta_indices/scope_index.hpp | 2 +- headers/meta.hpp/meta_indices/variable_index.hpp | 2 +- headers/meta.hpp/meta_states.hpp | 2 +- headers/meta.hpp/meta_states/argument.hpp | 2 +- headers/meta.hpp/meta_states/constructor.hpp | 2 +- headers/meta.hpp/meta_states/destructor.hpp | 2 +- headers/meta.hpp/meta_states/evalue.hpp | 2 +- headers/meta.hpp/meta_states/function.hpp | 2 +- headers/meta.hpp/meta_states/member.hpp | 2 +- headers/meta.hpp/meta_states/method.hpp | 2 +- headers/meta.hpp/meta_states/scope.hpp | 2 +- headers/meta.hpp/meta_states/variable.hpp | 2 +- headers/meta.hpp/meta_types.hpp | 2 +- headers/meta.hpp/meta_types/any_type.hpp | 2 +- headers/meta.hpp/meta_types/array_type.hpp | 2 +- headers/meta.hpp/meta_types/class_type.hpp | 2 +- headers/meta.hpp/meta_types/constructor_type.hpp | 2 +- headers/meta.hpp/meta_types/destructor_type.hpp | 2 +- headers/meta.hpp/meta_types/enum_type.hpp | 2 +- headers/meta.hpp/meta_types/function_type.hpp | 2 +- headers/meta.hpp/meta_types/member_type.hpp | 2 +- headers/meta.hpp/meta_types/method_type.hpp | 2 +- headers/meta.hpp/meta_types/nullptr_type.hpp | 2 +- headers/meta.hpp/meta_types/number_type.hpp | 2 +- headers/meta.hpp/meta_types/pointer_type.hpp | 2 +- headers/meta.hpp/meta_types/reference_type.hpp | 2 +- headers/meta.hpp/meta_types/void_type.hpp | 2 +- headers/meta.hpp/meta_value.hpp | 2 +- headers/meta.hpp/meta_value/value.hpp | 2 +- headers/meta.hpp/meta_value/vinvoke.hpp | 2 +- manuals/meta_examples/classes_example.cpp | 2 +- manuals/meta_examples/enums_examples.cpp | 2 +- manuals/meta_examples/functions_example.cpp | 2 +- manuals/meta_examples/members_example.cpp | 2 +- manuals/meta_examples/methods_example.cpp | 2 +- manuals/meta_examples/scopes_example.cpp | 2 +- manuals/meta_examples/values_example.cpp | 2 +- manuals/meta_examples/variables_example.cpp | 2 +- manuals/meta_manuals.hpp | 2 +- untests/meta_base/fixed_function_tests.cpp | 2 +- untests/meta_features/diamond_tests.cpp | 2 +- untests/meta_states/ctor_tests.cpp | 2 +- untests/meta_states/evalue_tests.cpp | 2 +- untests/meta_states/function2_tests.cpp | 2 +- untests/meta_states/function_tests.cpp | 2 +- untests/meta_states/member_tests.cpp | 2 +- untests/meta_states/method2_tests.cpp | 2 +- untests/meta_states/method_tests.cpp | 2 +- untests/meta_states/scope_tests.cpp | 2 +- untests/meta_states/variable_tests.cpp | 2 +- untests/meta_types/any_type_tests.cpp | 2 +- untests/meta_types/array_type_tests.cpp | 2 +- untests/meta_types/class_type_tests.cpp | 2 +- untests/meta_types/enum_type_tests.cpp | 2 +- untests/meta_types/function_type_tests.cpp | 2 +- untests/meta_types/member_type_tests.cpp | 2 +- untests/meta_types/method_type_tests.cpp | 2 +- untests/meta_types/number_type_tests.cpp | 2 +- untests/meta_types/pointer_type_tests.cpp | 2 +- untests/meta_types/reference_type_tests.cpp | 2 +- untests/meta_types/void_type_tests.cpp | 2 +- untests/meta_untests.cpp | 2 +- untests/meta_untests.hpp | 2 +- untests/meta_utilities/arg2_tests.cpp | 2 +- untests/meta_utilities/arg3_tests.cpp | 2 +- untests/meta_utilities/arg4_tests.cpp | 2 +- untests/meta_utilities/arg5_tests.cpp | 2 +- untests/meta_utilities/arg6_tests.cpp | 2 +- untests/meta_utilities/arg7_tests.cpp | 2 +- untests/meta_utilities/arg_tests.cpp | 2 +- untests/meta_utilities/detail_tests.cpp | 2 +- untests/meta_utilities/inst_tests.cpp | 2 +- untests/meta_utilities/invoke_tests.cpp | 2 +- untests/meta_utilities/value2_tests.cpp | 2 +- untests/meta_utilities/value_tests.cpp | 2 +- 123 files changed, 123 insertions(+), 123 deletions(-) diff --git a/LICENSE.md b/LICENSE.md index 0b1ade1..26d083d 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ MIT License -Copyright (C) 2021, by Matvey Cherevko (blackmatov@gmail.com) +Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/headers/meta.hpp/meta_all.hpp b/headers/meta.hpp/meta_all.hpp index 8936e65..6751447 100644 --- a/headers/meta.hpp/meta_all.hpp +++ b/headers/meta.hpp/meta_all.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_base.hpp b/headers/meta.hpp/meta_base.hpp index 6819a7b..a3db832 100644 --- a/headers/meta.hpp/meta_base.hpp +++ b/headers/meta.hpp/meta_base.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_base/cvref_traits.hpp b/headers/meta.hpp/meta_base/cvref_traits.hpp index 743bba1..697d70d 100644 --- a/headers/meta.hpp/meta_base/cvref_traits.hpp +++ b/headers/meta.hpp/meta_base/cvref_traits.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_base/fixed_function.hpp b/headers/meta.hpp/meta_base/fixed_function.hpp index ee31357..6f61d3b 100644 --- a/headers/meta.hpp/meta_base/fixed_function.hpp +++ b/headers/meta.hpp/meta_base/fixed_function.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_base/noncopyable.hpp b/headers/meta.hpp/meta_base/noncopyable.hpp index 2f26483..7b3a84c 100644 --- a/headers/meta.hpp/meta_base/noncopyable.hpp +++ b/headers/meta.hpp/meta_base/noncopyable.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_base/overloaded.hpp b/headers/meta.hpp/meta_base/overloaded.hpp index 4135fef..0ae408d 100644 --- a/headers/meta.hpp/meta_base/overloaded.hpp +++ b/headers/meta.hpp/meta_base/overloaded.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_base/select_overload.hpp b/headers/meta.hpp/meta_base/select_overload.hpp index f561a5c..8a275ef 100644 --- a/headers/meta.hpp/meta_base/select_overload.hpp +++ b/headers/meta.hpp/meta_base/select_overload.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_base/stdex.hpp b/headers/meta.hpp/meta_base/stdex.hpp index 5e6e30d..ab906e2 100644 --- a/headers/meta.hpp/meta_base/stdex.hpp +++ b/headers/meta.hpp/meta_base/stdex.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_base/type_id.hpp b/headers/meta.hpp/meta_base/type_id.hpp index 7b0da4f..a6b4961 100644 --- a/headers/meta.hpp/meta_base/type_id.hpp +++ b/headers/meta.hpp/meta_base/type_id.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_base/type_kinds.hpp b/headers/meta.hpp/meta_base/type_kinds.hpp index c0ea70e..ea72011 100644 --- a/headers/meta.hpp/meta_base/type_kinds.hpp +++ b/headers/meta.hpp/meta_base/type_kinds.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_base/type_list.hpp b/headers/meta.hpp/meta_base/type_list.hpp index f6c5854..43684b3 100644 --- a/headers/meta.hpp/meta_base/type_list.hpp +++ b/headers/meta.hpp/meta_base/type_list.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_binds.hpp b/headers/meta.hpp/meta_binds.hpp index 2ec5a53..ae030af 100644 --- a/headers/meta.hpp/meta_binds.hpp +++ b/headers/meta.hpp/meta_binds.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_binds/class_bind.hpp b/headers/meta.hpp/meta_binds/class_bind.hpp index e6cb114..1bcc488 100644 --- a/headers/meta.hpp/meta_binds/class_bind.hpp +++ b/headers/meta.hpp/meta_binds/class_bind.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_binds/enum_bind.hpp b/headers/meta.hpp/meta_binds/enum_bind.hpp index 28d91d6..4ea73de 100644 --- a/headers/meta.hpp/meta_binds/enum_bind.hpp +++ b/headers/meta.hpp/meta_binds/enum_bind.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_binds/scope_bind.hpp b/headers/meta.hpp/meta_binds/scope_bind.hpp index 93eb02b..66859c4 100644 --- a/headers/meta.hpp/meta_binds/scope_bind.hpp +++ b/headers/meta.hpp/meta_binds/scope_bind.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_detail/state_family.hpp b/headers/meta.hpp/meta_detail/state_family.hpp index 114caab..4ee2b2a 100644 --- a/headers/meta.hpp/meta_detail/state_family.hpp +++ b/headers/meta.hpp/meta_detail/state_family.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_detail/state_registry.hpp b/headers/meta.hpp/meta_detail/state_registry.hpp index 9a21ced..9d5b7e2 100644 --- a/headers/meta.hpp/meta_detail/state_registry.hpp +++ b/headers/meta.hpp/meta_detail/state_registry.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_detail/type_family.hpp b/headers/meta.hpp/meta_detail/type_family.hpp index 8655d3b..dbdc26e 100644 --- a/headers/meta.hpp/meta_detail/type_family.hpp +++ b/headers/meta.hpp/meta_detail/type_family.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_detail/type_registry.hpp b/headers/meta.hpp/meta_detail/type_registry.hpp index 9f63b31..ea03e40 100644 --- a/headers/meta.hpp/meta_detail/type_registry.hpp +++ b/headers/meta.hpp/meta_detail/type_registry.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_detail/type_traits/array_traits.hpp b/headers/meta.hpp/meta_detail/type_traits/array_traits.hpp index 0ff6aa4..89f1266 100644 --- a/headers/meta.hpp/meta_detail/type_traits/array_traits.hpp +++ b/headers/meta.hpp/meta_detail/type_traits/array_traits.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_detail/type_traits/class_traits.hpp b/headers/meta.hpp/meta_detail/type_traits/class_traits.hpp index b97a0da..16b679b 100644 --- a/headers/meta.hpp/meta_detail/type_traits/class_traits.hpp +++ b/headers/meta.hpp/meta_detail/type_traits/class_traits.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_detail/type_traits/constructor_traits.hpp b/headers/meta.hpp/meta_detail/type_traits/constructor_traits.hpp index 2d4e9ee..d932770 100644 --- a/headers/meta.hpp/meta_detail/type_traits/constructor_traits.hpp +++ b/headers/meta.hpp/meta_detail/type_traits/constructor_traits.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_detail/type_traits/destructor_traits.hpp b/headers/meta.hpp/meta_detail/type_traits/destructor_traits.hpp index e7ad092..64e9e4f 100644 --- a/headers/meta.hpp/meta_detail/type_traits/destructor_traits.hpp +++ b/headers/meta.hpp/meta_detail/type_traits/destructor_traits.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_detail/type_traits/enum_traits.hpp b/headers/meta.hpp/meta_detail/type_traits/enum_traits.hpp index ed72a6a..9ac5993 100644 --- a/headers/meta.hpp/meta_detail/type_traits/enum_traits.hpp +++ b/headers/meta.hpp/meta_detail/type_traits/enum_traits.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_detail/type_traits/function_traits.hpp b/headers/meta.hpp/meta_detail/type_traits/function_traits.hpp index 15b3046..68076ca 100644 --- a/headers/meta.hpp/meta_detail/type_traits/function_traits.hpp +++ b/headers/meta.hpp/meta_detail/type_traits/function_traits.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_detail/type_traits/member_traits.hpp b/headers/meta.hpp/meta_detail/type_traits/member_traits.hpp index e3bac94..a971600 100644 --- a/headers/meta.hpp/meta_detail/type_traits/member_traits.hpp +++ b/headers/meta.hpp/meta_detail/type_traits/member_traits.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_detail/type_traits/method_traits.hpp b/headers/meta.hpp/meta_detail/type_traits/method_traits.hpp index b434fba..20ad1ba 100644 --- a/headers/meta.hpp/meta_detail/type_traits/method_traits.hpp +++ b/headers/meta.hpp/meta_detail/type_traits/method_traits.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_detail/type_traits/number_traits.hpp b/headers/meta.hpp/meta_detail/type_traits/number_traits.hpp index 4126161..2bd8aa6 100644 --- a/headers/meta.hpp/meta_detail/type_traits/number_traits.hpp +++ b/headers/meta.hpp/meta_detail/type_traits/number_traits.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_detail/type_traits/pointer_traits.hpp b/headers/meta.hpp/meta_detail/type_traits/pointer_traits.hpp index 43be453..f969438 100644 --- a/headers/meta.hpp/meta_detail/type_traits/pointer_traits.hpp +++ b/headers/meta.hpp/meta_detail/type_traits/pointer_traits.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_detail/type_traits/reference_traits.hpp b/headers/meta.hpp/meta_detail/type_traits/reference_traits.hpp index 4acf314..918bc90 100644 --- a/headers/meta.hpp/meta_detail/type_traits/reference_traits.hpp +++ b/headers/meta.hpp/meta_detail/type_traits/reference_traits.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_detail/value_traits/deref_traits.hpp b/headers/meta.hpp/meta_detail/value_traits/deref_traits.hpp index 38187ad..d5d7059 100644 --- a/headers/meta.hpp/meta_detail/value_traits/deref_traits.hpp +++ b/headers/meta.hpp/meta_detail/value_traits/deref_traits.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_detail/value_traits/equals_traits.hpp b/headers/meta.hpp/meta_detail/value_traits/equals_traits.hpp index 19bf177..977781c 100644 --- a/headers/meta.hpp/meta_detail/value_traits/equals_traits.hpp +++ b/headers/meta.hpp/meta_detail/value_traits/equals_traits.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_detail/value_traits/index_traits.hpp b/headers/meta.hpp/meta_detail/value_traits/index_traits.hpp index 328c13f..7f55f5e 100644 --- a/headers/meta.hpp/meta_detail/value_traits/index_traits.hpp +++ b/headers/meta.hpp/meta_detail/value_traits/index_traits.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_detail/value_traits/istream_traits.hpp b/headers/meta.hpp/meta_detail/value_traits/istream_traits.hpp index 112a98a..06fc7fb 100644 --- a/headers/meta.hpp/meta_detail/value_traits/istream_traits.hpp +++ b/headers/meta.hpp/meta_detail/value_traits/istream_traits.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_detail/value_traits/less_traits.hpp b/headers/meta.hpp/meta_detail/value_traits/less_traits.hpp index 4140163..2901052 100644 --- a/headers/meta.hpp/meta_detail/value_traits/less_traits.hpp +++ b/headers/meta.hpp/meta_detail/value_traits/less_traits.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_detail/value_traits/ostream_traits.hpp b/headers/meta.hpp/meta_detail/value_traits/ostream_traits.hpp index ee8b701..9068b40 100644 --- a/headers/meta.hpp/meta_detail/value_traits/ostream_traits.hpp +++ b/headers/meta.hpp/meta_detail/value_traits/ostream_traits.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_detail/value_utilities/uarg.hpp b/headers/meta.hpp/meta_detail/value_utilities/uarg.hpp index 9fc33a4..458d735 100644 --- a/headers/meta.hpp/meta_detail/value_utilities/uarg.hpp +++ b/headers/meta.hpp/meta_detail/value_utilities/uarg.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_detail/value_utilities/uinst.hpp b/headers/meta.hpp/meta_detail/value_utilities/uinst.hpp index 18b1952..76c8f3f 100644 --- a/headers/meta.hpp/meta_detail/value_utilities/uinst.hpp +++ b/headers/meta.hpp/meta_detail/value_utilities/uinst.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_detail/value_utilities/utraits.hpp b/headers/meta.hpp/meta_detail/value_utilities/utraits.hpp index a832942..75a275d 100644 --- a/headers/meta.hpp/meta_detail/value_utilities/utraits.hpp +++ b/headers/meta.hpp/meta_detail/value_utilities/utraits.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_indices.hpp b/headers/meta.hpp/meta_indices.hpp index fc0a38b..33c5ccd 100644 --- a/headers/meta.hpp/meta_indices.hpp +++ b/headers/meta.hpp/meta_indices.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_indices/argument_index.hpp b/headers/meta.hpp/meta_indices/argument_index.hpp index 7cb3ef3..9a8db73 100644 --- a/headers/meta.hpp/meta_indices/argument_index.hpp +++ b/headers/meta.hpp/meta_indices/argument_index.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_indices/constructor_index.hpp b/headers/meta.hpp/meta_indices/constructor_index.hpp index 9ab13b6..9dc1c5e 100644 --- a/headers/meta.hpp/meta_indices/constructor_index.hpp +++ b/headers/meta.hpp/meta_indices/constructor_index.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_indices/destructor_index.hpp b/headers/meta.hpp/meta_indices/destructor_index.hpp index 2207b85..fd7e602 100644 --- a/headers/meta.hpp/meta_indices/destructor_index.hpp +++ b/headers/meta.hpp/meta_indices/destructor_index.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_indices/evalue_index.hpp b/headers/meta.hpp/meta_indices/evalue_index.hpp index 8d28db8..6cc78bb 100644 --- a/headers/meta.hpp/meta_indices/evalue_index.hpp +++ b/headers/meta.hpp/meta_indices/evalue_index.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_indices/function_index.hpp b/headers/meta.hpp/meta_indices/function_index.hpp index cc1e8af..3512ee7 100644 --- a/headers/meta.hpp/meta_indices/function_index.hpp +++ b/headers/meta.hpp/meta_indices/function_index.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_indices/member_index.hpp b/headers/meta.hpp/meta_indices/member_index.hpp index f9a8999..4512c34 100644 --- a/headers/meta.hpp/meta_indices/member_index.hpp +++ b/headers/meta.hpp/meta_indices/member_index.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_indices/method_index.hpp b/headers/meta.hpp/meta_indices/method_index.hpp index 5e7b0a3..0ae9d94 100644 --- a/headers/meta.hpp/meta_indices/method_index.hpp +++ b/headers/meta.hpp/meta_indices/method_index.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_indices/scope_index.hpp b/headers/meta.hpp/meta_indices/scope_index.hpp index 01efe9c..466daa1 100644 --- a/headers/meta.hpp/meta_indices/scope_index.hpp +++ b/headers/meta.hpp/meta_indices/scope_index.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_indices/variable_index.hpp b/headers/meta.hpp/meta_indices/variable_index.hpp index bdaa33a..41b13c5 100644 --- a/headers/meta.hpp/meta_indices/variable_index.hpp +++ b/headers/meta.hpp/meta_indices/variable_index.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_states.hpp b/headers/meta.hpp/meta_states.hpp index f238b80..d007ed5 100644 --- a/headers/meta.hpp/meta_states.hpp +++ b/headers/meta.hpp/meta_states.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_states/argument.hpp b/headers/meta.hpp/meta_states/argument.hpp index 4d47d9f..6637394 100644 --- a/headers/meta.hpp/meta_states/argument.hpp +++ b/headers/meta.hpp/meta_states/argument.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_states/constructor.hpp b/headers/meta.hpp/meta_states/constructor.hpp index fade6dc..ec6ddc7 100644 --- a/headers/meta.hpp/meta_states/constructor.hpp +++ b/headers/meta.hpp/meta_states/constructor.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_states/destructor.hpp b/headers/meta.hpp/meta_states/destructor.hpp index d408b1b..9df877e 100644 --- a/headers/meta.hpp/meta_states/destructor.hpp +++ b/headers/meta.hpp/meta_states/destructor.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_states/evalue.hpp b/headers/meta.hpp/meta_states/evalue.hpp index b05a72a..c2ecb07 100644 --- a/headers/meta.hpp/meta_states/evalue.hpp +++ b/headers/meta.hpp/meta_states/evalue.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_states/function.hpp b/headers/meta.hpp/meta_states/function.hpp index 6933a73..1efb637 100644 --- a/headers/meta.hpp/meta_states/function.hpp +++ b/headers/meta.hpp/meta_states/function.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_states/member.hpp b/headers/meta.hpp/meta_states/member.hpp index e16dd2b..7ccd730 100644 --- a/headers/meta.hpp/meta_states/member.hpp +++ b/headers/meta.hpp/meta_states/member.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_states/method.hpp b/headers/meta.hpp/meta_states/method.hpp index 28b8d82..d6e1340 100644 --- a/headers/meta.hpp/meta_states/method.hpp +++ b/headers/meta.hpp/meta_states/method.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_states/scope.hpp b/headers/meta.hpp/meta_states/scope.hpp index f4c3334..98922b5 100644 --- a/headers/meta.hpp/meta_states/scope.hpp +++ b/headers/meta.hpp/meta_states/scope.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_states/variable.hpp b/headers/meta.hpp/meta_states/variable.hpp index 004b0b8..011085c 100644 --- a/headers/meta.hpp/meta_states/variable.hpp +++ b/headers/meta.hpp/meta_states/variable.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_types.hpp b/headers/meta.hpp/meta_types.hpp index 0dd3579..71587f5 100644 --- a/headers/meta.hpp/meta_types.hpp +++ b/headers/meta.hpp/meta_types.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_types/any_type.hpp b/headers/meta.hpp/meta_types/any_type.hpp index ff42971..9c3a204 100644 --- a/headers/meta.hpp/meta_types/any_type.hpp +++ b/headers/meta.hpp/meta_types/any_type.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_types/array_type.hpp b/headers/meta.hpp/meta_types/array_type.hpp index dbf0836..548d1a7 100644 --- a/headers/meta.hpp/meta_types/array_type.hpp +++ b/headers/meta.hpp/meta_types/array_type.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_types/class_type.hpp b/headers/meta.hpp/meta_types/class_type.hpp index 9677349..3438291 100644 --- a/headers/meta.hpp/meta_types/class_type.hpp +++ b/headers/meta.hpp/meta_types/class_type.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_types/constructor_type.hpp b/headers/meta.hpp/meta_types/constructor_type.hpp index 8baacf3..56ba607 100644 --- a/headers/meta.hpp/meta_types/constructor_type.hpp +++ b/headers/meta.hpp/meta_types/constructor_type.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_types/destructor_type.hpp b/headers/meta.hpp/meta_types/destructor_type.hpp index 3517003..47cd0f8 100644 --- a/headers/meta.hpp/meta_types/destructor_type.hpp +++ b/headers/meta.hpp/meta_types/destructor_type.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_types/enum_type.hpp b/headers/meta.hpp/meta_types/enum_type.hpp index 69176a0..5fb4e42 100644 --- a/headers/meta.hpp/meta_types/enum_type.hpp +++ b/headers/meta.hpp/meta_types/enum_type.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_types/function_type.hpp b/headers/meta.hpp/meta_types/function_type.hpp index fa01a86..8dc2307 100644 --- a/headers/meta.hpp/meta_types/function_type.hpp +++ b/headers/meta.hpp/meta_types/function_type.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_types/member_type.hpp b/headers/meta.hpp/meta_types/member_type.hpp index 2ca258d..a5fd57a 100644 --- a/headers/meta.hpp/meta_types/member_type.hpp +++ b/headers/meta.hpp/meta_types/member_type.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_types/method_type.hpp b/headers/meta.hpp/meta_types/method_type.hpp index 3bff848..87920f2 100644 --- a/headers/meta.hpp/meta_types/method_type.hpp +++ b/headers/meta.hpp/meta_types/method_type.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_types/nullptr_type.hpp b/headers/meta.hpp/meta_types/nullptr_type.hpp index fe1b7bd..a6407c1 100644 --- a/headers/meta.hpp/meta_types/nullptr_type.hpp +++ b/headers/meta.hpp/meta_types/nullptr_type.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_types/number_type.hpp b/headers/meta.hpp/meta_types/number_type.hpp index 463f3ef..2bab290 100644 --- a/headers/meta.hpp/meta_types/number_type.hpp +++ b/headers/meta.hpp/meta_types/number_type.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_types/pointer_type.hpp b/headers/meta.hpp/meta_types/pointer_type.hpp index e6c178d..6b0ff1c 100644 --- a/headers/meta.hpp/meta_types/pointer_type.hpp +++ b/headers/meta.hpp/meta_types/pointer_type.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_types/reference_type.hpp b/headers/meta.hpp/meta_types/reference_type.hpp index e4e3cde..a923d42 100644 --- a/headers/meta.hpp/meta_types/reference_type.hpp +++ b/headers/meta.hpp/meta_types/reference_type.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_types/void_type.hpp b/headers/meta.hpp/meta_types/void_type.hpp index 19dc923..af30071 100644 --- a/headers/meta.hpp/meta_types/void_type.hpp +++ b/headers/meta.hpp/meta_types/void_type.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_value.hpp b/headers/meta.hpp/meta_value.hpp index b892aba..b43bb6e 100644 --- a/headers/meta.hpp/meta_value.hpp +++ b/headers/meta.hpp/meta_value.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_value/value.hpp b/headers/meta.hpp/meta_value/value.hpp index f553571..089df83 100644 --- a/headers/meta.hpp/meta_value/value.hpp +++ b/headers/meta.hpp/meta_value/value.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/headers/meta.hpp/meta_value/vinvoke.hpp b/headers/meta.hpp/meta_value/vinvoke.hpp index e9c291c..4173cf2 100644 --- a/headers/meta.hpp/meta_value/vinvoke.hpp +++ b/headers/meta.hpp/meta_value/vinvoke.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #pragma once diff --git a/manuals/meta_examples/classes_example.cpp b/manuals/meta_examples/classes_example.cpp index 83395d5..bdf38e9 100644 --- a/manuals/meta_examples/classes_example.cpp +++ b/manuals/meta_examples/classes_example.cpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #include "../meta_manuals.hpp" diff --git a/manuals/meta_examples/enums_examples.cpp b/manuals/meta_examples/enums_examples.cpp index d61aeb5..2f4bba0 100644 --- a/manuals/meta_examples/enums_examples.cpp +++ b/manuals/meta_examples/enums_examples.cpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #include "../meta_manuals.hpp" diff --git a/manuals/meta_examples/functions_example.cpp b/manuals/meta_examples/functions_example.cpp index c4c6dd0..a5529b1 100644 --- a/manuals/meta_examples/functions_example.cpp +++ b/manuals/meta_examples/functions_example.cpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #include "../meta_manuals.hpp" diff --git a/manuals/meta_examples/members_example.cpp b/manuals/meta_examples/members_example.cpp index 457c501..62854ef 100644 --- a/manuals/meta_examples/members_example.cpp +++ b/manuals/meta_examples/members_example.cpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #include "../meta_manuals.hpp" diff --git a/manuals/meta_examples/methods_example.cpp b/manuals/meta_examples/methods_example.cpp index be68952..af00a11 100644 --- a/manuals/meta_examples/methods_example.cpp +++ b/manuals/meta_examples/methods_example.cpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #include "../meta_manuals.hpp" diff --git a/manuals/meta_examples/scopes_example.cpp b/manuals/meta_examples/scopes_example.cpp index 8f948ee..65ab1ad 100644 --- a/manuals/meta_examples/scopes_example.cpp +++ b/manuals/meta_examples/scopes_example.cpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #include "../meta_manuals.hpp" diff --git a/manuals/meta_examples/values_example.cpp b/manuals/meta_examples/values_example.cpp index c0940df..6aa42b9 100644 --- a/manuals/meta_examples/values_example.cpp +++ b/manuals/meta_examples/values_example.cpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #include "../meta_manuals.hpp" diff --git a/manuals/meta_examples/variables_example.cpp b/manuals/meta_examples/variables_example.cpp index 8d51b8e..05d6fe6 100644 --- a/manuals/meta_examples/variables_example.cpp +++ b/manuals/meta_examples/variables_example.cpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #include "../meta_manuals.hpp" diff --git a/manuals/meta_manuals.hpp b/manuals/meta_manuals.hpp index e98de26..245c449 100644 --- a/manuals/meta_manuals.hpp +++ b/manuals/meta_manuals.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #include diff --git a/untests/meta_base/fixed_function_tests.cpp b/untests/meta_base/fixed_function_tests.cpp index 7d62185..a64dc64 100644 --- a/untests/meta_base/fixed_function_tests.cpp +++ b/untests/meta_base/fixed_function_tests.cpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #include "../meta_untests.hpp" diff --git a/untests/meta_features/diamond_tests.cpp b/untests/meta_features/diamond_tests.cpp index 9012553..d512120 100644 --- a/untests/meta_features/diamond_tests.cpp +++ b/untests/meta_features/diamond_tests.cpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #include "../meta_untests.hpp" diff --git a/untests/meta_states/ctor_tests.cpp b/untests/meta_states/ctor_tests.cpp index 2f0d9a1..cac2e2d 100644 --- a/untests/meta_states/ctor_tests.cpp +++ b/untests/meta_states/ctor_tests.cpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #include "../meta_untests.hpp" diff --git a/untests/meta_states/evalue_tests.cpp b/untests/meta_states/evalue_tests.cpp index 247bd1d..ddfd4db 100644 --- a/untests/meta_states/evalue_tests.cpp +++ b/untests/meta_states/evalue_tests.cpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #include "../meta_untests.hpp" diff --git a/untests/meta_states/function2_tests.cpp b/untests/meta_states/function2_tests.cpp index af4f62c..0ddf669 100644 --- a/untests/meta_states/function2_tests.cpp +++ b/untests/meta_states/function2_tests.cpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #include "../meta_untests.hpp" diff --git a/untests/meta_states/function_tests.cpp b/untests/meta_states/function_tests.cpp index 8498757..41d2092 100644 --- a/untests/meta_states/function_tests.cpp +++ b/untests/meta_states/function_tests.cpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #include "../meta_untests.hpp" diff --git a/untests/meta_states/member_tests.cpp b/untests/meta_states/member_tests.cpp index e1e13bc..130a635 100644 --- a/untests/meta_states/member_tests.cpp +++ b/untests/meta_states/member_tests.cpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #include "../meta_untests.hpp" diff --git a/untests/meta_states/method2_tests.cpp b/untests/meta_states/method2_tests.cpp index d7216b6..b96d934 100644 --- a/untests/meta_states/method2_tests.cpp +++ b/untests/meta_states/method2_tests.cpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #include "../meta_untests.hpp" diff --git a/untests/meta_states/method_tests.cpp b/untests/meta_states/method_tests.cpp index fac12d3..041be66 100644 --- a/untests/meta_states/method_tests.cpp +++ b/untests/meta_states/method_tests.cpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #include "../meta_untests.hpp" diff --git a/untests/meta_states/scope_tests.cpp b/untests/meta_states/scope_tests.cpp index 7664c6b..aa76c47 100644 --- a/untests/meta_states/scope_tests.cpp +++ b/untests/meta_states/scope_tests.cpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #include "../meta_untests.hpp" diff --git a/untests/meta_states/variable_tests.cpp b/untests/meta_states/variable_tests.cpp index ce9e824..fdfb2d3 100644 --- a/untests/meta_states/variable_tests.cpp +++ b/untests/meta_states/variable_tests.cpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #include "../meta_untests.hpp" diff --git a/untests/meta_types/any_type_tests.cpp b/untests/meta_types/any_type_tests.cpp index 256107d..564c890 100644 --- a/untests/meta_types/any_type_tests.cpp +++ b/untests/meta_types/any_type_tests.cpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #include "../meta_untests.hpp" diff --git a/untests/meta_types/array_type_tests.cpp b/untests/meta_types/array_type_tests.cpp index 4c6301e..5135898 100644 --- a/untests/meta_types/array_type_tests.cpp +++ b/untests/meta_types/array_type_tests.cpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #include "../meta_untests.hpp" diff --git a/untests/meta_types/class_type_tests.cpp b/untests/meta_types/class_type_tests.cpp index aac9d81..f2fce15 100644 --- a/untests/meta_types/class_type_tests.cpp +++ b/untests/meta_types/class_type_tests.cpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #include "../meta_untests.hpp" diff --git a/untests/meta_types/enum_type_tests.cpp b/untests/meta_types/enum_type_tests.cpp index 5e681ea..37a5522 100644 --- a/untests/meta_types/enum_type_tests.cpp +++ b/untests/meta_types/enum_type_tests.cpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #include "../meta_untests.hpp" diff --git a/untests/meta_types/function_type_tests.cpp b/untests/meta_types/function_type_tests.cpp index 9d02c58..e453eac 100644 --- a/untests/meta_types/function_type_tests.cpp +++ b/untests/meta_types/function_type_tests.cpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #include "../meta_untests.hpp" diff --git a/untests/meta_types/member_type_tests.cpp b/untests/meta_types/member_type_tests.cpp index 77be0e7..2173bb4 100644 --- a/untests/meta_types/member_type_tests.cpp +++ b/untests/meta_types/member_type_tests.cpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #include "../meta_untests.hpp" diff --git a/untests/meta_types/method_type_tests.cpp b/untests/meta_types/method_type_tests.cpp index 5d73a90..181e87a 100644 --- a/untests/meta_types/method_type_tests.cpp +++ b/untests/meta_types/method_type_tests.cpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #include "../meta_untests.hpp" diff --git a/untests/meta_types/number_type_tests.cpp b/untests/meta_types/number_type_tests.cpp index ccd6545..fad4b32 100644 --- a/untests/meta_types/number_type_tests.cpp +++ b/untests/meta_types/number_type_tests.cpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #include "../meta_untests.hpp" diff --git a/untests/meta_types/pointer_type_tests.cpp b/untests/meta_types/pointer_type_tests.cpp index 2469905..50f7c41 100644 --- a/untests/meta_types/pointer_type_tests.cpp +++ b/untests/meta_types/pointer_type_tests.cpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #include "../meta_untests.hpp" diff --git a/untests/meta_types/reference_type_tests.cpp b/untests/meta_types/reference_type_tests.cpp index 68a15ec..4de586a 100644 --- a/untests/meta_types/reference_type_tests.cpp +++ b/untests/meta_types/reference_type_tests.cpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #include "../meta_untests.hpp" diff --git a/untests/meta_types/void_type_tests.cpp b/untests/meta_types/void_type_tests.cpp index 8fb4104..88ce67c 100644 --- a/untests/meta_types/void_type_tests.cpp +++ b/untests/meta_types/void_type_tests.cpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #include "../meta_untests.hpp" diff --git a/untests/meta_untests.cpp b/untests/meta_untests.cpp index f9c6c27..faad719 100644 --- a/untests/meta_untests.cpp +++ b/untests/meta_untests.cpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #include "meta_untests.hpp" diff --git a/untests/meta_untests.hpp b/untests/meta_untests.hpp index 03493c7..0fa66b6 100644 --- a/untests/meta_untests.hpp +++ b/untests/meta_untests.hpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #include diff --git a/untests/meta_utilities/arg2_tests.cpp b/untests/meta_utilities/arg2_tests.cpp index d12b969..cc1436f 100644 --- a/untests/meta_utilities/arg2_tests.cpp +++ b/untests/meta_utilities/arg2_tests.cpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #include "../meta_untests.hpp" diff --git a/untests/meta_utilities/arg3_tests.cpp b/untests/meta_utilities/arg3_tests.cpp index 9475702..f498320 100644 --- a/untests/meta_utilities/arg3_tests.cpp +++ b/untests/meta_utilities/arg3_tests.cpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #include "../meta_untests.hpp" diff --git a/untests/meta_utilities/arg4_tests.cpp b/untests/meta_utilities/arg4_tests.cpp index 6a62042..7443877 100644 --- a/untests/meta_utilities/arg4_tests.cpp +++ b/untests/meta_utilities/arg4_tests.cpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #include "../meta_untests.hpp" diff --git a/untests/meta_utilities/arg5_tests.cpp b/untests/meta_utilities/arg5_tests.cpp index cd5536a..17b1b7f 100644 --- a/untests/meta_utilities/arg5_tests.cpp +++ b/untests/meta_utilities/arg5_tests.cpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #include "../meta_untests.hpp" diff --git a/untests/meta_utilities/arg6_tests.cpp b/untests/meta_utilities/arg6_tests.cpp index a7ff536..5b32f2e 100644 --- a/untests/meta_utilities/arg6_tests.cpp +++ b/untests/meta_utilities/arg6_tests.cpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #include "../meta_untests.hpp" diff --git a/untests/meta_utilities/arg7_tests.cpp b/untests/meta_utilities/arg7_tests.cpp index 5001b49..bf7616d 100644 --- a/untests/meta_utilities/arg7_tests.cpp +++ b/untests/meta_utilities/arg7_tests.cpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #include "../meta_untests.hpp" diff --git a/untests/meta_utilities/arg_tests.cpp b/untests/meta_utilities/arg_tests.cpp index eabcd78..245e2ff 100644 --- a/untests/meta_utilities/arg_tests.cpp +++ b/untests/meta_utilities/arg_tests.cpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #include "../meta_untests.hpp" diff --git a/untests/meta_utilities/detail_tests.cpp b/untests/meta_utilities/detail_tests.cpp index 079ace8..f80f88f 100644 --- a/untests/meta_utilities/detail_tests.cpp +++ b/untests/meta_utilities/detail_tests.cpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #include "../meta_untests.hpp" diff --git a/untests/meta_utilities/inst_tests.cpp b/untests/meta_utilities/inst_tests.cpp index ed46b5a..17da6db 100644 --- a/untests/meta_utilities/inst_tests.cpp +++ b/untests/meta_utilities/inst_tests.cpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #include "../meta_untests.hpp" diff --git a/untests/meta_utilities/invoke_tests.cpp b/untests/meta_utilities/invoke_tests.cpp index 330f525..6a284cc 100644 --- a/untests/meta_utilities/invoke_tests.cpp +++ b/untests/meta_utilities/invoke_tests.cpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #include "../meta_untests.hpp" diff --git a/untests/meta_utilities/value2_tests.cpp b/untests/meta_utilities/value2_tests.cpp index 8f08c37..cac770a 100644 --- a/untests/meta_utilities/value2_tests.cpp +++ b/untests/meta_utilities/value2_tests.cpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #include "../meta_untests.hpp" diff --git a/untests/meta_utilities/value_tests.cpp b/untests/meta_utilities/value_tests.cpp index 20b8321..4b0d388 100644 --- a/untests/meta_utilities/value_tests.cpp +++ b/untests/meta_utilities/value_tests.cpp @@ -1,7 +1,7 @@ /******************************************************************************* * 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) + * Copyright (C) 2021-2022, by Matvey Cherevko (blackmatov@gmail.com) ******************************************************************************/ #include "../meta_untests.hpp" From ccef5eae5d230e1d1878e53315c3034a000824bf Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sat, 12 Feb 2022 05:04:27 +0700 Subject: [PATCH 221/233] metadata member for every type --- headers/meta.hpp/meta_base.hpp | 1 + headers/meta.hpp/meta_types.hpp | 17 +++++++++++++++++ headers/meta.hpp/meta_types/any_type.hpp | 4 ++++ headers/meta.hpp/meta_types/array_type.hpp | 4 ++++ headers/meta.hpp/meta_types/class_type.hpp | 4 ++++ .../meta.hpp/meta_types/constructor_type.hpp | 4 ++++ headers/meta.hpp/meta_types/destructor_type.hpp | 4 ++++ headers/meta.hpp/meta_types/enum_type.hpp | 4 ++++ headers/meta.hpp/meta_types/function_type.hpp | 4 ++++ headers/meta.hpp/meta_types/member_type.hpp | 4 ++++ headers/meta.hpp/meta_types/method_type.hpp | 4 ++++ headers/meta.hpp/meta_types/nullptr_type.hpp | 4 ++++ headers/meta.hpp/meta_types/number_type.hpp | 4 ++++ headers/meta.hpp/meta_types/pointer_type.hpp | 4 ++++ headers/meta.hpp/meta_types/reference_type.hpp | 4 ++++ headers/meta.hpp/meta_types/void_type.hpp | 4 ++++ 16 files changed, 74 insertions(+) diff --git a/headers/meta.hpp/meta_base.hpp b/headers/meta.hpp/meta_base.hpp index a3db832..a0b294a 100644 --- a/headers/meta.hpp/meta_base.hpp +++ b/headers/meta.hpp/meta_base.hpp @@ -204,6 +204,7 @@ namespace meta_hpp namespace meta_hpp { using argument_list = std::vector; + using metadata_map = std::map>; using class_set = std::set>; using class_map = std::map>; diff --git a/headers/meta.hpp/meta_types.hpp b/headers/meta.hpp/meta_types.hpp index 71587f5..52034c4 100644 --- a/headers/meta.hpp/meta_types.hpp +++ b/headers/meta.hpp/meta_types.hpp @@ -70,6 +70,8 @@ namespace meta_hpp [[nodiscard]] type_id get_id() const noexcept; [[nodiscard]] type_kind get_kind() const noexcept; + [[nodiscard]] const metadata_map& get_metadata() const noexcept; + any_type(const array_type& other) noexcept; any_type(const class_type& other) noexcept; any_type(const constructor_type& other) noexcept; @@ -126,6 +128,7 @@ namespace meta_hpp [[nodiscard]] type_id get_id() const noexcept; [[nodiscard]] array_bitflags get_flags() const noexcept; + [[nodiscard]] const metadata_map& get_metadata() const noexcept; [[nodiscard]] std::size_t get_extent() const noexcept; [[nodiscard]] any_type get_data_type() const noexcept; @@ -144,6 +147,7 @@ namespace meta_hpp [[nodiscard]] type_id get_id() const noexcept; [[nodiscard]] class_bitflags get_flags() const noexcept; + [[nodiscard]] const metadata_map& get_metadata() const noexcept; [[nodiscard]] std::size_t get_size() const noexcept; @@ -216,6 +220,7 @@ namespace meta_hpp [[nodiscard]] type_id get_id() const noexcept; [[nodiscard]] constructor_bitflags get_flags() const noexcept; + [[nodiscard]] const metadata_map& get_metadata() const noexcept; [[nodiscard]] std::size_t get_arity() const noexcept; [[nodiscard]] any_type get_class_type() const noexcept; @@ -236,6 +241,7 @@ namespace meta_hpp [[nodiscard]] type_id get_id() const noexcept; [[nodiscard]] destructor_bitflags get_flags() const noexcept; + [[nodiscard]] const metadata_map& get_metadata() const noexcept; [[nodiscard]] any_type get_class_type() const noexcept; private: @@ -253,6 +259,7 @@ namespace meta_hpp [[nodiscard]] type_id get_id() const noexcept; [[nodiscard]] enum_bitflags get_flags() const noexcept; + [[nodiscard]] const metadata_map& get_metadata() const noexcept; [[nodiscard]] number_type get_underlying_type() const noexcept; @@ -278,6 +285,7 @@ namespace meta_hpp [[nodiscard]] type_id get_id() const noexcept; [[nodiscard]] function_bitflags get_flags() const noexcept; + [[nodiscard]] const metadata_map& get_metadata() const noexcept; [[nodiscard]] std::size_t get_arity() const noexcept; [[nodiscard]] any_type get_return_type() const noexcept; @@ -298,6 +306,7 @@ namespace meta_hpp [[nodiscard]] type_id get_id() const noexcept; [[nodiscard]] member_bitflags get_flags() const noexcept; + [[nodiscard]] const metadata_map& get_metadata() const noexcept; [[nodiscard]] class_type get_owner_type() const noexcept; [[nodiscard]] any_type get_value_type() const noexcept; @@ -316,6 +325,7 @@ namespace meta_hpp [[nodiscard]] type_id get_id() const noexcept; [[nodiscard]] method_bitflags get_flags() const noexcept; + [[nodiscard]] const metadata_map& get_metadata() const noexcept; [[nodiscard]] std::size_t get_arity() const noexcept; [[nodiscard]] class_type get_owner_type() const noexcept; @@ -336,6 +346,7 @@ namespace meta_hpp [[nodiscard]] explicit operator bool() const noexcept; [[nodiscard]] type_id get_id() const noexcept; + [[nodiscard]] const metadata_map& get_metadata() const noexcept; private: detail::nullptr_type_data_ptr data_; friend auto detail::type_access(const nullptr_type&); @@ -351,6 +362,7 @@ namespace meta_hpp [[nodiscard]] type_id get_id() const noexcept; [[nodiscard]] number_bitflags get_flags() const noexcept; + [[nodiscard]] const metadata_map& get_metadata() const noexcept; [[nodiscard]] std::size_t get_size() const noexcept; private: @@ -368,6 +380,7 @@ namespace meta_hpp [[nodiscard]] type_id get_id() const noexcept; [[nodiscard]] pointer_bitflags get_flags() const noexcept; + [[nodiscard]] const metadata_map& get_metadata() const noexcept; [[nodiscard]] any_type get_data_type() const noexcept; private: @@ -385,6 +398,7 @@ namespace meta_hpp [[nodiscard]] type_id get_id() const noexcept; [[nodiscard]] reference_bitflags get_flags() const noexcept; + [[nodiscard]] const metadata_map& get_metadata() const noexcept; [[nodiscard]] any_type get_data_type() const noexcept; private: @@ -401,6 +415,7 @@ namespace meta_hpp [[nodiscard]] explicit operator bool() const noexcept; [[nodiscard]] type_id get_id() const noexcept; + [[nodiscard]] const metadata_map& get_metadata() const noexcept; private: detail::void_type_data_ptr data_; friend auto detail::type_access(const void_type&); @@ -447,6 +462,8 @@ namespace meta_hpp::detail const type_id id; const type_kind kind; + metadata_map metadata; + explicit type_data_base(type_id id, type_kind kind) : id{id} , kind{kind} {} diff --git a/headers/meta.hpp/meta_types/any_type.hpp b/headers/meta.hpp/meta_types/any_type.hpp index 9c3a204..ec09c81 100644 --- a/headers/meta.hpp/meta_types/any_type.hpp +++ b/headers/meta.hpp/meta_types/any_type.hpp @@ -27,6 +27,10 @@ namespace meta_hpp return data_->kind; } + inline const metadata_map& any_type::get_metadata() const noexcept { + return data_->metadata; + } + inline any_type::any_type(const array_type& other) noexcept : data_{detail::type_access(other)} {} diff --git a/headers/meta.hpp/meta_types/array_type.hpp b/headers/meta.hpp/meta_types/array_type.hpp index 548d1a7..89566ec 100644 --- a/headers/meta.hpp/meta_types/array_type.hpp +++ b/headers/meta.hpp/meta_types/array_type.hpp @@ -47,6 +47,10 @@ namespace meta_hpp return data_->flags; } + inline const metadata_map& array_type::get_metadata() const noexcept { + return data_->metadata; + } + inline std::size_t array_type::get_extent() const noexcept { return data_->extent; } diff --git a/headers/meta.hpp/meta_types/class_type.hpp b/headers/meta.hpp/meta_types/class_type.hpp index 3438291..9723be0 100644 --- a/headers/meta.hpp/meta_types/class_type.hpp +++ b/headers/meta.hpp/meta_types/class_type.hpp @@ -53,6 +53,10 @@ namespace meta_hpp return data_->flags; } + inline const metadata_map& class_type::get_metadata() const noexcept { + return data_->metadata; + } + inline std::size_t class_type::get_size() const noexcept { return data_->size; } diff --git a/headers/meta.hpp/meta_types/constructor_type.hpp b/headers/meta.hpp/meta_types/constructor_type.hpp index 56ba607..0c4e900 100644 --- a/headers/meta.hpp/meta_types/constructor_type.hpp +++ b/headers/meta.hpp/meta_types/constructor_type.hpp @@ -47,6 +47,10 @@ namespace meta_hpp return data_->flags; } + inline const metadata_map& constructor_type::get_metadata() const noexcept { + return data_->metadata; + } + inline std::size_t constructor_type::get_arity() const noexcept { return data_->argument_types.size(); } diff --git a/headers/meta.hpp/meta_types/destructor_type.hpp b/headers/meta.hpp/meta_types/destructor_type.hpp index 47cd0f8..b6469af 100644 --- a/headers/meta.hpp/meta_types/destructor_type.hpp +++ b/headers/meta.hpp/meta_types/destructor_type.hpp @@ -46,6 +46,10 @@ namespace meta_hpp return data_->flags; } + inline const metadata_map& destructor_type::get_metadata() const noexcept { + return data_->metadata; + } + inline any_type destructor_type::get_class_type() const noexcept { return data_->class_type; } diff --git a/headers/meta.hpp/meta_types/enum_type.hpp b/headers/meta.hpp/meta_types/enum_type.hpp index 5fb4e42..a371600 100644 --- a/headers/meta.hpp/meta_types/enum_type.hpp +++ b/headers/meta.hpp/meta_types/enum_type.hpp @@ -49,6 +49,10 @@ namespace meta_hpp return data_->flags; } + inline const metadata_map& enum_type::get_metadata() const noexcept { + return data_->metadata; + } + inline number_type enum_type::get_underlying_type() const noexcept { return data_->underlying_type; } diff --git a/headers/meta.hpp/meta_types/function_type.hpp b/headers/meta.hpp/meta_types/function_type.hpp index 8dc2307..b92513c 100644 --- a/headers/meta.hpp/meta_types/function_type.hpp +++ b/headers/meta.hpp/meta_types/function_type.hpp @@ -47,6 +47,10 @@ namespace meta_hpp return data_->flags; } + inline const metadata_map& function_type::get_metadata() const noexcept { + return data_->metadata; + } + inline std::size_t function_type::get_arity() const noexcept { return data_->argument_types.size(); } diff --git a/headers/meta.hpp/meta_types/member_type.hpp b/headers/meta.hpp/meta_types/member_type.hpp index a5fd57a..98a478b 100644 --- a/headers/meta.hpp/meta_types/member_type.hpp +++ b/headers/meta.hpp/meta_types/member_type.hpp @@ -47,6 +47,10 @@ namespace meta_hpp return data_->flags; } + inline const metadata_map& member_type::get_metadata() const noexcept { + return data_->metadata; + } + inline class_type member_type::get_owner_type() const noexcept { return data_->owner_type; } diff --git a/headers/meta.hpp/meta_types/method_type.hpp b/headers/meta.hpp/meta_types/method_type.hpp index 87920f2..27db971 100644 --- a/headers/meta.hpp/meta_types/method_type.hpp +++ b/headers/meta.hpp/meta_types/method_type.hpp @@ -48,6 +48,10 @@ namespace meta_hpp return data_->flags; } + inline const metadata_map& method_type::get_metadata() const noexcept { + return data_->metadata; + } + inline std::size_t method_type::get_arity() const noexcept { return data_->argument_types.size(); } diff --git a/headers/meta.hpp/meta_types/nullptr_type.hpp b/headers/meta.hpp/meta_types/nullptr_type.hpp index a6407c1..0d3e01c 100644 --- a/headers/meta.hpp/meta_types/nullptr_type.hpp +++ b/headers/meta.hpp/meta_types/nullptr_type.hpp @@ -36,4 +36,8 @@ namespace meta_hpp inline type_id nullptr_type::get_id() const noexcept { return data_->id; } + + inline const metadata_map& nullptr_type::get_metadata() const noexcept { + return data_->metadata; + } } diff --git a/headers/meta.hpp/meta_types/number_type.hpp b/headers/meta.hpp/meta_types/number_type.hpp index 2bab290..30d4a80 100644 --- a/headers/meta.hpp/meta_types/number_type.hpp +++ b/headers/meta.hpp/meta_types/number_type.hpp @@ -45,6 +45,10 @@ namespace meta_hpp return data_->flags; } + inline const metadata_map& number_type::get_metadata() const noexcept { + return data_->metadata; + } + inline std::size_t number_type::get_size() const noexcept { return data_->size; } diff --git a/headers/meta.hpp/meta_types/pointer_type.hpp b/headers/meta.hpp/meta_types/pointer_type.hpp index 6b0ff1c..f963bc9 100644 --- a/headers/meta.hpp/meta_types/pointer_type.hpp +++ b/headers/meta.hpp/meta_types/pointer_type.hpp @@ -46,6 +46,10 @@ namespace meta_hpp return data_->flags; } + inline const metadata_map& pointer_type::get_metadata() const noexcept { + return data_->metadata; + } + inline any_type pointer_type::get_data_type() const noexcept { return data_->data_type; } diff --git a/headers/meta.hpp/meta_types/reference_type.hpp b/headers/meta.hpp/meta_types/reference_type.hpp index a923d42..37373b8 100644 --- a/headers/meta.hpp/meta_types/reference_type.hpp +++ b/headers/meta.hpp/meta_types/reference_type.hpp @@ -46,6 +46,10 @@ namespace meta_hpp return data_->flags; } + inline const metadata_map& reference_type::get_metadata() const noexcept { + return data_->metadata; + } + inline any_type reference_type::get_data_type() const noexcept { return data_->data_type; } diff --git a/headers/meta.hpp/meta_types/void_type.hpp b/headers/meta.hpp/meta_types/void_type.hpp index af30071..4b4a989 100644 --- a/headers/meta.hpp/meta_types/void_type.hpp +++ b/headers/meta.hpp/meta_types/void_type.hpp @@ -36,4 +36,8 @@ namespace meta_hpp inline type_id void_type::get_id() const noexcept { return data_->id; } + + inline const metadata_map& void_type::get_metadata() const noexcept { + return data_->metadata; + } } From c9a6f2d0716c492cde3e357f73f720f8f4b5fe52 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sat, 12 Feb 2022 05:06:18 +0700 Subject: [PATCH 222/233] metadata for every state --- headers/meta.hpp/meta_states.hpp | 97 ++++++++++++++------ headers/meta.hpp/meta_states/argument.hpp | 14 ++- headers/meta.hpp/meta_states/constructor.hpp | 16 +++- headers/meta.hpp/meta_states/destructor.hpp | 14 ++- headers/meta.hpp/meta_states/evalue.hpp | 14 ++- headers/meta.hpp/meta_states/function.hpp | 16 +++- headers/meta.hpp/meta_states/member.hpp | 14 ++- headers/meta.hpp/meta_states/method.hpp | 16 +++- headers/meta.hpp/meta_states/scope.hpp | 14 ++- headers/meta.hpp/meta_states/variable.hpp | 14 ++- 10 files changed, 182 insertions(+), 47 deletions(-) diff --git a/headers/meta.hpp/meta_states.hpp b/headers/meta.hpp/meta_states.hpp index d007ed5..a19196b 100644 --- a/headers/meta.hpp/meta_states.hpp +++ b/headers/meta.hpp/meta_states.hpp @@ -101,14 +101,18 @@ namespace meta_hpp class argument final { public: explicit argument() = default; - explicit argument(detail::argument_state_ptr state); + explicit argument(detail::argument_state_ptr state) noexcept; + argument& operator=(detail::argument_state_ptr state) noexcept; [[nodiscard]] bool is_valid() const noexcept; [[nodiscard]] explicit operator bool() const noexcept; [[nodiscard]] const argument_index& get_index() const noexcept; + [[nodiscard]] const metadata_map& get_metadata() const noexcept; + [[nodiscard]] const any_type& get_type() const noexcept; [[nodiscard]] std::size_t get_position() const noexcept; + [[nodiscard]] const std::string& get_name() const noexcept; private: detail::argument_state_ptr state_; @@ -118,12 +122,15 @@ namespace meta_hpp class constructor final { public: explicit constructor() = default; - explicit constructor(detail::constructor_state_ptr state); + explicit constructor(detail::constructor_state_ptr state) noexcept; + constructor& operator=(detail::constructor_state_ptr state) noexcept; [[nodiscard]] bool is_valid() const noexcept; [[nodiscard]] explicit operator bool() const noexcept; [[nodiscard]] const constructor_index& get_index() const noexcept; + [[nodiscard]] const metadata_map& get_metadata() const noexcept; + [[nodiscard]] const constructor_type& get_type() const noexcept; template < typename... Args > @@ -148,12 +155,15 @@ namespace meta_hpp class destructor final { public: explicit destructor() = default; - explicit destructor(detail::destructor_state_ptr state); + explicit destructor(detail::destructor_state_ptr state) noexcept; + destructor& operator=(detail::destructor_state_ptr state) noexcept; [[nodiscard]] bool is_valid() const noexcept; [[nodiscard]] explicit operator bool() const noexcept; [[nodiscard]] const destructor_index& get_index() const noexcept; + [[nodiscard]] const metadata_map& get_metadata() const noexcept; + [[nodiscard]] const destructor_type& get_type() const noexcept; template < typename Arg > @@ -175,12 +185,15 @@ namespace meta_hpp class evalue final { public: explicit evalue() = default; - explicit evalue(detail::evalue_state_ptr state); + explicit evalue(detail::evalue_state_ptr state) noexcept; + evalue& operator=(detail::evalue_state_ptr state) noexcept; [[nodiscard]] bool is_valid() const noexcept; [[nodiscard]] explicit operator bool() const noexcept; [[nodiscard]] const evalue_index& get_index() const noexcept; + [[nodiscard]] const metadata_map& get_metadata() const noexcept; + [[nodiscard]] const enum_type& get_type() const noexcept; [[nodiscard]] const std::string& get_name() const noexcept; @@ -194,12 +207,15 @@ namespace meta_hpp class function final { public: explicit function() = default; - explicit function(detail::function_state_ptr state); + explicit function(detail::function_state_ptr state) noexcept; + function& operator=(detail::function_state_ptr state) noexcept; [[nodiscard]] bool is_valid() const noexcept; [[nodiscard]] explicit operator bool() const noexcept; [[nodiscard]] const function_index& get_index() const noexcept; + [[nodiscard]] const metadata_map& get_metadata() const noexcept; + [[nodiscard]] const function_type& get_type() const noexcept; [[nodiscard]] const std::string& get_name() const noexcept; @@ -225,12 +241,15 @@ namespace meta_hpp class member final { public: explicit member() = default; - explicit member(detail::member_state_ptr state); + explicit member(detail::member_state_ptr state) noexcept; + member& operator=(detail::member_state_ptr state) noexcept; [[nodiscard]] bool is_valid() const noexcept; [[nodiscard]] explicit operator bool() const noexcept; [[nodiscard]] const member_index& get_index() const noexcept; + [[nodiscard]] const metadata_map& get_metadata() const noexcept; + [[nodiscard]] const member_type& get_type() const noexcept; [[nodiscard]] const std::string& get_name() const noexcept; @@ -265,12 +284,15 @@ namespace meta_hpp class method final { public: explicit method() = default; - explicit method(detail::method_state_ptr state); + explicit method(detail::method_state_ptr state) noexcept; + method& operator=(detail::method_state_ptr state) noexcept; [[nodiscard]] bool is_valid() const noexcept; [[nodiscard]] explicit operator bool() const noexcept; [[nodiscard]] const method_index& get_index() const noexcept; + [[nodiscard]] const metadata_map& get_metadata() const noexcept; + [[nodiscard]] const method_type& get_type() const noexcept; [[nodiscard]] const std::string& get_name() const noexcept; @@ -296,12 +318,15 @@ namespace meta_hpp class scope final { public: explicit scope() = default; - explicit scope(detail::scope_state_ptr state); + explicit scope(detail::scope_state_ptr state) noexcept; + scope& operator=(detail::scope_state_ptr state) noexcept; [[nodiscard]] bool is_valid() const noexcept; [[nodiscard]] explicit operator bool() const noexcept; [[nodiscard]] const scope_index& get_index() const noexcept; + [[nodiscard]] const metadata_map& get_metadata() const noexcept; + [[nodiscard]] const std::string& get_name() const noexcept; [[nodiscard]] const class_map& get_classes() const noexcept; @@ -328,12 +353,15 @@ namespace meta_hpp class variable final { public: explicit variable() = default; - explicit variable(detail::variable_state_ptr state); + explicit variable(detail::variable_state_ptr state) noexcept; + variable& operator=(detail::variable_state_ptr state) noexcept; [[nodiscard]] bool is_valid() const noexcept; [[nodiscard]] explicit operator bool() const noexcept; [[nodiscard]] const variable_index& get_index() const noexcept; + [[nodiscard]] const metadata_map& get_metadata() const noexcept; + [[nodiscard]] const pointer_type& get_type() const noexcept; [[nodiscard]] const std::string& get_name() const noexcept; @@ -394,18 +422,30 @@ namespace meta_hpp namespace meta_hpp::detail { + struct argument_state final { + argument_index index; + metadata_map metadata; + + std::string name{}; + + template < typename Argument > + [[nodiscard]] static argument_state_ptr make(std::size_t position, metadata_map metadata); + }; + struct constructor_state final { using invoke_impl = fixed_function)>; using is_invocable_with_impl = fixed_function)>; constructor_index index; + metadata_map metadata; + invoke_impl invoke; is_invocable_with_impl is_invocable_with; argument_list arguments; template < constructor_policy_kind Policy, class_kind Class, typename... Args > - [[nodiscard]] static constructor_state_ptr make(); + [[nodiscard]] static constructor_state_ptr make(metadata_map metadata); }; struct destructor_state final { @@ -413,20 +453,24 @@ namespace meta_hpp::detail using is_invocable_with_impl = fixed_function; destructor_index index; + metadata_map metadata; + invoke_impl invoke; is_invocable_with_impl is_invocable_with; template < class_kind Class > - [[nodiscard]] static destructor_state_ptr make(); + [[nodiscard]] static destructor_state_ptr make(metadata_map metadata); }; struct evalue_state final { evalue_index index; + metadata_map metadata; + uvalue enum_value; uvalue underlying_value; template < enum_kind Enum > - [[nodiscard]] static evalue_state_ptr make(std::string name, Enum evalue); + [[nodiscard]] static evalue_state_ptr make(std::string name, Enum evalue, metadata_map metadata); }; struct function_state final { @@ -434,13 +478,15 @@ namespace meta_hpp::detail using is_invocable_with_impl = fixed_function)>; function_index index; + metadata_map metadata; + invoke_impl invoke; is_invocable_with_impl is_invocable_with; argument_list arguments; template < function_policy_kind Policy, function_kind Function > - [[nodiscard]] static function_state_ptr make(std::string name, Function function); + [[nodiscard]] static function_state_ptr make(std::string name, Function function, metadata_map metadata); }; struct member_state final { @@ -451,13 +497,16 @@ namespace meta_hpp::detail using is_settable_with_impl = fixed_function; member_index index; + metadata_map metadata; + getter_impl getter; setter_impl setter; is_gettable_with_impl is_gettable_with; is_settable_with_impl is_settable_with; + template < member_policy_kind Policy, member_kind Member > - [[nodiscard]] static member_state_ptr make(std::string name, Member member); + [[nodiscard]] static member_state_ptr make(std::string name, Member member, metadata_map metadata); }; struct method_state final { @@ -465,33 +514,27 @@ namespace meta_hpp::detail using is_invocable_with_impl = fixed_function)>; method_index index; + metadata_map metadata; + invoke_impl invoke; is_invocable_with_impl is_invocable_with; argument_list arguments; template < method_policy_kind Policy, method_kind Method > - [[nodiscard]] static method_state_ptr make(std::string name, Method method); - }; - - struct argument_state final { - argument_index index; - - std::string name{}; - - template < typename Argument > - [[nodiscard]] static argument_state_ptr make(std::size_t position); + [[nodiscard]] static method_state_ptr make(std::string name, Method method, metadata_map metadata); }; struct scope_state final { scope_index index; + metadata_map metadata; class_map classes{}; enum_map enums{}; function_map functions{}; variable_map variables{}; - [[nodiscard]] static scope_state_ptr make(std::string name); + [[nodiscard]] static scope_state_ptr make(std::string name, metadata_map metadata); }; struct variable_state final { @@ -500,11 +543,13 @@ namespace meta_hpp::detail using is_settable_with_impl = fixed_function; variable_index index; + metadata_map metadata; + getter_impl getter; setter_impl setter; is_settable_with_impl is_settable_with; template < variable_policy_kind Policy, pointer_kind Pointer > - [[nodiscard]] static variable_state_ptr make(std::string name, Pointer pointer); + [[nodiscard]] static variable_state_ptr make(std::string name, Pointer pointer, metadata_map metadata); }; } diff --git a/headers/meta.hpp/meta_states/argument.hpp b/headers/meta.hpp/meta_states/argument.hpp index 6637394..371fd5b 100644 --- a/headers/meta.hpp/meta_states/argument.hpp +++ b/headers/meta.hpp/meta_states/argument.hpp @@ -12,9 +12,10 @@ namespace meta_hpp::detail { template < typename Argument > - inline argument_state_ptr argument_state::make(std::size_t position) { + inline argument_state_ptr argument_state::make(std::size_t position, metadata_map metadata) { return std::make_shared(argument_state{ .index{argument_index::make(position)}, + .metadata{std::move(metadata)}, }); } } @@ -22,9 +23,14 @@ namespace meta_hpp::detail namespace meta_hpp { - inline argument::argument(detail::argument_state_ptr state) + inline argument::argument(detail::argument_state_ptr state) noexcept : state_{std::move(state)} {} + inline argument& argument::operator=(detail::argument_state_ptr state) noexcept { + state_ = std::move(state); + return *this; + } + inline bool argument::is_valid() const noexcept { return !!state_; } @@ -37,6 +43,10 @@ namespace meta_hpp return state_->index; } + inline const metadata_map& argument::get_metadata() const noexcept { + return state_->metadata; + } + inline const any_type& argument::get_type() const noexcept { return state_->index.get_type(); } diff --git a/headers/meta.hpp/meta_states/constructor.hpp b/headers/meta.hpp/meta_states/constructor.hpp index ec6ddc7..927ec5a 100644 --- a/headers/meta.hpp/meta_states/constructor.hpp +++ b/headers/meta.hpp/meta_states/constructor.hpp @@ -100,7 +100,7 @@ namespace meta_hpp::detail [&arguments](std::index_sequence) mutable { (arguments.push_back([](){ using P = detail::type_list_at_t; - return argument{detail::argument_state::make

(I)}; + return argument{detail::argument_state::make

(I, metadata_map{})}; }.template operator()()), ...); }(std::make_index_sequence()); @@ -111,9 +111,10 @@ namespace meta_hpp::detail namespace meta_hpp::detail { template < constructor_policy_kind Policy, class_kind Class, typename... Args > - constructor_state_ptr constructor_state::make() { + constructor_state_ptr constructor_state::make(metadata_map metadata) { return std::make_shared(constructor_state{ .index{constructor_index::make()}, + .metadata{std::move(metadata)}, .invoke{make_constructor_invoke()}, .is_invocable_with{make_constructor_is_invocable_with()}, .arguments{make_constructor_arguments()}, @@ -123,9 +124,14 @@ namespace meta_hpp::detail namespace meta_hpp { - inline constructor::constructor(detail::constructor_state_ptr state) + inline constructor::constructor(detail::constructor_state_ptr state) noexcept : state_{std::move(state)} {} + inline constructor& constructor::operator=(detail::constructor_state_ptr state) noexcept { + state_ = std::move(state); + return *this; + } + inline bool constructor::is_valid() const noexcept { return !!state_; } @@ -138,6 +144,10 @@ namespace meta_hpp return state_->index; } + inline const metadata_map& constructor::get_metadata() const noexcept { + return state_->metadata; + } + inline const constructor_type& constructor::get_type() const noexcept { return state_->index.get_type(); } diff --git a/headers/meta.hpp/meta_states/destructor.hpp b/headers/meta.hpp/meta_states/destructor.hpp index 9df877e..3f7df85 100644 --- a/headers/meta.hpp/meta_states/destructor.hpp +++ b/headers/meta.hpp/meta_states/destructor.hpp @@ -54,9 +54,10 @@ namespace meta_hpp::detail namespace meta_hpp::detail { template < class_kind Class > - destructor_state_ptr destructor_state::make() { + destructor_state_ptr destructor_state::make(metadata_map metadata) { return std::make_shared(destructor_state{ .index{destructor_index::make()}, + .metadata{std::move(metadata)}, .invoke{make_destructor_invoke()}, .is_invocable_with{make_destructor_is_invocable_with()}, }); @@ -65,9 +66,14 @@ namespace meta_hpp::detail namespace meta_hpp { - inline destructor::destructor(detail::destructor_state_ptr state) + inline destructor::destructor(detail::destructor_state_ptr state) noexcept : state_{std::move(state)} {} + inline destructor& destructor::operator=(detail::destructor_state_ptr state) noexcept { + state_ = std::move(state); + return *this; + } + inline bool destructor::is_valid() const noexcept { return !!state_; } @@ -80,6 +86,10 @@ namespace meta_hpp return state_->index; } + inline const metadata_map& destructor::get_metadata() const noexcept { + return state_->metadata; + } + inline const destructor_type& destructor::get_type() const noexcept { return state_->index.get_type(); } diff --git a/headers/meta.hpp/meta_states/evalue.hpp b/headers/meta.hpp/meta_states/evalue.hpp index c2ecb07..1f74966 100644 --- a/headers/meta.hpp/meta_states/evalue.hpp +++ b/headers/meta.hpp/meta_states/evalue.hpp @@ -14,9 +14,10 @@ namespace meta_hpp::detail { template < enum_kind Enum > - evalue_state_ptr evalue_state::make(std::string name, Enum evalue) { + evalue_state_ptr evalue_state::make(std::string name, Enum evalue, metadata_map metadata) { return std::make_shared(evalue_state{ .index{evalue_index::make(std::move(name))}, + .metadata{std::move(metadata)}, .enum_value{uvalue{evalue}}, .underlying_value{uvalue{stdex::to_underlying(evalue)}}, }); @@ -25,9 +26,14 @@ namespace meta_hpp::detail namespace meta_hpp { - inline evalue::evalue(detail::evalue_state_ptr state) + inline evalue::evalue(detail::evalue_state_ptr state) noexcept : state_{std::move(state)} {} + inline evalue& evalue::operator=(detail::evalue_state_ptr state) noexcept { + state_ = std::move(state); + return *this; + } + inline bool evalue::is_valid() const noexcept { return !!state_; } @@ -40,6 +46,10 @@ namespace meta_hpp return state_->index; } + inline const metadata_map& evalue::get_metadata() const noexcept { + return state_->metadata; + } + inline const enum_type& evalue::get_type() const noexcept { return state_->index.get_type(); } diff --git a/headers/meta.hpp/meta_states/function.hpp b/headers/meta.hpp/meta_states/function.hpp index 1efb637..287c71b 100644 --- a/headers/meta.hpp/meta_states/function.hpp +++ b/headers/meta.hpp/meta_states/function.hpp @@ -106,7 +106,7 @@ namespace meta_hpp::detail [&arguments](std::index_sequence) mutable { (arguments.push_back([](){ using P = detail::type_list_at_t; - return argument{detail::argument_state::make

(I)}; + return argument{detail::argument_state::make

(I, metadata_map{})}; }.template operator()()), ...); }(std::make_index_sequence()); @@ -117,9 +117,10 @@ namespace meta_hpp::detail namespace meta_hpp::detail { template < function_policy_kind Policy, function_kind Function > - function_state_ptr function_state::make(std::string name, Function function) { + function_state_ptr function_state::make(std::string name, Function function, metadata_map metadata) { return std::make_shared(function_state{ .index{function_index::make(std::move(name))}, + .metadata{std::move(metadata)}, .invoke{make_function_invoke(std::move(function))}, .is_invocable_with{make_function_is_invocable_with()}, .arguments{make_function_arguments()}, @@ -129,9 +130,14 @@ namespace meta_hpp::detail namespace meta_hpp { - inline function::function(detail::function_state_ptr state) + inline function::function(detail::function_state_ptr state) noexcept : state_{std::move(state)} {} + inline function& function::operator=(detail::function_state_ptr state) noexcept { + state_ = std::move(state); + return *this; + } + inline bool function::is_valid() const noexcept { return !!state_; } @@ -144,6 +150,10 @@ namespace meta_hpp return state_->index; } + inline const metadata_map& function::get_metadata() const noexcept { + return state_->metadata; + } + inline const function_type& function::get_type() const noexcept { return state_->index.get_type(); } diff --git a/headers/meta.hpp/meta_states/member.hpp b/headers/meta.hpp/meta_states/member.hpp index 7ccd730..f6a4e78 100644 --- a/headers/meta.hpp/meta_states/member.hpp +++ b/headers/meta.hpp/meta_states/member.hpp @@ -147,9 +147,10 @@ namespace meta_hpp::detail namespace meta_hpp::detail { template < member_policy_kind Policy, member_kind Member > - member_state_ptr member_state::make(std::string name, Member member) { + member_state_ptr member_state::make(std::string name, Member member, metadata_map metadata) { return std::make_shared(member_state{ .index{member_index::make(std::move(name))}, + .metadata{std::move(metadata)}, .getter{make_member_getter(member)}, .setter{make_member_setter(member)}, .is_gettable_with{make_member_is_gettable_with()}, @@ -160,9 +161,14 @@ namespace meta_hpp::detail namespace meta_hpp { - inline member::member(detail::member_state_ptr state) + inline member::member(detail::member_state_ptr state) noexcept : state_{std::move(state)} {} + inline member& member::operator=(detail::member_state_ptr state) noexcept { + state_ = std::move(state); + return *this; + } + inline bool member::is_valid() const noexcept { return !!state_; } @@ -175,6 +181,10 @@ namespace meta_hpp return state_->index; } + inline const metadata_map& member::get_metadata() const noexcept { + return state_->metadata; + } + inline const member_type& member::get_type() const noexcept { return state_->index.get_type(); } diff --git a/headers/meta.hpp/meta_states/method.hpp b/headers/meta.hpp/meta_states/method.hpp index d6e1340..890d663 100644 --- a/headers/meta.hpp/meta_states/method.hpp +++ b/headers/meta.hpp/meta_states/method.hpp @@ -119,7 +119,7 @@ namespace meta_hpp::detail [&arguments](std::index_sequence) mutable { (arguments.push_back([](){ using P = detail::type_list_at_t; - return argument{detail::argument_state::make

(I)}; + return argument{detail::argument_state::make

(I, metadata_map{})}; }.template operator()()), ...); }(std::make_index_sequence()); @@ -130,9 +130,10 @@ namespace meta_hpp::detail namespace meta_hpp::detail { template < method_policy_kind Policy, method_kind Method > - method_state_ptr method_state::make(std::string name, Method method) { + method_state_ptr method_state::make(std::string name, Method method, metadata_map metadata) { return std::make_shared(method_state{ .index{method_index::make(std::move(name))}, + .metadata{std::move(metadata)}, .invoke{make_method_invoke(std::move(method))}, .is_invocable_with{make_method_is_invocable_with()}, .arguments{make_method_arguments()}, @@ -142,9 +143,14 @@ namespace meta_hpp::detail namespace meta_hpp { - inline method::method(detail::method_state_ptr state) + inline method::method(detail::method_state_ptr state) noexcept : state_{std::move(state)} {} + inline method& method::operator=(detail::method_state_ptr state) noexcept { + state_ = std::move(state); + return *this; + } + inline bool method::is_valid() const noexcept { return !!state_; } @@ -157,6 +163,10 @@ namespace meta_hpp return state_->index; } + inline const metadata_map& method::get_metadata() const noexcept { + return state_->metadata; + } + inline const method_type& method::get_type() const noexcept { return state_->index.get_type(); } diff --git a/headers/meta.hpp/meta_states/scope.hpp b/headers/meta.hpp/meta_states/scope.hpp index 98922b5..24ae2f6 100644 --- a/headers/meta.hpp/meta_states/scope.hpp +++ b/headers/meta.hpp/meta_states/scope.hpp @@ -20,18 +20,24 @@ namespace meta_hpp::detail { - inline scope_state_ptr scope_state::make(std::string name) { + inline scope_state_ptr scope_state::make(std::string name, metadata_map metadata) { return std::make_shared(scope_state{ .index{scope_index::make(std::move(name))}, + .metadata{std::move(metadata)}, }); } } namespace meta_hpp { - inline scope::scope(detail::scope_state_ptr state) + inline scope::scope(detail::scope_state_ptr state) noexcept : state_{std::move(state)} {} + inline scope& scope::operator=(detail::scope_state_ptr state) noexcept { + state_ = std::move(state); + return *this; + } + inline bool scope::is_valid() const noexcept { return !!state_; } @@ -44,6 +50,10 @@ namespace meta_hpp return state_->index; } + inline const metadata_map& scope::get_metadata() const noexcept { + return state_->metadata; + } + inline const std::string& scope::get_name() const noexcept { return state_->index.get_name(); } diff --git a/headers/meta.hpp/meta_states/variable.hpp b/headers/meta.hpp/meta_states/variable.hpp index 011085c..657dee5 100644 --- a/headers/meta.hpp/meta_states/variable.hpp +++ b/headers/meta.hpp/meta_states/variable.hpp @@ -96,9 +96,10 @@ namespace meta_hpp::detail namespace meta_hpp::detail { template < variable_policy_kind Policy, pointer_kind Pointer > - variable_state_ptr variable_state::make(std::string name, Pointer pointer) { + variable_state_ptr variable_state::make(std::string name, Pointer pointer, metadata_map metadata) { return std::make_shared(variable_state{ .index{variable_index::make(std::move(name))}, + .metadata{std::move(metadata)}, .getter{make_variable_getter(pointer)}, .setter{make_variable_setter(pointer)}, .is_settable_with{make_variable_is_settable_with()}, @@ -108,9 +109,14 @@ namespace meta_hpp::detail namespace meta_hpp { - inline variable::variable(detail::variable_state_ptr state) + inline variable::variable(detail::variable_state_ptr state) noexcept : state_{std::move(state)} {} + inline variable& variable::operator=(detail::variable_state_ptr state) noexcept { + state_ = std::move(state); + return *this; + } + inline bool variable::is_valid() const noexcept { return !!state_; } @@ -123,6 +129,10 @@ namespace meta_hpp return state_->index; } + inline const metadata_map& variable::get_metadata() const noexcept { + return state_->metadata; + } + inline const pointer_type& variable::get_type() const noexcept { return state_->index.get_type(); } From 201fdbf1cb6e6b590a17253e67a5a3fb041a2a1d Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sat, 12 Feb 2022 05:06:53 +0700 Subject: [PATCH 223/233] add state registry mutex --- headers/meta.hpp/meta_detail/state_registry.hpp | 17 +++++++++-------- headers/meta.hpp/meta_detail/type_registry.hpp | 4 ++++ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/headers/meta.hpp/meta_detail/state_registry.hpp b/headers/meta.hpp/meta_detail/state_registry.hpp index 9d5b7e2..c17f3e0 100644 --- a/headers/meta.hpp/meta_detail/state_registry.hpp +++ b/headers/meta.hpp/meta_detail/state_registry.hpp @@ -19,28 +19,29 @@ namespace meta_hpp::detail } [[nodiscard]] scope get_scope_by_name(std::string_view name) const noexcept { + const std::lock_guard lock{mutex_}; + if ( auto iter = scopes_.find(name); iter != scopes_.end() ) { return iter->second; } + return scope{}; } [[nodiscard]] scope resolve_scope(std::string_view name) { - return ensure_scope(name); - } - private: - state_registry() = default; + const std::lock_guard lock{mutex_}; - scope ensure_scope(std::string_view name) { if ( auto iter = scopes_.find(name); iter != scopes_.end() ) { return iter->second; } - return scopes_.emplace( - std::string{name}, - scope_state::make(std::string{name})).first->second; + auto state = scope_state::make(std::string{name}, metadata_map{}); + return scopes_.emplace(std::string{name}, std::move(state)).first->second; } private: + state_registry() = default; + private: + mutable std::mutex mutex_; std::map> scopes_; }; } diff --git a/headers/meta.hpp/meta_detail/type_registry.hpp b/headers/meta.hpp/meta_detail/type_registry.hpp index ea03e40..d7a59e1 100644 --- a/headers/meta.hpp/meta_detail/type_registry.hpp +++ b/headers/meta.hpp/meta_detail/type_registry.hpp @@ -20,17 +20,21 @@ namespace meta_hpp::detail [[nodiscard]] any_type get_type_by_id(type_id id) const noexcept { const std::lock_guard lock{mutex_}; + if ( auto iter = type_by_id_.find(id); iter != type_by_id_.end() ) { return iter->second; } + return any_type{}; } [[nodiscard]] any_type get_type_by_rtti(const std::type_index& index) const noexcept { const std::lock_guard lock{mutex_}; + if ( auto iter = type_by_rtti_.find(index); iter != type_by_rtti_.end() ) { return iter->second; } + return any_type{}; } From aa24ed37e885ec4cc1f0a7be8280e7af5fde6ea3 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sat, 12 Feb 2022 08:07:46 +0700 Subject: [PATCH 224/233] binds opts with metadata --- headers/meta.hpp/meta_binds.hpp | 244 +++++++++++++++----- headers/meta.hpp/meta_binds/class_bind.hpp | 211 +++++++++++++++--- headers/meta.hpp/meta_binds/enum_bind.hpp | 19 +- headers/meta.hpp/meta_binds/scope_bind.hpp | 91 ++++++-- untests/meta_states/metadata_tests.cpp | 246 +++++++++++++++++++++ untests/meta_utilities/arg_tests.cpp | 4 +- untests/meta_utilities/inst_tests.cpp | 4 +- 7 files changed, 711 insertions(+), 108 deletions(-) create mode 100644 untests/meta_states/metadata_tests.cpp diff --git a/headers/meta.hpp/meta_binds.hpp b/headers/meta.hpp/meta_binds.hpp index ae030af..d3aa25f 100644 --- a/headers/meta.hpp/meta_binds.hpp +++ b/headers/meta.hpp/meta_binds.hpp @@ -9,42 +9,98 @@ #include "meta_base.hpp" #include "meta_states.hpp" +namespace meta_hpp::detail +{ + template < typename Class, typename... Args > + concept class_bind_constructor_kind = + class_kind && + requires(Args&&... args) { { Class{std::forward(args)...} }; }; + + template < typename Class > + concept class_bind_destructor_kind = + class_kind && + requires(Class&& inst) { { inst.~Class() }; }; + + 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>; +} + namespace meta_hpp { - namespace detail - { - template < typename Class, typename... Args > - concept class_bind_constructor_kind = - class_kind && - requires(Args&&... args) { { Class{std::forward(args)...} }; }; + struct class_opts final { + metadata_map metadata{}; + }; - template < typename Class > - concept class_bind_destructor_kind = - class_kind && - requires(Class&& inst) { { inst.~Class() }; }; + struct enum_opts final { + metadata_map metadata{}; + }; - template < typename Class, typename Base > - concept class_bind_base_kind = - class_kind && class_kind && - stdex::derived_from; + struct scope_opts final { + metadata_map metadata{}; + }; +} - template < typename Class, typename Member > - concept class_bind_member_kind = - class_kind && member_kind && - stdex::same_as::class_type>; +namespace meta_hpp +{ + struct argument_opts final { + std::string name{}; + metadata_map metadata{}; + }; - template < typename Class, typename Method > - concept class_bind_method_kind = - class_kind && method_kind && - stdex::same_as::class_type>; - } + struct constructor_opts final { + std::vector arguments{}; + metadata_map metadata{}; + }; + struct destructor_opts final { + metadata_map metadata{}; + }; + + struct evalue_opts final { + metadata_map metadata{}; + }; + + struct function_opts final { + std::vector arguments{}; + metadata_map metadata{}; + }; + + struct member_opts final { + metadata_map metadata{}; + }; + + struct method_opts final { + std::vector arguments{}; + metadata_map metadata{}; + }; + + struct variable_opts final { + metadata_map metadata{}; + }; +} + +namespace meta_hpp +{ template < detail::class_kind Class > class class_bind final { public: - explicit class_bind(); + explicit class_bind(class_opts opts); operator class_type() const noexcept; + // constructor_ + template < typename... Args , constructor_policy_kind Policy = constructor_policy::as_object > class_bind& constructor_(Policy = Policy{}) @@ -52,38 +108,75 @@ namespace meta_hpp template < typename... Args , constructor_policy_kind Policy = constructor_policy::as_object > - class_bind& constructor_( - std::initializer_list anames, - Policy = Policy{}) + class_bind& constructor_(constructor_opts opts, Policy = Policy{}) requires detail::class_bind_constructor_kind; + // destructor_ + class_bind& destructor_() requires detail::class_bind_destructor_kind; + class_bind& destructor_(destructor_opts opts) + requires detail::class_bind_destructor_kind; + + // base_ + template < detail::class_kind Base > class_bind& base_() requires detail::class_bind_base_kind; - template < detail::function_kind Function - , function_policy_kind Policy = function_policy::as_copy > - class_bind& function_(std::string name, Function function, Policy = Policy{}); + // function_ template < detail::function_kind Function , function_policy_kind Policy = function_policy::as_copy > class_bind& function_( std::string name, Function function, - std::initializer_list anames, Policy = Policy{}); + template < detail::function_kind Function + , function_policy_kind Policy = function_policy::as_copy > + class_bind& function_( + std::string name, + Function function, + function_opts opts, + Policy = Policy{}); + + template < detail::function_kind Function + , function_policy_kind Policy = function_policy::as_copy > + class_bind& function_( + std::string name, + Function function, + std::initializer_list arguments, + Policy = Policy{}); + + // member_ + template < detail::member_kind Member , member_policy_kind Policy = member_policy::as_copy > - class_bind& member_(std::string name, Member member, Policy = Policy{}) + class_bind& member_( + std::string name, + Member member, + Policy = Policy{}) requires detail::class_bind_member_kind; + template < detail::member_kind Member + , member_policy_kind Policy = member_policy::as_copy > + class_bind& member_( + std::string name, + Member member, + member_opts opts, + Policy = Policy{}) + requires detail::class_bind_member_kind; + + // method_ + template < detail::method_kind Method , method_policy_kind Policy = method_policy::as_copy > - class_bind& method_(std::string name, Method method, Policy = Policy{}) + class_bind& method_( + std::string name, + Method method, + Policy = Policy{}) requires detail::class_bind_method_kind; template < detail::method_kind Method @@ -91,13 +184,35 @@ namespace meta_hpp class_bind& method_( std::string name, Method method, - std::initializer_list anames, + method_opts opts, Policy = Policy{}) requires detail::class_bind_method_kind; + template < detail::method_kind Method + , method_policy_kind Policy = method_policy::as_copy > + class_bind& method_( + std::string name, + Method method, + std::initializer_list arguments, + Policy = Policy{}) + requires detail::class_bind_method_kind; + + // variable_ + template < detail::pointer_kind Pointer , variable_policy_kind Policy = variable_policy::as_copy > - class_bind& variable_(std::string name, Pointer pointer, Policy = Policy{}); + class_bind& variable_( + std::string name, + Pointer pointer, + Policy = Policy{}); + + template < detail::pointer_kind Pointer + , variable_policy_kind Policy = variable_policy::as_copy > + class_bind& variable_( + std::string name, + Pointer pointer, + variable_opts opts, + Policy = Policy{}); private: detail::class_type_data_ptr data_; }; @@ -108,10 +223,11 @@ namespace meta_hpp template < detail::enum_kind Enum > class enum_bind final { public: - explicit enum_bind(); + explicit enum_bind(enum_opts opts); operator enum_type() const noexcept; enum_bind& evalue_(std::string name, Enum value); + enum_bind& evalue_(std::string name, Enum value, evalue_opts opts); private: detail::enum_type_data_ptr data_; }; @@ -124,8 +240,8 @@ namespace meta_hpp struct local_tag {}; struct static_tag {}; - explicit scope_bind(std::string name, local_tag); - explicit scope_bind(std::string_view name, static_tag); + explicit scope_bind(std::string name, scope_opts opts, local_tag); + explicit scope_bind(std::string_view name, scope_opts opts, static_tag); operator scope() const noexcept; template < detail::class_kind Class > @@ -134,21 +250,47 @@ namespace meta_hpp template < detail::enum_kind Enum > scope_bind& enum_(std::string name); - template < detail::function_kind Function - , function_policy_kind Policy = function_policy::as_copy > - scope_bind& function_(std::string name, Function function, Policy = Policy{}); + // function_ template < detail::function_kind Function , function_policy_kind Policy = function_policy::as_copy > scope_bind& function_( std::string name, Function function, - std::initializer_list anames, + Policy = Policy{}); + + template < detail::function_kind Function + , function_policy_kind Policy = function_policy::as_copy > + scope_bind& function_( + std::string name, + Function function, + function_opts opts, + Policy = Policy{}); + + template < detail::function_kind Function + , function_policy_kind Policy = function_policy::as_copy > + scope_bind& function_( + std::string name, + Function function, + std::initializer_list arguments, + Policy = Policy{}); + + // variable_ + + template < detail::pointer_kind Pointer + , variable_policy_kind Policy = variable_policy::as_copy > + scope_bind& variable_( + std::string name, + Pointer pointer, Policy = Policy{}); template < detail::pointer_kind Pointer , variable_policy_kind Policy = variable_policy::as_copy > - scope_bind& variable_(std::string name, Pointer pointer, Policy = Policy{}); + scope_bind& variable_( + std::string name, + Pointer pointer, + variable_opts opts, + Policy = Policy{}); private: detail::scope_state_ptr state_; }; @@ -157,20 +299,20 @@ namespace meta_hpp namespace meta_hpp { template < detail::class_kind Class > - class_bind class_() { - return class_bind{}; + class_bind class_(class_opts opts = {}) { + return class_bind{std::move(opts)}; } template < detail::enum_kind Enum > - enum_bind enum_() { - return enum_bind{}; + enum_bind enum_(enum_opts opts = {}) { + return enum_bind{std::move(opts)}; } - inline scope_bind local_scope_(std::string name) { - return scope_bind{std::move(name), scope_bind::local_tag()}; + inline scope_bind local_scope_(std::string name, scope_opts opts = {}) { + return scope_bind{std::move(name), std::move(opts), scope_bind::local_tag()}; } - inline scope_bind static_scope_(std::string_view name) { - return scope_bind{name, scope_bind::static_tag()}; + inline scope_bind static_scope_(std::string_view name, scope_opts opts = {}) { + return scope_bind{name, std::move(opts), scope_bind::static_tag()}; } } diff --git a/headers/meta.hpp/meta_binds/class_bind.hpp b/headers/meta.hpp/meta_binds/class_bind.hpp index 1bcc488..034fd61 100644 --- a/headers/meta.hpp/meta_binds/class_bind.hpp +++ b/headers/meta.hpp/meta_binds/class_bind.hpp @@ -14,14 +14,21 @@ namespace meta_hpp { template < detail::class_kind Class > - class_bind::class_bind() - : data_{detail::type_access(detail::resolve_type())} {} + class_bind::class_bind(class_opts opts) + : data_{detail::type_access(detail::resolve_type())} { + data_->metadata.swap(opts.metadata); + data_->metadata.merge(opts.metadata); + } template < detail::class_kind Class > class_bind::operator class_type() const noexcept { return class_type{data_}; } + // + // constructor_ + // + template < detail::class_kind Class > template < typename... Args, constructor_policy_kind Policy > class_bind& class_bind::constructor_(Policy policy) @@ -33,34 +40,50 @@ namespace meta_hpp template < detail::class_kind Class > template < typename... Args, constructor_policy_kind Policy > class_bind& class_bind::constructor_( - std::initializer_list anames, + constructor_opts opts, [[maybe_unused]] Policy policy) requires detail::class_bind_constructor_kind { - auto constructor_state = detail::constructor_state::make(); + auto state = detail::constructor_state::make(std::move(opts.metadata)); - if ( anames.size() > constructor_state->arguments.size() ) { + if ( opts.arguments.size() > state->arguments.size() ) { detail::throw_exception_with("provided argument names don't match constructor argument count"); } - for ( std::size_t i = 0; i < anames.size(); ++i ) { - argument& arg = constructor_state->arguments[i]; - detail::state_access(arg)->name = std::string{std::data(anames)[i]}; + for ( std::size_t i = 0; i < opts.arguments.size(); ++i ) { + argument& arg = state->arguments[i]; + detail::state_access(arg)->name = std::move(opts.arguments[i].name); + detail::state_access(arg)->metadata = std::move(opts.arguments[i].metadata); } - data_->constructors.emplace(constructor_state->index, std::move(constructor_state)); + data_->constructors.insert_or_assign(state->index, std::move(state)); return *this; } + // + // destructor_ + // + template < detail::class_kind Class > class_bind& class_bind::destructor_() requires detail::class_bind_destructor_kind { - auto destructor_state = detail::destructor_state::make(); - data_->destructors.emplace(destructor_state->index, std::move(destructor_state)); + return destructor_({}); + } + + template < detail::class_kind Class > + class_bind& class_bind::destructor_(destructor_opts opts) + requires detail::class_bind_destructor_kind + { + auto state = detail::destructor_state::make(std::move(opts.metadata)); + data_->destructors.insert_or_assign(state->index, std::move(state)); return *this; } + // + // base_ + // + template < detail::class_kind Class > template < detail::class_kind Base > class_bind& class_bind::base_() @@ -75,9 +98,17 @@ namespace meta_hpp return *this; } + // + // function_ + // + template < detail::class_kind Class > template < detail::function_kind Function, function_policy_kind Policy > - class_bind& class_bind::function_(std::string name, Function function, Policy policy) { + class_bind& class_bind::function_( + std::string name, + Function function, + Policy policy) + { return function_(std::move(name), std::move(function), {}, policy); } @@ -86,37 +117,96 @@ namespace meta_hpp class_bind& class_bind::function_( std::string name, Function function, - std::initializer_list anames, + function_opts opts, [[maybe_unused]] Policy policy) { - auto function_state = detail::function_state::make(std::move(name), std::move(function)); + auto state = detail::function_state::make( + std::move(name), + std::move(function), + std::move(opts.metadata)); - if ( anames.size() > function_state->arguments.size() ) { + if ( opts.arguments.size() > state->arguments.size() ) { + detail::throw_exception_with("provided arguments don't match function argument count"); + } + + for ( std::size_t i = 0; i < opts.arguments.size(); ++i ) { + argument& arg = state->arguments[i]; + detail::state_access(arg)->name = std::move(opts.arguments[i].name); + detail::state_access(arg)->metadata = std::move(opts.arguments[i].metadata); + } + + data_->functions.insert_or_assign(state->index, std::move(state)); + return *this; + } + + template < detail::class_kind Class > + template < detail::function_kind Function, function_policy_kind Policy > + class_bind& class_bind::function_( + std::string name, + Function function, + std::initializer_list arguments, + [[maybe_unused]] Policy policy) + { + auto state = detail::function_state::make( + std::move(name), + std::move(function), + {}); + + if ( arguments.size() > state->arguments.size() ) { detail::throw_exception_with("provided argument names don't match function argument count"); } - for ( std::size_t i = 0; i < anames.size(); ++i ) { - argument& arg = function_state->arguments[i]; - detail::state_access(arg)->name = std::string{std::data(anames)[i]}; + for ( std::size_t i = 0; i < arguments.size(); ++i ) { + argument& arg = state->arguments[i]; + detail::state_access(arg)->name = std::data(arguments)[i]; } - data_->functions.emplace(function_state->index, std::move(function_state)); + data_->functions.insert_or_assign(state->index, std::move(state)); return *this; } + // + // member_ + // + + template < detail::class_kind Class > + template < detail::member_kind Member, member_policy_kind Policy > + class_bind& class_bind::member_( + std::string name, + Member member, + Policy policy) + requires detail::class_bind_member_kind + { + return member_(std::move(name), std::move(member), {}, policy); + } + template < detail::class_kind Class > template < detail::member_kind Member, member_policy_kind Policy > - class_bind& class_bind::member_(std::string name, Member member, [[maybe_unused]] Policy policy) + class_bind& class_bind::member_( + std::string name, + Member member, + member_opts opts, + [[maybe_unused]] Policy policy) requires detail::class_bind_member_kind { - auto member_state = detail::member_state::make(std::move(name), std::move(member)); - data_->members.emplace(member_state->index, std::move(member_state)); + auto state = detail::member_state::make( + std::move(name), + std::move(member), + std::move(opts.metadata)); + data_->members.insert_or_assign(state->index, std::move(state)); return *this; } + // + // method_ + // + template < detail::class_kind Class > template < detail::method_kind Method, method_policy_kind Policy > - class_bind& class_bind::method_(std::string name, Method method, Policy policy) + class_bind& class_bind::method_( + std::string name, + Method method, + Policy policy) requires detail::class_bind_method_kind { return method_(std::move(name), std::move(method), {}, policy); @@ -127,30 +217,83 @@ namespace meta_hpp class_bind& class_bind::method_( std::string name, Method method, - std::initializer_list anames, + method_opts opts, [[maybe_unused]] Policy policy) requires detail::class_bind_method_kind { - auto method_state = detail::method_state::make(std::move(name), std::move(method)); + auto state = detail::method_state::make( + std::move(name), + std::move(method), + std::move(opts.metadata)); - if ( anames.size() > method_state->arguments.size() ) { - detail::throw_exception_with("provided argument names don't match method argument count"); + if ( opts.arguments.size() > state->arguments.size() ) { + detail::throw_exception_with("provided arguments don't match method argument count"); } - for ( std::size_t i = 0; i < anames.size(); ++i ) { - argument& arg = method_state->arguments[i]; - detail::state_access(arg)->name = std::string{std::data(anames)[i]}; + for ( std::size_t i = 0; i < opts.arguments.size(); ++i ) { + argument& arg = state->arguments[i]; + detail::state_access(arg)->name = std::move(opts.arguments[i].name); + detail::state_access(arg)->metadata = std::move(opts.arguments[i].metadata); } - data_->methods.emplace(method_state->index, std::move(method_state)); + data_->methods.insert_or_assign(state->index, std::move(state)); return *this; } + template < detail::class_kind Class > + template < detail::method_kind Method, method_policy_kind Policy > + class_bind& class_bind::method_( + std::string name, + Method method, + std::initializer_list arguments, + [[maybe_unused]] Policy policy) + requires detail::class_bind_method_kind + { + auto state = detail::method_state::make( + std::move(name), + std::move(method), + {}); + + if ( arguments.size() > state->arguments.size() ) { + detail::throw_exception_with("provided argument names don't match method argument count"); + } + + for ( std::size_t i = 0; i < arguments.size(); ++i ) { + argument& arg = state->arguments[i]; + detail::state_access(arg)->name = std::data(arguments)[i]; + } + + data_->methods.insert_or_assign(state->index, std::move(state)); + return *this; + } + + // + // variable_ + // + template < detail::class_kind Class > template < detail::pointer_kind Pointer, variable_policy_kind Policy > - class_bind& class_bind::variable_( std::string name, Pointer pointer, [[maybe_unused]] Policy policy) { - auto variable_state = detail::variable_state::make(std::move(name), std::move(pointer)); - data_->variables.emplace(variable_state->index, std::move(variable_state)); + class_bind& class_bind::variable_( + std::string name, + Pointer pointer, + Policy policy) + { + return variable_(std::move(name), std::move(pointer), {}, policy); + } + + template < detail::class_kind Class > + template < detail::pointer_kind Pointer, variable_policy_kind Policy > + class_bind& class_bind::variable_( + std::string name, + Pointer pointer, + variable_opts opts, + [[maybe_unused]] Policy policy) + { + auto state = detail::variable_state::make( + std::move(name), + std::move(pointer), + std::move(opts.metadata)); + data_->variables.insert_or_assign(state->index, std::move(state)); return *this; } } diff --git a/headers/meta.hpp/meta_binds/enum_bind.hpp b/headers/meta.hpp/meta_binds/enum_bind.hpp index 4ea73de..5c347b3 100644 --- a/headers/meta.hpp/meta_binds/enum_bind.hpp +++ b/headers/meta.hpp/meta_binds/enum_bind.hpp @@ -14,8 +14,11 @@ namespace meta_hpp { template < detail::enum_kind Enum > - enum_bind::enum_bind() - : data_{detail::type_access(detail::resolve_type())} {} + enum_bind::enum_bind(enum_opts opts) + : data_{detail::type_access(detail::resolve_type())} { + data_->metadata.swap(opts.metadata); + data_->metadata.merge(opts.metadata); + } template < detail::enum_kind Enum > enum_bind::operator enum_type() const noexcept { @@ -24,8 +27,16 @@ namespace meta_hpp template < detail::enum_kind Enum > enum_bind& enum_bind::evalue_(std::string name, Enum value) { - auto evalue_state = detail::evalue_state::make(std::move(name), std::move(value)); - data_->evalues.emplace(evalue_state->index, std::move(evalue_state)); + return evalue_(std::move(name), std::move(value), {}); + } + + template < detail::enum_kind Enum > + enum_bind& enum_bind::evalue_(std::string name, Enum value, evalue_opts opts) { + auto state = detail::evalue_state::make( + std::move(name), + std::move(value), + std::move(opts.metadata)); + data_->evalues.insert_or_assign(state->index, std::move(state)); return *this; } } diff --git a/headers/meta.hpp/meta_binds/scope_bind.hpp b/headers/meta.hpp/meta_binds/scope_bind.hpp index 66859c4..5ed613d 100644 --- a/headers/meta.hpp/meta_binds/scope_bind.hpp +++ b/headers/meta.hpp/meta_binds/scope_bind.hpp @@ -15,12 +15,15 @@ namespace meta_hpp { // NOLINTNEXTLINE(readability-named-parameter) - inline scope_bind::scope_bind(std::string name, local_tag) - : state_{detail::scope_state::make(std::move(name))} {} + inline scope_bind::scope_bind(std::string name, scope_opts opts, local_tag) + : state_{detail::scope_state::make(std::move(name), std::move(opts.metadata))} {} // NOLINTNEXTLINE(readability-named-parameter) - inline scope_bind::scope_bind(std::string_view name, static_tag) - : state_{detail::state_access(detail::resolve_scope(name))} {} + inline scope_bind::scope_bind(std::string_view name, scope_opts opts, static_tag) + : state_{detail::state_access(detail::resolve_scope(name))} { + state_->metadata.swap(opts.metadata); + state_->metadata.merge(opts.metadata); + } inline scope_bind::operator scope() const noexcept { return scope{state_}; @@ -38,8 +41,16 @@ namespace meta_hpp return *this; } + // + // function_ + // + template < detail::function_kind Function, function_policy_kind Policy > - scope_bind& scope_bind::function_(std::string name, Function function, Policy policy) { + scope_bind& scope_bind::function_( + std::string name, + Function function, + Policy policy) + { return function_(std::move(name), std::move(function), {}, policy); } @@ -47,28 +58,78 @@ namespace meta_hpp scope_bind& scope_bind::function_( std::string name, Function function, - std::initializer_list anames, + function_opts opts, [[maybe_unused]] Policy policy) { - auto function_state = detail::function_state::make(std::move(name), std::move(function)); + auto state = detail::function_state::make( + std::move(name), + std::move(function), + std::move(opts.metadata)); - if ( anames.size() > function_state->arguments.size() ) { + if ( opts.arguments.size() > state->arguments.size() ) { + detail::throw_exception_with("provided arguments don't match function argument count"); + } + + for ( std::size_t i = 0; i < opts.arguments.size(); ++i ) { + argument& arg = state->arguments[i]; + detail::state_access(arg)->name = std::move(opts.arguments[i].name); + detail::state_access(arg)->metadata = std::move(opts.arguments[i].metadata); + } + + state_->functions.insert_or_assign(state->index, std::move(state)); + return *this; + } + + template < detail::function_kind Function, function_policy_kind Policy > + scope_bind& scope_bind::function_( + std::string name, + Function function, + std::initializer_list arguments, + [[maybe_unused]] Policy policy) + { + auto state = detail::function_state::make( + std::move(name), + std::move(function), + {}); + + if ( arguments.size() > state->arguments.size() ) { detail::throw_exception_with("provided argument names don't match function argument count"); } - for ( std::size_t i = 0; i < anames.size(); ++i ) { - argument& arg = function_state->arguments[i]; - detail::state_access(arg)->name = std::string{std::data(anames)[i]}; + for ( std::size_t i = 0; i < arguments.size(); ++i ) { + argument& arg = state->arguments[i]; + detail::state_access(arg)->name = std::data(arguments)[i]; } - state_->functions.emplace(function_state->index, std::move(function_state)); + state_->functions.insert_or_assign(state->index, std::move(state)); return *this; } + // + // variable_ + // + + template < detail::pointer_kind Pointer, variable_policy_kind Policy > + scope_bind& scope_bind::variable_( + std::string name, + Pointer pointer, + Policy policy) + { + return variable_(std::move(name), std::move(pointer), {}, policy); + } + template < detail::pointer_kind Pointer, variable_policy_kind Policy > - scope_bind& scope_bind::variable_(std::string name, Pointer pointer, [[maybe_unused]] Policy policy) { - auto variable_state = detail::variable_state::make(std::move(name), std::move(pointer)); - state_->variables.emplace(variable_state->index, std::move(variable_state)); + scope_bind& scope_bind::variable_( + std::string name, + Pointer pointer, + variable_opts opts, + [[maybe_unused]] Policy policy) + { + auto state = detail::variable_state::make( + std::move(name), + std::move(pointer), + std::move(opts.metadata)); + state_->variables.insert_or_assign(state->index, std::move(state)); return *this; } } diff --git a/untests/meta_states/metadata_tests.cpp b/untests/meta_states/metadata_tests.cpp new file mode 100644 index 0000000..07794b0 --- /dev/null +++ b/untests/meta_states/metadata_tests.cpp @@ -0,0 +1,246 @@ +/******************************************************************************* + * 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-2022, by Matvey Cherevko (blackmatov@gmail.com) + ******************************************************************************/ + +#include "../meta_untests.hpp" + +namespace +{ + enum class color : unsigned { + red = 0xFF0000, + green = 0x00FF00, + blue = 0x0000FF, + }; + + struct ivec2 { + int x{}; + int y{}; + + explicit ivec2(int v) : x{v}, y{v} {} + ivec2(int x, int y) : x{x}, y{y} {} + + ivec2& add(const ivec2& other) noexcept { + x += other.x; + y += other.y; + return *this; + } + + static ivec2 iadd(const ivec2& l, const ivec2& r) noexcept { + return {l.x + r.x, l.y + r.y}; + } + }; +} + +TEST_CASE("meta/meta_states/metadata/enum") { + namespace meta = meta_hpp; + using namespace std::string_literals; + + meta::enum_({ + .metadata{ + {"desc1", meta::uvalue{"enum-desc1"s}}, + {"desc2", meta::uvalue{"enum-desc2"s}}, + } + }) + .evalue_("red", color::red, { + .metadata{{"desc1", meta::uvalue{"red-color"s}}} + }) + .evalue_("green", color::green, { + .metadata{{"desc1", meta::uvalue{"green-color"s}}} + }) + .evalue_("blue", color::blue, { + .metadata{{"desc1", meta::uvalue{"blue-color"s}}} + }); + + // metadata override + + meta::enum_({ + .metadata{ + {"desc2", meta::uvalue{"new-enum-desc2"s}}, + {"desc3", meta::uvalue{"new-enum-desc3"s}}, + } + }); + + meta::enum_() + .evalue_("red", color::red, { + .metadata{ + {"desc2", meta::uvalue{"new-red-color"s}}, + } + }); + + // + + const meta::enum_type color_type = meta::resolve_type(); + REQUIRE(color_type); + + SUBCASE("color") { + CHECK(color_type.get_metadata().at("desc1") == "enum-desc1"s); + CHECK(color_type.get_metadata().at("desc2") == "new-enum-desc2"s); + CHECK(color_type.get_metadata().at("desc3") == "new-enum-desc3"s); + } + + SUBCASE("color::red") { + const meta::evalue red_evalue = color_type.get_evalue("red"); + REQUIRE(red_evalue); + CHECK_FALSE(red_evalue.get_metadata().contains("desc1")); + CHECK(red_evalue.get_metadata().at("desc2") == "new-red-color"s); + } +} + +TEST_CASE("meta/meta_states/metadata/class") { + namespace meta = meta_hpp; + using namespace std::string_literals; + + meta::class_({ + .metadata{ + {"desc1", meta::uvalue{"class-desc1"s}}, + {"desc2", meta::uvalue{"class-desc2"s}}, + }, + }) + .constructor_({ + .arguments{{ + .name{"v"}, + .metadata{{"desc", meta::uvalue{"the ctor arg"s}}}, + }}, + .metadata{{"desc", meta::uvalue{"one arg 2d vector ctor"s}}}, + }) + .constructor_({ + .arguments{{ + .name{"x"}, + .metadata{{"desc", meta::uvalue{"the 1st ctor arg"s}}}, + },{ + .name{"y"}, + .metadata{{"desc", meta::uvalue{"the 2nd ctor arg"s}}}, + }}, + .metadata{{"desc", meta::uvalue{"two args 2d vector ctor"s}}} + }) + .member_("x", &ivec2::x, { + .metadata{{"desc", meta::uvalue{"x-member"s}}} + }) + .member_("y", &ivec2::y, { + .metadata{{"desc", meta::uvalue{"y-member"s}}} + }) + .method_("add", &ivec2::add, { + .arguments{{ + .name{"other"}, + .metadata{{"desc", meta::uvalue{"other-arg"s}}} + }}, + .metadata{{"desc", meta::uvalue{"add-method"s}}} + }) + .function_("iadd", &ivec2::iadd, { + .arguments{{ + .name{"l"}, + .metadata{{"desc", meta::uvalue{"l-arg"s}}} + },{ + .name{"r"}, + .metadata{{"desc", meta::uvalue{"r-arg"s}}} + }}, + .metadata{{"desc", meta::uvalue{"iadd-function"s}}} + }); + + // metadata override + + meta::class_({ + .metadata{ + {"desc2", meta::uvalue{"new-class-desc2"s}}, + {"desc3", meta::uvalue{"new-class-desc3"s}}, + } + }); + + // + + const meta::class_type ivec2_type = meta::resolve_type(); + REQUIRE(ivec2_type); + + SUBCASE("ivec2") { + CHECK(ivec2_type.get_metadata().at("desc1") == "class-desc1"s); + CHECK(ivec2_type.get_metadata().at("desc2") == "new-class-desc2"s); + CHECK(ivec2_type.get_metadata().at("desc3") == "new-class-desc3"s); + } + + SUBCASE("ivec2(int)") { + const meta::constructor ivec2_ctor = ivec2_type.get_constructor_with(); + REQUIRE(ivec2_ctor); + + REQUIRE(ivec2_ctor.get_metadata().contains("desc")); + CHECK(ivec2_ctor.get_metadata().at("desc") == "one arg 2d vector ctor"s); + + REQUIRE(ivec2_ctor.get_argument(0)); + CHECK(ivec2_ctor.get_argument(0).get_name() == "v"); + CHECK(ivec2_ctor.get_argument(0).get_position() == 0); + CHECK(ivec2_ctor.get_argument(0).get_type() == meta::resolve_type()); + REQUIRE(ivec2_ctor.get_argument(0).get_metadata().contains("desc")); + CHECK(ivec2_ctor.get_argument(0).get_metadata().at("desc") == "the ctor arg"s); + + REQUIRE_FALSE(ivec2_ctor.get_argument(1)); + } + + SUBCASE("ivec2(int, int)") { + const meta::constructor ivec2_ctor = ivec2_type.get_constructor_with(); + REQUIRE(ivec2_ctor); + + REQUIRE(ivec2_ctor.get_metadata().contains("desc")); + CHECK(ivec2_ctor.get_metadata().at("desc") == "two args 2d vector ctor"s); + + REQUIRE(ivec2_ctor.get_argument(0)); + CHECK(ivec2_ctor.get_argument(0).get_name() == "x"); + CHECK(ivec2_ctor.get_argument(0).get_position() == 0); + CHECK(ivec2_ctor.get_argument(0).get_type() == meta::resolve_type()); + REQUIRE(ivec2_ctor.get_argument(0).get_metadata().contains("desc")); + CHECK(ivec2_ctor.get_argument(0).get_metadata().at("desc") == "the 1st ctor arg"s); + + REQUIRE(ivec2_ctor.get_argument(1)); + CHECK(ivec2_ctor.get_argument(1).get_name() == "y"); + CHECK(ivec2_ctor.get_argument(1).get_position() == 1); + CHECK(ivec2_ctor.get_argument(1).get_type() == meta::resolve_type()); + REQUIRE(ivec2_ctor.get_argument(1).get_metadata().contains("desc")); + CHECK(ivec2_ctor.get_argument(1).get_metadata().at("desc") == "the 2nd ctor arg"s); + + REQUIRE_FALSE(ivec2_ctor.get_argument(2)); + } + + SUBCASE("ivec2::x") { + const meta::member ivec2_x = ivec2_type.get_member("x"); + REQUIRE(ivec2_x); + + REQUIRE(ivec2_x.get_metadata().contains("desc")); + CHECK(ivec2_x.get_metadata().at("desc") == "x-member"s); + } + + SUBCASE("ivec2::y") { + const meta::member ivec2_y = ivec2_type.get_member("y"); + REQUIRE(ivec2_y); + + REQUIRE(ivec2_y.get_metadata().contains("desc")); + CHECK(ivec2_y.get_metadata().at("desc") == "y-member"s); + } + + SUBCASE("ivec2::add") { + const meta::method ivec2_add = ivec2_type.get_method("add"); + REQUIRE(ivec2_add); + + REQUIRE(ivec2_add.get_metadata().contains("desc")); + CHECK(ivec2_add.get_metadata().at("desc") == "add-method"s); + + REQUIRE(ivec2_add.get_argument(0)); + REQUIRE(ivec2_add.get_argument(0).get_metadata().contains("desc")); + CHECK(ivec2_add.get_argument(0).get_metadata().at("desc") == "other-arg"s); + } + + SUBCASE("ivec2::iadd") { + const meta::function ivec2_iadd = ivec2_type.get_function("iadd"); + REQUIRE(ivec2_iadd); + + REQUIRE(ivec2_iadd.get_metadata().contains("desc")); + CHECK(ivec2_iadd.get_metadata().at("desc") == "iadd-function"s); + + REQUIRE(ivec2_iadd.get_argument(0)); + REQUIRE(ivec2_iadd.get_argument(0).get_metadata().contains("desc")); + CHECK(ivec2_iadd.get_argument(0).get_metadata().at("desc") == "l-arg"s); + + REQUIRE(ivec2_iadd.get_argument(1)); + REQUIRE(ivec2_iadd.get_argument(1).get_metadata().contains("desc")); + CHECK(ivec2_iadd.get_argument(1).get_metadata().at("desc") == "r-arg"s); + } +} diff --git a/untests/meta_utilities/arg_tests.cpp b/untests/meta_utilities/arg_tests.cpp index 245e2ff..666025b 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_overload(&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(uarg{FromValue}.can_cast_to());\ @@ -94,7 +94,7 @@ namespace {\ using namespace meta::detail;\ auto function_ptr = meta::select_overload(&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 17da6db..82ee784 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_overload(&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(uinst{Inst}.can_cast_to());\ @@ -54,7 +54,7 @@ namespace {\ using namespace meta::detail;\ auto method_ptr = meta::select_overload(&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());\ From 9277668573ff64cce50c7bee3b92db45ada08ccf Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sat, 12 Feb 2022 08:40:17 +0700 Subject: [PATCH 225/233] metadata binds for all types --- headers/meta.hpp/meta_all.hpp | 10 + headers/meta.hpp/meta_binds.hpp | 181 ++++++++++++++++-- headers/meta.hpp/meta_binds/array_bind.hpp | 27 +++ headers/meta.hpp/meta_binds/class_bind.hpp | 2 +- headers/meta.hpp/meta_binds/enum_bind.hpp | 2 +- headers/meta.hpp/meta_binds/function_bind.hpp | 27 +++ headers/meta.hpp/meta_binds/member_bind.hpp | 27 +++ headers/meta.hpp/meta_binds/method_bind.hpp | 27 +++ headers/meta.hpp/meta_binds/nullptr_bind.hpp | 27 +++ headers/meta.hpp/meta_binds/number_bind.hpp | 27 +++ headers/meta.hpp/meta_binds/pointer_bind.hpp | 27 +++ .../meta.hpp/meta_binds/reference_bind.hpp | 27 +++ headers/meta.hpp/meta_binds/void_bind.hpp | 27 +++ untests/meta_states/metadata_tests.cpp | 86 +++++++++ 14 files changed, 506 insertions(+), 18 deletions(-) create mode 100644 headers/meta.hpp/meta_binds/array_bind.hpp create mode 100644 headers/meta.hpp/meta_binds/function_bind.hpp create mode 100644 headers/meta.hpp/meta_binds/member_bind.hpp create mode 100644 headers/meta.hpp/meta_binds/method_bind.hpp create mode 100644 headers/meta.hpp/meta_binds/nullptr_bind.hpp create mode 100644 headers/meta.hpp/meta_binds/number_bind.hpp create mode 100644 headers/meta.hpp/meta_binds/pointer_bind.hpp create mode 100644 headers/meta.hpp/meta_binds/reference_bind.hpp create mode 100644 headers/meta.hpp/meta_binds/void_bind.hpp diff --git a/headers/meta.hpp/meta_all.hpp b/headers/meta.hpp/meta_all.hpp index 6751447..67bf982 100644 --- a/headers/meta.hpp/meta_all.hpp +++ b/headers/meta.hpp/meta_all.hpp @@ -9,9 +9,19 @@ #include "meta_base.hpp" #include "meta_binds.hpp" + +#include "meta_binds/array_bind.hpp" #include "meta_binds/class_bind.hpp" #include "meta_binds/enum_bind.hpp" +#include "meta_binds/function_bind.hpp" +#include "meta_binds/member_bind.hpp" +#include "meta_binds/method_bind.hpp" +#include "meta_binds/nullptr_bind.hpp" +#include "meta_binds/number_bind.hpp" +#include "meta_binds/pointer_bind.hpp" +#include "meta_binds/reference_bind.hpp" #include "meta_binds/scope_bind.hpp" +#include "meta_binds/void_bind.hpp" #include "meta_indices.hpp" #include "meta_indices/argument_index.hpp" diff --git a/headers/meta.hpp/meta_binds.hpp b/headers/meta.hpp/meta_binds.hpp index d3aa25f..1ccebba 100644 --- a/headers/meta.hpp/meta_binds.hpp +++ b/headers/meta.hpp/meta_binds.hpp @@ -39,21 +39,10 @@ namespace meta_hpp::detail namespace meta_hpp { - struct class_opts final { + struct type_opts final { metadata_map metadata{}; }; - struct enum_opts final { - metadata_map metadata{}; - }; - - struct scope_opts final { - metadata_map metadata{}; - }; -} - -namespace meta_hpp -{ struct argument_opts final { std::string name{}; metadata_map metadata{}; @@ -86,17 +75,33 @@ namespace meta_hpp metadata_map metadata{}; }; + struct scope_opts final { + metadata_map metadata{}; + }; + struct variable_opts final { metadata_map metadata{}; }; } +namespace meta_hpp +{ + template < detail::array_kind Array > + class array_bind final { + public: + explicit array_bind(type_opts opts); + operator array_type() const noexcept; + private: + detail::array_type_data_ptr data_; + }; +} + namespace meta_hpp { template < detail::class_kind Class > class class_bind final { public: - explicit class_bind(class_opts opts); + explicit class_bind(type_opts opts); operator class_type() const noexcept; // constructor_ @@ -223,7 +228,7 @@ namespace meta_hpp template < detail::enum_kind Enum > class enum_bind final { public: - explicit enum_bind(enum_opts opts); + explicit enum_bind(type_opts opts); operator enum_type() const noexcept; enum_bind& evalue_(std::string name, Enum value); @@ -233,6 +238,102 @@ namespace meta_hpp }; } +namespace meta_hpp +{ + template < detail::function_kind Function > + class function_bind final { + public: + explicit function_bind(type_opts opts); + operator function_type() const noexcept; + private: + detail::function_type_data_ptr data_; + }; +} + +namespace meta_hpp +{ + template < detail::member_kind Member > + class member_bind final { + public: + explicit member_bind(type_opts opts); + operator member_type() const noexcept; + private: + detail::member_type_data_ptr data_; + }; +} + +namespace meta_hpp +{ + template < detail::method_kind Method > + class method_bind final { + public: + explicit method_bind(type_opts opts); + operator method_type() const noexcept; + private: + detail::method_type_data_ptr data_; + }; +} + +namespace meta_hpp +{ + template < detail::nullptr_kind Nullptr > + class nullptr_bind final { + public: + explicit nullptr_bind(type_opts opts); + operator nullptr_type() const noexcept; + private: + detail::nullptr_type_data_ptr data_; + }; +} + +namespace meta_hpp +{ + template < detail::number_kind Number > + class number_bind final { + public: + explicit number_bind(type_opts opts); + operator number_type() const noexcept; + private: + detail::number_type_data_ptr data_; + }; +} + +namespace meta_hpp +{ + template < detail::pointer_kind Pointer > + class pointer_bind final { + public: + explicit pointer_bind(type_opts opts); + operator pointer_type() const noexcept; + private: + detail::pointer_type_data_ptr data_; + }; +} + +namespace meta_hpp +{ + template < detail::reference_kind Reference > + class reference_bind final { + public: + explicit reference_bind(type_opts opts); + operator reference_type() const noexcept; + private: + detail::reference_type_data_ptr data_; + }; +} + +namespace meta_hpp +{ + template < detail::void_kind Void > + class void_bind final { + public: + explicit void_bind(type_opts opts); + operator void_type() const noexcept; + private: + detail::void_type_data_ptr data_; + }; +} + namespace meta_hpp { class scope_bind final { @@ -298,16 +399,64 @@ namespace meta_hpp namespace meta_hpp { + template < detail::array_kind Array > + array_bind array_(type_opts opts = {}) { + return array_bind{std::move(opts)}; + } + template < detail::class_kind Class > - class_bind class_(class_opts opts = {}) { + class_bind class_(type_opts opts = {}) { return class_bind{std::move(opts)}; } template < detail::enum_kind Enum > - enum_bind enum_(enum_opts opts = {}) { + enum_bind enum_(type_opts opts = {}) { return enum_bind{std::move(opts)}; } + template < detail::function_kind Function > + function_bind function_(type_opts opts = {}) { + return function_bind{std::move(opts)}; + } + + template < detail::member_kind Member > + member_bind member_(type_opts opts = {}) { + return member_bind{std::move(opts)}; + } + + template < detail::method_kind Method > + method_bind method_(type_opts opts = {}) { + return method_bind{std::move(opts)}; + } + + template < detail::nullptr_kind Nullptr > + nullptr_bind nullptr_(type_opts opts = {}) { + return nullptr_bind{std::move(opts)}; + } + + template < detail::number_kind Number > + number_bind number_(type_opts opts = {}) { + return number_bind{std::move(opts)}; + } + + template < detail::pointer_kind Pointer > + pointer_bind pointer_(type_opts opts = {}) { + return pointer_bind{std::move(opts)}; + } + + template < detail::reference_kind Reference > + reference_bind reference_(type_opts opts = {}) { + return reference_bind{std::move(opts)}; + } + + template < detail::void_kind Void > + void_bind void_(type_opts opts = {}) { + return void_bind{std::move(opts)}; + } +} + +namespace meta_hpp +{ inline scope_bind local_scope_(std::string name, scope_opts opts = {}) { return scope_bind{std::move(name), std::move(opts), scope_bind::local_tag()}; } diff --git a/headers/meta.hpp/meta_binds/array_bind.hpp b/headers/meta.hpp/meta_binds/array_bind.hpp new file mode 100644 index 0000000..d7277e9 --- /dev/null +++ b/headers/meta.hpp/meta_binds/array_bind.hpp @@ -0,0 +1,27 @@ +/******************************************************************************* + * 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-2022, by Matvey Cherevko (blackmatov@gmail.com) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_binds.hpp" + +#include "../meta_detail/type_registry.hpp" + +namespace meta_hpp +{ + template < detail::array_kind Array > + array_bind::array_bind(type_opts opts) + : data_{detail::type_access(detail::resolve_type())} { + data_->metadata.swap(opts.metadata); + data_->metadata.merge(opts.metadata); + } + + template < detail::array_kind Array > + array_bind::operator array_type() const noexcept { + return array_type{data_}; + } +} diff --git a/headers/meta.hpp/meta_binds/class_bind.hpp b/headers/meta.hpp/meta_binds/class_bind.hpp index 034fd61..9038360 100644 --- a/headers/meta.hpp/meta_binds/class_bind.hpp +++ b/headers/meta.hpp/meta_binds/class_bind.hpp @@ -14,7 +14,7 @@ namespace meta_hpp { template < detail::class_kind Class > - class_bind::class_bind(class_opts opts) + class_bind::class_bind(type_opts opts) : data_{detail::type_access(detail::resolve_type())} { data_->metadata.swap(opts.metadata); data_->metadata.merge(opts.metadata); diff --git a/headers/meta.hpp/meta_binds/enum_bind.hpp b/headers/meta.hpp/meta_binds/enum_bind.hpp index 5c347b3..5c19926 100644 --- a/headers/meta.hpp/meta_binds/enum_bind.hpp +++ b/headers/meta.hpp/meta_binds/enum_bind.hpp @@ -14,7 +14,7 @@ namespace meta_hpp { template < detail::enum_kind Enum > - enum_bind::enum_bind(enum_opts opts) + enum_bind::enum_bind(type_opts opts) : data_{detail::type_access(detail::resolve_type())} { data_->metadata.swap(opts.metadata); data_->metadata.merge(opts.metadata); diff --git a/headers/meta.hpp/meta_binds/function_bind.hpp b/headers/meta.hpp/meta_binds/function_bind.hpp new file mode 100644 index 0000000..45424f1 --- /dev/null +++ b/headers/meta.hpp/meta_binds/function_bind.hpp @@ -0,0 +1,27 @@ +/******************************************************************************* + * 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-2022, by Matvey Cherevko (blackmatov@gmail.com) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_binds.hpp" + +#include "../meta_detail/type_registry.hpp" + +namespace meta_hpp +{ + template < detail::function_kind Function > + function_bind::function_bind(type_opts opts) + : data_{detail::type_access(detail::resolve_type())} { + data_->metadata.swap(opts.metadata); + data_->metadata.merge(opts.metadata); + } + + template < detail::function_kind Function > + function_bind::operator function_type() const noexcept { + return function_type{data_}; + } +} diff --git a/headers/meta.hpp/meta_binds/member_bind.hpp b/headers/meta.hpp/meta_binds/member_bind.hpp new file mode 100644 index 0000000..c1636ec --- /dev/null +++ b/headers/meta.hpp/meta_binds/member_bind.hpp @@ -0,0 +1,27 @@ +/******************************************************************************* + * 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-2022, by Matvey Cherevko (blackmatov@gmail.com) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_binds.hpp" + +#include "../meta_detail/type_registry.hpp" + +namespace meta_hpp +{ + template < detail::member_kind Member > + member_bind::member_bind(type_opts opts) + : data_{detail::type_access(detail::resolve_type())} { + data_->metadata.swap(opts.metadata); + data_->metadata.merge(opts.metadata); + } + + template < detail::member_kind Member > + member_bind::operator member_type() const noexcept { + return member_type{data_}; + } +} diff --git a/headers/meta.hpp/meta_binds/method_bind.hpp b/headers/meta.hpp/meta_binds/method_bind.hpp new file mode 100644 index 0000000..b860973 --- /dev/null +++ b/headers/meta.hpp/meta_binds/method_bind.hpp @@ -0,0 +1,27 @@ +/******************************************************************************* + * 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-2022, by Matvey Cherevko (blackmatov@gmail.com) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_binds.hpp" + +#include "../meta_detail/type_registry.hpp" + +namespace meta_hpp +{ + template < detail::method_kind Method > + method_bind::method_bind(type_opts opts) + : data_{detail::type_access(detail::resolve_type())} { + data_->metadata.swap(opts.metadata); + data_->metadata.merge(opts.metadata); + } + + template < detail::method_kind Method > + method_bind::operator method_type() const noexcept { + return method_type{data_}; + } +} diff --git a/headers/meta.hpp/meta_binds/nullptr_bind.hpp b/headers/meta.hpp/meta_binds/nullptr_bind.hpp new file mode 100644 index 0000000..daa79e9 --- /dev/null +++ b/headers/meta.hpp/meta_binds/nullptr_bind.hpp @@ -0,0 +1,27 @@ +/******************************************************************************* + * 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-2022, by Matvey Cherevko (blackmatov@gmail.com) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_binds.hpp" + +#include "../meta_detail/type_registry.hpp" + +namespace meta_hpp +{ + template < detail::nullptr_kind Nullptr > + nullptr_bind::nullptr_bind(type_opts opts) + : data_{detail::type_access(detail::resolve_type())} { + data_->metadata.swap(opts.metadata); + data_->metadata.merge(opts.metadata); + } + + template < detail::nullptr_kind Nullptr > + nullptr_bind::operator nullptr_type() const noexcept { + return nullptr_type{data_}; + } +} diff --git a/headers/meta.hpp/meta_binds/number_bind.hpp b/headers/meta.hpp/meta_binds/number_bind.hpp new file mode 100644 index 0000000..3a0c83f --- /dev/null +++ b/headers/meta.hpp/meta_binds/number_bind.hpp @@ -0,0 +1,27 @@ +/******************************************************************************* + * 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-2022, by Matvey Cherevko (blackmatov@gmail.com) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_binds.hpp" + +#include "../meta_detail/type_registry.hpp" + +namespace meta_hpp +{ + template < detail::number_kind Number > + number_bind::number_bind(type_opts opts) + : data_{detail::type_access(detail::resolve_type())} { + data_->metadata.swap(opts.metadata); + data_->metadata.merge(opts.metadata); + } + + template < detail::number_kind Number > + number_bind::operator number_type() const noexcept { + return number_type{data_}; + } +} diff --git a/headers/meta.hpp/meta_binds/pointer_bind.hpp b/headers/meta.hpp/meta_binds/pointer_bind.hpp new file mode 100644 index 0000000..bef44f3 --- /dev/null +++ b/headers/meta.hpp/meta_binds/pointer_bind.hpp @@ -0,0 +1,27 @@ +/******************************************************************************* + * 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-2022, by Matvey Cherevko (blackmatov@gmail.com) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_binds.hpp" + +#include "../meta_detail/type_registry.hpp" + +namespace meta_hpp +{ + template < detail::pointer_kind Pointer > + pointer_bind::pointer_bind(type_opts opts) + : data_{detail::type_access(detail::resolve_type())} { + data_->metadata.swap(opts.metadata); + data_->metadata.merge(opts.metadata); + } + + template < detail::pointer_kind Pointer > + pointer_bind::operator pointer_type() const noexcept { + return pointer_type{data_}; + } +} diff --git a/headers/meta.hpp/meta_binds/reference_bind.hpp b/headers/meta.hpp/meta_binds/reference_bind.hpp new file mode 100644 index 0000000..9511984 --- /dev/null +++ b/headers/meta.hpp/meta_binds/reference_bind.hpp @@ -0,0 +1,27 @@ +/******************************************************************************* + * 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-2022, by Matvey Cherevko (blackmatov@gmail.com) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_binds.hpp" + +#include "../meta_detail/type_registry.hpp" + +namespace meta_hpp +{ + template < detail::reference_kind Reference > + reference_bind::reference_bind(type_opts opts) + : data_{detail::type_access(detail::resolve_type())} { + data_->metadata.swap(opts.metadata); + data_->metadata.merge(opts.metadata); + } + + template < detail::reference_kind Reference > + reference_bind::operator reference_type() const noexcept { + return reference_type{data_}; + } +} diff --git a/headers/meta.hpp/meta_binds/void_bind.hpp b/headers/meta.hpp/meta_binds/void_bind.hpp new file mode 100644 index 0000000..17c7497 --- /dev/null +++ b/headers/meta.hpp/meta_binds/void_bind.hpp @@ -0,0 +1,27 @@ +/******************************************************************************* + * 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-2022, by Matvey Cherevko (blackmatov@gmail.com) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" +#include "../meta_binds.hpp" + +#include "../meta_detail/type_registry.hpp" + +namespace meta_hpp +{ + template < detail::void_kind Void > + void_bind::void_bind(type_opts opts) + : data_{detail::type_access(detail::resolve_type())} { + data_->metadata.swap(opts.metadata); + data_->metadata.merge(opts.metadata); + } + + template < detail::void_kind Void > + void_bind::operator void_type() const noexcept { + return void_type{data_}; + } +} diff --git a/untests/meta_states/metadata_tests.cpp b/untests/meta_states/metadata_tests.cpp index 07794b0..9a8720a 100644 --- a/untests/meta_states/metadata_tests.cpp +++ b/untests/meta_states/metadata_tests.cpp @@ -244,3 +244,89 @@ TEST_CASE("meta/meta_states/metadata/class") { CHECK(ivec2_iadd.get_argument(1).get_metadata().at("desc") == "r-arg"s); } } + +TEST_CASE("meta/meta_states/metadata/other") { + namespace meta = meta_hpp; + using namespace std::string_literals; + + SUBCASE("array") { + meta::array_({ + .metadata{ + {"desc", meta::uvalue{"int[]-type"s}} + } + }); + CHECK(meta::resolve_type().get_metadata().at("desc") == "int[]-type"s); + } + + SUBCASE("function") { + meta::function_({ + .metadata{ + {"desc", meta::uvalue{"int->int"s}} + } + }); + CHECK(meta::resolve_type().get_metadata().at("desc") == "int->int"s); + } + + SUBCASE("member") { + meta::member_({ + .metadata{ + {"desc", meta::uvalue{"ivec2::int"s}} + } + }); + CHECK(meta::resolve_type().get_metadata().at("desc") == "ivec2::int"s); + } + + SUBCASE("method") { + meta::method_({ + .metadata{ + {"desc", meta::uvalue{"ivec2(int -> int)"s}} + } + }); + CHECK(meta::resolve_type().get_metadata().at("desc") == "ivec2(int -> int)"s); + } + + SUBCASE("nullptr") { + meta::nullptr_({ + .metadata{ + {"desc", meta::uvalue{"nullptr_t"s}} + } + }); + CHECK(meta::resolve_type().get_metadata().at("desc") == "nullptr_t"s); + } + + SUBCASE("number") { + meta::number_({ + .metadata{ + {"desc", meta::uvalue{"int-type"s}} + } + }); + CHECK(meta::resolve_type().get_metadata().at("desc") == "int-type"s); + } + + SUBCASE("pointer") { + meta::pointer_({ + .metadata{ + {"desc", meta::uvalue{"int*-type"s}} + } + }); + CHECK(meta::resolve_type().get_metadata().at("desc") == "int*-type"s); + } + + SUBCASE("reference") { + meta::reference_({ + .metadata{ + {"desc", meta::uvalue{"int&-type"s}} + } + }); + CHECK(meta::resolve_type().get_metadata().at("desc") == "int&-type"s); + } + + SUBCASE("void") { + meta::void_({ + .metadata{ + {"desc", meta::uvalue{"void-type"s}} + } + }); + CHECK(meta::resolve_type().get_metadata().at("desc") == "void-type"s); + } +} From 360a68eb5d84b99009fa46ef2df9510ff3c57623 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sat, 12 Feb 2022 08:55:14 +0700 Subject: [PATCH 226/233] fix clang CI warnings --- untests/meta_states/metadata_tests.cpp | 4 ++-- untests/meta_utilities/arg6_tests.cpp | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/untests/meta_states/metadata_tests.cpp b/untests/meta_states/metadata_tests.cpp index 9a8720a..04e59eb 100644 --- a/untests/meta_states/metadata_tests.cpp +++ b/untests/meta_states/metadata_tests.cpp @@ -286,12 +286,12 @@ TEST_CASE("meta/meta_states/metadata/other") { } SUBCASE("nullptr") { - meta::nullptr_({ + meta::nullptr_({ .metadata{ {"desc", meta::uvalue{"nullptr_t"s}} } }); - CHECK(meta::resolve_type().get_metadata().at("desc") == "nullptr_t"s); + CHECK(meta::resolve_type().get_metadata().at("desc") == "nullptr_t"s); } SUBCASE("number") { diff --git a/untests/meta_utilities/arg6_tests.cpp b/untests/meta_utilities/arg6_tests.cpp index 5b32f2e..65dba9e 100644 --- a/untests/meta_utilities/arg6_tests.cpp +++ b/untests/meta_utilities/arg6_tests.cpp @@ -9,6 +9,8 @@ namespace { struct base { + base() = default; + base(const base&) = default; virtual ~base() = default; virtual int int_method() const = 0; }; From 4bde9daa09de2360ced776cad91a5bbfc6e329f6 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sun, 13 Feb 2022 03:54:47 +0700 Subject: [PATCH 227/233] top binds without type_opts --- TODO.md | 2 + headers/meta.hpp/meta_binds.hpp | 86 +++++++++---------- headers/meta.hpp/meta_binds/array_bind.hpp | 6 +- headers/meta.hpp/meta_binds/class_bind.hpp | 6 +- headers/meta.hpp/meta_binds/enum_bind.hpp | 6 +- headers/meta.hpp/meta_binds/function_bind.hpp | 6 +- headers/meta.hpp/meta_binds/member_bind.hpp | 6 +- headers/meta.hpp/meta_binds/method_bind.hpp | 6 +- headers/meta.hpp/meta_binds/nullptr_bind.hpp | 6 +- headers/meta.hpp/meta_binds/number_bind.hpp | 6 +- headers/meta.hpp/meta_binds/pointer_bind.hpp | 6 +- .../meta.hpp/meta_binds/reference_bind.hpp | 6 +- headers/meta.hpp/meta_binds/scope_bind.hpp | 10 +-- headers/meta.hpp/meta_binds/void_bind.hpp | 6 +- untests/meta_states/metadata_tests.cpp | 79 ++++++++--------- 15 files changed, 115 insertions(+), 128 deletions(-) diff --git a/TODO.md b/TODO.md index 75a811d..e792242 100644 --- a/TODO.md +++ b/TODO.md @@ -13,3 +13,5 @@ - (?) move-only value type support - (?) type names - (?) properties + +(???) Why does local scope have a name? diff --git a/headers/meta.hpp/meta_binds.hpp b/headers/meta.hpp/meta_binds.hpp index 1ccebba..0ad21b2 100644 --- a/headers/meta.hpp/meta_binds.hpp +++ b/headers/meta.hpp/meta_binds.hpp @@ -39,10 +39,6 @@ namespace meta_hpp::detail namespace meta_hpp { - struct type_opts final { - metadata_map metadata{}; - }; - struct argument_opts final { std::string name{}; metadata_map metadata{}; @@ -75,10 +71,6 @@ namespace meta_hpp metadata_map metadata{}; }; - struct scope_opts final { - metadata_map metadata{}; - }; - struct variable_opts final { metadata_map metadata{}; }; @@ -89,7 +81,7 @@ namespace meta_hpp template < detail::array_kind Array > class array_bind final { public: - explicit array_bind(type_opts opts); + explicit array_bind(metadata_map metadata); operator array_type() const noexcept; private: detail::array_type_data_ptr data_; @@ -101,7 +93,7 @@ namespace meta_hpp template < detail::class_kind Class > class class_bind final { public: - explicit class_bind(type_opts opts); + explicit class_bind(metadata_map metadata); operator class_type() const noexcept; // constructor_ @@ -228,7 +220,7 @@ namespace meta_hpp template < detail::enum_kind Enum > class enum_bind final { public: - explicit enum_bind(type_opts opts); + explicit enum_bind(metadata_map metadata); operator enum_type() const noexcept; enum_bind& evalue_(std::string name, Enum value); @@ -243,7 +235,7 @@ namespace meta_hpp template < detail::function_kind Function > class function_bind final { public: - explicit function_bind(type_opts opts); + explicit function_bind(metadata_map metadata); operator function_type() const noexcept; private: detail::function_type_data_ptr data_; @@ -255,7 +247,7 @@ namespace meta_hpp template < detail::member_kind Member > class member_bind final { public: - explicit member_bind(type_opts opts); + explicit member_bind(metadata_map metadata); operator member_type() const noexcept; private: detail::member_type_data_ptr data_; @@ -267,7 +259,7 @@ namespace meta_hpp template < detail::method_kind Method > class method_bind final { public: - explicit method_bind(type_opts opts); + explicit method_bind(metadata_map metadata); operator method_type() const noexcept; private: detail::method_type_data_ptr data_; @@ -279,7 +271,7 @@ namespace meta_hpp template < detail::nullptr_kind Nullptr > class nullptr_bind final { public: - explicit nullptr_bind(type_opts opts); + explicit nullptr_bind(metadata_map metadata); operator nullptr_type() const noexcept; private: detail::nullptr_type_data_ptr data_; @@ -291,7 +283,7 @@ namespace meta_hpp template < detail::number_kind Number > class number_bind final { public: - explicit number_bind(type_opts opts); + explicit number_bind(metadata_map metadata); operator number_type() const noexcept; private: detail::number_type_data_ptr data_; @@ -303,7 +295,7 @@ namespace meta_hpp template < detail::pointer_kind Pointer > class pointer_bind final { public: - explicit pointer_bind(type_opts opts); + explicit pointer_bind(metadata_map metadata); operator pointer_type() const noexcept; private: detail::pointer_type_data_ptr data_; @@ -315,7 +307,7 @@ namespace meta_hpp template < detail::reference_kind Reference > class reference_bind final { public: - explicit reference_bind(type_opts opts); + explicit reference_bind(metadata_map metadata); operator reference_type() const noexcept; private: detail::reference_type_data_ptr data_; @@ -327,7 +319,7 @@ namespace meta_hpp template < detail::void_kind Void > class void_bind final { public: - explicit void_bind(type_opts opts); + explicit void_bind(metadata_map metadata); operator void_type() const noexcept; private: detail::void_type_data_ptr data_; @@ -341,8 +333,8 @@ namespace meta_hpp struct local_tag {}; struct static_tag {}; - explicit scope_bind(std::string name, scope_opts opts, local_tag); - explicit scope_bind(std::string_view name, scope_opts opts, static_tag); + explicit scope_bind(std::string name, metadata_map metadata, local_tag); + explicit scope_bind(std::string_view name, metadata_map metadata, static_tag); operator scope() const noexcept; template < detail::class_kind Class > @@ -400,68 +392,68 @@ namespace meta_hpp namespace meta_hpp { template < detail::array_kind Array > - array_bind array_(type_opts opts = {}) { - return array_bind{std::move(opts)}; + array_bind array_(metadata_map metadata = {}) { + return array_bind{std::move(metadata)}; } template < detail::class_kind Class > - class_bind class_(type_opts opts = {}) { - return class_bind{std::move(opts)}; + class_bind class_(metadata_map metadata = {}) { + return class_bind{std::move(metadata)}; } template < detail::enum_kind Enum > - enum_bind enum_(type_opts opts = {}) { - return enum_bind{std::move(opts)}; + enum_bind enum_(metadata_map metadata = {}) { + return enum_bind{std::move(metadata)}; } template < detail::function_kind Function > - function_bind function_(type_opts opts = {}) { - return function_bind{std::move(opts)}; + function_bind function_(metadata_map metadata = {}) { + return function_bind{std::move(metadata)}; } template < detail::member_kind Member > - member_bind member_(type_opts opts = {}) { - return member_bind{std::move(opts)}; + member_bind member_(metadata_map metadata = {}) { + return member_bind{std::move(metadata)}; } template < detail::method_kind Method > - method_bind method_(type_opts opts = {}) { - return method_bind{std::move(opts)}; + method_bind method_(metadata_map metadata = {}) { + return method_bind{std::move(metadata)}; } template < detail::nullptr_kind Nullptr > - nullptr_bind nullptr_(type_opts opts = {}) { - return nullptr_bind{std::move(opts)}; + nullptr_bind nullptr_(metadata_map metadata = {}) { + return nullptr_bind{std::move(metadata)}; } template < detail::number_kind Number > - number_bind number_(type_opts opts = {}) { - return number_bind{std::move(opts)}; + number_bind number_(metadata_map metadata = {}) { + return number_bind{std::move(metadata)}; } template < detail::pointer_kind Pointer > - pointer_bind pointer_(type_opts opts = {}) { - return pointer_bind{std::move(opts)}; + pointer_bind pointer_(metadata_map metadata = {}) { + return pointer_bind{std::move(metadata)}; } template < detail::reference_kind Reference > - reference_bind reference_(type_opts opts = {}) { - return reference_bind{std::move(opts)}; + reference_bind reference_(metadata_map metadata = {}) { + return reference_bind{std::move(metadata)}; } template < detail::void_kind Void > - void_bind void_(type_opts opts = {}) { - return void_bind{std::move(opts)}; + void_bind void_(metadata_map metadata = {}) { + return void_bind{std::move(metadata)}; } } namespace meta_hpp { - inline scope_bind local_scope_(std::string name, scope_opts opts = {}) { - return scope_bind{std::move(name), std::move(opts), scope_bind::local_tag()}; + inline scope_bind local_scope_(std::string name, metadata_map metadata = {}) { + return scope_bind{std::move(name), std::move(metadata), scope_bind::local_tag()}; } - inline scope_bind static_scope_(std::string_view name, scope_opts opts = {}) { - return scope_bind{name, std::move(opts), scope_bind::static_tag()}; + inline scope_bind static_scope_(std::string_view name, metadata_map metadata = {}) { + return scope_bind{name, std::move(metadata), scope_bind::static_tag()}; } } diff --git a/headers/meta.hpp/meta_binds/array_bind.hpp b/headers/meta.hpp/meta_binds/array_bind.hpp index d7277e9..1985278 100644 --- a/headers/meta.hpp/meta_binds/array_bind.hpp +++ b/headers/meta.hpp/meta_binds/array_bind.hpp @@ -14,10 +14,10 @@ namespace meta_hpp { template < detail::array_kind Array > - array_bind::array_bind(type_opts opts) + array_bind::array_bind(metadata_map metadata) : data_{detail::type_access(detail::resolve_type())} { - data_->metadata.swap(opts.metadata); - data_->metadata.merge(opts.metadata); + data_->metadata.swap(metadata); + data_->metadata.merge(metadata); } template < detail::array_kind Array > diff --git a/headers/meta.hpp/meta_binds/class_bind.hpp b/headers/meta.hpp/meta_binds/class_bind.hpp index 9038360..6a7b37a 100644 --- a/headers/meta.hpp/meta_binds/class_bind.hpp +++ b/headers/meta.hpp/meta_binds/class_bind.hpp @@ -14,10 +14,10 @@ namespace meta_hpp { template < detail::class_kind Class > - class_bind::class_bind(type_opts opts) + class_bind::class_bind(metadata_map metadata) : data_{detail::type_access(detail::resolve_type())} { - data_->metadata.swap(opts.metadata); - data_->metadata.merge(opts.metadata); + data_->metadata.swap(metadata); + data_->metadata.merge(metadata); } template < detail::class_kind Class > diff --git a/headers/meta.hpp/meta_binds/enum_bind.hpp b/headers/meta.hpp/meta_binds/enum_bind.hpp index 5c19926..d44512b 100644 --- a/headers/meta.hpp/meta_binds/enum_bind.hpp +++ b/headers/meta.hpp/meta_binds/enum_bind.hpp @@ -14,10 +14,10 @@ namespace meta_hpp { template < detail::enum_kind Enum > - enum_bind::enum_bind(type_opts opts) + enum_bind::enum_bind(metadata_map metadata) : data_{detail::type_access(detail::resolve_type())} { - data_->metadata.swap(opts.metadata); - data_->metadata.merge(opts.metadata); + data_->metadata.swap(metadata); + data_->metadata.merge(metadata); } template < detail::enum_kind Enum > diff --git a/headers/meta.hpp/meta_binds/function_bind.hpp b/headers/meta.hpp/meta_binds/function_bind.hpp index 45424f1..0c1634e 100644 --- a/headers/meta.hpp/meta_binds/function_bind.hpp +++ b/headers/meta.hpp/meta_binds/function_bind.hpp @@ -14,10 +14,10 @@ namespace meta_hpp { template < detail::function_kind Function > - function_bind::function_bind(type_opts opts) + function_bind::function_bind(metadata_map metadata) : data_{detail::type_access(detail::resolve_type())} { - data_->metadata.swap(opts.metadata); - data_->metadata.merge(opts.metadata); + data_->metadata.swap(metadata); + data_->metadata.merge(metadata); } template < detail::function_kind Function > diff --git a/headers/meta.hpp/meta_binds/member_bind.hpp b/headers/meta.hpp/meta_binds/member_bind.hpp index c1636ec..4bd30d5 100644 --- a/headers/meta.hpp/meta_binds/member_bind.hpp +++ b/headers/meta.hpp/meta_binds/member_bind.hpp @@ -14,10 +14,10 @@ namespace meta_hpp { template < detail::member_kind Member > - member_bind::member_bind(type_opts opts) + member_bind::member_bind(metadata_map metadata) : data_{detail::type_access(detail::resolve_type())} { - data_->metadata.swap(opts.metadata); - data_->metadata.merge(opts.metadata); + data_->metadata.swap(metadata); + data_->metadata.merge(metadata); } template < detail::member_kind Member > diff --git a/headers/meta.hpp/meta_binds/method_bind.hpp b/headers/meta.hpp/meta_binds/method_bind.hpp index b860973..05651d1 100644 --- a/headers/meta.hpp/meta_binds/method_bind.hpp +++ b/headers/meta.hpp/meta_binds/method_bind.hpp @@ -14,10 +14,10 @@ namespace meta_hpp { template < detail::method_kind Method > - method_bind::method_bind(type_opts opts) + method_bind::method_bind(metadata_map metadata) : data_{detail::type_access(detail::resolve_type())} { - data_->metadata.swap(opts.metadata); - data_->metadata.merge(opts.metadata); + data_->metadata.swap(metadata); + data_->metadata.merge(metadata); } template < detail::method_kind Method > diff --git a/headers/meta.hpp/meta_binds/nullptr_bind.hpp b/headers/meta.hpp/meta_binds/nullptr_bind.hpp index daa79e9..4b53d3e 100644 --- a/headers/meta.hpp/meta_binds/nullptr_bind.hpp +++ b/headers/meta.hpp/meta_binds/nullptr_bind.hpp @@ -14,10 +14,10 @@ namespace meta_hpp { template < detail::nullptr_kind Nullptr > - nullptr_bind::nullptr_bind(type_opts opts) + nullptr_bind::nullptr_bind(metadata_map metadata) : data_{detail::type_access(detail::resolve_type())} { - data_->metadata.swap(opts.metadata); - data_->metadata.merge(opts.metadata); + data_->metadata.swap(metadata); + data_->metadata.merge(metadata); } template < detail::nullptr_kind Nullptr > diff --git a/headers/meta.hpp/meta_binds/number_bind.hpp b/headers/meta.hpp/meta_binds/number_bind.hpp index 3a0c83f..fff3f19 100644 --- a/headers/meta.hpp/meta_binds/number_bind.hpp +++ b/headers/meta.hpp/meta_binds/number_bind.hpp @@ -14,10 +14,10 @@ namespace meta_hpp { template < detail::number_kind Number > - number_bind::number_bind(type_opts opts) + number_bind::number_bind(metadata_map metadata) : data_{detail::type_access(detail::resolve_type())} { - data_->metadata.swap(opts.metadata); - data_->metadata.merge(opts.metadata); + data_->metadata.swap(metadata); + data_->metadata.merge(metadata); } template < detail::number_kind Number > diff --git a/headers/meta.hpp/meta_binds/pointer_bind.hpp b/headers/meta.hpp/meta_binds/pointer_bind.hpp index bef44f3..1be0b01 100644 --- a/headers/meta.hpp/meta_binds/pointer_bind.hpp +++ b/headers/meta.hpp/meta_binds/pointer_bind.hpp @@ -14,10 +14,10 @@ namespace meta_hpp { template < detail::pointer_kind Pointer > - pointer_bind::pointer_bind(type_opts opts) + pointer_bind::pointer_bind(metadata_map metadata) : data_{detail::type_access(detail::resolve_type())} { - data_->metadata.swap(opts.metadata); - data_->metadata.merge(opts.metadata); + data_->metadata.swap(metadata); + data_->metadata.merge(metadata); } template < detail::pointer_kind Pointer > diff --git a/headers/meta.hpp/meta_binds/reference_bind.hpp b/headers/meta.hpp/meta_binds/reference_bind.hpp index 9511984..1ed1235 100644 --- a/headers/meta.hpp/meta_binds/reference_bind.hpp +++ b/headers/meta.hpp/meta_binds/reference_bind.hpp @@ -14,10 +14,10 @@ namespace meta_hpp { template < detail::reference_kind Reference > - reference_bind::reference_bind(type_opts opts) + reference_bind::reference_bind(metadata_map metadata) : data_{detail::type_access(detail::resolve_type())} { - data_->metadata.swap(opts.metadata); - data_->metadata.merge(opts.metadata); + data_->metadata.swap(metadata); + data_->metadata.merge(metadata); } template < detail::reference_kind Reference > diff --git a/headers/meta.hpp/meta_binds/scope_bind.hpp b/headers/meta.hpp/meta_binds/scope_bind.hpp index 5ed613d..4f25d51 100644 --- a/headers/meta.hpp/meta_binds/scope_bind.hpp +++ b/headers/meta.hpp/meta_binds/scope_bind.hpp @@ -15,14 +15,14 @@ namespace meta_hpp { // NOLINTNEXTLINE(readability-named-parameter) - inline scope_bind::scope_bind(std::string name, scope_opts opts, local_tag) - : state_{detail::scope_state::make(std::move(name), std::move(opts.metadata))} {} + inline scope_bind::scope_bind(std::string name, metadata_map metadata, local_tag) + : state_{detail::scope_state::make(std::move(name), std::move(metadata))} {} // NOLINTNEXTLINE(readability-named-parameter) - inline scope_bind::scope_bind(std::string_view name, scope_opts opts, static_tag) + inline scope_bind::scope_bind(std::string_view name, metadata_map metadata, static_tag) : state_{detail::state_access(detail::resolve_scope(name))} { - state_->metadata.swap(opts.metadata); - state_->metadata.merge(opts.metadata); + state_->metadata.swap(metadata); + state_->metadata.merge(metadata); } inline scope_bind::operator scope() const noexcept { diff --git a/headers/meta.hpp/meta_binds/void_bind.hpp b/headers/meta.hpp/meta_binds/void_bind.hpp index 17c7497..62fddb4 100644 --- a/headers/meta.hpp/meta_binds/void_bind.hpp +++ b/headers/meta.hpp/meta_binds/void_bind.hpp @@ -14,10 +14,10 @@ namespace meta_hpp { template < detail::void_kind Void > - void_bind::void_bind(type_opts opts) + void_bind::void_bind(metadata_map metadata) : data_{detail::type_access(detail::resolve_type())} { - data_->metadata.swap(opts.metadata); - data_->metadata.merge(opts.metadata); + data_->metadata.swap(metadata); + data_->metadata.merge(metadata); } template < detail::void_kind Void > diff --git a/untests/meta_states/metadata_tests.cpp b/untests/meta_states/metadata_tests.cpp index 04e59eb..34c55d8 100644 --- a/untests/meta_states/metadata_tests.cpp +++ b/untests/meta_states/metadata_tests.cpp @@ -38,10 +38,8 @@ TEST_CASE("meta/meta_states/metadata/enum") { using namespace std::string_literals; meta::enum_({ - .metadata{ - {"desc1", meta::uvalue{"enum-desc1"s}}, - {"desc2", meta::uvalue{"enum-desc2"s}}, - } + {"desc1", meta::uvalue{"enum-desc1"s}}, + {"desc2", meta::uvalue{"enum-desc2"s}}, }) .evalue_("red", color::red, { .metadata{{"desc1", meta::uvalue{"red-color"s}}} @@ -56,10 +54,8 @@ TEST_CASE("meta/meta_states/metadata/enum") { // metadata override meta::enum_({ - .metadata{ - {"desc2", meta::uvalue{"new-enum-desc2"s}}, - {"desc3", meta::uvalue{"new-enum-desc3"s}}, - } + {"desc2", meta::uvalue{"new-enum-desc2"s}}, + {"desc3", meta::uvalue{"new-enum-desc3"s}}, }); meta::enum_() @@ -93,10 +89,8 @@ TEST_CASE("meta/meta_states/metadata/class") { using namespace std::string_literals; meta::class_({ - .metadata{ - {"desc1", meta::uvalue{"class-desc1"s}}, - {"desc2", meta::uvalue{"class-desc2"s}}, - }, + {"desc1", meta::uvalue{"class-desc1"s}}, + {"desc2", meta::uvalue{"class-desc2"s}}, }) .constructor_({ .arguments{{ @@ -142,10 +136,8 @@ TEST_CASE("meta/meta_states/metadata/class") { // metadata override meta::class_({ - .metadata{ - {"desc2", meta::uvalue{"new-class-desc2"s}}, - {"desc3", meta::uvalue{"new-class-desc3"s}}, - } + {"desc2", meta::uvalue{"new-class-desc2"s}}, + {"desc3", meta::uvalue{"new-class-desc3"s}}, }); // @@ -245,87 +237,88 @@ TEST_CASE("meta/meta_states/metadata/class") { } } +TEST_CASE("meta/meta_states/metadata/scope") { + namespace meta = meta_hpp; + using namespace std::string_literals; + + SUBCASE("local_scope") { + const meta::scope lscope = meta::local_scope_("local-scope", { + {"desc", meta::uvalue{"scope-desc"s}} + }); + CHECK(lscope.get_metadata().at("desc") == "scope-desc"s); + } + + SUBCASE("static_scope") { + meta::static_scope_("meta/meta_states/metadata/scope/static-scope", { + {"desc", meta::uvalue{"scope-desc"s}} + }); + CHECK(meta::resolve_scope("meta/meta_states/metadata/scope/static-scope").get_metadata().at("desc") == "scope-desc"s); + } +} + TEST_CASE("meta/meta_states/metadata/other") { namespace meta = meta_hpp; using namespace std::string_literals; SUBCASE("array") { meta::array_({ - .metadata{ - {"desc", meta::uvalue{"int[]-type"s}} - } + {"desc", meta::uvalue{"int[]-type"s}} }); CHECK(meta::resolve_type().get_metadata().at("desc") == "int[]-type"s); } SUBCASE("function") { meta::function_({ - .metadata{ - {"desc", meta::uvalue{"int->int"s}} - } + {"desc", meta::uvalue{"int->int"s}} }); CHECK(meta::resolve_type().get_metadata().at("desc") == "int->int"s); } SUBCASE("member") { meta::member_({ - .metadata{ - {"desc", meta::uvalue{"ivec2::int"s}} - } + {"desc", meta::uvalue{"ivec2::int"s}} }); CHECK(meta::resolve_type().get_metadata().at("desc") == "ivec2::int"s); } SUBCASE("method") { meta::method_({ - .metadata{ - {"desc", meta::uvalue{"ivec2(int -> int)"s}} - } + {"desc", meta::uvalue{"ivec2(int -> int)"s}} }); CHECK(meta::resolve_type().get_metadata().at("desc") == "ivec2(int -> int)"s); } SUBCASE("nullptr") { meta::nullptr_({ - .metadata{ - {"desc", meta::uvalue{"nullptr_t"s}} - } + {"desc", meta::uvalue{"nullptr_t"s}} }); CHECK(meta::resolve_type().get_metadata().at("desc") == "nullptr_t"s); } SUBCASE("number") { meta::number_({ - .metadata{ - {"desc", meta::uvalue{"int-type"s}} - } + {"desc", meta::uvalue{"int-type"s}} }); CHECK(meta::resolve_type().get_metadata().at("desc") == "int-type"s); } SUBCASE("pointer") { meta::pointer_({ - .metadata{ - {"desc", meta::uvalue{"int*-type"s}} - } + {"desc", meta::uvalue{"int*-type"s}} }); CHECK(meta::resolve_type().get_metadata().at("desc") == "int*-type"s); } SUBCASE("reference") { meta::reference_({ - .metadata{ - {"desc", meta::uvalue{"int&-type"s}} - } + {"desc", meta::uvalue{"int&-type"s}} }); CHECK(meta::resolve_type().get_metadata().at("desc") == "int&-type"s); } SUBCASE("void") { meta::void_({ - .metadata{ - {"desc", meta::uvalue{"void-type"s}} - } + {"desc", meta::uvalue{"void-type"s}} }); CHECK(meta::resolve_type().get_metadata().at("desc") == "void-type"s); } From ac6ee9d7cb743740c879a52aafbaf1b5dd09c287 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sun, 13 Feb 2022 04:16:55 +0700 Subject: [PATCH 228/233] lock registry while binds --- headers/meta.hpp/meta_binds.hpp | 15 +++++++++++++++ headers/meta.hpp/meta_detail/state_registry.hpp | 14 +++++++++++--- headers/meta.hpp/meta_detail/type_registry.hpp | 16 ++++++++++++---- 3 files changed, 38 insertions(+), 7 deletions(-) diff --git a/headers/meta.hpp/meta_binds.hpp b/headers/meta.hpp/meta_binds.hpp index 0ad21b2..cb1bddc 100644 --- a/headers/meta.hpp/meta_binds.hpp +++ b/headers/meta.hpp/meta_binds.hpp @@ -9,6 +9,9 @@ #include "meta_base.hpp" #include "meta_states.hpp" +#include "meta_detail/state_registry.hpp" +#include "meta_detail/type_registry.hpp" + namespace meta_hpp::detail { template < typename Class, typename... Args > @@ -85,6 +88,7 @@ namespace meta_hpp operator array_type() const noexcept; private: detail::array_type_data_ptr data_; + detail::type_registry::locker locker_; }; } @@ -212,6 +216,7 @@ namespace meta_hpp Policy = Policy{}); private: detail::class_type_data_ptr data_; + detail::type_registry::locker locker_; }; } @@ -227,6 +232,7 @@ namespace meta_hpp enum_bind& evalue_(std::string name, Enum value, evalue_opts opts); private: detail::enum_type_data_ptr data_; + detail::type_registry::locker locker_; }; } @@ -239,6 +245,7 @@ namespace meta_hpp operator function_type() const noexcept; private: detail::function_type_data_ptr data_; + detail::type_registry::locker locker_; }; } @@ -251,6 +258,7 @@ namespace meta_hpp operator member_type() const noexcept; private: detail::member_type_data_ptr data_; + detail::type_registry::locker locker_; }; } @@ -263,6 +271,7 @@ namespace meta_hpp operator method_type() const noexcept; private: detail::method_type_data_ptr data_; + detail::type_registry::locker locker_; }; } @@ -275,6 +284,7 @@ namespace meta_hpp operator nullptr_type() const noexcept; private: detail::nullptr_type_data_ptr data_; + detail::type_registry::locker locker_; }; } @@ -287,6 +297,7 @@ namespace meta_hpp operator number_type() const noexcept; private: detail::number_type_data_ptr data_; + detail::type_registry::locker locker_; }; } @@ -299,6 +310,7 @@ namespace meta_hpp operator pointer_type() const noexcept; private: detail::pointer_type_data_ptr data_; + detail::type_registry::locker locker_; }; } @@ -311,6 +323,7 @@ namespace meta_hpp operator reference_type() const noexcept; private: detail::reference_type_data_ptr data_; + detail::type_registry::locker locker_; }; } @@ -323,6 +336,7 @@ namespace meta_hpp operator void_type() const noexcept; private: detail::void_type_data_ptr data_; + detail::type_registry::locker locker_; }; } @@ -386,6 +400,7 @@ namespace meta_hpp Policy = Policy{}); private: detail::scope_state_ptr state_; + detail::state_registry::locker locker_; }; } diff --git a/headers/meta.hpp/meta_detail/state_registry.hpp b/headers/meta.hpp/meta_detail/state_registry.hpp index c17f3e0..077c6ec 100644 --- a/headers/meta.hpp/meta_detail/state_registry.hpp +++ b/headers/meta.hpp/meta_detail/state_registry.hpp @@ -19,7 +19,7 @@ namespace meta_hpp::detail } [[nodiscard]] scope get_scope_by_name(std::string_view name) const noexcept { - const std::lock_guard lock{mutex_}; + const locker lock; if ( auto iter = scopes_.find(name); iter != scopes_.end() ) { return iter->second; @@ -29,7 +29,7 @@ namespace meta_hpp::detail } [[nodiscard]] scope resolve_scope(std::string_view name) { - const std::lock_guard lock{mutex_}; + const locker lock; if ( auto iter = scopes_.find(name); iter != scopes_.end() ) { return iter->second; @@ -38,10 +38,18 @@ namespace meta_hpp::detail auto state = scope_state::make(std::string{name}, metadata_map{}); return scopes_.emplace(std::string{name}, std::move(state)).first->second; } + public: + class locker : noncopyable { + public: + explicit locker() + : lock_{instance().mutex_} {} + private: + std::lock_guard lock_; + }; private: state_registry() = default; private: - mutable std::mutex mutex_; + std::recursive_mutex mutex_; std::map> scopes_; }; } diff --git a/headers/meta.hpp/meta_detail/type_registry.hpp b/headers/meta.hpp/meta_detail/type_registry.hpp index d7a59e1..b20ef51 100644 --- a/headers/meta.hpp/meta_detail/type_registry.hpp +++ b/headers/meta.hpp/meta_detail/type_registry.hpp @@ -19,7 +19,7 @@ namespace meta_hpp::detail } [[nodiscard]] any_type get_type_by_id(type_id id) const noexcept { - const std::lock_guard lock{mutex_}; + const locker lock; if ( auto iter = type_by_id_.find(id); iter != type_by_id_.end() ) { return iter->second; @@ -29,7 +29,7 @@ namespace meta_hpp::detail } [[nodiscard]] any_type get_type_by_rtti(const std::type_index& index) const noexcept { - const std::lock_guard lock{mutex_}; + const locker lock; if ( auto iter = type_by_rtti_.find(index); iter != type_by_rtti_.end() ) { return iter->second; @@ -199,6 +199,14 @@ namespace meta_hpp::detail static void_type_data_ptr data{std::make_shared(type_list{})}; return ensure_type(data); } + public: + class locker : noncopyable { + public: + explicit locker() + : lock_{instance().mutex_} {} + private: + std::lock_guard lock_; + }; private: type_registry() = default; @@ -206,7 +214,7 @@ namespace meta_hpp::detail TypeData ensure_type(const TypeData& type_data) { static std::once_flag init_flag{}; std::call_once(init_flag, [this, &type_data](){ - const std::lock_guard lock{mutex_}; + const locker lock; type_by_id_[type_data->id] = any_type{type_data}; #ifndef META_HPP_NO_RTTI type_by_rtti_[typeid(Type)] = any_type{type_data}; @@ -215,7 +223,7 @@ namespace meta_hpp::detail return type_data; } private: - mutable std::mutex mutex_; + std::recursive_mutex mutex_; std::map> type_by_id_; std::map> type_by_rtti_; }; From 53776b30eb2b7617bd98aa4d4e8b76615160ef47 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sun, 13 Feb 2022 04:52:29 +0700 Subject: [PATCH 229/233] internal classes and enums for class_type --- headers/meta.hpp/meta_binds.hpp | 18 +++++-- headers/meta.hpp/meta_binds/class_bind.hpp | 48 ++++++++++++++----- headers/meta.hpp/meta_binds/scope_bind.hpp | 12 ++++- .../meta.hpp/meta_detail/state_registry.hpp | 2 +- headers/meta.hpp/meta_types.hpp | 10 +++- headers/meta.hpp/meta_types/class_type.hpp | 26 +++++++++- untests/meta_types/class_type2_tests.cpp | 37 ++++++++++++++ 7 files changed, 131 insertions(+), 22 deletions(-) create mode 100644 untests/meta_types/class_type2_tests.cpp diff --git a/headers/meta.hpp/meta_binds.hpp b/headers/meta.hpp/meta_binds.hpp index cb1bddc..15bb5af 100644 --- a/headers/meta.hpp/meta_binds.hpp +++ b/headers/meta.hpp/meta_binds.hpp @@ -100,6 +100,17 @@ namespace meta_hpp explicit class_bind(metadata_map metadata); operator class_type() const noexcept; + // class_ + + template < detail::class_kind InternalClass > + class_bind& class_(std::string name); + + // base_ + + template < detail::class_kind Base > + class_bind& base_() + requires detail::class_bind_base_kind; + // constructor_ template < typename... Args @@ -120,11 +131,10 @@ namespace meta_hpp class_bind& destructor_(destructor_opts opts) requires detail::class_bind_destructor_kind; - // base_ + // enum_ - template < detail::class_kind Base > - class_bind& base_() - requires detail::class_bind_base_kind; + template < detail::enum_kind InternalEnum > + class_bind& enum_(std::string name); // function_ diff --git a/headers/meta.hpp/meta_binds/class_bind.hpp b/headers/meta.hpp/meta_binds/class_bind.hpp index 6a7b37a..29ae9ba 100644 --- a/headers/meta.hpp/meta_binds/class_bind.hpp +++ b/headers/meta.hpp/meta_binds/class_bind.hpp @@ -25,6 +25,39 @@ namespace meta_hpp return class_type{data_}; } + // class_ + + template < detail::class_kind Class > + template < detail::class_kind InternalClass > + class_bind& class_bind::class_(std::string name) { + data_->classes.insert_or_assign(std::move(name), detail::resolve_type()); + return *this; + } + + // + // base_ + // + + template < detail::class_kind Class > + template < detail::class_kind Base > + class_bind& class_bind::base_() + requires detail::class_bind_base_kind + { + const class_type base_type = detail::resolve_type(); + if ( data_->bases.contains(base_type) ) { + return *this; + } + + data_->bases.emplace(base_type); + data_->bases_info.emplace(base_type, detail::class_type_data::base_info{ + .upcast = +[](void* derived) -> void* { + return static_cast(static_cast(derived)); + } + }); + + return *this; + } + // // constructor_ // @@ -81,20 +114,13 @@ namespace meta_hpp } // - // base_ + // enum_ // template < detail::class_kind Class > - template < detail::class_kind Base > - class_bind& class_bind::base_() - requires detail::class_bind_base_kind - { - data_->bases.emplace(detail::resolve_type()); - data_->bases_info.emplace(detail::resolve_type(), detail::class_type_data::base_info{ - .upcast = +[](void* derived) -> void* { - return static_cast(static_cast(derived)); - } - }); + template < detail::enum_kind InternalEnum > + class_bind& class_bind::enum_(std::string name) { + data_->enums.insert_or_assign(std::move(name), detail::resolve_type()); return *this; } diff --git a/headers/meta.hpp/meta_binds/scope_bind.hpp b/headers/meta.hpp/meta_binds/scope_bind.hpp index 4f25d51..d5d6a2b 100644 --- a/headers/meta.hpp/meta_binds/scope_bind.hpp +++ b/headers/meta.hpp/meta_binds/scope_bind.hpp @@ -29,15 +29,23 @@ namespace meta_hpp return scope{state_}; } + // + // class_ + // + template < detail::class_kind Class > scope_bind& scope_bind::class_(std::string name) { - state_->classes.emplace(std::move(name), detail::resolve_type()); + state_->classes.insert_or_assign(std::move(name), detail::resolve_type()); return *this; } + // + // enum_ + // + template < detail::enum_kind Enum > scope_bind& scope_bind::enum_(std::string name) { - state_->enums.emplace(std::move(name), detail::resolve_type()); + state_->enums.insert_or_assign(std::move(name), detail::resolve_type()); return *this; } diff --git a/headers/meta.hpp/meta_detail/state_registry.hpp b/headers/meta.hpp/meta_detail/state_registry.hpp index 077c6ec..0c2a56f 100644 --- a/headers/meta.hpp/meta_detail/state_registry.hpp +++ b/headers/meta.hpp/meta_detail/state_registry.hpp @@ -36,7 +36,7 @@ namespace meta_hpp::detail } auto state = scope_state::make(std::string{name}, metadata_map{}); - return scopes_.emplace(std::string{name}, std::move(state)).first->second; + return scopes_.insert_or_assign(std::string{name}, std::move(state)).first->second; } public: class locker : noncopyable { diff --git a/headers/meta.hpp/meta_types.hpp b/headers/meta.hpp/meta_types.hpp index 52034c4..d2260ce 100644 --- a/headers/meta.hpp/meta_types.hpp +++ b/headers/meta.hpp/meta_types.hpp @@ -155,9 +155,11 @@ namespace meta_hpp [[nodiscard]] any_type get_argument_type(std::size_t position) const noexcept; [[nodiscard]] const std::vector& get_argument_types() const noexcept; + [[nodiscard]] const class_map& get_classes() const noexcept; + [[nodiscard]] const class_set& get_bases() const noexcept; [[nodiscard]] const constructor_map& get_ctors() const noexcept; [[nodiscard]] const destructor_map& get_dtors() const noexcept; - [[nodiscard]] const class_set& get_bases() const noexcept; + [[nodiscard]] const enum_map& get_enums() const noexcept; [[nodiscard]] const function_map& get_functions() const noexcept; [[nodiscard]] const member_map& get_members() const noexcept; [[nodiscard]] const method_map& get_methods() const noexcept; @@ -180,6 +182,8 @@ namespace meta_hpp [[nodiscard]] bool is_derived_from() const noexcept; [[nodiscard]] bool is_derived_from(const class_type& base) const noexcept; + [[nodiscard]] class_type get_class(std::string_view name) const noexcept; + [[nodiscard]] enum_type get_enum(std::string_view name) const noexcept; [[nodiscard]] function get_function(std::string_view name) const noexcept; [[nodiscard]] member get_member(std::string_view name) const noexcept; [[nodiscard]] method get_method(std::string_view name) const noexcept; @@ -483,9 +487,11 @@ namespace meta_hpp::detail const std::size_t size; const std::vector argument_types; + class_map classes; + class_set bases; constructor_map constructors; destructor_map destructors; - class_set bases; + enum_map enums; function_map functions; member_map members; method_map methods; diff --git a/headers/meta.hpp/meta_types/class_type.hpp b/headers/meta.hpp/meta_types/class_type.hpp index 9723be0..8b46b1d 100644 --- a/headers/meta.hpp/meta_types/class_type.hpp +++ b/headers/meta.hpp/meta_types/class_type.hpp @@ -73,6 +73,14 @@ namespace meta_hpp return data_->argument_types; } + inline const class_map& class_type::get_classes() const noexcept { + return data_->classes; + } + + inline const class_set& class_type::get_bases() const noexcept { + return data_->bases; + } + inline const constructor_map& class_type::get_ctors() const noexcept { return data_->constructors; } @@ -81,8 +89,8 @@ namespace meta_hpp return data_->destructors; } - inline const class_set& class_type::get_bases() const noexcept { - return data_->bases; + inline const enum_map& class_type::get_enums() const noexcept { + return data_->enums; } inline const function_map& class_type::get_functions() const noexcept { @@ -173,6 +181,20 @@ namespace meta_hpp return false; } + inline class_type class_type::get_class(std::string_view name) const noexcept { + if ( auto iter = data_->classes.find(name); iter != data_->classes.end() ) { + return iter->second; + } + return class_type{}; + } + + inline enum_type class_type::get_enum(std::string_view name) const noexcept { + if ( auto iter = data_->enums.find(name); iter != data_->enums.end() ) { + return iter->second; + } + return enum_type{}; + } + inline function class_type::get_function(std::string_view name) const noexcept { for ( auto&& [index, function] : data_->functions ) { if ( index.get_name() == name ) { diff --git a/untests/meta_types/class_type2_tests.cpp b/untests/meta_types/class_type2_tests.cpp new file mode 100644 index 0000000..f4870c1 --- /dev/null +++ b/untests/meta_types/class_type2_tests.cpp @@ -0,0 +1,37 @@ +/******************************************************************************* + * 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-2022, by Matvey Cherevko (blackmatov@gmail.com) + ******************************************************************************/ + +#include "../meta_untests.hpp" + +namespace +{ + struct clazz { + struct internal_clazz {}; + enum class internal_enum {}; + }; +} + +TEST_CASE("meta/meta_types/class_type2") { + namespace meta = meta_hpp; + + meta::class_() + .class_("internal_clazz") + .enum_("internal_enum"); + + const meta::class_type clazz_type = meta::resolve_type(); + REQUIRE(clazz_type); + + CHECK(clazz_type.get_class("internal_clazz") == meta::resolve_type()); + CHECK(clazz_type.get_enum("internal_enum") == meta::resolve_type()); + + CHECK(clazz_type.get_classes() == meta::class_map{ + {"internal_clazz", meta::resolve_type()} + }); + + CHECK(clazz_type.get_enums() == meta::enum_map{ + {"internal_enum", meta::resolve_type()} + }); +} From e93f89d4e5c38de47b4d66c3ac55457d85c7e10f Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sun, 13 Feb 2022 07:10:25 +0700 Subject: [PATCH 230/233] typedefs instead class_ and enum_ --- headers/meta.hpp/meta_base.hpp | 1 + headers/meta.hpp/meta_binds.hpp | 26 ++++++-------- headers/meta.hpp/meta_binds/class_bind.hpp | 31 ++++++---------- headers/meta.hpp/meta_binds/scope_bind.hpp | 30 ++++++---------- headers/meta.hpp/meta_states.hpp | 9 ++--- headers/meta.hpp/meta_states/scope.hpp | 35 +++++++----------- headers/meta.hpp/meta_types.hpp | 9 ++--- headers/meta.hpp/meta_types/class_type.hpp | 42 +++++++++++----------- manuals/meta_examples/classes_example.cpp | 3 ++ manuals/meta_manuals.hpp | 1 + untests/meta_states/scope_tests.cpp | 26 +++++++------- untests/meta_types/class_type2_tests.cpp | 17 ++++----- 12 files changed, 94 insertions(+), 136 deletions(-) diff --git a/headers/meta.hpp/meta_base.hpp b/headers/meta.hpp/meta_base.hpp index a0b294a..258ac8c 100644 --- a/headers/meta.hpp/meta_base.hpp +++ b/headers/meta.hpp/meta_base.hpp @@ -205,6 +205,7 @@ namespace meta_hpp { using argument_list = std::vector; using metadata_map = std::map>; + using typedef_map = std::map>; using class_set = std::set>; using class_map = std::map>; diff --git a/headers/meta.hpp/meta_binds.hpp b/headers/meta.hpp/meta_binds.hpp index 15bb5af..560f263 100644 --- a/headers/meta.hpp/meta_binds.hpp +++ b/headers/meta.hpp/meta_binds.hpp @@ -100,11 +100,6 @@ namespace meta_hpp explicit class_bind(metadata_map metadata); operator class_type() const noexcept; - // class_ - - template < detail::class_kind InternalClass > - class_bind& class_(std::string name); - // base_ template < detail::class_kind Base > @@ -131,11 +126,6 @@ namespace meta_hpp class_bind& destructor_(destructor_opts opts) requires detail::class_bind_destructor_kind; - // enum_ - - template < detail::enum_kind InternalEnum > - class_bind& enum_(std::string name); - // function_ template < detail::function_kind Function @@ -208,6 +198,11 @@ namespace meta_hpp Policy = Policy{}) requires detail::class_bind_method_kind; + // typdef_ + + template < typename Type > + class_bind& typedef_(std::string name); + // variable_ template < detail::pointer_kind Pointer @@ -361,12 +356,6 @@ namespace meta_hpp explicit scope_bind(std::string_view name, metadata_map metadata, static_tag); operator scope() const noexcept; - template < detail::class_kind Class > - scope_bind& class_(std::string name); - - template < detail::enum_kind Enum > - scope_bind& enum_(std::string name); - // function_ template < detail::function_kind Function @@ -392,6 +381,11 @@ namespace meta_hpp std::initializer_list arguments, Policy = Policy{}); + // typedef_ + + template < typename Type > + scope_bind& typedef_(std::string name); + // variable_ template < detail::pointer_kind Pointer diff --git a/headers/meta.hpp/meta_binds/class_bind.hpp b/headers/meta.hpp/meta_binds/class_bind.hpp index 29ae9ba..ec44df0 100644 --- a/headers/meta.hpp/meta_binds/class_bind.hpp +++ b/headers/meta.hpp/meta_binds/class_bind.hpp @@ -25,15 +25,6 @@ namespace meta_hpp return class_type{data_}; } - // class_ - - template < detail::class_kind Class > - template < detail::class_kind InternalClass > - class_bind& class_bind::class_(std::string name) { - data_->classes.insert_or_assign(std::move(name), detail::resolve_type()); - return *this; - } - // // base_ // @@ -113,17 +104,6 @@ namespace meta_hpp return *this; } - // - // enum_ - // - - template < detail::class_kind Class > - template < detail::enum_kind InternalEnum > - class_bind& class_bind::enum_(std::string name) { - data_->enums.insert_or_assign(std::move(name), detail::resolve_type()); - return *this; - } - // // function_ // @@ -293,6 +273,17 @@ namespace meta_hpp return *this; } + // + // typedef_ + // + + template < detail::class_kind Class > + template < typename Type > + class_bind& class_bind::typedef_(std::string name) { + data_->typedefs.insert_or_assign(std::move(name), detail::resolve_type()); + return *this; + } + // // variable_ // diff --git a/headers/meta.hpp/meta_binds/scope_bind.hpp b/headers/meta.hpp/meta_binds/scope_bind.hpp index d5d6a2b..9e207ba 100644 --- a/headers/meta.hpp/meta_binds/scope_bind.hpp +++ b/headers/meta.hpp/meta_binds/scope_bind.hpp @@ -29,26 +29,6 @@ namespace meta_hpp return scope{state_}; } - // - // class_ - // - - template < detail::class_kind Class > - scope_bind& scope_bind::class_(std::string name) { - state_->classes.insert_or_assign(std::move(name), detail::resolve_type()); - return *this; - } - - // - // enum_ - // - - template < detail::enum_kind Enum > - scope_bind& scope_bind::enum_(std::string name) { - state_->enums.insert_or_assign(std::move(name), detail::resolve_type()); - return *this; - } - // // function_ // @@ -113,6 +93,16 @@ namespace meta_hpp return *this; } + // + // typedef_ + // + + template < typename Type > + scope_bind& scope_bind::typedef_(std::string name) { + state_->typedefs.insert_or_assign(std::move(name), detail::resolve_type()); + return *this; + } + // // variable_ // diff --git a/headers/meta.hpp/meta_states.hpp b/headers/meta.hpp/meta_states.hpp index a19196b..8926119 100644 --- a/headers/meta.hpp/meta_states.hpp +++ b/headers/meta.hpp/meta_states.hpp @@ -329,14 +329,12 @@ namespace meta_hpp [[nodiscard]] const std::string& get_name() const noexcept; - [[nodiscard]] const class_map& get_classes() const noexcept; - [[nodiscard]] const enum_map& get_enums() const noexcept; [[nodiscard]] const function_map& get_functions() const noexcept; + [[nodiscard]] const typedef_map& get_typedefs() const noexcept; [[nodiscard]] const variable_map& get_variables() const noexcept; - [[nodiscard]] class_type get_class(std::string_view name) const noexcept; - [[nodiscard]] enum_type get_enum(std::string_view name) const noexcept; [[nodiscard]] function get_function(std::string_view name) const noexcept; + [[nodiscard]] any_type get_typedef(std::string_view name) const noexcept; [[nodiscard]] variable get_variable(std::string_view name) const noexcept; template < typename... Args > @@ -529,9 +527,8 @@ namespace meta_hpp::detail scope_index index; metadata_map metadata; - class_map classes{}; - enum_map enums{}; function_map functions{}; + typedef_map typedefs{}; variable_map variables{}; [[nodiscard]] static scope_state_ptr make(std::string name, metadata_map metadata); diff --git a/headers/meta.hpp/meta_states/scope.hpp b/headers/meta.hpp/meta_states/scope.hpp index 24ae2f6..5b95a37 100644 --- a/headers/meta.hpp/meta_states/scope.hpp +++ b/headers/meta.hpp/meta_states/scope.hpp @@ -58,36 +58,18 @@ namespace meta_hpp return state_->index.get_name(); } - inline const class_map& scope::get_classes() const noexcept { - return state_->classes; - } - - inline const enum_map& scope::get_enums() const noexcept { - return state_->enums; - } - inline const function_map& scope::get_functions() const noexcept { return state_->functions; } + inline const typedef_map& scope::get_typedefs() const noexcept { + return state_->typedefs; + } + inline const variable_map& scope::get_variables() const noexcept { return state_->variables; } - inline class_type scope::get_class(std::string_view name) const noexcept { - if ( auto iter = state_->classes.find(name); iter != state_->classes.end() ) { - return iter->second; - } - return class_type{}; - } - - inline enum_type scope::get_enum(std::string_view name) const noexcept { - if ( auto iter = state_->enums.find(name); iter != state_->enums.end() ) { - return iter->second; - } - return enum_type{}; - } - inline function scope::get_function(std::string_view name) const noexcept { for ( auto&& [index, function] : state_->functions ) { if ( index.get_name() == name ) { @@ -97,6 +79,15 @@ namespace meta_hpp return function{}; } + inline any_type scope::get_typedef(std::string_view name) const noexcept { + for ( auto&& [index, type] : state_->typedefs ) { + if ( index == name ) { + return type; + } + } + return any_type{}; + } + inline variable scope::get_variable(std::string_view name) const noexcept { for ( auto&& [index, variable] : state_->variables ) { if ( index.get_name() == name ) { diff --git a/headers/meta.hpp/meta_types.hpp b/headers/meta.hpp/meta_types.hpp index d2260ce..3b8c620 100644 --- a/headers/meta.hpp/meta_types.hpp +++ b/headers/meta.hpp/meta_types.hpp @@ -155,14 +155,13 @@ namespace meta_hpp [[nodiscard]] any_type get_argument_type(std::size_t position) const noexcept; [[nodiscard]] const std::vector& get_argument_types() const noexcept; - [[nodiscard]] const class_map& get_classes() const noexcept; [[nodiscard]] const class_set& get_bases() const noexcept; [[nodiscard]] const constructor_map& get_ctors() const noexcept; [[nodiscard]] const destructor_map& get_dtors() const noexcept; - [[nodiscard]] const enum_map& get_enums() const noexcept; [[nodiscard]] const function_map& get_functions() const noexcept; [[nodiscard]] const member_map& get_members() const noexcept; [[nodiscard]] const method_map& get_methods() const noexcept; + [[nodiscard]] const typedef_map& get_typedefs() const noexcept; [[nodiscard]] const variable_map& get_variables() const noexcept; template < typename... Args > @@ -182,11 +181,10 @@ namespace meta_hpp [[nodiscard]] bool is_derived_from() const noexcept; [[nodiscard]] bool is_derived_from(const class_type& base) const noexcept; - [[nodiscard]] class_type get_class(std::string_view name) const noexcept; - [[nodiscard]] enum_type get_enum(std::string_view name) const noexcept; [[nodiscard]] function get_function(std::string_view name) const noexcept; [[nodiscard]] member get_member(std::string_view name) const noexcept; [[nodiscard]] method get_method(std::string_view name) const noexcept; + [[nodiscard]] any_type get_typedef(std::string_view name) const noexcept; [[nodiscard]] variable get_variable(std::string_view name) const noexcept; template < typename... Args > @@ -487,14 +485,13 @@ namespace meta_hpp::detail const std::size_t size; const std::vector argument_types; - class_map classes; class_set bases; constructor_map constructors; destructor_map destructors; - enum_map enums; function_map functions; member_map members; method_map methods; + typedef_map typedefs; variable_map variables; struct base_info final { diff --git a/headers/meta.hpp/meta_types/class_type.hpp b/headers/meta.hpp/meta_types/class_type.hpp index 8b46b1d..c46466d 100644 --- a/headers/meta.hpp/meta_types/class_type.hpp +++ b/headers/meta.hpp/meta_types/class_type.hpp @@ -73,10 +73,6 @@ namespace meta_hpp return data_->argument_types; } - inline const class_map& class_type::get_classes() const noexcept { - return data_->classes; - } - inline const class_set& class_type::get_bases() const noexcept { return data_->bases; } @@ -89,10 +85,6 @@ namespace meta_hpp return data_->destructors; } - inline const enum_map& class_type::get_enums() const noexcept { - return data_->enums; - } - inline const function_map& class_type::get_functions() const noexcept { return data_->functions; } @@ -105,6 +97,10 @@ namespace meta_hpp return data_->methods; } + inline const typedef_map& class_type::get_typedefs() const noexcept { + return data_->typedefs; + } + inline const variable_map& class_type::get_variables() const noexcept { return data_->variables; } @@ -181,20 +177,6 @@ namespace meta_hpp return false; } - inline class_type class_type::get_class(std::string_view name) const noexcept { - if ( auto iter = data_->classes.find(name); iter != data_->classes.end() ) { - return iter->second; - } - return class_type{}; - } - - inline enum_type class_type::get_enum(std::string_view name) const noexcept { - if ( auto iter = data_->enums.find(name); iter != data_->enums.end() ) { - return iter->second; - } - return enum_type{}; - } - inline function class_type::get_function(std::string_view name) const noexcept { for ( auto&& [index, function] : data_->functions ) { if ( index.get_name() == name ) { @@ -243,6 +225,22 @@ namespace meta_hpp return method{}; } + inline any_type class_type::get_typedef(std::string_view name) const noexcept { + for ( auto&& [index, type] : data_->typedefs ) { + if ( index == name ) { + return type; + } + } + + for ( auto&& base : data_->bases ) { + if ( any_type type = base.get_typedef(name); type ) { + return type; + } + } + + return any_type{}; + } + inline variable class_type::get_variable(std::string_view name) const noexcept { for ( auto&& [index, variable] : data_->variables ) { if ( index.get_name() == name ) { diff --git a/manuals/meta_examples/classes_example.cpp b/manuals/meta_examples/classes_example.cpp index bdf38e9..e258d93 100644 --- a/manuals/meta_examples/classes_example.cpp +++ b/manuals/meta_examples/classes_example.cpp @@ -10,7 +10,10 @@ namespace { class shape { public: + shape() = default; + shape(const shape&) = default; virtual ~shape() = default; + virtual int get_area() const = 0; }; diff --git a/manuals/meta_manuals.hpp b/manuals/meta_manuals.hpp index 245c449..d135216 100644 --- a/manuals/meta_manuals.hpp +++ b/manuals/meta_manuals.hpp @@ -11,6 +11,7 @@ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wc++20-compat" #pragma clang diagnostic ignored "-Wdocumentation-unknown-command" +#pragma clang diagnostic ignored "-Wreserved-identifier" #pragma clang diagnostic ignored "-Wsigned-enum-bitfield" #pragma clang diagnostic ignored "-Wswitch-enum" #pragma clang diagnostic ignored "-Wundefined-func-template" diff --git a/untests/meta_states/scope_tests.cpp b/untests/meta_states/scope_tests.cpp index aa76c47..6aecd6b 100644 --- a/untests/meta_states/scope_tests.cpp +++ b/untests/meta_states/scope_tests.cpp @@ -41,9 +41,9 @@ TEST_CASE("meta/meta_states/scope") { namespace meta = meta_hpp; meta::static_scope_("meta/meta_states/scope/math") - .enum_("color") - .class_("ivec2") - .class_("ivec3") + .typedef_("color") + .typedef_("ivec2") + .typedef_("ivec3") .function_("iadd2", &iadd2, {"l", "r"}) .function_("iadd3", &iadd3, {"l"}) .variable_("static_ivec2", &static_ivec2) @@ -54,10 +54,8 @@ TEST_CASE("meta/meta_states/scope") { REQUIRE(math_scope.is_valid()); CHECK(math_scope.get_name() == "meta/meta_states/scope/math"); - CHECK(math_scope.get_classes().size() == 2); - CHECK(math_scope.get_enums().size() == 1); - CHECK(math_scope.get_functions().size() == 2); CHECK(math_scope.get_variables().size() == 2); + CHECK(math_scope.get_typedefs().size() == 3); SUBCASE("") { const meta::scope scope; @@ -74,20 +72,20 @@ TEST_CASE("meta/meta_states/scope") { } SUBCASE("classes") { - CHECK_FALSE(math_scope.get_class("non-existent-class")); + CHECK_FALSE(math_scope.get_typedef("non-existent-class")); - const meta::class_type ivec2_type = math_scope.get_class("ivec2"); - REQUIRE(ivec2_type); + const meta::any_type ivec2_type = math_scope.get_typedef("ivec2"); + CHECK(ivec2_type == meta::resolve_type()); - const meta::class_type ivec3_type = math_scope.get_class("ivec3"); - REQUIRE(ivec3_type); + const meta::any_type ivec3_type = math_scope.get_typedef("ivec3"); + CHECK(ivec3_type == meta::resolve_type()); } SUBCASE("enums") { - CHECK_FALSE(math_scope.get_enum("non-existent-enum")); + CHECK_FALSE(math_scope.get_typedef("non-existent-enum")); - const meta::enum_type color_type = math_scope.get_enum("color"); - REQUIRE(color_type); + const meta::any_type color_type = math_scope.get_typedef("color"); + CHECK(color_type == meta::resolve_type()); } SUBCASE("functions") { diff --git a/untests/meta_types/class_type2_tests.cpp b/untests/meta_types/class_type2_tests.cpp index f4870c1..1c5dc8a 100644 --- a/untests/meta_types/class_type2_tests.cpp +++ b/untests/meta_types/class_type2_tests.cpp @@ -18,20 +18,17 @@ TEST_CASE("meta/meta_types/class_type2") { namespace meta = meta_hpp; meta::class_() - .class_("internal_clazz") - .enum_("internal_enum"); + .typedef_("internal_clazz") + .typedef_("internal_enum"); const meta::class_type clazz_type = meta::resolve_type(); REQUIRE(clazz_type); - CHECK(clazz_type.get_class("internal_clazz") == meta::resolve_type()); - CHECK(clazz_type.get_enum("internal_enum") == meta::resolve_type()); + CHECK(clazz_type.get_typedef("internal_clazz") == meta::resolve_type()); + CHECK(clazz_type.get_typedef("internal_enum") == meta::resolve_type()); - CHECK(clazz_type.get_classes() == meta::class_map{ - {"internal_clazz", meta::resolve_type()} - }); - - CHECK(clazz_type.get_enums() == meta::enum_map{ - {"internal_enum", meta::resolve_type()} + CHECK(clazz_type.get_typedefs() == meta::typedef_map{ + {"internal_clazz", meta::resolve_type()}, + {"internal_enum", meta::resolve_type()}, }); } From 4072c525ca67dbf258a28081b050478524c73eb0 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sun, 13 Feb 2022 07:15:25 +0700 Subject: [PATCH 231/233] update todo --- TODO.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/TODO.md b/TODO.md index e792242..dad92e6 100644 --- a/TODO.md +++ b/TODO.md @@ -1,17 +1,11 @@ # meta.hpp -- metadata - add policy tests -- rebind types support - rewrite ctor/dtor system * argument defaults -* argument names * type conversions - (?) enum_type::create, number_type::create, and so on - (?) move-only value type support -- (?) type names - (?) properties - -(???) Why does local scope have a name? From 1a87937719ee713a667834a7b208f79e556f940e Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sun, 13 Feb 2022 07:34:33 +0700 Subject: [PATCH 232/233] example style fixes --- README.md | 7 ++++++- .../{classes_example.cpp => class_example.cpp} | 4 ++-- .../{enums_examples.cpp => enum_example.cpp} | 4 ++-- ...functions_example.cpp => function_example.cpp} | 4 ++-- .../{members_example.cpp => member_example.cpp} | 4 ++-- .../{methods_example.cpp => method_example.cpp} | 4 ++-- manuals/meta_examples/scopes_example.cpp | 15 --------------- manuals/meta_examples/values_example.cpp | 15 --------------- ...variables_example.cpp => variable_example.cpp} | 2 +- 9 files changed, 17 insertions(+), 42 deletions(-) rename manuals/meta_examples/{classes_example.cpp => class_example.cpp} (96%) rename manuals/meta_examples/{enums_examples.cpp => enum_example.cpp} (95%) rename manuals/meta_examples/{functions_example.cpp => function_example.cpp} (96%) rename manuals/meta_examples/{members_example.cpp => member_example.cpp} (95%) rename manuals/meta_examples/{methods_example.cpp => method_example.cpp} (96%) delete mode 100644 manuals/meta_examples/scopes_example.cpp delete mode 100644 manuals/meta_examples/values_example.cpp rename manuals/meta_examples/{variables_example.cpp => variable_example.cpp} (97%) diff --git a/README.md b/README.md index 4f33c3c..3fd4411 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,12 @@ target_link_libraries(your_project_target meta.hpp) ## Examples -> coming soon +- [Class](./manuals/meta_examples/class_example.cpp) +- [Enum](./manuals/meta_examples/enum_example.cpp) +- [Function](./manuals/meta_examples/function_example.cpp) +- [Member](./manuals/meta_examples/member_example.cpp) +- [Method](./manuals/meta_examples/method_example.cpp) +- [Variable](./manuals/meta_examples/variable_example.cpp) ## API diff --git a/manuals/meta_examples/classes_example.cpp b/manuals/meta_examples/class_example.cpp similarity index 96% rename from manuals/meta_examples/classes_example.cpp rename to manuals/meta_examples/class_example.cpp index e258d93..fcd8fde 100644 --- a/manuals/meta_examples/classes_example.cpp +++ b/manuals/meta_examples/class_example.cpp @@ -40,7 +40,7 @@ namespace }; } -TEST_CASE("meta/meta_examples/classes/type") { +TEST_CASE("meta/meta_examples/class/type") { namespace meta = meta_hpp; // 'shape' class type registration @@ -64,7 +64,7 @@ TEST_CASE("meta/meta_examples/classes/type") { } } -TEST_CASE("meta/meta_examples/classes/usage") { +TEST_CASE("meta/meta_examples/class/usage") { namespace meta = meta_hpp; // resolves a class type by static class type diff --git a/manuals/meta_examples/enums_examples.cpp b/manuals/meta_examples/enum_example.cpp similarity index 95% rename from manuals/meta_examples/enums_examples.cpp rename to manuals/meta_examples/enum_example.cpp index 2f4bba0..e96a0a5 100644 --- a/manuals/meta_examples/enums_examples.cpp +++ b/manuals/meta_examples/enum_example.cpp @@ -15,7 +15,7 @@ namespace }; } -TEST_CASE("meta/meta_examples/enums/type") { +TEST_CASE("meta/meta_examples/enum/type") { namespace meta = meta_hpp; // 'align' enumeration type registration @@ -40,7 +40,7 @@ TEST_CASE("meta/meta_examples/enums/type") { } } -TEST_CASE("meta/meta_examples/enums/usage") { +TEST_CASE("meta/meta_examples/enum/usage") { namespace meta = meta_hpp; const align e = align::center; diff --git a/manuals/meta_examples/functions_example.cpp b/manuals/meta_examples/function_example.cpp similarity index 96% rename from manuals/meta_examples/functions_example.cpp rename to manuals/meta_examples/function_example.cpp index a5529b1..a127907 100644 --- a/manuals/meta_examples/functions_example.cpp +++ b/manuals/meta_examples/function_example.cpp @@ -17,7 +17,7 @@ namespace } } -TEST_CASE("meta/meta_examples/functions/type") { +TEST_CASE("meta/meta_examples/function/type") { namespace meta = meta_hpp; // resolves a function type by pointer @@ -37,7 +37,7 @@ TEST_CASE("meta/meta_examples/functions/type") { CHECK(add_function_type.get_argument_type(1) == meta::resolve_type()); } -TEST_CASE("meta/meta_examples/functions/usage") { +TEST_CASE("meta/meta_examples/function/usage") { namespace meta = meta_hpp; // 'math' local scope declaration diff --git a/manuals/meta_examples/members_example.cpp b/manuals/meta_examples/member_example.cpp similarity index 95% rename from manuals/meta_examples/members_example.cpp rename to manuals/meta_examples/member_example.cpp index 62854ef..252a0b6 100644 --- a/manuals/meta_examples/members_example.cpp +++ b/manuals/meta_examples/member_example.cpp @@ -14,7 +14,7 @@ namespace }; } -TEST_CASE("meta/meta_examples/members/type") { +TEST_CASE("meta/meta_examples/member/type") { namespace meta = meta_hpp; // 'ivec2' class type registration @@ -35,7 +35,7 @@ TEST_CASE("meta/meta_examples/members/type") { CHECK(x_member_type.get_value_type() == meta::resolve_type()); } -TEST_CASE("meta/meta_examples/members/usage") { +TEST_CASE("meta/meta_examples/member/usage") { namespace meta = meta_hpp; ivec2 v{42, 21}; diff --git a/manuals/meta_examples/methods_example.cpp b/manuals/meta_examples/method_example.cpp similarity index 96% rename from manuals/meta_examples/methods_example.cpp rename to manuals/meta_examples/method_example.cpp index af00a11..f149adb 100644 --- a/manuals/meta_examples/methods_example.cpp +++ b/manuals/meta_examples/method_example.cpp @@ -24,7 +24,7 @@ namespace }; } -TEST_CASE("meta/meta_examples/methods/type") { +TEST_CASE("meta/meta_examples/method/type") { namespace meta = meta_hpp; // 'ivec2' class type registration @@ -50,7 +50,7 @@ TEST_CASE("meta/meta_examples/methods/type") { CHECK(add_method_type.get_argument_type(0) == meta::resolve_type()); } -TEST_CASE("meta/meta_examples/methods/usage") { +TEST_CASE("meta/meta_examples/method/usage") { namespace meta = meta_hpp; ivec2 v{20, 10}; diff --git a/manuals/meta_examples/scopes_example.cpp b/manuals/meta_examples/scopes_example.cpp deleted file mode 100644 index 65ab1ad..0000000 --- a/manuals/meta_examples/scopes_example.cpp +++ /dev/null @@ -1,15 +0,0 @@ -/******************************************************************************* - * 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-2022, by Matvey Cherevko (blackmatov@gmail.com) - ******************************************************************************/ - -#include "../meta_manuals.hpp" - -namespace -{ -} - -TEST_CASE("meta/meta_examples/scopes") { - namespace meta = meta_hpp; -} diff --git a/manuals/meta_examples/values_example.cpp b/manuals/meta_examples/values_example.cpp deleted file mode 100644 index 6aa42b9..0000000 --- a/manuals/meta_examples/values_example.cpp +++ /dev/null @@ -1,15 +0,0 @@ -/******************************************************************************* - * 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-2022, by Matvey Cherevko (blackmatov@gmail.com) - ******************************************************************************/ - -#include "../meta_manuals.hpp" - -namespace -{ -} - -TEST_CASE("meta/meta_examples/values") { - namespace meta = meta_hpp; -} diff --git a/manuals/meta_examples/variables_example.cpp b/manuals/meta_examples/variable_example.cpp similarity index 97% rename from manuals/meta_examples/variables_example.cpp rename to manuals/meta_examples/variable_example.cpp index 05d6fe6..634f3cc 100644 --- a/manuals/meta_examples/variables_example.cpp +++ b/manuals/meta_examples/variable_example.cpp @@ -12,7 +12,7 @@ namespace const double sqrt2_v{1.4142135624}; } -TEST_CASE("meta/meta_examples/variables/usage") { +TEST_CASE("meta/meta_examples/variable/usage") { namespace meta = meta_hpp; // 'constants' local scope declaration From b92478038fbb4cf735edee7103701713ac945027 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sun, 13 Feb 2022 07:59:08 +0700 Subject: [PATCH 233/233] move todo to github issues --- TODO.md | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 TODO.md diff --git a/TODO.md b/TODO.md deleted file mode 100644 index dad92e6..0000000 --- a/TODO.md +++ /dev/null @@ -1,11 +0,0 @@ -# meta.hpp - -- add policy tests -- rewrite ctor/dtor system - -* argument defaults -* type conversions - -- (?) enum_type::create, number_type::create, and so on -- (?) move-only value type support -- (?) properties

(I)}; + }.template operator()()), ...); + }(std::make_index_sequence()); + + return parameters; + } } namespace meta_hpp::detail @@ -117,6 +135,7 @@ namespace meta_hpp::detail .index{method_index::make(std::move(name))}, .invoke{make_method_invoke(std::move(method))}, .is_invocable_with{make_method_is_invocable_with()}, + .parameters{make_method_parameters()}, }); } } @@ -186,4 +205,12 @@ namespace meta_hpp return state_->is_invocable_with(vinst, {}); } } + + inline parameter method::get_parameter(std::size_t position) const noexcept { + return position < state_->parameters.size() ? state_->parameters[position] : parameter{}; + } + + inline const parameter_list& method::get_parameters() const noexcept { + return state_->parameters; + } } diff --git a/headers/meta.hpp/meta_types.hpp b/headers/meta.hpp/meta_types.hpp index c9105dd..a72820d 100644 --- a/headers/meta.hpp/meta_types.hpp +++ b/headers/meta.hpp/meta_types.hpp @@ -148,7 +148,7 @@ namespace meta_hpp [[nodiscard]] std::size_t get_size() const noexcept; [[nodiscard]] std::size_t get_arity() const noexcept; - [[nodiscard]] any_type get_argument_type(std::size_t index) const noexcept; + [[nodiscard]] any_type get_argument_type(std::size_t position) const noexcept; [[nodiscard]] const std::vector& get_argument_types() const noexcept; [[nodiscard]] const ctor_map& get_ctors() const noexcept; @@ -219,7 +219,7 @@ namespace meta_hpp [[nodiscard]] std::size_t get_arity() const noexcept; [[nodiscard]] any_type get_class_type() const noexcept; - [[nodiscard]] any_type get_argument_type(std::size_t index) const noexcept; + [[nodiscard]] any_type get_argument_type(std::size_t position) const noexcept; [[nodiscard]] const std::vector& get_argument_types() const noexcept; private: detail::ctor_type_data_ptr data_; @@ -281,7 +281,7 @@ namespace meta_hpp [[nodiscard]] std::size_t get_arity() const noexcept; [[nodiscard]] any_type get_return_type() const noexcept; - [[nodiscard]] any_type get_argument_type(std::size_t index) const noexcept; + [[nodiscard]] any_type get_argument_type(std::size_t position) const noexcept; [[nodiscard]] const std::vector& get_argument_types() const noexcept; private: detail::function_type_data_ptr data_; @@ -320,7 +320,7 @@ namespace meta_hpp [[nodiscard]] std::size_t get_arity() const noexcept; [[nodiscard]] class_type get_owner_type() const noexcept; [[nodiscard]] any_type get_return_type() const noexcept; - [[nodiscard]] any_type get_argument_type(std::size_t index) const noexcept; + [[nodiscard]] any_type get_argument_type(std::size_t position) const noexcept; [[nodiscard]] const std::vector& get_argument_types() const noexcept; private: detail::method_type_data_ptr data_; diff --git a/headers/meta.hpp/meta_types/class_type.hpp b/headers/meta.hpp/meta_types/class_type.hpp index 542d71c..3366643 100644 --- a/headers/meta.hpp/meta_types/class_type.hpp +++ b/headers/meta.hpp/meta_types/class_type.hpp @@ -61,8 +61,8 @@ namespace meta_hpp return data_->argument_types.size(); } - inline any_type class_type::get_argument_type(std::size_t index) const noexcept { - return index < data_->argument_types.size() ? data_->argument_types[index] : any_type{}; + inline any_type class_type::get_argument_type(std::size_t position) const noexcept { + return position < data_->argument_types.size() ? data_->argument_types[position] : any_type{}; } inline const std::vector& class_type::get_argument_types() const noexcept { diff --git a/headers/meta.hpp/meta_types/ctor_type.hpp b/headers/meta.hpp/meta_types/ctor_type.hpp index c08ea0a..c525f2e 100644 --- a/headers/meta.hpp/meta_types/ctor_type.hpp +++ b/headers/meta.hpp/meta_types/ctor_type.hpp @@ -55,8 +55,8 @@ namespace meta_hpp return data_->class_type; } - inline any_type ctor_type::get_argument_type(std::size_t index) const noexcept { - return index < data_->argument_types.size() ? data_->argument_types[index] : any_type{}; + inline any_type ctor_type::get_argument_type(std::size_t position) const noexcept { + return position < data_->argument_types.size() ? data_->argument_types[position] : any_type{}; } inline const std::vector& ctor_type::get_argument_types() const noexcept { diff --git a/headers/meta.hpp/meta_types/function_type.hpp b/headers/meta.hpp/meta_types/function_type.hpp index 52fb118..fa01a86 100644 --- a/headers/meta.hpp/meta_types/function_type.hpp +++ b/headers/meta.hpp/meta_types/function_type.hpp @@ -55,8 +55,8 @@ namespace meta_hpp return data_->return_type; } - inline any_type function_type::get_argument_type(std::size_t index) const noexcept { - return index < data_->argument_types.size() ? data_->argument_types[index] : any_type{}; + inline any_type function_type::get_argument_type(std::size_t position) const noexcept { + return position < data_->argument_types.size() ? data_->argument_types[position] : any_type{}; } inline const std::vector& function_type::get_argument_types() const noexcept { diff --git a/headers/meta.hpp/meta_types/method_type.hpp b/headers/meta.hpp/meta_types/method_type.hpp index 2e8e193..3bff848 100644 --- a/headers/meta.hpp/meta_types/method_type.hpp +++ b/headers/meta.hpp/meta_types/method_type.hpp @@ -60,8 +60,8 @@ namespace meta_hpp return data_->return_type; } - inline any_type method_type::get_argument_type(std::size_t index) const noexcept { - return index < data_->argument_types.size() ? data_->argument_types[index] : any_type{}; + inline any_type method_type::get_argument_type(std::size_t position) const noexcept { + return position < data_->argument_types.size() ? data_->argument_types[position] : any_type{}; } inline const std::vector& method_type::get_argument_types() const noexcept { diff --git a/untests/meta_states/function2_tests.cpp b/untests/meta_states/function2_tests.cpp new file mode 100644 index 0000000..ab76043 --- /dev/null +++ b/untests/meta_states/function2_tests.cpp @@ -0,0 +1,72 @@ +/******************************************************************************* + * 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 ivec2 { + int x{}; + int y{}; + + static ivec2 iadd(const ivec2& l, const ivec2& r) noexcept { + return {l.x + r.x, l.y + r.y}; + } + + static ivec2 isub(const ivec2& l, const ivec2& r) noexcept { + return {l.x - r.x, l.y - r.y}; + } + }; +} + +TEST_CASE("meta/meta_states/function2") { + namespace meta = meta_hpp; + + meta::class_() + .function_("iadd", &ivec2::iadd, { "l" }) + .function_("isub", &ivec2::isub, { "l", "r" }); + + const meta::class_type ivec2_type = meta::resolve_type(); + REQUIRE(ivec2_type); + + SUBCASE("iadd2") { + const meta::function func = ivec2_type.get_function("iadd"); + REQUIRE(func); + + CHECK(func.get_parameters().size() == 2); + + REQUIRE(func.get_parameter(0)); + CHECK(func.get_parameter(0).get_type() == meta::resolve_type()); + CHECK(func.get_parameter(0).get_position() == 0); + CHECK(func.get_parameter(0).get_name() == "l"); + + REQUIRE(func.get_parameter(1)); + CHECK(func.get_parameter(1).get_type() == meta::resolve_type()); + CHECK(func.get_parameter(1).get_position() == 1); + CHECK(func.get_parameter(1).get_name() == ""); + + CHECK_FALSE(func.get_parameter(2)); + } + + SUBCASE("isub2") { + const meta::function func = ivec2_type.get_function("isub"); + REQUIRE(func); + + REQUIRE(func.get_parameters().size() == 2); + + REQUIRE(func.get_parameter(0)); + CHECK(func.get_parameter(0).get_type() == meta::resolve_type()); + CHECK(func.get_parameter(0).get_position() == 0); + CHECK(func.get_parameter(0).get_name() == "l"); + + REQUIRE(func.get_parameter(1)); + CHECK(func.get_parameter(1).get_type() == meta::resolve_type()); + CHECK(func.get_parameter(1).get_position() == 1); + CHECK(func.get_parameter(1).get_name() == "r"); + + CHECK_FALSE(func.get_parameter(2)); + } +} diff --git a/untests/meta_states/method2_tests.cpp b/untests/meta_states/method2_tests.cpp new file mode 100644 index 0000000..a5ffbad --- /dev/null +++ b/untests/meta_states/method2_tests.cpp @@ -0,0 +1,45 @@ +/******************************************************************************* + * 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 ivec2 { + int x{}; + int y{}; + + ivec2& add(const ivec2& other) { + x += other.x; + y += other.y; + return *this; + } + }; +} + +TEST_CASE("meta/meta_states/method2") { + namespace meta = meta_hpp; + + meta::class_() + .method_("add", &ivec2::add, {"other"}); + + const meta::class_type ivec2_type = meta::resolve_type(); + REQUIRE(ivec2_type); + + SUBCASE("add") { + const meta::method add_m = ivec2_type.get_method("add"); + REQUIRE(add_m); + + CHECK(add_m.get_parameters().size() == 1); + + REQUIRE(add_m.get_parameter(0)); + CHECK(add_m.get_parameter(0).get_type() == meta::resolve_type()); + CHECK(add_m.get_parameter(0).get_position() == 0); + CHECK(add_m.get_parameter(0).get_name() == "other"); + + CHECK_FALSE(add_m.get_parameter(1)); + } +} diff --git a/untests/meta_states/scope_tests.cpp b/untests/meta_states/scope_tests.cpp index 8128e2a..da8be1b 100644 --- a/untests/meta_states/scope_tests.cpp +++ b/untests/meta_states/scope_tests.cpp @@ -44,8 +44,8 @@ TEST_CASE("meta/meta_states/scope") { .enum_("color") .class_("ivec2") .class_("ivec3") - .function_("iadd2", &iadd2) - .function_("iadd3", &iadd3) + .function_("iadd2", &iadd2, {"l", "r"}) + .function_("iadd3", &iadd3, {"l"}) .variable_("static_ivec2", &static_ivec2) .variable_("static_const_ivec3", &static_const_ivec3); @@ -96,8 +96,40 @@ TEST_CASE("meta/meta_states/scope") { const meta::function iadd2_func = math_scope.get_function("iadd2"); REQUIRE(iadd2_func); + { + CHECK(iadd2_func.get_parameters().size() == 2); + + REQUIRE(iadd2_func.get_parameter(0)); + CHECK(iadd2_func.get_parameter(0).get_type() == meta::resolve_type()); + CHECK(iadd2_func.get_parameter(0).get_position() == 0); + CHECK(iadd2_func.get_parameter(0).get_name() == "l"); + + REQUIRE(iadd2_func.get_parameter(1)); + CHECK(iadd2_func.get_parameter(1).get_type() == meta::resolve_type()); + CHECK(iadd2_func.get_parameter(1).get_position() == 1); + CHECK(iadd2_func.get_parameter(1).get_name() == "r"); + + CHECK_FALSE(iadd2_func.get_parameter(2)); + } + const meta::function iadd3_func = math_scope.get_function("iadd3"); REQUIRE(iadd3_func); + + { + CHECK(iadd3_func.get_parameters().size() == 2); + + REQUIRE(iadd3_func.get_parameter(0)); + CHECK(iadd3_func.get_parameter(0).get_type() == meta::resolve_type()); + CHECK(iadd3_func.get_parameter(0).get_position() == 0); + CHECK(iadd3_func.get_parameter(0).get_name() == "l"); + + REQUIRE(iadd3_func.get_parameter(1)); + CHECK(iadd3_func.get_parameter(1).get_type() == meta::resolve_type()); + CHECK(iadd3_func.get_parameter(1).get_position() == 1); + CHECK(iadd3_func.get_parameter(1).get_name() == ""); + + CHECK_FALSE(iadd3_func.get_parameter(2)); + } } SUBCASE("variables") { From 8e18c858236d5d0b401841a2624f7137e5ccc70f Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Tue, 8 Feb 2022 20:45:08 +0700 Subject: [PATCH 218/233] rename: arg -> uarg, inst -> uinst, value -> uvalue --- headers/meta.hpp/meta_base.hpp | 10 +- .../meta_detail/value_traits/deref_traits.hpp | 18 +- .../meta_detail/value_traits/index_traits.hpp | 26 +- .../value_utilities/{arg.hpp => uarg.hpp} | 60 ++-- .../value_utilities/{inst.hpp => uinst.hpp} | 60 ++-- .../meta_detail/value_utilities/utraits.hpp | 10 +- headers/meta.hpp/meta_states.hpp | 58 ++-- headers/meta.hpp/meta_states/ctor.hpp | 24 +- headers/meta.hpp/meta_states/dtor.hpp | 12 +- headers/meta.hpp/meta_states/evalue.hpp | 8 +- headers/meta.hpp/meta_states/function.hpp | 26 +- headers/meta.hpp/meta_states/member.hpp | 50 +-- headers/meta.hpp/meta_states/method.hpp | 34 +- headers/meta.hpp/meta_states/variable.hpp | 26 +- headers/meta.hpp/meta_types.hpp | 6 +- headers/meta.hpp/meta_types/class_type.hpp | 6 +- headers/meta.hpp/meta_types/enum_type.hpp | 8 +- headers/meta.hpp/meta_value.hpp | 36 +-- headers/meta.hpp/meta_value/value.hpp | 118 +++---- headers/meta.hpp/meta_value/vinvoke.hpp | 40 +-- manuals/meta_examples/classes_example.cpp | 2 +- manuals/meta_examples/enums_examples.cpp | 2 +- manuals/meta_examples/functions_example.cpp | 2 +- manuals/meta_examples/members_example.cpp | 2 +- manuals/meta_examples/methods_example.cpp | 2 +- manuals/meta_examples/variables_example.cpp | 2 +- untests/meta_features/diamond_tests.cpp | 40 +-- untests/meta_states/ctor_tests.cpp | 12 +- untests/meta_states/function_tests.cpp | 32 +- untests/meta_types/enum_type_tests.cpp | 2 +- untests/meta_utilities/arg2_tests.cpp | 306 +++++++++--------- untests/meta_utilities/arg3_tests.cpp | 50 +-- untests/meta_utilities/arg4_tests.cpp | 162 +++++----- untests/meta_utilities/arg5_tests.cpp | 162 +++++----- untests/meta_utilities/arg6_tests.cpp | 10 +- untests/meta_utilities/arg7_tests.cpp | 116 +++---- untests/meta_utilities/arg_tests.cpp | 232 ++++++------- untests/meta_utilities/inst_tests.cpp | 84 ++--- untests/meta_utilities/invoke_tests.cpp | 24 +- untests/meta_utilities/value2_tests.cpp | 44 +-- untests/meta_utilities/value_tests.cpp | 182 +++++------ 41 files changed, 1053 insertions(+), 1053 deletions(-) rename headers/meta.hpp/meta_detail/value_utilities/{arg.hpp => uarg.hpp} (91%) rename headers/meta.hpp/meta_detail/value_utilities/{inst.hpp => uinst.hpp} (82%) diff --git a/headers/meta.hpp/meta_base.hpp b/headers/meta.hpp/meta_base.hpp index 5a1996a..4921cd8 100644 --- a/headers/meta.hpp/meta_base.hpp +++ b/headers/meta.hpp/meta_base.hpp @@ -89,15 +89,15 @@ namespace meta_hpp namespace meta_hpp { - class value; + class uvalue; namespace detail { - class arg_base; - class arg; + class uarg_base; + class uarg; - class inst_base; - class inst; + class uinst_base; + class uinst; } } diff --git a/headers/meta.hpp/meta_detail/value_traits/deref_traits.hpp b/headers/meta.hpp/meta_detail/value_traits/deref_traits.hpp index b7a5f3f..38187ad 100644 --- a/headers/meta.hpp/meta_detail/value_traits/deref_traits.hpp +++ b/headers/meta.hpp/meta_detail/value_traits/deref_traits.hpp @@ -16,7 +16,7 @@ namespace meta_hpp::detail template < typename T > concept has_deref_traits = requires(const T& v) { - { deref_traits{}(v) } -> stdex::convertible_to; + { deref_traits{}(v) } -> stdex::convertible_to; }; } @@ -24,29 +24,29 @@ namespace meta_hpp::detail { template < stdex::copy_constructible T > struct deref_traits { - value operator()(T* v) const { - return value{*v}; + uvalue operator()(T* v) const { + return uvalue{*v}; } }; template < stdex::copy_constructible T > struct deref_traits { - value operator()(const T* v) const { - return value{*v}; + uvalue operator()(const T* v) const { + return uvalue{*v}; } }; template < stdex::copy_constructible T > struct deref_traits> { - value operator()(const std::shared_ptr& v) const { - return value{*v}; + uvalue operator()(const std::shared_ptr& v) const { + return uvalue{*v}; } }; template < stdex::copy_constructible T > struct deref_traits> { - value operator()(const std::unique_ptr& v) const { - return value{*v}; + uvalue operator()(const std::unique_ptr& v) const { + return uvalue{*v}; } }; } diff --git a/headers/meta.hpp/meta_detail/value_traits/index_traits.hpp b/headers/meta.hpp/meta_detail/value_traits/index_traits.hpp index 53e6f14..328c13f 100644 --- a/headers/meta.hpp/meta_detail/value_traits/index_traits.hpp +++ b/headers/meta.hpp/meta_detail/value_traits/index_traits.hpp @@ -16,7 +16,7 @@ namespace meta_hpp::detail template < typename T > concept has_index_traits = requires(const T& v, std::size_t i) { - { index_traits{}(v, i) } -> stdex::convertible_to; + { index_traits{}(v, i) } -> stdex::convertible_to; }; } @@ -24,43 +24,43 @@ namespace meta_hpp::detail { template < stdex::copy_constructible T > struct index_traits { - value operator()(T* v, std::size_t i) const { - return value{v[i]}; + uvalue operator()(T* v, std::size_t i) const { + return uvalue{v[i]}; } }; template < stdex::copy_constructible T > struct index_traits { - value operator()(const T* v, std::size_t i) const { - return value{v[i]}; + uvalue operator()(const T* v, std::size_t i) const { + return uvalue{v[i]}; } }; template < stdex::copy_constructible T, std::size_t Size > struct index_traits> { - value operator()(const std::array& v, std::size_t i) const { - return value{v[i]}; + uvalue operator()(const std::array& v, std::size_t i) const { + return uvalue{v[i]}; } }; template < stdex::copy_constructible T, std::size_t Extent > struct index_traits> { - value operator()(const std::span& v, std::size_t i) const { - return value{v[i]}; + uvalue operator()(const std::span& v, std::size_t i) const { + return uvalue{v[i]}; } }; template < stdex::copy_constructible T, typename Traits, typename Allocator > struct index_traits> { - value operator()(const std::basic_string& v, std::size_t i) const { - return value{v[i]}; + uvalue operator()(const std::basic_string& v, std::size_t i) const { + return uvalue{v[i]}; } }; template < stdex::copy_constructible T, typename Allocator > struct index_traits> { - value operator()(const std::vector& v, std::size_t i) { - return value{v[i]}; + uvalue operator()(const std::vector& v, std::size_t i) { + return uvalue{v[i]}; } }; } diff --git a/headers/meta.hpp/meta_detail/value_utilities/arg.hpp b/headers/meta.hpp/meta_detail/value_utilities/uarg.hpp similarity index 91% rename from headers/meta.hpp/meta_detail/value_utilities/arg.hpp rename to headers/meta.hpp/meta_detail/value_utilities/uarg.hpp index 678cf88..9fc33a4 100644 --- a/headers/meta.hpp/meta_detail/value_utilities/arg.hpp +++ b/headers/meta.hpp/meta_detail/value_utilities/uarg.hpp @@ -13,7 +13,7 @@ namespace meta_hpp::detail { - class arg_base { + class uarg_base { public: enum class ref_types { lvalue, @@ -22,29 +22,29 @@ namespace meta_hpp::detail const_rvalue, }; public: - arg_base() = delete; + uarg_base() = delete; - arg_base(arg_base&&) = default; - arg_base(const arg_base&) = default; + uarg_base(uarg_base&&) = default; + uarg_base(const uarg_base&) = default; - arg_base& operator=(arg_base&&) = delete; - arg_base& operator=(const arg_base&) = delete; + uarg_base& operator=(uarg_base&&) = delete; + uarg_base& operator=(const uarg_base&) = delete; - virtual ~arg_base() = default; + virtual ~uarg_base() = default; template < decay_value_kind T > // NOLINTNEXTLINE(readability-named-parameter) - explicit arg_base(T&&) - : arg_base{type_list{}} {} + explicit uarg_base(T&&) + : uarg_base{type_list{}} {} template < decay_non_uvalue_kind T > // NOLINTNEXTLINE(readability-named-parameter) - explicit arg_base(T&&) - : arg_base{type_list{}} {} + explicit uarg_base(T&&) + : uarg_base{type_list{}} {} template < arg_lvalue_ref_kind T > // NOLINTNEXTLINE(readability-named-parameter) - explicit arg_base(type_list) + explicit uarg_base(type_list) : ref_type_{std::is_const_v> ? ref_types::const_lvalue : ref_types::lvalue} @@ -52,25 +52,25 @@ namespace meta_hpp::detail template < arg_rvalue_ref_kind T > // NOLINTNEXTLINE(readability-named-parameter) - explicit arg_base(type_list) + explicit uarg_base(type_list) : ref_type_{std::is_const_v> ? ref_types::const_rvalue : ref_types::rvalue} , raw_type_{resolve_type>()} {} - explicit arg_base(value& v) + explicit uarg_base(uvalue& v) : ref_type_{ref_types::lvalue} , raw_type_{v.get_type()} {} - explicit arg_base(const value& v) + explicit uarg_base(const uvalue& v) : ref_type_{ref_types::const_lvalue} , raw_type_{v.get_type()} {} - explicit arg_base(value&& v) + explicit uarg_base(uvalue&& v) : ref_type_{ref_types::rvalue} , raw_type_{v.get_type()} {} - explicit arg_base(const value&& v) + explicit uarg_base(const uvalue&& v) : ref_type_{ref_types::const_rvalue} , raw_type_{v.get_type()} {} @@ -107,27 +107,27 @@ namespace meta_hpp::detail namespace meta_hpp::detail { - class arg final : public arg_base { + class uarg final : public uarg_base { public: - arg() = delete; + uarg() = delete; - arg(arg&&) = default; - arg(const arg&) = default; + uarg(uarg&&) = default; + uarg(const uarg&) = default; - arg& operator=(arg&&) = delete; - arg& operator=(const arg&) = delete; + uarg& operator=(uarg&&) = delete; + uarg& operator=(const uarg&) = delete; - ~arg() override = default; + ~uarg() override = default; template < decay_value_kind T > - explicit arg(T&& v) - : arg_base{std::forward(v)} + explicit uarg(T&& v) + : uarg_base{std::forward(v)} // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast) , data_{const_cast(v.data())} {} template < decay_non_uvalue_kind T > - explicit arg(T&& v) - : arg_base{std::forward(v)} + explicit uarg(T&& v) + : uarg_base{std::forward(v)} // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast) , data_{const_cast*>(std::addressof(v))} {} @@ -142,7 +142,7 @@ namespace meta_hpp::detail { template < typename To > // NOLINTNEXTLINE(readability-function-cognitive-complexity) - bool arg_base::can_cast_to() const noexcept { + bool uarg_base::can_cast_to() const noexcept { using to_raw_type_cv = std::remove_reference_t; using to_raw_type = std::remove_cv_t; @@ -248,7 +248,7 @@ namespace meta_hpp::detail { template < typename To > // NOLINTNEXTLINE(readability-function-cognitive-complexity) - To arg::cast() const { + To uarg::cast() const { if ( !can_cast_to() ) { throw_exception_with("bad argument cast"); } diff --git a/headers/meta.hpp/meta_detail/value_utilities/inst.hpp b/headers/meta.hpp/meta_detail/value_utilities/uinst.hpp similarity index 82% rename from headers/meta.hpp/meta_detail/value_utilities/inst.hpp rename to headers/meta.hpp/meta_detail/value_utilities/uinst.hpp index 019ff27..18b1952 100644 --- a/headers/meta.hpp/meta_detail/value_utilities/inst.hpp +++ b/headers/meta.hpp/meta_detail/value_utilities/uinst.hpp @@ -13,7 +13,7 @@ namespace meta_hpp::detail { - class inst_base { + class uinst_base { public: enum class ref_types { lvalue, @@ -22,29 +22,29 @@ namespace meta_hpp::detail const_rvalue, }; public: - inst_base() = delete; + uinst_base() = delete; - inst_base(inst_base&&) = default; - inst_base(const inst_base&) = default; + uinst_base(uinst_base&&) = default; + uinst_base(const uinst_base&) = default; - inst_base& operator=(inst_base&&) = delete; - inst_base& operator=(const inst_base&) = delete; + uinst_base& operator=(uinst_base&&) = delete; + uinst_base& operator=(const uinst_base&) = delete; - virtual ~inst_base() = default; + virtual ~uinst_base() = default; template < decay_value_kind T > // NOLINTNEXTLINE(readability-named-parameter) - explicit inst_base(T&&) - : inst_base{type_list{}} {} + explicit uinst_base(T&&) + : uinst_base{type_list{}} {} template < decay_non_uvalue_kind T > // NOLINTNEXTLINE(readability-named-parameter) - explicit inst_base(T&&) - : inst_base{type_list{}} {} + explicit uinst_base(T&&) + : uinst_base{type_list{}} {} template < inst_class_lvalue_ref_kind T > // NOLINTNEXTLINE(readability-named-parameter) - explicit inst_base(type_list) + explicit uinst_base(type_list) : ref_type_{std::is_const_v> ? ref_types::const_lvalue : ref_types::lvalue} @@ -52,25 +52,25 @@ namespace meta_hpp::detail template < inst_class_rvalue_ref_kind T > // NOLINTNEXTLINE(readability-named-parameter) - explicit inst_base(type_list) + explicit uinst_base(type_list) : ref_type_{std::is_const_v> ? ref_types::const_rvalue : ref_types::rvalue} , raw_type_{resolve_type>()} {} - explicit inst_base(value& v) + explicit uinst_base(uvalue& v) : ref_type_{ref_types::lvalue} , raw_type_{v.get_type()} {} - explicit inst_base(const value& v) + explicit uinst_base(const uvalue& v) : ref_type_{ref_types::const_lvalue} , raw_type_{v.get_type()} {} - explicit inst_base(value&& v) + explicit uinst_base(uvalue&& v) : ref_type_{ref_types::rvalue} , raw_type_{v.get_type()} {} - explicit inst_base(const value&& v) + explicit uinst_base(const uvalue&& v) : ref_type_{ref_types::const_rvalue} , raw_type_{v.get_type()} {} @@ -107,27 +107,27 @@ namespace meta_hpp::detail namespace meta_hpp::detail { - class inst final : public inst_base { + class uinst final : public uinst_base { public: - inst() = delete; + uinst() = delete; - inst(inst&&) = default; - inst(const inst&) = default; + uinst(uinst&&) = default; + uinst(const uinst&) = default; - inst& operator=(inst&&) = delete; - inst& operator=(const inst&) = delete; + uinst& operator=(uinst&&) = delete; + uinst& operator=(const uinst&) = delete; - ~inst() override = default; + ~uinst() override = default; template < decay_value_kind T > - explicit inst(T&& v) - : inst_base{std::forward(v)} + explicit uinst(T&& v) + : uinst_base{std::forward(v)} // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast) , data_{const_cast(v.data())} {} template < decay_non_uvalue_kind T > - explicit inst(T&& v) - : inst_base{std::forward(v)} + explicit uinst(T&& v) + : uinst_base{std::forward(v)} // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast) , data_{const_cast*>(std::addressof(v))} {} @@ -141,7 +141,7 @@ namespace meta_hpp::detail namespace meta_hpp::detail { template < inst_class_ref_kind Q > - bool inst_base::can_cast_to() const noexcept { + bool uinst_base::can_cast_to() const noexcept { using inst_class = typename inst_traits::class_type; using inst_method = typename inst_traits::method_type; @@ -175,7 +175,7 @@ namespace meta_hpp::detail namespace meta_hpp::detail { template < inst_class_ref_kind Q > - decltype(auto) inst::cast() const { + decltype(auto) uinst::cast() const { if ( !can_cast_to() ) { throw_exception_with("bad instance cast"); } diff --git a/headers/meta.hpp/meta_detail/value_utilities/utraits.hpp b/headers/meta.hpp/meta_detail/value_utilities/utraits.hpp index e00ab79..a832942 100644 --- a/headers/meta.hpp/meta_detail/value_utilities/utraits.hpp +++ b/headers/meta.hpp/meta_detail/value_utilities/utraits.hpp @@ -13,11 +13,11 @@ namespace meta_hpp::detail { template < typename T > inline constexpr bool is_uvalue_kind_v = - std::is_same_v || - std::is_same_v || - std::is_same_v || - std::is_same_v || - std::is_same_v; + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v; template < typename T > concept uvalue_kind = is_uvalue_kind_v; diff --git a/headers/meta.hpp/meta_states.hpp b/headers/meta.hpp/meta_states.hpp index 9546758..3e4d3d3 100644 --- a/headers/meta.hpp/meta_states.hpp +++ b/headers/meta.hpp/meta_states.hpp @@ -110,10 +110,10 @@ namespace meta_hpp [[nodiscard]] const ctor_type& get_type() const noexcept; template < typename... Args > - value invoke(Args&&... args) const; + uvalue invoke(Args&&... args) const; template < typename... Args > - value operator()(Args&&... args) const; + uvalue operator()(Args&&... args) const; template < typename... Args > [[nodiscard]] bool is_invocable_with() const noexcept; @@ -167,8 +167,8 @@ namespace meta_hpp [[nodiscard]] const enum_type& get_type() const noexcept; [[nodiscard]] const std::string& get_name() const noexcept; - [[nodiscard]] const value& get_value() const noexcept; - [[nodiscard]] const value& get_underlying_value() const noexcept; + [[nodiscard]] const uvalue& get_value() const noexcept; + [[nodiscard]] const uvalue& get_underlying_value() const noexcept; private: detail::evalue_state_ptr state_; friend auto detail::state_access(const evalue&); @@ -187,10 +187,10 @@ namespace meta_hpp [[nodiscard]] const std::string& get_name() const noexcept; template < typename... Args > - value invoke(Args&&... args) const; + uvalue invoke(Args&&... args) const; template < typename... Args > - value operator()(Args&&... args) const; + uvalue operator()(Args&&... args) const; template < typename... Args > [[nodiscard]] bool is_invocable_with() const noexcept; @@ -218,13 +218,13 @@ namespace meta_hpp [[nodiscard]] const std::string& get_name() const noexcept; template < typename Instance > - [[nodiscard]] value get(Instance&& instance) const; + [[nodiscard]] uvalue get(Instance&& instance) const; template < typename Instance, typename Value > void set(Instance&& instance, Value&& value) const; template < typename Instance > - [[nodiscard]] value operator()(Instance&& instance) const; + [[nodiscard]] uvalue operator()(Instance&& instance) const; template < typename Instance, typename Value > void operator()(Instance&& instance, Value&& value) const; @@ -258,10 +258,10 @@ namespace meta_hpp [[nodiscard]] const std::string& get_name() const noexcept; template < typename Instance, typename... Args > - value invoke(Instance&& instance, Args&&... args) const; + uvalue invoke(Instance&& instance, Args&&... args) const; template < typename Instance, typename... Args > - value operator()(Instance&& instance, Args&&... args) const; + uvalue operator()(Instance&& instance, Args&&... args) const; template < typename Instance, typename... Args > [[nodiscard]] bool is_invocable_with() const noexcept; @@ -337,12 +337,12 @@ namespace meta_hpp [[nodiscard]] const pointer_type& get_type() const noexcept; [[nodiscard]] const std::string& get_name() const noexcept; - [[nodiscard]] value get() const; + [[nodiscard]] uvalue get() const; template < typename Value > void set(Value&& value) const; - [[nodiscard]] value operator()() const; + [[nodiscard]] uvalue operator()() const; template < typename Value > void operator()(Value&& value) const; @@ -395,8 +395,8 @@ namespace meta_hpp namespace meta_hpp::detail { struct ctor_state final { - using invoke_impl = fixed_function)>; - using is_invocable_with_impl = fixed_function)>; + using invoke_impl = fixed_function)>; + using is_invocable_with_impl = fixed_function)>; ctor_index index; invoke_impl invoke; @@ -409,8 +409,8 @@ namespace meta_hpp::detail }; struct dtor_state final { - using invoke_impl = fixed_function; - using is_invocable_with_impl = fixed_function; + using invoke_impl = fixed_function; + using is_invocable_with_impl = fixed_function; dtor_index index; invoke_impl invoke; @@ -422,16 +422,16 @@ namespace meta_hpp::detail struct evalue_state final { evalue_index index; - value enum_value; - value underlying_value; + uvalue enum_value; + uvalue underlying_value; template < enum_kind Enum > [[nodiscard]] static evalue_state_ptr make(std::string name, Enum evalue); }; struct function_state final { - using invoke_impl = fixed_function)>; - using is_invocable_with_impl = fixed_function)>; + using invoke_impl = fixed_function)>; + using is_invocable_with_impl = fixed_function)>; function_index index; invoke_impl invoke; @@ -444,11 +444,11 @@ namespace meta_hpp::detail }; struct member_state final { - using getter_impl = fixed_function; - using setter_impl = fixed_function; + using getter_impl = fixed_function; + using setter_impl = fixed_function; - using is_gettable_with_impl = fixed_function; - using is_settable_with_impl = fixed_function; + using is_gettable_with_impl = fixed_function; + using is_settable_with_impl = fixed_function; member_index index; getter_impl getter; @@ -461,8 +461,8 @@ namespace meta_hpp::detail }; struct method_state final { - using invoke_impl = fixed_function)>; - using is_invocable_with_impl = fixed_function)>; + using invoke_impl = fixed_function)>; + using is_invocable_with_impl = fixed_function)>; method_index index; invoke_impl invoke; @@ -495,9 +495,9 @@ namespace meta_hpp::detail }; struct variable_state final { - using getter_impl = fixed_function; - using setter_impl = fixed_function; - using is_settable_with_impl = fixed_function; + using getter_impl = fixed_function; + using setter_impl = fixed_function; + using is_settable_with_impl = fixed_function; variable_index index; getter_impl getter; diff --git a/headers/meta.hpp/meta_states/ctor.hpp b/headers/meta.hpp/meta_states/ctor.hpp index 509064d..432d665 100644 --- a/headers/meta.hpp/meta_states/ctor.hpp +++ b/headers/meta.hpp/meta_states/ctor.hpp @@ -10,12 +10,12 @@ #include "../meta_states.hpp" #include "../meta_types/ctor_type.hpp" -#include "../meta_detail/value_utilities/arg.hpp" +#include "../meta_detail/value_utilities/uarg.hpp" namespace meta_hpp::detail { template < ctor_policy_kind Policy, class_kind Class, typename... Args > - value raw_ctor_invoke(std::span args) { + uvalue raw_ctor_invoke(std::span args) { using ct = ctor_traits; using class_type = typename ct::class_type; using argument_types = typename ct::argument_types; @@ -39,30 +39,30 @@ namespace meta_hpp::detail return std::invoke([ args // NOLINTNEXTLINE(readability-named-parameter) - ](std::index_sequence) -> value { + ](std::index_sequence) -> uvalue { if ( !(... && args[Is].can_cast_to>()) ) { throw_exception_with("an attempt to call a constructor with incorrect argument types"); } if constexpr ( as_object ) { class_type return_value{args[Is].cast>()...}; - return value{std::move(return_value)}; + return uvalue{std::move(return_value)}; } if constexpr ( as_raw_ptr ) { auto return_value{std::make_unique(args[Is].cast>()...)}; - return value{return_value.release()}; + return uvalue{return_value.release()}; } if constexpr ( as_shared_ptr ) { auto return_value{std::make_shared(args[Is].cast>()...)}; - return value{std::move(return_value)}; + return uvalue{std::move(return_value)}; } }, std::make_index_sequence()); } template < class_kind Class, typename... Args > - bool raw_ctor_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; @@ -143,10 +143,10 @@ namespace meta_hpp } template < typename... Args > - value ctor::invoke(Args&&... args) const { + uvalue ctor::invoke(Args&&... args) const { if constexpr ( sizeof...(Args) > 0 ) { using namespace detail; - const std::array vargs{arg{std::forward(args)}...}; + const std::array vargs{uarg{std::forward(args)}...}; return state_->invoke(vargs); } else { return state_->invoke({}); @@ -154,7 +154,7 @@ namespace meta_hpp } template < typename... Args > - value ctor::operator()(Args&&... args) const { + uvalue ctor::operator()(Args&&... args) const { return invoke(std::forward(args)...); } @@ -162,7 +162,7 @@ namespace meta_hpp bool ctor::is_invocable_with() const noexcept { if constexpr ( sizeof...(Args) > 0 ) { using namespace detail; - const std::array vargs{arg_base{type_list{}}...}; + const std::array vargs{uarg_base{type_list{}}...}; return state_->is_invocable_with(vargs); } else { return state_->is_invocable_with({}); @@ -173,7 +173,7 @@ namespace meta_hpp bool ctor::is_invocable_with(Args&&... args) const noexcept { if constexpr ( sizeof...(Args) > 0 ) { using namespace detail; - const std::array vargs{arg_base{std::forward(args)}...}; + const std::array vargs{uarg_base{std::forward(args)}...}; return state_->is_invocable_with(vargs); } else { return state_->is_invocable_with({}); diff --git a/headers/meta.hpp/meta_states/dtor.hpp b/headers/meta.hpp/meta_states/dtor.hpp index 08b0d3b..079c563 100644 --- a/headers/meta.hpp/meta_states/dtor.hpp +++ b/headers/meta.hpp/meta_states/dtor.hpp @@ -10,12 +10,12 @@ #include "../meta_states.hpp" #include "../meta_types/dtor_type.hpp" -#include "../meta_detail/value_utilities/arg.hpp" +#include "../meta_detail/value_utilities/uarg.hpp" namespace meta_hpp::detail { template < class_kind Class > - void raw_dtor_invoke(const arg& ptr) { + void raw_dtor_invoke(const uarg& ptr) { using dt = dtor_traits; using class_type = typename dt::class_type; @@ -30,7 +30,7 @@ namespace meta_hpp::detail } template < class_kind Class > - bool raw_dtor_is_invocable_with(const arg_base& ptr) { + bool raw_dtor_is_invocable_with(const uarg_base& ptr) { using dt = dtor_traits; using class_type = typename dt::class_type; @@ -87,7 +87,7 @@ namespace meta_hpp template < typename Arg > void dtor::invoke(Arg&& ptr) const { using namespace detail; - const arg varg{std::forward(ptr)}; + const uarg varg{std::forward(ptr)}; state_->invoke(varg); } @@ -99,14 +99,14 @@ namespace meta_hpp template < typename Arg > bool dtor::is_invocable_with() const noexcept { using namespace detail; - const arg_base varg{type_list{}}; + const uarg_base varg{type_list{}}; return state_->is_invocable_with(varg); } template < typename Arg > bool dtor::is_invocable_with(Arg&& ptr) const noexcept { using namespace detail; - const arg_base varg{std::forward(ptr)}; + const uarg_base varg{std::forward(ptr)}; return state_->is_invocable_with(varg); } } diff --git a/headers/meta.hpp/meta_states/evalue.hpp b/headers/meta.hpp/meta_states/evalue.hpp index a46da97..b05a72a 100644 --- a/headers/meta.hpp/meta_states/evalue.hpp +++ b/headers/meta.hpp/meta_states/evalue.hpp @@ -17,8 +17,8 @@ namespace meta_hpp::detail evalue_state_ptr evalue_state::make(std::string name, Enum evalue) { return std::make_shared(evalue_state{ .index{evalue_index::make(std::move(name))}, - .enum_value{value{evalue}}, - .underlying_value{value{stdex::to_underlying(evalue)}}, + .enum_value{uvalue{evalue}}, + .underlying_value{uvalue{stdex::to_underlying(evalue)}}, }); } } @@ -48,11 +48,11 @@ namespace meta_hpp return state_->index.get_name(); } - inline const value& evalue::get_value() const noexcept { + inline const uvalue& evalue::get_value() const noexcept { return state_->enum_value; } - inline const value& evalue::get_underlying_value() const noexcept { + inline const uvalue& evalue::get_underlying_value() const noexcept { return state_->underlying_value; } } diff --git a/headers/meta.hpp/meta_states/function.hpp b/headers/meta.hpp/meta_states/function.hpp index 0d3da8c..f219171 100644 --- a/headers/meta.hpp/meta_states/function.hpp +++ b/headers/meta.hpp/meta_states/function.hpp @@ -10,12 +10,12 @@ #include "../meta_states.hpp" #include "../meta_types/function_type.hpp" -#include "../meta_detail/value_utilities/arg.hpp" +#include "../meta_detail/value_utilities/uarg.hpp" namespace meta_hpp::detail { template < function_policy_kind Policy, function_kind Function > - value raw_function_invoke(const Function& function, std::span args) { + uvalue raw_function_invoke(const Function& function, std::span args) { using ft = function_traits; using return_type = typename ft::return_type; using argument_types = typename ft::argument_types; @@ -41,7 +41,7 @@ namespace meta_hpp::detail return std::invoke([ &function, args // NOLINTNEXTLINE(readability-named-parameter) - ](std::index_sequence) -> value { + ](std::index_sequence) -> uvalue { if ( !(... && args[Is].can_cast_to>()) ) { throw_exception_with("an attempt to call a function with incorrect argument types"); } @@ -50,23 +50,23 @@ namespace meta_hpp::detail std::ignore = std::invoke( function, args[Is].cast>()...); - return value{}; + return uvalue{}; } else { return_type&& return_value = std::invoke( function, args[Is].cast>()...); if constexpr ( ref_as_ptr ) { - return value{std::addressof(return_value)}; + return uvalue{std::addressof(return_value)}; } else { - return value{std::forward(return_value)}; + return uvalue{std::forward(return_value)}; } } }, std::make_index_sequence()); } template < function_kind Function > - bool raw_function_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; @@ -85,7 +85,7 @@ namespace meta_hpp::detail { template < function_policy_kind Policy, function_kind Function > function_state::invoke_impl make_function_invoke(Function function) { - return [function = std::move(function)](std::span args){ + return [function = std::move(function)](std::span args){ return raw_function_invoke(function, args); }; } @@ -153,10 +153,10 @@ namespace meta_hpp } template < typename... Args > - value function::invoke(Args&&... args) const { + uvalue function::invoke(Args&&... args) const { if constexpr ( sizeof...(Args) > 0 ) { using namespace detail; - const std::array vargs{arg{std::forward(args)}...}; + const std::array vargs{uarg{std::forward(args)}...}; return state_->invoke(vargs); } else { return state_->invoke({}); @@ -164,7 +164,7 @@ namespace meta_hpp } template < typename... Args > - value function::operator()(Args&&... args) const { + uvalue function::operator()(Args&&... args) const { return invoke(std::forward(args)...); } @@ -172,7 +172,7 @@ namespace meta_hpp bool function::is_invocable_with() const noexcept { if constexpr ( sizeof...(Args) > 0 ) { using namespace detail; - const std::array vargs{arg_base{type_list{}}...}; + const std::array vargs{uarg_base{type_list{}}...}; return state_->is_invocable_with(vargs); } else { return state_->is_invocable_with({}); @@ -183,7 +183,7 @@ namespace meta_hpp bool function::is_invocable_with(Args&&... args) const noexcept { if constexpr ( sizeof...(Args) > 0 ) { using namespace detail; - const std::array vargs{arg_base{std::forward(args)}...}; + const std::array vargs{uarg_base{std::forward(args)}...}; return state_->is_invocable_with(vargs); } else { return state_->is_invocable_with({}); diff --git a/headers/meta.hpp/meta_states/member.hpp b/headers/meta.hpp/meta_states/member.hpp index 3ea8518..e16dd2b 100644 --- a/headers/meta.hpp/meta_states/member.hpp +++ b/headers/meta.hpp/meta_states/member.hpp @@ -10,13 +10,13 @@ #include "../meta_states.hpp" #include "../meta_types/member_type.hpp" -#include "../meta_detail/value_utilities/arg.hpp" -#include "../meta_detail/value_utilities/inst.hpp" +#include "../meta_detail/value_utilities/uarg.hpp" +#include "../meta_detail/value_utilities/uinst.hpp" namespace meta_hpp::detail { template < member_policy_kind Policy, member_kind Member > - value raw_member_getter(const Member& member, const inst& inst) { + uvalue raw_member_getter(const Member& member, const uinst& inst) { using mt = member_traits; using class_type = typename mt::class_type; using value_type = typename mt::value_type; @@ -41,35 +41,35 @@ namespace meta_hpp::detail auto&& return_value = std::invoke(member, inst.cast()); if constexpr ( as_copy ) { - return value{std::forward(return_value)}; + return uvalue{std::forward(return_value)}; } if constexpr ( as_ptr ) { - return value{std::addressof(return_value)}; + return uvalue{std::addressof(return_value)}; } if constexpr ( as_ref_wrap ) { - return value{std::ref(return_value)}; + return uvalue{std::ref(return_value)}; } } else { auto&& return_value = std::invoke(member, inst.cast()); if constexpr ( as_copy ) { - return value{std::forward(return_value)}; + return uvalue{std::forward(return_value)}; } if constexpr ( as_ptr ) { - return value{std::addressof(return_value)}; + return uvalue{std::addressof(return_value)}; } if constexpr ( as_ref_wrap ) { - return value{std::ref(return_value)}; + return uvalue{std::ref(return_value)}; } } } template < member_kind Member > - bool raw_member_is_gettable_with(const inst_base& inst) { + bool raw_member_is_gettable_with(const uinst_base& inst) { using mt = member_traits; using class_type = typename mt::class_type; @@ -80,7 +80,7 @@ namespace meta_hpp::detail namespace meta_hpp::detail { template < member_kind Member > - void raw_member_setter([[maybe_unused]] const Member& member, const inst& inst, const arg& arg) { + void raw_member_setter([[maybe_unused]] const Member& member, const uinst& inst, const uarg& arg) { using mt = member_traits; using class_type = typename mt::class_type; using value_type = typename mt::value_type; @@ -105,7 +105,7 @@ namespace meta_hpp::detail } template < member_kind Member > - bool raw_member_is_settable_with(const inst_base& inst, const arg_base& arg) { + bool raw_member_is_settable_with(const uinst_base& inst, const uarg_base& arg) { using mt = member_traits; using class_type = typename mt::class_type; using value_type = typename mt::value_type; @@ -121,7 +121,7 @@ namespace meta_hpp::detail { template < member_policy_kind Policy, member_kind Member > member_state::getter_impl make_member_getter(Member member) { - return [member = std::move(member)](const inst& inst){ + return [member = std::move(member)](const uinst& inst){ return raw_member_getter(member, inst); }; } @@ -133,7 +133,7 @@ namespace meta_hpp::detail template < member_kind Member > member_state::setter_impl make_member_setter(Member member) { - return [member = std::move(member)](const inst& inst, const arg& arg){ + return [member = std::move(member)](const uinst& inst, const uarg& arg){ return raw_member_setter(member, inst, arg); }; } @@ -184,22 +184,22 @@ namespace meta_hpp } template < typename Instance > - value member::get(Instance&& instance) const { + uvalue member::get(Instance&& instance) const { using namespace detail; - const inst vinst{std::forward(instance)}; + const uinst vinst{std::forward(instance)}; return state_->getter(vinst); } template < typename Instance, typename Value > void member::set(Instance&& instance, Value&& value) const { using namespace detail; - const inst vinst{std::forward(instance)}; - const arg vvalue{std::forward(value)}; + const uinst vinst{std::forward(instance)}; + const uarg vvalue{std::forward(value)}; state_->setter(vinst, vvalue); } template < typename Instance > - value member::operator()(Instance&& instance) const { + uvalue member::operator()(Instance&& instance) const { return get(std::forward(instance)); } @@ -211,30 +211,30 @@ namespace meta_hpp template < typename Instance > [[nodiscard]] bool member::is_gettable_with() const noexcept { using namespace detail; - const inst_base vinst{type_list{}}; + const uinst_base vinst{type_list{}}; return state_->is_gettable_with(vinst); } template < typename Instance > [[nodiscard]] bool member::is_gettable_with(Instance&& instance) const noexcept { using namespace detail; - const inst_base vinst{std::forward(instance)}; + const uinst_base vinst{std::forward(instance)}; return state_->is_gettable_with(vinst); } template < typename Instance, typename Value > [[nodiscard]] bool member::is_settable_with() const noexcept { using namespace detail; - const inst_base vinst{type_list{}}; - const arg_base vvalue{type_list{}}; + const uinst_base vinst{type_list{}}; + const uarg_base vvalue{type_list{}}; return state_->is_settable_with(vinst, vvalue); } template < typename Instance, typename Value > [[nodiscard]] bool member::is_settable_with(Instance&& instance, Value&& value) const noexcept { using namespace detail; - const inst_base vinst{std::forward(instance)}; - const arg_base vvalue{std::forward(value)}; + const uinst_base vinst{std::forward(instance)}; + const uarg_base vvalue{std::forward(value)}; return state_->is_settable_with(vinst, vvalue); } } diff --git a/headers/meta.hpp/meta_states/method.hpp b/headers/meta.hpp/meta_states/method.hpp index efd2c9c..db02f03 100644 --- a/headers/meta.hpp/meta_states/method.hpp +++ b/headers/meta.hpp/meta_states/method.hpp @@ -10,13 +10,13 @@ #include "../meta_states.hpp" #include "../meta_types/method_type.hpp" -#include "../meta_detail/value_utilities/arg.hpp" -#include "../meta_detail/value_utilities/inst.hpp" +#include "../meta_detail/value_utilities/uarg.hpp" +#include "../meta_detail/value_utilities/uinst.hpp" namespace meta_hpp::detail { template < method_policy_kind Policy, method_kind Method > - value raw_method_invoke(const Method& method, const inst& inst, std::span args) { + uvalue raw_method_invoke(const Method& method, const uinst& inst, std::span args) { using mt = method_traits; using return_type = typename mt::return_type; using qualified_type = typename mt::qualified_type; @@ -47,7 +47,7 @@ namespace meta_hpp::detail return std::invoke([ &method, &inst, args // NOLINTNEXTLINE(readability-named-parameter) - ](std::index_sequence) -> value { + ](std::index_sequence) -> uvalue { if ( !(... && args[Is].can_cast_to>()) ) { throw_exception_with("an attempt to call a method with incorrect argument types"); } @@ -57,7 +57,7 @@ namespace meta_hpp::detail method, inst.cast(), args[Is].cast>()...); - return value{}; + return uvalue{}; } else { return_type&& return_value = std::invoke( method, @@ -65,16 +65,16 @@ namespace meta_hpp::detail args[Is].cast>()...); if constexpr ( ref_as_ptr ) { - return value{std::addressof(return_value)}; + return uvalue{std::addressof(return_value)}; } else { - return value{std::forward(return_value)}; + return uvalue{std::forward(return_value)}; } } }, std::make_index_sequence()); } template < method_kind Method > - bool raw_method_is_invocable_with(const inst_base& inst, std::span args) { + bool raw_method_is_invocable_with(const uinst_base& inst, std::span args) { using mt = method_traits; using qualified_type = typename mt::qualified_type; using argument_types = typename mt::argument_types; @@ -98,7 +98,7 @@ namespace meta_hpp::detail { template < method_policy_kind Policy, method_kind Method > method_state::invoke_impl make_method_invoke(Method method) { - return [method = std::move(method)](const inst& inst, std::span args){ + return [method = std::move(method)](const uinst& inst, std::span args){ return raw_method_invoke(method, inst, args); }; } @@ -166,11 +166,11 @@ namespace meta_hpp } template < typename Instance, typename... Args > - value method::invoke(Instance&& instance, Args&&... args) const { + uvalue method::invoke(Instance&& instance, Args&&... args) const { using namespace detail; - const inst vinst{std::forward(instance)}; + const uinst vinst{std::forward(instance)}; if constexpr ( sizeof...(Args) > 0 ) { - const std::array vargs{arg{std::forward(args)}...}; + const std::array vargs{uarg{std::forward(args)}...}; return state_->invoke(vinst, vargs); } else { return state_->invoke(vinst, {}); @@ -178,16 +178,16 @@ namespace meta_hpp } template < typename Instance, typename... Args > - value method::operator()(Instance&& instance, Args&&... args) const { + uvalue method::operator()(Instance&& instance, Args&&... args) const { return invoke(std::forward(instance), std::forward(args)...); } template < typename Instance, typename... Args > bool method::is_invocable_with() const noexcept { using namespace detail; - const inst_base vinst{type_list{}}; + const uinst_base vinst{type_list{}}; if constexpr ( sizeof...(Args) > 0 ) { - const std::array vargs{arg_base{type_list{}}...}; + const std::array vargs{uarg_base{type_list{}}...}; return state_->is_invocable_with(vinst, vargs); } else { return state_->is_invocable_with(vinst, {}); @@ -197,9 +197,9 @@ namespace meta_hpp template < typename Instance, typename... Args > bool method::is_invocable_with(Instance&& instance, Args&&... args) const noexcept { using namespace detail; - const inst_base vinst{std::forward(instance)}; + const uinst_base vinst{std::forward(instance)}; if constexpr ( sizeof...(Args) > 0 ) { - const std::array vargs{arg_base{std::forward(args)}...}; + const std::array vargs{uarg_base{std::forward(args)}...}; return state_->is_invocable_with(vinst, vargs); } else { return state_->is_invocable_with(vinst, {}); diff --git a/headers/meta.hpp/meta_states/variable.hpp b/headers/meta.hpp/meta_states/variable.hpp index 54db7b7..004b0b8 100644 --- a/headers/meta.hpp/meta_states/variable.hpp +++ b/headers/meta.hpp/meta_states/variable.hpp @@ -10,12 +10,12 @@ #include "../meta_states.hpp" #include "../meta_types/pointer_type.hpp" -#include "../meta_detail/value_utilities/arg.hpp" +#include "../meta_detail/value_utilities/uarg.hpp" namespace meta_hpp::detail { template < variable_policy_kind Policy, pointer_kind Pointer > - value raw_variable_getter(const Pointer& pointer) { + uvalue raw_variable_getter(const Pointer& pointer) { using pt = pointer_traits; using data_type = typename pt::data_type; @@ -34,20 +34,20 @@ namespace meta_hpp::detail auto&& return_value = *pointer; if constexpr ( as_copy ) { - return value{std::forward(return_value)}; + return uvalue{std::forward(return_value)}; } if constexpr ( as_ptr ) { - return value{std::addressof(return_value)}; + return uvalue{std::addressof(return_value)}; } if constexpr ( as_ref_wrap) { - return value{std::ref(return_value)}; + return uvalue{std::ref(return_value)}; } } template < pointer_kind Pointer > - void raw_variable_setter([[maybe_unused]] const Pointer& pointer, const arg& arg) { + void raw_variable_setter([[maybe_unused]] const Pointer& pointer, const uarg& arg) { using pt = pointer_traits; using data_type = typename pt::data_type; @@ -62,7 +62,7 @@ namespace meta_hpp::detail } template < pointer_kind Pointer > - bool raw_variable_is_settable_with(const arg_base& arg) { + bool raw_variable_is_settable_with(const uarg_base& arg) { using pt = pointer_traits; using data_type = typename pt::data_type; @@ -82,7 +82,7 @@ namespace meta_hpp::detail template < pointer_kind Pointer > variable_state::setter_impl make_variable_setter(Pointer pointer) { - return [pointer = std::move(pointer)](const arg& arg){ + return [pointer = std::move(pointer)](const uarg& arg){ return raw_variable_setter(pointer, arg); }; } @@ -131,18 +131,18 @@ namespace meta_hpp return state_->index.get_name(); } - inline value variable::get() const { + inline uvalue variable::get() const { return state_->getter(); } template < typename Value > void variable::set(Value&& value) const { using namespace detail; - const arg vvalue{std::forward(value)}; + const uarg vvalue{std::forward(value)}; state_->setter(vvalue); } - inline value variable::operator()() const { + inline uvalue variable::operator()() const { return get(); } @@ -154,14 +154,14 @@ namespace meta_hpp template < typename Value > bool variable::is_settable_with() const noexcept { using namespace detail; - const arg_base vvalue{type_list{}}; + const uarg_base vvalue{type_list{}}; return state_->is_settable_with(vvalue); } template < typename Value > bool variable::is_settable_with(Value&& value) const noexcept { using namespace detail; - const arg vvalue{std::forward(value)}; + const uarg 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 a72820d..7cb9bbb 100644 --- a/headers/meta.hpp/meta_types.hpp +++ b/headers/meta.hpp/meta_types.hpp @@ -160,10 +160,10 @@ namespace meta_hpp [[nodiscard]] const variable_map& get_variables() const noexcept; template < typename... Args > - [[nodiscard]] value create(Args&&... args) const; + [[nodiscard]] uvalue create(Args&&... args) const; template < typename... Args > - [[nodiscard]] value operator()(Args&&... args) const; + [[nodiscard]] uvalue operator()(Args&&... args) const; template < typename Arg > bool destroy(Arg&& ptr) const; @@ -262,7 +262,7 @@ namespace meta_hpp template < typename Value > [[nodiscard]] std::string_view value_to_name(Value&& value) const noexcept; - [[nodiscard]] value name_to_value(std::string_view name) const noexcept; + [[nodiscard]] uvalue name_to_value(std::string_view name) const noexcept; private: detail::enum_type_data_ptr data_; friend auto detail::type_access(const enum_type&); diff --git a/headers/meta.hpp/meta_types/class_type.hpp b/headers/meta.hpp/meta_types/class_type.hpp index 3366643..64e3dfc 100644 --- a/headers/meta.hpp/meta_types/class_type.hpp +++ b/headers/meta.hpp/meta_types/class_type.hpp @@ -98,17 +98,17 @@ namespace meta_hpp } template < typename... Args > - value class_type::create(Args&&... args) const { + uvalue class_type::create(Args&&... args) const { for ( auto&& ctor : data_->ctors ) { if ( ctor.second.is_invocable_with(std::forward(args)...) ) { return ctor.second.invoke(std::forward(args)...); } } - return value{}; + return uvalue{}; } template < typename... Args > - value class_type::operator()(Args&&... args) const { + uvalue class_type::operator()(Args&&... args) const { return create(std::forward(args)...); } diff --git a/headers/meta.hpp/meta_types/enum_type.hpp b/headers/meta.hpp/meta_types/enum_type.hpp index d515d9f..69176a0 100644 --- a/headers/meta.hpp/meta_types/enum_type.hpp +++ b/headers/meta.hpp/meta_types/enum_type.hpp @@ -13,7 +13,7 @@ #include "../meta_detail/type_registry.hpp" #include "../meta_detail/type_traits/enum_traits.hpp" -#include "../meta_detail/value_utilities/arg.hpp" +#include "../meta_detail/value_utilities/uarg.hpp" namespace meta_hpp::detail { @@ -68,7 +68,7 @@ namespace meta_hpp template < typename Value > std::string_view enum_type::value_to_name(Value&& value) const noexcept { - const detail::arg value_arg{std::forward(value)}; + const detail::uarg value_arg{std::forward(value)}; if ( value_arg.get_raw_type() != *this ) { return std::string_view{}; @@ -83,11 +83,11 @@ namespace meta_hpp return std::string_view{}; } - inline value enum_type::name_to_value(std::string_view name) const noexcept { + inline uvalue enum_type::name_to_value(std::string_view name) const noexcept { if ( const evalue value = get_evalue(name); value ) { return value.get_value(); } - return value{}; + return uvalue{}; } } diff --git a/headers/meta.hpp/meta_value.hpp b/headers/meta.hpp/meta_value.hpp index 9dba8d1..b892aba 100644 --- a/headers/meta.hpp/meta_value.hpp +++ b/headers/meta.hpp/meta_value.hpp @@ -12,7 +12,7 @@ namespace meta_hpp::detail { template < typename T > - inline constexpr bool is_value_kind_v = std::is_same_v; + inline constexpr bool is_value_kind_v = std::is_same_v; template < typename T > concept value_kind = is_value_kind_v; @@ -26,30 +26,30 @@ namespace meta_hpp::detail namespace meta_hpp { - class value final { + class uvalue final { public: - value() = default; - ~value(); + uvalue() = default; + ~uvalue(); - value(value&& other) noexcept; - value(const value& other); + uvalue(uvalue&& other) noexcept; + uvalue(const uvalue& other); - value& operator=(value&& other) noexcept; - value& operator=(const value& other); + uvalue& operator=(uvalue&& other) noexcept; + uvalue& operator=(const uvalue& other); template < detail::decay_non_value_kind T > requires stdex::copy_constructible> - explicit value(T&& val); + explicit uvalue(T&& val); template < detail::decay_non_value_kind T > requires stdex::copy_constructible> - value& operator=(T&& val); + uvalue& operator=(T&& val); [[nodiscard]] bool is_valid() const noexcept; [[nodiscard]] explicit operator bool() const noexcept; void reset(); - void swap(value& other) noexcept; + void swap(uvalue& other) noexcept; [[nodiscard]] const any_type& get_type() const noexcept; @@ -57,8 +57,8 @@ namespace meta_hpp [[nodiscard]] const void* data() const noexcept; [[nodiscard]] const void* cdata() const noexcept; - [[nodiscard]] value operator*() const; - [[nodiscard]] value operator[](std::size_t index) const; + [[nodiscard]] uvalue operator*() const; + [[nodiscard]] uvalue operator[](std::size_t index) const; template < typename T > [[nodiscard]] std::decay_t& cast() &; @@ -78,10 +78,10 @@ namespace meta_hpp template < typename T > [[nodiscard]] const std::decay_t* try_cast() const noexcept; - friend bool operator<(const value& l, const value& r); - friend bool operator==(const value& l, const value& r); - friend std::istream& operator>>(std::istream& is, value& v); - friend std::ostream& operator<<(std::ostream& os, const value& v); + friend bool operator<(const uvalue& l, const uvalue& r); + friend bool operator==(const uvalue& l, const uvalue& r); + friend std::istream& operator>>(std::istream& is, uvalue& v); + friend std::ostream& operator<<(std::ostream& os, const uvalue& v); private: struct vtable_t; vtable_t* vtable_{}; @@ -91,7 +91,7 @@ namespace meta_hpp storage_u storage_{}; }; - inline void swap(value& l, value& r) noexcept { + inline void swap(uvalue& l, uvalue& r) noexcept { l.swap(r); } } diff --git a/headers/meta.hpp/meta_value/value.hpp b/headers/meta.hpp/meta_value/value.hpp index b86b1b9..f553571 100644 --- a/headers/meta.hpp/meta_value/value.hpp +++ b/headers/meta.hpp/meta_value/value.hpp @@ -20,24 +20,24 @@ namespace meta_hpp { - struct value::vtable_t final { + struct uvalue::vtable_t final { const any_type type; void* (*const data)(storage_u& from) noexcept; const void* (*const cdata)(const storage_u& from) noexcept; - void (*const move)(value& from, value& to) noexcept; - void (*const copy)(const value& from, value& to); - void (*const destroy)(value& self) noexcept; + void (*const move)(uvalue& from, uvalue& to) noexcept; + void (*const copy)(const uvalue& from, uvalue& to); + void (*const destroy)(uvalue& self) noexcept; - value (*const deref)(const value& from); - value (*const index)(const value& from, std::size_t); + uvalue (*const deref)(const uvalue& from); + uvalue (*const index)(const uvalue& from, std::size_t); - bool (*const less)(const value&, const value&); - bool (*const equals)(const value&, const value&); + bool (*const less)(const uvalue&, const uvalue&); + bool (*const equals)(const uvalue&, const uvalue&); - std::istream& (*const istream)(std::istream&, value&); - std::ostream& (*const ostream)(std::ostream&, const value&); + std::istream& (*const istream)(std::istream&, uvalue&); + std::ostream& (*const ostream)(std::ostream&, const uvalue&); template < typename T > static T* buffer_cast(buffer_t& buffer) noexcept { @@ -70,7 +70,7 @@ namespace meta_hpp } template < typename T > - static void construct(value& dst, T&& val) { + static void construct(uvalue& dst, T&& val) { using Tp = std::decay_t; constexpr bool in_buffer = @@ -88,19 +88,19 @@ namespace meta_hpp dst.vtable_ = vtable_t::get(); } - static void swap(value& l, value& r) noexcept { + static void swap(uvalue& l, uvalue& r) noexcept { if ( (&l == &r) || (!l && !r) ) { return; } if ( l && r ) { if ( std::holds_alternative(l.storage_) ) { - value temp; + uvalue temp; r.vtable_->move(r, temp); l.vtable_->move(l, r); temp.vtable_->move(temp, l); } else { - value temp; + uvalue temp; l.vtable_->move(l, temp); r.vtable_->move(r, l); temp.vtable_->move(temp, r); @@ -128,7 +128,7 @@ namespace meta_hpp return storage_cast(from); }, - .move = [](value& from, value& to) noexcept { + .move = [](uvalue& from, uvalue& to) noexcept { assert(from && !to); std::visit(detail::overloaded { @@ -148,7 +148,7 @@ namespace meta_hpp from.vtable_ = nullptr; }, - .copy = [](const value& from, value& to){ + .copy = [](const uvalue& from, uvalue& to){ assert(from && !to); std::visit(detail::overloaded { @@ -166,7 +166,7 @@ namespace meta_hpp to.vtable_ = from.vtable_; }, - .destroy = [](value& self) noexcept { + .destroy = [](uvalue& self) noexcept { assert(self); std::visit(detail::overloaded { @@ -184,7 +184,7 @@ namespace meta_hpp self.vtable_ = nullptr; }, - .deref = +[]([[maybe_unused]] const value& v) -> value { + .deref = +[]([[maybe_unused]] const uvalue& v) -> uvalue { if constexpr ( detail::has_deref_traits ) { return detail::deref_traits{}(v.cast()); } else { @@ -192,7 +192,7 @@ namespace meta_hpp } }, - .index = +[]([[maybe_unused]] const value& v, [[maybe_unused]] std::size_t i) -> value { + .index = +[]([[maybe_unused]] const uvalue& v, [[maybe_unused]] std::size_t i) -> uvalue { if constexpr ( detail::has_index_traits ) { return detail::index_traits{}(v.cast(), i); } else { @@ -200,7 +200,7 @@ namespace meta_hpp } }, - .less = +[]([[maybe_unused]] const value& l, [[maybe_unused]] const value& r) -> bool { + .less = +[]([[maybe_unused]] const uvalue& l, [[maybe_unused]] const uvalue& r) -> bool { if constexpr ( detail::has_less_traits ) { return detail::less_traits{}(l.cast(), r.cast()); } else { @@ -208,7 +208,7 @@ namespace meta_hpp } }, - .equals = +[]([[maybe_unused]] const value& l, [[maybe_unused]] const value& r) -> bool { + .equals = +[]([[maybe_unused]] const uvalue& l, [[maybe_unused]] const uvalue& r) -> bool { if constexpr ( detail::has_equals_traits ) { return detail::equals_traits{}(l.cast(), r.cast()); } else { @@ -216,7 +216,7 @@ namespace meta_hpp } }, - .istream = +[]([[maybe_unused]] std::istream& is, [[maybe_unused]] value& v) -> std::istream& { + .istream = +[]([[maybe_unused]] std::istream& is, [[maybe_unused]] uvalue& v) -> std::istream& { if constexpr ( detail::has_istream_traits ) { return detail::istream_traits{}(is, v.cast()); } else { @@ -224,7 +224,7 @@ namespace meta_hpp } }, - .ostream = +[]([[maybe_unused]] std::ostream& os, [[maybe_unused]] const value& v) -> std::ostream& { + .ostream = +[]([[maybe_unused]] std::ostream& os, [[maybe_unused]] const uvalue& v) -> std::ostream& { if constexpr ( detail::has_ostream_traits ) { return detail::ostream_traits{}(os, v.cast()); } else { @@ -240,94 +240,94 @@ namespace meta_hpp namespace meta_hpp { - inline value::~value() { + inline uvalue::~uvalue() { reset(); } - inline value::value(value&& other) noexcept { + inline uvalue::uvalue(uvalue&& other) noexcept { if ( other.vtable_ != nullptr ) { other.vtable_->move(other, *this); } } - inline value::value(const value& other) { + inline uvalue::uvalue(const uvalue& other) { if ( other.vtable_ != nullptr ) { other.vtable_->copy(other, *this); } } - inline value& value::operator=(value&& other) noexcept { + inline uvalue& uvalue::operator=(uvalue&& other) noexcept { if ( this != &other ) { - value{std::move(other)}.swap(*this); + uvalue{std::move(other)}.swap(*this); } return *this; } - inline value& value::operator=(const value& other) { + inline uvalue& uvalue::operator=(const uvalue& other) { if ( this != &other ) { - value{other}.swap(*this); + uvalue{other}.swap(*this); } return *this; } template < detail::decay_non_value_kind T > requires stdex::copy_constructible> - value::value(T&& val) { + uvalue::uvalue(T&& val) { vtable_t::construct(*this, std::forward(val)); } template < detail::decay_non_value_kind T > requires stdex::copy_constructible> - value& value::operator=(T&& val) { - value{std::forward(val)}.swap(*this); + uvalue& uvalue::operator=(T&& val) { + uvalue{std::forward(val)}.swap(*this); return *this; } - inline bool value::is_valid() const noexcept { + inline bool uvalue::is_valid() const noexcept { return vtable_ != nullptr; } - inline value::operator bool() const noexcept { + inline uvalue::operator bool() const noexcept { return is_valid(); } - inline void value::reset() { + inline void uvalue::reset() { if ( vtable_ != nullptr ) { vtable_->destroy(*this); } } - inline void value::swap(value& other) noexcept { + inline void uvalue::swap(uvalue& other) noexcept { vtable_t::swap(*this, other); } - inline const any_type& value::get_type() const noexcept { + inline const any_type& uvalue::get_type() const noexcept { static any_type void_type = detail::resolve_type(); return vtable_ != nullptr ? vtable_->type : void_type; } - inline void* value::data() noexcept { + inline void* uvalue::data() noexcept { return vtable_ != nullptr ? vtable_->data(storage_) : nullptr; } - inline const void* value::data() const noexcept { + inline const void* uvalue::data() const noexcept { return vtable_ != nullptr ? vtable_->cdata(storage_) : nullptr; } - inline const void* value::cdata() const noexcept { + inline const void* uvalue::cdata() const noexcept { return vtable_ != nullptr ? vtable_->cdata(storage_) : nullptr; } - inline value value::operator*() const { - return vtable_ != nullptr ? vtable_->deref(*this) : value{}; + inline uvalue uvalue::operator*() const { + return vtable_ != nullptr ? vtable_->deref(*this) : uvalue{}; } - inline value value::operator[](std::size_t index) const { - return vtable_ != nullptr ? vtable_->index(*this, index) : value{}; + inline uvalue uvalue::operator[](std::size_t index) const { + return vtable_ != nullptr ? vtable_->index(*this, index) : uvalue{}; } template < typename T > - std::decay_t& value::cast() & { + std::decay_t& uvalue::cast() & { using Tp = std::decay_t; if ( Tp* ptr = try_cast() ) { return *ptr; @@ -336,7 +336,7 @@ namespace meta_hpp } template < typename T > - std::decay_t&& value::cast() && { + std::decay_t&& uvalue::cast() && { using Tp = std::decay_t; if ( Tp* ptr = try_cast() ) { return std::move(*ptr); @@ -345,7 +345,7 @@ namespace meta_hpp } template < typename T > - const std::decay_t& value::cast() const & { + const std::decay_t& uvalue::cast() const & { using Tp = std::decay_t; if ( const Tp* ptr = try_cast() ) { return *ptr; @@ -354,7 +354,7 @@ namespace meta_hpp } template < typename T > - const std::decay_t&& value::cast() const && { + const std::decay_t&& uvalue::cast() const && { using Tp = std::decay_t; if ( const Tp* ptr = try_cast() ) { return std::move(*ptr); @@ -363,7 +363,7 @@ namespace meta_hpp } template < typename T > - std::decay_t* value::try_cast() noexcept { + std::decay_t* uvalue::try_cast() noexcept { using Tp = std::decay_t; return get_type() == detail::resolve_type() ? vtable_t::storage_cast(storage_) @@ -371,7 +371,7 @@ namespace meta_hpp } template < typename T > - const std::decay_t* value::try_cast() const noexcept { + const std::decay_t* uvalue::try_cast() const noexcept { using Tp = std::decay_t; return get_type() == detail::resolve_type() ? vtable_t::storage_cast(storage_) @@ -382,7 +382,7 @@ namespace meta_hpp namespace meta_hpp { template < typename T > - [[nodiscard]] bool operator<(const value& l, const T& r) { + [[nodiscard]] bool operator<(const uvalue& l, const T& r) { if ( !static_cast(l) ) { return true; } @@ -394,7 +394,7 @@ namespace meta_hpp } template < typename T > - [[nodiscard]] bool operator<(const T& l, const value& r) { + [[nodiscard]] bool operator<(const T& l, const uvalue& r) { if ( !static_cast(r) ) { return false; } @@ -405,7 +405,7 @@ namespace meta_hpp return (l_type < r_type) || (l_type == r_type && l < r.cast()); } - [[nodiscard]] inline bool operator<(const value& l, const value& r) { + [[nodiscard]] inline bool operator<(const uvalue& l, const uvalue& r) { if ( !static_cast(r) ) { return false; } @@ -424,7 +424,7 @@ namespace meta_hpp namespace meta_hpp { template < typename T > - [[nodiscard]] bool operator==(const value& l, const T& r) { + [[nodiscard]] bool operator==(const uvalue& l, const T& r) { if ( !static_cast(l) ) { return false; } @@ -436,7 +436,7 @@ namespace meta_hpp } template < typename T > - [[nodiscard]] bool operator==(const T& l, const value& r) { + [[nodiscard]] bool operator==(const T& l, const uvalue& r) { if ( !static_cast(r) ) { return false; } @@ -447,7 +447,7 @@ namespace meta_hpp return l_type == r_type && l == r.cast(); } - [[nodiscard]] inline bool operator==(const value& l, const value& r) { + [[nodiscard]] inline bool operator==(const uvalue& l, const uvalue& r) { if ( static_cast(l) != static_cast(r) ) { return false; } @@ -465,11 +465,11 @@ namespace meta_hpp namespace meta_hpp { - inline std::istream& operator>>(std::istream& is, value& v) { + inline std::istream& operator>>(std::istream& is, uvalue& v) { return v.vtable_->istream(is, v); } - inline std::ostream& operator<<(std::ostream& os, const value& v) { + inline std::ostream& operator<<(std::ostream& os, const uvalue& v) { return v.vtable_->ostream(os, v); } } diff --git a/headers/meta.hpp/meta_value/vinvoke.hpp b/headers/meta.hpp/meta_value/vinvoke.hpp index 6b96b04..e9c291c 100644 --- a/headers/meta.hpp/meta_value/vinvoke.hpp +++ b/headers/meta.hpp/meta_value/vinvoke.hpp @@ -10,21 +10,21 @@ #include "../meta_states.hpp" #include "../meta_value.hpp" -#include "../meta_detail/value_utilities/arg.hpp" -#include "../meta_detail/value_utilities/inst.hpp" +#include "../meta_detail/value_utilities/uarg.hpp" +#include "../meta_detail/value_utilities/uinst.hpp" namespace meta_hpp { template < typename... Args > - value invoke(const function& function, Args&&... args) { + uvalue invoke(const function& function, Args&&... args) { return function.invoke(std::forward(args)...); } template < detail::function_kind Function, typename... Args > - value invoke(Function&& function, Args&&... args) { + uvalue invoke(Function&& function, Args&&... args) { using namespace detail; if constexpr ( sizeof...(Args) > 0 ) { - const std::array vargs{arg{std::forward(args)}...}; + const std::array vargs{uarg{std::forward(args)}...}; return raw_function_invoke(std::forward(function), vargs); } else { return raw_function_invoke(std::forward(function), {}); @@ -35,14 +35,14 @@ namespace meta_hpp namespace meta_hpp { template < typename Instance > - value invoke(const member& member, Instance&& instance) { + uvalue invoke(const member& member, Instance&& instance) { return member.get(std::forward(instance)); } template < detail::member_kind Member, typename Instance > - value invoke(Member&& member, Instance&& instance) { + uvalue invoke(Member&& member, Instance&& instance) { using namespace detail; - const inst vinst{std::forward(instance)}; + const uinst vinst{std::forward(instance)}; return raw_member_getter(std::forward(member), vinst); } } @@ -50,16 +50,16 @@ namespace meta_hpp namespace meta_hpp { template < typename Instance, typename... Args > - value invoke(const method& method, Instance&& instance, Args&&... args) { + uvalue invoke(const method& method, Instance&& instance, Args&&... args) { return method.invoke(std::forward(instance), std::forward(args)...); } template < detail::method_kind Method, typename Instance, typename... Args > - value invoke(Method&& method, Instance&& instance, Args&&... args) { + uvalue invoke(Method&& method, Instance&& instance, Args&&... args) { using namespace detail; - const inst vinst{std::forward(instance)}; + const uinst vinst{std::forward(instance)}; if constexpr ( sizeof...(Args) > 0 ) { - const std::array vargs{arg{std::forward(args)}...}; + const std::array vargs{uarg{std::forward(args)}...}; return raw_method_invoke(std::forward(method), vinst, vargs); } else { return raw_method_invoke(std::forward(method), vinst, {}); @@ -83,7 +83,7 @@ namespace meta_hpp bool is_invocable_with() { if constexpr ( sizeof...(Args) > 0 ) { using namespace detail; - const std::array vargs{arg_base{type_list{}}...}; + const std::array vargs{uarg_base{type_list{}}...}; return raw_function_is_invocable_with(vargs); } else { return raw_function_is_invocable_with({}); @@ -94,7 +94,7 @@ namespace meta_hpp bool is_invocable_with(Args&&... args) { if constexpr ( sizeof...(Args) > 0 ) { using namespace detail; - const std::array vargs{arg_base{std::forward(args)}...}; + const std::array vargs{uarg_base{std::forward(args)}...}; return raw_function_is_invocable_with(vargs); } else { return raw_function_is_invocable_with({}); @@ -133,14 +133,14 @@ namespace meta_hpp template < detail::member_kind Member, typename Instance > bool is_invocable_with() { using namespace detail; - const inst_base vinst{type_list{}}; + const uinst_base vinst{type_list{}}; 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)}; + const uinst_base vinst{std::forward(instance)}; return raw_member_is_gettable_with(vinst); } } @@ -150,9 +150,9 @@ namespace meta_hpp template < detail::method_kind Method, typename Instance, typename... Args > bool is_invocable_with() { using namespace detail; - const inst_base vinst{type_list{}}; + const uinst_base vinst{type_list{}}; if constexpr ( sizeof...(Args) > 0 ) { - const std::array vargs{arg_base{type_list{}}...}; + const std::array vargs{uarg_base{type_list{}}...}; return raw_method_is_invocable_with(vinst, vargs); } else { return raw_method_is_invocable_with(vinst, {}); @@ -162,9 +162,9 @@ namespace meta_hpp template < detail::method_kind Method, typename Instance, typename... Args > bool is_invocable_with(Instance&& instance, Args&&... args) { using namespace detail; - const inst_base vinst{std::forward(instance)}; + const uinst_base vinst{std::forward(instance)}; if constexpr ( sizeof...(Args) > 0 ) { - const std::array vargs{arg_base{std::forward(args)}...}; + const std::array vargs{uarg_base{std::forward(args)}...}; return raw_method_is_invocable_with(vinst, vargs); } else { return raw_method_is_invocable_with(vinst, {}); diff --git a/manuals/meta_examples/classes_example.cpp b/manuals/meta_examples/classes_example.cpp index 0306c2a..a969a21 100644 --- a/manuals/meta_examples/classes_example.cpp +++ b/manuals/meta_examples/classes_example.cpp @@ -71,7 +71,7 @@ TEST_CASE("meta/meta_examples/classes/usage") { const meta::method rectangle_area = rectangle_type.get_method("get_area"); // creates a rectangle instance by the registered constructor(int, int) - const meta::value rectangle_v = rectangle_type.create(10, 20); + const meta::uvalue rectangle_v = rectangle_type.create(10, 20); // calls the method with the dynamic rectangle instance 'rectangle_v' CHECK(rectangle_area.invoke(rectangle_v) == 200); diff --git a/manuals/meta_examples/enums_examples.cpp b/manuals/meta_examples/enums_examples.cpp index 9ebfe00..d61aeb5 100644 --- a/manuals/meta_examples/enums_examples.cpp +++ b/manuals/meta_examples/enums_examples.cpp @@ -52,7 +52,7 @@ TEST_CASE("meta/meta_examples/enums/usage") { CHECK(align_type.value_to_name(e) == "center"); // also, it works with dynamic value types - CHECK(align_type.value_to_name(meta::value{e}) == "center"); + CHECK(align_type.value_to_name(meta::uvalue{e}) == "center"); // ... and back again CHECK(align_type.name_to_value("center") == e); diff --git a/manuals/meta_examples/functions_example.cpp b/manuals/meta_examples/functions_example.cpp index 294a625..0008a3c 100644 --- a/manuals/meta_examples/functions_example.cpp +++ b/manuals/meta_examples/functions_example.cpp @@ -59,7 +59,7 @@ TEST_CASE("meta/meta_examples/functions/usage") { CHECK(sub_function.is_invocable_with()); // calls the function and retrieves a returned value - const meta::value sub_result_value = sub_function.invoke(60, 18); + const meta::uvalue sub_result_value = sub_function.invoke(60, 18); // checks the type of the returned value CHECK(sub_result_value.get_type() == meta::resolve_type()); diff --git a/manuals/meta_examples/members_example.cpp b/manuals/meta_examples/members_example.cpp index 350a0e3..457c501 100644 --- a/manuals/meta_examples/members_example.cpp +++ b/manuals/meta_examples/members_example.cpp @@ -50,7 +50,7 @@ TEST_CASE("meta/meta_examples/members/usage") { CHECK(ivec2_x.get_type() == meta::resolve_type()); // retrieves a member value of the class instance 'v' - const meta::value ivec2_x_value = ivec2_x.get(v); + const meta::uvalue ivec2_x_value = ivec2_x.get(v); // checks the type of the retrieved value CHECK(ivec2_x_value.get_type() == meta::resolve_type()); diff --git a/manuals/meta_examples/methods_example.cpp b/manuals/meta_examples/methods_example.cpp index 5d1f170..a9957ec 100644 --- a/manuals/meta_examples/methods_example.cpp +++ b/manuals/meta_examples/methods_example.cpp @@ -69,7 +69,7 @@ TEST_CASE("meta/meta_examples/methods/usage") { CHECK(ivec2_add.is_invocable_with()); // calls the method and retrieves a returned value - const meta::value ivec2_add_result_value = ivec2_add.invoke(v, ivec2{22, 11}); + const meta::uvalue ivec2_add_result_value = ivec2_add.invoke(v, ivec2{22, 11}); // checks the type and value of the result CHECK(ivec2_add_result_value.get_type() == meta::resolve_type()); diff --git a/manuals/meta_examples/variables_example.cpp b/manuals/meta_examples/variables_example.cpp index c3de612..8d51b8e 100644 --- a/manuals/meta_examples/variables_example.cpp +++ b/manuals/meta_examples/variables_example.cpp @@ -28,7 +28,7 @@ TEST_CASE("meta/meta_examples/variables/usage") { CHECK(pi_variable.get_type().get_data_type() == meta::resolve_type()); // retrieves a variable value - const meta::value pi_variable_value = pi_variable.get(); + const meta::uvalue pi_variable_value = pi_variable.get(); // checks the type of the retrieved value CHECK(pi_variable_value.get_type() == meta::resolve_type()); diff --git a/untests/meta_features/diamond_tests.cpp b/untests/meta_features/diamond_tests.cpp index 6a7db53..9012553 100644 --- a/untests/meta_features/diamond_tests.cpp +++ b/untests/meta_features/diamond_tests.cpp @@ -162,10 +162,10 @@ TEST_CASE("meta/meta_features/diamond") { SUBCASE("arg/cast") { { A a; - meta::value a_val{&a}; + meta::uvalue a_val{&a}; CHECK(*static_cast(a_val.data()) == &a); - meta::detail::arg a_arg{a_val}; + meta::detail::uarg a_arg{a_val}; CHECK(a_arg.can_cast_to()); CHECK(!a_arg.can_cast_to()); @@ -177,10 +177,10 @@ TEST_CASE("meta/meta_features/diamond") { } { B b; - meta::value b_val{&b}; + meta::uvalue b_val{&b}; CHECK(*static_cast(b_val.data()) == &b); - meta::detail::arg b_arg{b_val}; + meta::detail::uarg b_arg{b_val}; CHECK(b_arg.can_cast_to()); CHECK(b_arg.can_cast_to()); @@ -193,10 +193,10 @@ TEST_CASE("meta/meta_features/diamond") { } { C c; - meta::value c_val{&c}; + meta::uvalue c_val{&c}; CHECK(*static_cast(c_val.data()) == &c); - meta::detail::arg c_arg{c_val}; + meta::detail::uarg c_arg{c_val}; CHECK(c_arg.can_cast_to()); CHECK(!c_arg.can_cast_to()); @@ -209,10 +209,10 @@ TEST_CASE("meta/meta_features/diamond") { } { D d; - meta::value d_val{&d}; + meta::uvalue d_val{&d}; CHECK(*static_cast(d_val.data()) == &d); - meta::detail::arg d_arg{d_val}; + meta::detail::uarg d_arg{d_val}; CHECK(d_arg.can_cast_to()); CHECK(d_arg.can_cast_to()); @@ -227,10 +227,10 @@ TEST_CASE("meta/meta_features/diamond") { } { E e; - meta::value e_val{&e}; + meta::uvalue e_val{&e}; CHECK(*static_cast(e_val.data()) == &e); - meta::detail::arg e_arg{e_val}; + meta::detail::uarg e_arg{e_val}; CHECK(!e_arg.can_cast_to()); CHECK(!e_arg.can_cast_to()); @@ -244,8 +244,8 @@ TEST_CASE("meta/meta_features/diamond") { SUBCASE("inst/cast") { { - meta::value a_val{A{}}; - meta::detail::inst a_inst{a_val}; + meta::uvalue a_val{A{}}; + meta::detail::uinst a_inst{a_val}; CHECK(a_inst.can_cast_to()); CHECK_FALSE(a_inst.can_cast_to()); @@ -256,8 +256,8 @@ TEST_CASE("meta/meta_features/diamond") { CHECK(&a_inst.cast() == a_val.try_cast()); } { - meta::value b_val{B{}}; - meta::detail::inst b_inst{b_val}; + meta::uvalue b_val{B{}}; + meta::detail::uinst b_inst{b_val}; CHECK(b_inst.can_cast_to()); CHECK(b_inst.can_cast_to()); @@ -271,8 +271,8 @@ TEST_CASE("meta/meta_features/diamond") { CHECK(&b_inst.cast() == b_val.try_cast()); } { - meta::value c_val{C{}}; - meta::detail::inst c_inst{c_val}; + meta::uvalue c_val{C{}}; + meta::detail::uinst c_inst{c_val}; CHECK(c_inst.can_cast_to()); CHECK_FALSE(c_inst.can_cast_to()); @@ -284,8 +284,8 @@ TEST_CASE("meta/meta_features/diamond") { CHECK(&c_inst.cast() == c_val.try_cast()); } { - meta::value d_val{D{}}; - meta::detail::inst d_inst{d_val}; + meta::uvalue d_val{D{}}; + meta::detail::uinst d_inst{d_val}; CHECK(d_inst.can_cast_to()); CHECK(d_inst.can_cast_to()); @@ -304,8 +304,8 @@ TEST_CASE("meta/meta_features/diamond") { CHECK(&d_inst.cast() == d_val.try_cast()); } { - meta::value e_val{E{}}; - meta::detail::inst e_inst{e_val}; + meta::uvalue e_val{E{}}; + meta::detail::uinst e_inst{e_val}; CHECK_FALSE(e_inst.can_cast_to()); CHECK_FALSE(e_inst.can_cast_to()); diff --git a/untests/meta_states/ctor_tests.cpp b/untests/meta_states/ctor_tests.cpp index 60d1267..f5a223f 100644 --- a/untests/meta_states/ctor_tests.cpp +++ b/untests/meta_states/ctor_tests.cpp @@ -90,12 +90,12 @@ TEST_CASE("meta/meta_states/ctor") { { CHECK_FALSE(clazz_type.create(10, 20)); - const meta::value v = clazz_type.create(10); + const meta::uvalue v = clazz_type.create(10); CHECK(v.get_type() == meta::resolve_type>()); CHECK(v.cast>().i == 10); CHECK(clazz_type.destroy(nullptr)); - CHECK(clazz_type.destroy(meta::value{nullptr})); + CHECK(clazz_type.destroy(meta::uvalue{nullptr})); } CHECK(clazz<1>::ctor_counter == 1); @@ -110,13 +110,13 @@ TEST_CASE("meta/meta_states/ctor") { { CHECK_FALSE(clazz_type.create(10, 20)); - const meta::value v = clazz_type.create(20); + const meta::uvalue v = clazz_type.create(20); CHECK(v.get_type() == meta::resolve_type*>()); CHECK(v.cast*>()->i == 20); CHECK(clazz_type.destroy(v)); CHECK(clazz_type.destroy(nullptr)); - CHECK(clazz_type.destroy(meta::value{nullptr})); + CHECK(clazz_type.destroy(meta::uvalue{nullptr})); } CHECK(clazz<2>::ctor_counter == 1); @@ -131,12 +131,12 @@ TEST_CASE("meta/meta_states/ctor") { { CHECK_FALSE(clazz_type.create(10, 20)); - const meta::value v = clazz_type.create(30); + const meta::uvalue v = clazz_type.create(30); CHECK(v.get_type() == meta::resolve_type>>()); CHECK(v.cast>>()->i == 30); CHECK(clazz_type.destroy(nullptr)); - CHECK(clazz_type.destroy(meta::value{nullptr})); + CHECK(clazz_type.destroy(meta::uvalue{nullptr})); } CHECK(clazz<3>::ctor_counter == 1); diff --git a/untests/meta_states/function_tests.cpp b/untests/meta_states/function_tests.cpp index 67a5275..8498757 100644 --- a/untests/meta_states/function_tests.cpp +++ b/untests/meta_states/function_tests.cpp @@ -150,10 +150,10 @@ TEST_CASE("meta/meta_states/function") { CHECK_THROWS(func1.invoke(bounded_const_arr)); CHECK_THROWS(func1.invoke(unbounded_const_arr)); - CHECK(func1.invoke(meta::value{bounded_arr}) == 10); - CHECK(func1.invoke(meta::value{unbounded_arr}) == 10); - CHECK_THROWS(func1.invoke(meta::value{bounded_const_arr})); - CHECK_THROWS(func1.invoke(meta::value{unbounded_const_arr})); + CHECK(func1.invoke(meta::uvalue{bounded_arr}) == 10); + CHECK(func1.invoke(meta::uvalue{unbounded_arr}) == 10); + CHECK_THROWS(func1.invoke(meta::uvalue{bounded_const_arr})); + CHECK_THROWS(func1.invoke(meta::uvalue{unbounded_const_arr})); static_assert(std::is_invocable_v); static_assert(std::is_invocable_v); @@ -175,10 +175,10 @@ TEST_CASE("meta/meta_states/function") { CHECK_THROWS(func2.invoke(bounded_const_arr)); CHECK_THROWS(func2.invoke(unbounded_const_arr)); - CHECK(func2.invoke(meta::value{bounded_arr}) == 10); - CHECK(func2.invoke(meta::value{unbounded_arr}) == 10); - CHECK_THROWS(func2.invoke(meta::value{bounded_const_arr})); - CHECK_THROWS(func2.invoke(meta::value{unbounded_const_arr})); + CHECK(func2.invoke(meta::uvalue{bounded_arr}) == 10); + CHECK(func2.invoke(meta::uvalue{unbounded_arr}) == 10); + CHECK_THROWS(func2.invoke(meta::uvalue{bounded_const_arr})); + CHECK_THROWS(func2.invoke(meta::uvalue{unbounded_const_arr})); static_assert(std::is_invocable_v); static_assert(std::is_invocable_v); @@ -208,10 +208,10 @@ TEST_CASE("meta/meta_states/function") { CHECK(func1.invoke(bounded_const_arr) == 10); CHECK(func1.invoke(unbounded_const_arr) == 10); - CHECK(func1.invoke(meta::value{bounded_arr}) == 10); - CHECK(func1.invoke(meta::value{unbounded_arr}) == 10); - CHECK(func1.invoke(meta::value{bounded_const_arr}) == 10); - CHECK(func1.invoke(meta::value{unbounded_const_arr}) == 10); + CHECK(func1.invoke(meta::uvalue{bounded_arr}) == 10); + CHECK(func1.invoke(meta::uvalue{unbounded_arr}) == 10); + CHECK(func1.invoke(meta::uvalue{bounded_const_arr}) == 10); + CHECK(func1.invoke(meta::uvalue{unbounded_const_arr}) == 10); static_assert(std::is_invocable_v); static_assert(std::is_invocable_v); @@ -233,10 +233,10 @@ TEST_CASE("meta/meta_states/function") { CHECK(func2.invoke(bounded_const_arr) == 10); CHECK(func2.invoke(unbounded_const_arr) == 10); - CHECK(func2.invoke(meta::value{bounded_arr}) == 10); - CHECK(func2.invoke(meta::value{unbounded_arr}) == 10); - CHECK(func2.invoke(meta::value{bounded_const_arr}) == 10); - CHECK(func2.invoke(meta::value{unbounded_const_arr}) == 10); + CHECK(func2.invoke(meta::uvalue{bounded_arr}) == 10); + CHECK(func2.invoke(meta::uvalue{unbounded_arr}) == 10); + CHECK(func2.invoke(meta::uvalue{bounded_const_arr}) == 10); + CHECK(func2.invoke(meta::uvalue{unbounded_const_arr}) == 10); static_assert(std::is_invocable_v); static_assert(std::is_invocable_v); diff --git a/untests/meta_types/enum_type_tests.cpp b/untests/meta_types/enum_type_tests.cpp index d1505e5..5e681ea 100644 --- a/untests/meta_types/enum_type_tests.cpp +++ b/untests/meta_types/enum_type_tests.cpp @@ -131,7 +131,7 @@ TEST_CASE("meta/meta_types/enum_type") { REQUIRE(ecolor_type); CHECK(ecolor_type.value_to_name(ecolor_red) == "red"); - CHECK(ecolor_type.value_to_name(meta::value{ecolor_blue}) == "blue"); + CHECK(ecolor_type.value_to_name(meta::uvalue{ecolor_blue}) == "blue"); CHECK(ecolor_type.value_to_name(100500).empty()); CHECK(ecolor_type.value_to_name(ecolor{100500}).empty()); } diff --git a/untests/meta_utilities/arg2_tests.cpp b/untests/meta_utilities/arg2_tests.cpp index 4fb27cc..d12b969 100644 --- a/untests/meta_utilities/arg2_tests.cpp +++ b/untests/meta_utilities/arg2_tests.cpp @@ -59,7 +59,7 @@ TEST_CASE("meta/meta_utilities/arg2") { TEST_CASE("meta/meta_utilities/arg2/cast") { namespace meta = meta_hpp; - using meta::detail::arg; + using meta::detail::uarg; auto LV = []() -> D& { static D v; return v; }; auto CLV = []() -> const D& { static D v; return v; }; @@ -99,254 +99,254 @@ TEST_CASE("meta/meta_utilities/arg2/cast") { A::move_ctors_ = 0; SUBCASE("LV") { - CHECK(arg{LV()}.can_cast_to()); - CHECK(arg{LV()}.can_cast_to()); - CHECK(arg{LV()}.can_cast_to()); - CHECK(arg{LV()}.can_cast_to()); - CHECK_FALSE(arg{LV()}.can_cast_to()); - CHECK_FALSE(arg{LV()}.can_cast_to()); + CHECK(uarg{LV()}.can_cast_to()); + CHECK(uarg{LV()}.can_cast_to()); + CHECK(uarg{LV()}.can_cast_to()); + CHECK(uarg{LV()}.can_cast_to()); + CHECK_FALSE(uarg{LV()}.can_cast_to()); + CHECK_FALSE(uarg{LV()}.can_cast_to()); CHECK(A::copy_ctors_ == 0); CHECK(A::move_ctors_ == 0); - CHECK(arg{LV()}.cast().f() == 1); - CHECK(arg{LV()}.cast().f() == 1); - CHECK(arg{LV()}.cast().f() == 1); - CHECK(arg{LV()}.cast().f() == 1); - CHECK_THROWS(std::ignore = arg{LV()}.cast()); - CHECK_THROWS(std::ignore = arg{LV()}.cast()); + CHECK(uarg{LV()}.cast().f() == 1); + 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(A::copy_ctors_ == 2); CHECK(A::move_ctors_ == 0); } SUBCASE("CLV") { - CHECK(arg{CLV()}.can_cast_to()); - CHECK(arg{CLV()}.can_cast_to()); - CHECK_FALSE(arg{CLV()}.can_cast_to()); - CHECK(arg{CLV()}.can_cast_to()); - CHECK_FALSE(arg{CLV()}.can_cast_to()); - CHECK_FALSE(arg{CLV()}.can_cast_to()); + CHECK(uarg{CLV()}.can_cast_to()); + CHECK(uarg{CLV()}.can_cast_to()); + CHECK_FALSE(uarg{CLV()}.can_cast_to()); + CHECK(uarg{CLV()}.can_cast_to()); + CHECK_FALSE(uarg{CLV()}.can_cast_to()); + CHECK_FALSE(uarg{CLV()}.can_cast_to()); CHECK(A::copy_ctors_ == 0); CHECK(A::move_ctors_ == 0); - CHECK(arg{CLV()}.cast().f() == 1); - CHECK(arg{CLV()}.cast().f() == 1); - CHECK_THROWS(std::ignore = arg{CLV()}.cast()); - CHECK(arg{CLV()}.cast().f() == 1); - CHECK_THROWS(std::ignore = arg{CLV()}.cast()); - CHECK_THROWS(std::ignore = arg{CLV()}.cast()); + CHECK(uarg{CLV()}.cast().f() == 1); + CHECK(uarg{CLV()}.cast().f() == 1); + 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(A::copy_ctors_ == 2); CHECK(A::move_ctors_ == 0); } SUBCASE("XV") { - CHECK(arg{XV()}.can_cast_to()); - CHECK(arg{XV()}.can_cast_to()); - CHECK_FALSE(arg{XV()}.can_cast_to()); - CHECK(arg{XV()}.can_cast_to()); - CHECK(arg{XV()}.can_cast_to()); - CHECK(arg{XV()}.can_cast_to()); + CHECK(uarg{XV()}.can_cast_to()); + CHECK(uarg{XV()}.can_cast_to()); + CHECK_FALSE(uarg{XV()}.can_cast_to()); + CHECK(uarg{XV()}.can_cast_to()); + CHECK(uarg{XV()}.can_cast_to()); + CHECK(uarg{XV()}.can_cast_to()); CHECK(A::copy_ctors_ == 0); CHECK(A::move_ctors_ == 0); - CHECK(arg{XV()}.cast().f() == 1); - CHECK(arg{XV()}.cast().f() == 1); - CHECK_THROWS(std::ignore = arg{XV()}.cast()); - CHECK(arg{XV()}.cast().f() == 1); - CHECK(arg{XV()}.cast().f() == 1); - CHECK(arg{XV()}.cast().f() == 1); + CHECK(uarg{XV()}.cast().f() == 1); + CHECK(uarg{XV()}.cast().f() == 1); + 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); CHECK(A::copy_ctors_ == 0); CHECK(A::move_ctors_ == 2); } SUBCASE("CXV") { - CHECK(arg{CXV()}.can_cast_to()); - CHECK(arg{CXV()}.can_cast_to()); - CHECK_FALSE(arg{CXV()}.can_cast_to()); - CHECK(arg{CXV()}.can_cast_to()); - CHECK_FALSE(arg{CXV()}.can_cast_to()); - CHECK(arg{CXV()}.can_cast_to()); + CHECK(uarg{CXV()}.can_cast_to()); + CHECK(uarg{CXV()}.can_cast_to()); + CHECK_FALSE(uarg{CXV()}.can_cast_to()); + CHECK(uarg{CXV()}.can_cast_to()); + CHECK_FALSE(uarg{CXV()}.can_cast_to()); + CHECK(uarg{CXV()}.can_cast_to()); CHECK(A::copy_ctors_ == 0); CHECK(A::move_ctors_ == 0); - CHECK(arg{CXV()}.cast().f() == 1); - CHECK(arg{CXV()}.cast().f() == 1); - CHECK_THROWS(std::ignore = arg{CXV()}.cast()); - CHECK(arg{CXV()}.cast().f() == 1); - CHECK_THROWS(std::ignore = arg{CXV()}.cast()); - CHECK(arg{CXV()}.cast().f() == 1); + CHECK(uarg{CXV()}.cast().f() == 1); + CHECK(uarg{CXV()}.cast().f() == 1); + CHECK_THROWS(std::ignore = uarg{CXV()}.cast()); + CHECK(uarg{CXV()}.cast().f() == 1); + CHECK_THROWS(std::ignore = uarg{CXV()}.cast()); + CHECK(uarg{CXV()}.cast().f() == 1); CHECK(A::copy_ctors_ == 2); CHECK(A::move_ctors_ == 0); } SUBCASE("PRV") { - CHECK(arg{PRV()}.can_cast_to()); - CHECK(arg{PRV()}.can_cast_to()); - CHECK_FALSE(arg{PRV()}.can_cast_to()); - CHECK(arg{PRV()}.can_cast_to()); - CHECK(arg{PRV()}.can_cast_to()); - CHECK(arg{PRV()}.can_cast_to()); + CHECK(uarg{PRV()}.can_cast_to()); + CHECK(uarg{PRV()}.can_cast_to()); + CHECK_FALSE(uarg{PRV()}.can_cast_to()); + CHECK(uarg{PRV()}.can_cast_to()); + CHECK(uarg{PRV()}.can_cast_to()); + CHECK(uarg{PRV()}.can_cast_to()); CHECK(A::copy_ctors_ == 0); CHECK(A::move_ctors_ == 0); - CHECK(arg{PRV()}.cast().f() == 1); - CHECK(arg{PRV()}.cast().f() == 1); - CHECK_THROWS(std::ignore = arg{PRV()}.cast()); - CHECK(arg{PRV()}.cast().f() == 1); - CHECK(arg{PRV()}.cast().f() == 1); - CHECK(arg{PRV()}.cast().f() == 1); + CHECK(uarg{PRV()}.cast().f() == 1); + CHECK(uarg{PRV()}.cast().f() == 1); + 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); CHECK(A::copy_ctors_ == 0); CHECK(A::move_ctors_ == 2); } SUBCASE("CPRV") { - CHECK(arg{CPRV()}.can_cast_to()); - CHECK(arg{CPRV()}.can_cast_to()); - CHECK_FALSE(arg{CPRV()}.can_cast_to()); - CHECK(arg{CPRV()}.can_cast_to()); - CHECK_FALSE(arg{CPRV()}.can_cast_to()); - CHECK(arg{CPRV()}.can_cast_to()); + CHECK(uarg{CPRV()}.can_cast_to()); + CHECK(uarg{CPRV()}.can_cast_to()); + CHECK_FALSE(uarg{CPRV()}.can_cast_to()); + CHECK(uarg{CPRV()}.can_cast_to()); + CHECK_FALSE(uarg{CPRV()}.can_cast_to()); + CHECK(uarg{CPRV()}.can_cast_to()); CHECK(A::copy_ctors_ == 0); CHECK(A::move_ctors_ == 0); - CHECK(arg{CPRV()}.cast().f() == 1); - CHECK(arg{CPRV()}.cast().f() == 1); - CHECK_THROWS(std::ignore = arg{CPRV()}.cast()); - CHECK(arg{CPRV()}.cast().f() == 1); - CHECK_THROWS(std::ignore = arg{CPRV()}.cast()); - CHECK(arg{CPRV()}.cast().f() == 1); + CHECK(uarg{CPRV()}.cast().f() == 1); + CHECK(uarg{CPRV()}.cast().f() == 1); + CHECK_THROWS(std::ignore = uarg{CPRV()}.cast()); + CHECK(uarg{CPRV()}.cast().f() == 1); + CHECK_THROWS(std::ignore = uarg{CPRV()}.cast()); + CHECK(uarg{CPRV()}.cast().f() == 1); CHECK(A::copy_ctors_ == 2); CHECK(A::move_ctors_ == 0); } SUBCASE("LV_PTR") { - CHECK(arg{LV_PTR()}.can_cast_to()); - CHECK(arg{LV_PTR()}.can_cast_to()); - CHECK(arg{LV_PTR()}.can_cast_to()); - CHECK(arg{LV_PTR()}.can_cast_to()); + CHECK(uarg{LV_PTR()}.can_cast_to()); + CHECK(uarg{LV_PTR()}.can_cast_to()); + CHECK(uarg{LV_PTR()}.can_cast_to()); + CHECK(uarg{LV_PTR()}.can_cast_to()); - CHECK(arg{LV_PTR()}.cast()->f() == 1); - CHECK(arg{LV_PTR()}.cast()->f() == 1); - CHECK(arg{LV_PTR()}.cast()->f() == 1); - CHECK(arg{LV_PTR()}.cast()->f() == 1); + CHECK(uarg{LV_PTR()}.cast()->f() == 1); + CHECK(uarg{LV_PTR()}.cast()->f() == 1); + CHECK(uarg{LV_PTR()}.cast()->f() == 1); + CHECK(uarg{LV_PTR()}.cast()->f() == 1); } SUBCASE("LV_CPTR") { - CHECK_FALSE(arg{LV_CPTR()}.can_cast_to()); - CHECK_FALSE(arg{LV_CPTR()}.can_cast_to()); - CHECK(arg{LV_CPTR()}.can_cast_to()); - CHECK(arg{LV_CPTR()}.can_cast_to()); + CHECK_FALSE(uarg{LV_CPTR()}.can_cast_to()); + CHECK_FALSE(uarg{LV_CPTR()}.can_cast_to()); + CHECK(uarg{LV_CPTR()}.can_cast_to()); + CHECK(uarg{LV_CPTR()}.can_cast_to()); - CHECK_THROWS(std::ignore = arg{LV_CPTR()}.cast()); - CHECK_THROWS(std::ignore = arg{LV_CPTR()}.cast()); - CHECK(arg{LV_CPTR()}.cast()->f() == 1); - CHECK(arg{LV_CPTR()}.cast()->f() == 1); + 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); } SUBCASE("CLV_PTR") { - CHECK(arg{CLV_PTR()}.can_cast_to()); - CHECK(arg{CLV_PTR()}.can_cast_to()); - CHECK(arg{CLV_PTR()}.can_cast_to()); - CHECK(arg{CLV_PTR()}.can_cast_to()); + CHECK(uarg{CLV_PTR()}.can_cast_to()); + CHECK(uarg{CLV_PTR()}.can_cast_to()); + CHECK(uarg{CLV_PTR()}.can_cast_to()); + CHECK(uarg{CLV_PTR()}.can_cast_to()); - CHECK(arg{CLV_PTR()}.cast()->f() == 1); - CHECK(arg{CLV_PTR()}.cast()->f() == 1); - CHECK(arg{CLV_PTR()}.cast()->f() == 1); - CHECK(arg{CLV_PTR()}.cast()->f() == 1); + CHECK(uarg{CLV_PTR()}.cast()->f() == 1); + CHECK(uarg{CLV_PTR()}.cast()->f() == 1); + CHECK(uarg{CLV_PTR()}.cast()->f() == 1); + CHECK(uarg{CLV_PTR()}.cast()->f() == 1); } SUBCASE("CLV_CPTR") { - CHECK_FALSE(arg{CLV_CPTR()}.can_cast_to()); - CHECK_FALSE(arg{CLV_CPTR()}.can_cast_to()); - CHECK(arg{CLV_CPTR()}.can_cast_to()); - CHECK(arg{CLV_CPTR()}.can_cast_to()); + CHECK_FALSE(uarg{CLV_CPTR()}.can_cast_to()); + CHECK_FALSE(uarg{CLV_CPTR()}.can_cast_to()); + CHECK(uarg{CLV_CPTR()}.can_cast_to()); + CHECK(uarg{CLV_CPTR()}.can_cast_to()); - CHECK_THROWS(std::ignore = arg{CLV_CPTR()}.cast()); - CHECK_THROWS(std::ignore = arg{CLV_CPTR()}.cast()); - CHECK(arg{CLV_CPTR()}.cast()->f() == 1); - CHECK(arg{CLV_CPTR()}.cast()->f() == 1); + 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); } SUBCASE("XV_PTR") { - CHECK(arg{XV_PTR()}.can_cast_to()); - CHECK(arg{XV_PTR()}.can_cast_to()); - CHECK(arg{XV_PTR()}.can_cast_to()); - CHECK(arg{XV_PTR()}.can_cast_to()); + CHECK(uarg{XV_PTR()}.can_cast_to()); + CHECK(uarg{XV_PTR()}.can_cast_to()); + CHECK(uarg{XV_PTR()}.can_cast_to()); + CHECK(uarg{XV_PTR()}.can_cast_to()); - CHECK(arg{XV_PTR()}.cast()->f() == 1); - CHECK(arg{XV_PTR()}.cast()->f() == 1); - CHECK(arg{XV_PTR()}.cast()->f() == 1); - CHECK(arg{XV_PTR()}.cast()->f() == 1); + CHECK(uarg{XV_PTR()}.cast()->f() == 1); + CHECK(uarg{XV_PTR()}.cast()->f() == 1); + CHECK(uarg{XV_PTR()}.cast()->f() == 1); + CHECK(uarg{XV_PTR()}.cast()->f() == 1); } SUBCASE("XV_CPTR") { - CHECK_FALSE(arg{XV_CPTR()}.can_cast_to()); - CHECK_FALSE(arg{XV_CPTR()}.can_cast_to()); - CHECK(arg{XV_CPTR()}.can_cast_to()); - CHECK(arg{XV_CPTR()}.can_cast_to()); + CHECK_FALSE(uarg{XV_CPTR()}.can_cast_to()); + CHECK_FALSE(uarg{XV_CPTR()}.can_cast_to()); + CHECK(uarg{XV_CPTR()}.can_cast_to()); + CHECK(uarg{XV_CPTR()}.can_cast_to()); - CHECK_THROWS(std::ignore = arg{XV_CPTR()}.cast()); - CHECK_THROWS(std::ignore = arg{XV_CPTR()}.cast()); - CHECK(arg{XV_CPTR()}.cast()->f() == 1); - CHECK(arg{XV_CPTR()}.cast()->f() == 1); + 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); } SUBCASE("CXV_PTR") { - CHECK(arg{CXV_PTR()}.can_cast_to()); - CHECK(arg{CXV_PTR()}.can_cast_to()); - CHECK(arg{CXV_PTR()}.can_cast_to()); - CHECK(arg{CXV_PTR()}.can_cast_to()); + CHECK(uarg{CXV_PTR()}.can_cast_to()); + CHECK(uarg{CXV_PTR()}.can_cast_to()); + CHECK(uarg{CXV_PTR()}.can_cast_to()); + CHECK(uarg{CXV_PTR()}.can_cast_to()); - CHECK(arg{CXV_PTR()}.cast()->f() == 1); - CHECK(arg{CXV_PTR()}.cast()->f() == 1); - CHECK(arg{CXV_PTR()}.cast()->f() == 1); - CHECK(arg{CXV_PTR()}.cast()->f() == 1); + CHECK(uarg{CXV_PTR()}.cast()->f() == 1); + CHECK(uarg{CXV_PTR()}.cast()->f() == 1); + CHECK(uarg{CXV_PTR()}.cast()->f() == 1); + CHECK(uarg{CXV_PTR()}.cast()->f() == 1); } SUBCASE("CXV_CPTR") { - CHECK_FALSE(arg{CXV_CPTR()}.can_cast_to()); - CHECK_FALSE(arg{CXV_CPTR()}.can_cast_to()); - CHECK(arg{CXV_CPTR()}.can_cast_to()); - CHECK(arg{CXV_CPTR()}.can_cast_to()); + CHECK_FALSE(uarg{CXV_CPTR()}.can_cast_to()); + CHECK_FALSE(uarg{CXV_CPTR()}.can_cast_to()); + CHECK(uarg{CXV_CPTR()}.can_cast_to()); + CHECK(uarg{CXV_CPTR()}.can_cast_to()); - CHECK_THROWS(std::ignore = arg{CXV_CPTR()}.cast()); - CHECK_THROWS(std::ignore = arg{CXV_CPTR()}.cast()); - CHECK(arg{CXV_CPTR()}.cast()->f() == 1); - CHECK(arg{CXV_CPTR()}.cast()->f() == 1); + 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); } SUBCASE("PRV_PTR") { - CHECK(arg{PRV_PTR()}.can_cast_to()); - CHECK(arg{PRV_PTR()}.can_cast_to()); - CHECK(arg{PRV_PTR()}.can_cast_to()); - CHECK(arg{PRV_PTR()}.can_cast_to()); + CHECK(uarg{PRV_PTR()}.can_cast_to()); + CHECK(uarg{PRV_PTR()}.can_cast_to()); + CHECK(uarg{PRV_PTR()}.can_cast_to()); + CHECK(uarg{PRV_PTR()}.can_cast_to()); - CHECK(arg{PRV_PTR()}.cast()->f() == 1); - CHECK(arg{PRV_PTR()}.cast()->f() == 1); - CHECK(arg{PRV_PTR()}.cast()->f() == 1); - CHECK(arg{PRV_PTR()}.cast()->f() == 1); + CHECK(uarg{PRV_PTR()}.cast()->f() == 1); + CHECK(uarg{PRV_PTR()}.cast()->f() == 1); + CHECK(uarg{PRV_PTR()}.cast()->f() == 1); + CHECK(uarg{PRV_PTR()}.cast()->f() == 1); } SUBCASE("PRV_CPTR") { - CHECK_FALSE(arg{PRV_CPTR()}.can_cast_to()); - CHECK_FALSE(arg{PRV_CPTR()}.can_cast_to()); - CHECK(arg{PRV_CPTR()}.can_cast_to()); - CHECK(arg{PRV_CPTR()}.can_cast_to()); + CHECK_FALSE(uarg{PRV_CPTR()}.can_cast_to()); + CHECK_FALSE(uarg{PRV_CPTR()}.can_cast_to()); + CHECK(uarg{PRV_CPTR()}.can_cast_to()); + CHECK(uarg{PRV_CPTR()}.can_cast_to()); - CHECK_THROWS(std::ignore = arg{PRV_CPTR()}.cast()); - CHECK_THROWS(std::ignore = arg{PRV_CPTR()}.cast()); - CHECK(arg{PRV_CPTR()}.cast()->f() == 1); - CHECK(arg{PRV_CPTR()}.cast()->f() == 1); + 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/untests/meta_utilities/arg3_tests.cpp b/untests/meta_utilities/arg3_tests.cpp index 2b84f8d..9475702 100644 --- a/untests/meta_utilities/arg3_tests.cpp +++ b/untests/meta_utilities/arg3_tests.cpp @@ -52,7 +52,7 @@ TEST_CASE("meta/meta_utilities/arg3") { TEST_CASE("meta/meta_utilities/arg3/cast") { namespace meta = meta_hpp; - using meta::detail::arg; + using meta::detail::uarg; auto LV = []() -> D& { static D v; return v; }; auto CLV = []() -> const D& { static D v; return v; }; @@ -78,50 +78,50 @@ TEST_CASE("meta/meta_utilities/arg3/cast") { // *------------------------------------------------------------* SUBCASE("LV") { - CHECK_FALSE(arg{LV()}.can_cast_to()); - CHECK_FALSE(arg{LV()}.can_cast_to()); + CHECK_FALSE(uarg{LV()}.can_cast_to()); + CHECK_FALSE(uarg{LV()}.can_cast_to()); - CHECK_THROWS(std::ignore = arg{LV()}.cast()); - CHECK_THROWS(std::ignore = arg{LV()}.cast()); + CHECK_THROWS(std::ignore = uarg{LV()}.cast()); + CHECK_THROWS(std::ignore = uarg{LV()}.cast()); } SUBCASE("CLV") { - CHECK_FALSE(arg{CLV()}.can_cast_to()); - CHECK_FALSE(arg{CLV()}.can_cast_to()); + CHECK_FALSE(uarg{CLV()}.can_cast_to()); + CHECK_FALSE(uarg{CLV()}.can_cast_to()); - CHECK_THROWS(std::ignore = arg{CLV()}.cast()); - CHECK_THROWS(std::ignore = arg{CLV()}.cast()); + CHECK_THROWS(std::ignore = uarg{CLV()}.cast()); + CHECK_THROWS(std::ignore = uarg{CLV()}.cast()); } SUBCASE("XV") { - CHECK_FALSE(arg{XV()}.can_cast_to()); - CHECK_FALSE(arg{XV()}.can_cast_to()); + CHECK_FALSE(uarg{XV()}.can_cast_to()); + CHECK_FALSE(uarg{XV()}.can_cast_to()); - CHECK_THROWS(std::ignore = arg{XV()}.cast()); - CHECK_THROWS(std::ignore = arg{XV()}.cast()); + CHECK_THROWS(std::ignore = uarg{XV()}.cast()); + CHECK_THROWS(std::ignore = uarg{XV()}.cast()); } SUBCASE("CXV") { - CHECK_FALSE(arg{CXV()}.can_cast_to()); - CHECK_FALSE(arg{CXV()}.can_cast_to()); + CHECK_FALSE(uarg{CXV()}.can_cast_to()); + CHECK_FALSE(uarg{CXV()}.can_cast_to()); - CHECK_THROWS(std::ignore = arg{CXV()}.cast()); - CHECK_THROWS(std::ignore = arg{CXV()}.cast()); + CHECK_THROWS(std::ignore = uarg{CXV()}.cast()); + CHECK_THROWS(std::ignore = uarg{CXV()}.cast()); } SUBCASE("PRV") { - CHECK_FALSE(arg{PRV()}.can_cast_to()); - CHECK_FALSE(arg{PRV()}.can_cast_to()); + CHECK_FALSE(uarg{PRV()}.can_cast_to()); + CHECK_FALSE(uarg{PRV()}.can_cast_to()); - CHECK_THROWS(std::ignore = arg{PRV()}.cast()); - CHECK_THROWS(std::ignore = arg{PRV()}.cast()); + CHECK_THROWS(std::ignore = uarg{PRV()}.cast()); + CHECK_THROWS(std::ignore = uarg{PRV()}.cast()); } SUBCASE("CPRV") { - CHECK_FALSE(arg{CPRV()}.can_cast_to()); - CHECK_FALSE(arg{CPRV()}.can_cast_to()); + CHECK_FALSE(uarg{CPRV()}.can_cast_to()); + CHECK_FALSE(uarg{CPRV()}.can_cast_to()); - CHECK_THROWS(std::ignore = arg{CPRV()}.cast()); - CHECK_THROWS(std::ignore = arg{CPRV()}.cast()); + CHECK_THROWS(std::ignore = uarg{CPRV()}.cast()); + CHECK_THROWS(std::ignore = uarg{CPRV()}.cast()); } } diff --git a/untests/meta_utilities/arg4_tests.cpp b/untests/meta_utilities/arg4_tests.cpp index 549c8a4..6a62042 100644 --- a/untests/meta_utilities/arg4_tests.cpp +++ b/untests/meta_utilities/arg4_tests.cpp @@ -8,7 +8,7 @@ TEST_CASE("meta/meta_utilities/arg4/cast") { namespace meta = meta_hpp; - using meta::detail::arg; + using meta::detail::uarg; auto LV_PTR = []() -> int*& { static int v{42}; static int* p{&v}; return p; }; auto CLV_PTR = []() -> int* const& { static int v{42}; static int* p{&v}; return p; }; @@ -23,122 +23,122 @@ TEST_CASE("meta/meta_utilities/arg4/cast") { auto PRV_CPTR = []() -> const int* { static int v{42}; static const int* p{&v}; return p; }; SUBCASE("LV_PTR") { - CHECK(arg{LV_PTR()}.can_cast_to()); - CHECK(arg{LV_PTR()}.can_cast_to()); - CHECK(arg{LV_PTR()}.can_cast_to()); - CHECK(arg{LV_PTR()}.can_cast_to()); + CHECK(uarg{LV_PTR()}.can_cast_to()); + CHECK(uarg{LV_PTR()}.can_cast_to()); + CHECK(uarg{LV_PTR()}.can_cast_to()); + CHECK(uarg{LV_PTR()}.can_cast_to()); - CHECK(*arg{LV_PTR()}.cast() == 42); - CHECK(*arg{LV_PTR()}.cast() == 42); - CHECK(*arg{LV_PTR()}.cast() == 42); - CHECK(*arg{LV_PTR()}.cast() == 42); + CHECK(*uarg{LV_PTR()}.cast() == 42); + CHECK(*uarg{LV_PTR()}.cast() == 42); + CHECK(*uarg{LV_PTR()}.cast() == 42); + CHECK(*uarg{LV_PTR()}.cast() == 42); } SUBCASE("CLV_PTR") { - CHECK(arg{CLV_PTR()}.can_cast_to()); - CHECK(arg{CLV_PTR()}.can_cast_to()); - CHECK(arg{CLV_PTR()}.can_cast_to()); - CHECK(arg{CLV_PTR()}.can_cast_to()); + CHECK(uarg{CLV_PTR()}.can_cast_to()); + CHECK(uarg{CLV_PTR()}.can_cast_to()); + CHECK(uarg{CLV_PTR()}.can_cast_to()); + CHECK(uarg{CLV_PTR()}.can_cast_to()); - CHECK(*arg{CLV_PTR()}.cast() == 42); - CHECK(*arg{CLV_PTR()}.cast() == 42); - CHECK(*arg{CLV_PTR()}.cast() == 42); - CHECK(*arg{CLV_PTR()}.cast() == 42); + CHECK(*uarg{CLV_PTR()}.cast() == 42); + CHECK(*uarg{CLV_PTR()}.cast() == 42); + CHECK(*uarg{CLV_PTR()}.cast() == 42); + CHECK(*uarg{CLV_PTR()}.cast() == 42); } SUBCASE("XV_PTR") { - CHECK(arg{XV_PTR()}.can_cast_to()); - CHECK(arg{XV_PTR()}.can_cast_to()); - CHECK(arg{XV_PTR()}.can_cast_to()); - CHECK(arg{XV_PTR()}.can_cast_to()); + CHECK(uarg{XV_PTR()}.can_cast_to()); + CHECK(uarg{XV_PTR()}.can_cast_to()); + CHECK(uarg{XV_PTR()}.can_cast_to()); + CHECK(uarg{XV_PTR()}.can_cast_to()); - CHECK(*arg{XV_PTR()}.cast() == 42); - CHECK(*arg{XV_PTR()}.cast() == 42); - CHECK(*arg{XV_PTR()}.cast() == 42); - CHECK(*arg{XV_PTR()}.cast() == 42); + CHECK(*uarg{XV_PTR()}.cast() == 42); + CHECK(*uarg{XV_PTR()}.cast() == 42); + CHECK(*uarg{XV_PTR()}.cast() == 42); + CHECK(*uarg{XV_PTR()}.cast() == 42); } SUBCASE("CXV_PTR") { - CHECK(arg{CXV_PTR()}.can_cast_to()); - CHECK(arg{CXV_PTR()}.can_cast_to()); - CHECK(arg{CXV_PTR()}.can_cast_to()); - CHECK(arg{CXV_PTR()}.can_cast_to()); + CHECK(uarg{CXV_PTR()}.can_cast_to()); + CHECK(uarg{CXV_PTR()}.can_cast_to()); + CHECK(uarg{CXV_PTR()}.can_cast_to()); + CHECK(uarg{CXV_PTR()}.can_cast_to()); - CHECK(*arg{CXV_PTR()}.cast() == 42); - CHECK(*arg{CXV_PTR()}.cast() == 42); - CHECK(*arg{CXV_PTR()}.cast() == 42); - CHECK(*arg{CXV_PTR()}.cast() == 42); + CHECK(*uarg{CXV_PTR()}.cast() == 42); + CHECK(*uarg{CXV_PTR()}.cast() == 42); + CHECK(*uarg{CXV_PTR()}.cast() == 42); + CHECK(*uarg{CXV_PTR()}.cast() == 42); } SUBCASE("PRV_PTR") { - CHECK(arg{PRV_PTR()}.can_cast_to()); - CHECK(arg{PRV_PTR()}.can_cast_to()); - CHECK(arg{PRV_PTR()}.can_cast_to()); - CHECK(arg{PRV_PTR()}.can_cast_to()); + CHECK(uarg{PRV_PTR()}.can_cast_to()); + CHECK(uarg{PRV_PTR()}.can_cast_to()); + CHECK(uarg{PRV_PTR()}.can_cast_to()); + CHECK(uarg{PRV_PTR()}.can_cast_to()); - CHECK(*arg{PRV_PTR()}.cast() == 42); - CHECK(*arg{PRV_PTR()}.cast() == 42); - CHECK(*arg{PRV_PTR()}.cast() == 42); - CHECK(*arg{PRV_PTR()}.cast() == 42); + CHECK(*uarg{PRV_PTR()}.cast() == 42); + CHECK(*uarg{PRV_PTR()}.cast() == 42); + CHECK(*uarg{PRV_PTR()}.cast() == 42); + CHECK(*uarg{PRV_PTR()}.cast() == 42); } SUBCASE("LV_CPTR") { - CHECK_FALSE(arg{LV_CPTR()}.can_cast_to()); - CHECK_FALSE(arg{LV_CPTR()}.can_cast_to()); - CHECK(arg{LV_CPTR()}.can_cast_to()); - CHECK(arg{LV_CPTR()}.can_cast_to()); + CHECK_FALSE(uarg{LV_CPTR()}.can_cast_to()); + CHECK_FALSE(uarg{LV_CPTR()}.can_cast_to()); + CHECK(uarg{LV_CPTR()}.can_cast_to()); + CHECK(uarg{LV_CPTR()}.can_cast_to()); - CHECK_THROWS(std::ignore = arg{LV_CPTR()}.cast()); - CHECK_THROWS(std::ignore = arg{LV_CPTR()}.cast()); - CHECK(*arg{LV_CPTR()}.cast() == 42); - CHECK(*arg{LV_CPTR()}.cast() == 42); + 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); } SUBCASE("CLV_CPTR") { - CHECK_FALSE(arg{CLV_CPTR()}.can_cast_to()); - CHECK_FALSE(arg{CLV_CPTR()}.can_cast_to()); - CHECK(arg{CLV_CPTR()}.can_cast_to()); - CHECK(arg{CLV_CPTR()}.can_cast_to()); + CHECK_FALSE(uarg{CLV_CPTR()}.can_cast_to()); + CHECK_FALSE(uarg{CLV_CPTR()}.can_cast_to()); + CHECK(uarg{CLV_CPTR()}.can_cast_to()); + CHECK(uarg{CLV_CPTR()}.can_cast_to()); - CHECK_THROWS(std::ignore = arg{CLV_CPTR()}.cast()); - CHECK_THROWS(std::ignore = arg{CLV_CPTR()}.cast()); - CHECK(*arg{CLV_CPTR()}.cast() == 42); - CHECK(*arg{CLV_CPTR()}.cast() == 42); + 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); } SUBCASE("XV_CPTR") { - CHECK_FALSE(arg{XV_CPTR()}.can_cast_to()); - CHECK_FALSE(arg{XV_CPTR()}.can_cast_to()); - CHECK(arg{XV_CPTR()}.can_cast_to()); - CHECK(arg{XV_CPTR()}.can_cast_to()); + CHECK_FALSE(uarg{XV_CPTR()}.can_cast_to()); + CHECK_FALSE(uarg{XV_CPTR()}.can_cast_to()); + CHECK(uarg{XV_CPTR()}.can_cast_to()); + CHECK(uarg{XV_CPTR()}.can_cast_to()); - CHECK_THROWS(std::ignore = arg{XV_CPTR()}.cast()); - CHECK_THROWS(std::ignore = arg{XV_CPTR()}.cast()); - CHECK(*arg{XV_CPTR()}.cast() == 42); - CHECK(*arg{XV_CPTR()}.cast() == 42); + 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); } SUBCASE("CXV_CPTR") { - CHECK_FALSE(arg{CXV_CPTR()}.can_cast_to()); - CHECK_FALSE(arg{CXV_CPTR()}.can_cast_to()); - CHECK(arg{CXV_CPTR()}.can_cast_to()); - CHECK(arg{CXV_CPTR()}.can_cast_to()); + CHECK_FALSE(uarg{CXV_CPTR()}.can_cast_to()); + CHECK_FALSE(uarg{CXV_CPTR()}.can_cast_to()); + CHECK(uarg{CXV_CPTR()}.can_cast_to()); + CHECK(uarg{CXV_CPTR()}.can_cast_to()); - CHECK_THROWS(std::ignore = arg{CXV_CPTR()}.cast()); - CHECK_THROWS(std::ignore = arg{CXV_CPTR()}.cast()); - CHECK(*arg{CXV_CPTR()}.cast() == 42); - CHECK(*arg{CXV_CPTR()}.cast() == 42); + 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); } SUBCASE("PRV_CPTR") { - CHECK_FALSE(arg{PRV_CPTR()}.can_cast_to()); - CHECK_FALSE(arg{PRV_CPTR()}.can_cast_to()); - CHECK(arg{PRV_CPTR()}.can_cast_to()); - CHECK(arg{PRV_CPTR()}.can_cast_to()); + CHECK_FALSE(uarg{PRV_CPTR()}.can_cast_to()); + CHECK_FALSE(uarg{PRV_CPTR()}.can_cast_to()); + CHECK(uarg{PRV_CPTR()}.can_cast_to()); + CHECK(uarg{PRV_CPTR()}.can_cast_to()); - CHECK_THROWS(std::ignore = arg{PRV_CPTR()}.cast()); - CHECK_THROWS(std::ignore = arg{PRV_CPTR()}.cast()); - CHECK(*arg{PRV_CPTR()}.cast() == 42); - CHECK(*arg{PRV_CPTR()}.cast() == 42); + 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/untests/meta_utilities/arg5_tests.cpp b/untests/meta_utilities/arg5_tests.cpp index c8b9ae7..cd5536a 100644 --- a/untests/meta_utilities/arg5_tests.cpp +++ b/untests/meta_utilities/arg5_tests.cpp @@ -48,86 +48,86 @@ TEST_CASE("meta/meta_utilities/arg5") { TEST_CASE("meta/meta_utilities/arg5/cast") { namespace meta = meta_hpp; - using meta::detail::arg; + using meta::detail::uarg; SUBCASE("int[2]") { int arr[2]{1,2}; - CHECK(arg(arr).get_raw_type() == meta::resolve_type(arr)); + CHECK(uarg(arr).get_raw_type() == meta::resolve_type(arr)); static_assert(std::is_invocable_v); static_assert(std::is_invocable_v); static_assert(std::is_invocable_v); static_assert(std::is_invocable_v); - CHECK(arg(arr).can_cast_to()); - CHECK(arg(arr).can_cast_to()); - CHECK(arg(arr).can_cast_to()); - CHECK(arg(arr).can_cast_to()); + CHECK(uarg(arr).can_cast_to()); + CHECK(uarg(arr).can_cast_to()); + CHECK(uarg(arr).can_cast_to()); + CHECK(uarg(arr).can_cast_to()); - CHECK(arg(arr).cast() == static_cast(arr)); - CHECK(arg(arr).cast() == static_cast(arr)); - CHECK(arg(arr).cast() == static_cast(arr)); - CHECK(arg(arr).cast() == static_cast(arr)); + CHECK(uarg(arr).cast() == static_cast(arr)); + CHECK(uarg(arr).cast() == static_cast(arr)); + CHECK(uarg(arr).cast() == static_cast(arr)); + CHECK(uarg(arr).cast() == static_cast(arr)); } SUBCASE("const int[2]") { const int arr[2]{1,2}; - CHECK(arg(arr).get_raw_type() == meta::resolve_type(arr)); + CHECK(uarg(arr).get_raw_type() == meta::resolve_type(arr)); static_assert(!std::is_invocable_v); static_assert(std::is_invocable_v); static_assert(!std::is_invocable_v); static_assert(std::is_invocable_v); - CHECK_FALSE(arg(arr).can_cast_to()); - CHECK(arg(arr).can_cast_to()); - CHECK_FALSE(arg(arr).can_cast_to()); - CHECK(arg(arr).can_cast_to()); + CHECK_FALSE(uarg(arr).can_cast_to()); + CHECK(uarg(arr).can_cast_to()); + CHECK_FALSE(uarg(arr).can_cast_to()); + CHECK(uarg(arr).can_cast_to()); - CHECK_THROWS(std::ignore = arg(arr).cast()); - CHECK(arg(arr).cast() == static_cast(arr)); - CHECK_THROWS(std::ignore = arg(arr).cast()); - CHECK(arg(arr).cast() == static_cast(arr)); + CHECK_THROWS(std::ignore = uarg(arr).cast()); + CHECK(uarg(arr).cast() == static_cast(arr)); + CHECK_THROWS(std::ignore = uarg(arr).cast()); + CHECK(uarg(arr).cast() == static_cast(arr)); } SUBCASE("D[2]") { D arr[2]; - CHECK(arg(arr).get_raw_type() == meta::resolve_type(arr)); + CHECK(uarg(arr).get_raw_type() == meta::resolve_type(arr)); static_assert(std::is_invocable_v); static_assert(std::is_invocable_v); static_assert(std::is_invocable_v); static_assert(std::is_invocable_v); - CHECK(arg(arr).can_cast_to()); - CHECK(arg(arr).can_cast_to()); - CHECK(arg(arr).can_cast_to()); - CHECK(arg(arr).can_cast_to()); + CHECK(uarg(arr).can_cast_to()); + CHECK(uarg(arr).can_cast_to()); + CHECK(uarg(arr).can_cast_to()); + CHECK(uarg(arr).can_cast_to()); - CHECK(arg(arr).cast() == static_cast(arr)); - CHECK(arg(arr).cast() == static_cast(arr)); - CHECK(arg(arr).cast() == static_cast(arr)); - CHECK(arg(arr).cast() == static_cast(arr)); + CHECK(uarg(arr).cast() == static_cast(arr)); + CHECK(uarg(arr).cast() == static_cast(arr)); + CHECK(uarg(arr).cast() == static_cast(arr)); + CHECK(uarg(arr).cast() == static_cast(arr)); } SUBCASE("const D[2]") { const D arr[2]; - CHECK(arg(arr).get_raw_type() == meta::resolve_type(arr)); + CHECK(uarg(arr).get_raw_type() == meta::resolve_type(arr)); static_assert(!std::is_invocable_v); static_assert(std::is_invocable_v); static_assert(!std::is_invocable_v); static_assert(std::is_invocable_v); - CHECK_FALSE(arg(arr).can_cast_to()); - CHECK(arg(arr).can_cast_to()); - CHECK_FALSE(arg(arr).can_cast_to()); - CHECK(arg(arr).can_cast_to()); + CHECK_FALSE(uarg(arr).can_cast_to()); + CHECK(uarg(arr).can_cast_to()); + CHECK_FALSE(uarg(arr).can_cast_to()); + CHECK(uarg(arr).can_cast_to()); - CHECK_THROWS(std::ignore = arg(arr).cast()); - CHECK(arg(arr).cast() == static_cast(arr)); - CHECK_THROWS(std::ignore = arg(arr).cast()); - CHECK(arg(arr).cast() == static_cast(arr)); + CHECK_THROWS(std::ignore = uarg(arr).cast()); + CHECK(uarg(arr).cast() == static_cast(arr)); + CHECK_THROWS(std::ignore = uarg(arr).cast()); + CHECK(uarg(arr).cast() == static_cast(arr)); } SUBCASE("&") { @@ -136,7 +136,7 @@ TEST_CASE("meta/meta_utilities/arg5/cast") { { auto LV = []() -> T& { return src; }; - CHECK(arg{LV()}.get_raw_type() == meta::resolve_type()); + CHECK(uarg{LV()}.get_raw_type() == meta::resolve_type()); static_assert(std::is_invocable_v); static_assert(std::is_invocable_v); @@ -148,55 +148,55 @@ TEST_CASE("meta/meta_utilities/arg5/cast") { CHECK_NOTHROW([](A* const){}(LV())); CHECK_NOTHROW([](const A* const){}(LV())); - CHECK(arg(LV()).cast() == static_cast(src)); - CHECK(arg(LV()).cast() == static_cast(src)); - CHECK(arg(LV()).cast() == static_cast(src)); - CHECK(arg(LV()).cast() == static_cast(src)); + CHECK(uarg(LV()).cast() == static_cast(src)); + CHECK(uarg(LV()).cast() == static_cast(src)); + CHECK(uarg(LV()).cast() == static_cast(src)); + CHECK(uarg(LV()).cast() == static_cast(src)); } { auto CLV = []() -> const T& { return src; }; - CHECK(arg{CLV()}.get_raw_type() == meta::resolve_type()); + CHECK(uarg{CLV()}.get_raw_type() == meta::resolve_type()); static_assert(!std::is_invocable_v); static_assert(std::is_invocable_v); static_assert(!std::is_invocable_v); static_assert(std::is_invocable_v); - CHECK_THROWS(std::ignore = arg(CLV()).cast()); - CHECK(arg(CLV()).cast() == static_cast(src)); - CHECK_THROWS(std::ignore = arg(CLV()).cast()); - CHECK(arg(CLV()).cast() == static_cast(src)); + CHECK_THROWS(std::ignore = uarg(CLV()).cast()); + CHECK(uarg(CLV()).cast() == static_cast(src)); + CHECK_THROWS(std::ignore = uarg(CLV()).cast()); + CHECK(uarg(CLV()).cast() == static_cast(src)); } { auto XV = []() -> T&& { return std::move(src); }; - CHECK(arg{XV()}.get_raw_type() == meta::resolve_type()); + CHECK(uarg{XV()}.get_raw_type() == meta::resolve_type()); static_assert(std::is_invocable_v); static_assert(std::is_invocable_v); static_assert(std::is_invocable_v); static_assert(std::is_invocable_v); - CHECK(arg(XV()).cast() == static_cast(src)); - CHECK(arg(XV()).cast() == static_cast(src)); - CHECK(arg(XV()).cast() == static_cast(src)); - CHECK(arg(XV()).cast() == static_cast(src)); + CHECK(uarg(XV()).cast() == static_cast(src)); + CHECK(uarg(XV()).cast() == static_cast(src)); + CHECK(uarg(XV()).cast() == static_cast(src)); + CHECK(uarg(XV()).cast() == static_cast(src)); } { auto CXV = []() -> const T&& { return std::move(src); }; - CHECK(arg{CXV()}.get_raw_type() == meta::resolve_type()); + CHECK(uarg{CXV()}.get_raw_type() == meta::resolve_type()); static_assert(!std::is_invocable_v); static_assert(std::is_invocable_v); static_assert(!std::is_invocable_v); static_assert(std::is_invocable_v); - CHECK_THROWS(std::ignore = arg(CXV()).cast()); - CHECK(arg(CXV()).cast() == static_cast(src)); - CHECK_THROWS(std::ignore = arg(CXV()).cast()); - CHECK(arg(CXV()).cast() == static_cast(src)); + CHECK_THROWS(std::ignore = uarg(CXV()).cast()); + CHECK(uarg(CXV()).cast() == static_cast(src)); + CHECK_THROWS(std::ignore = uarg(CXV()).cast()); + CHECK(uarg(CXV()).cast() == static_cast(src)); } } @@ -211,19 +211,19 @@ TEST_CASE("meta/meta_utilities/arg5/cast") { static_assert(std::is_invocable_v); static_assert(std::is_invocable_v); - CHECK(arg{arr}.can_cast_to()); - CHECK(arg{arr}.can_cast_to()); - CHECK(arg{&arr}.can_cast_to()); - CHECK(arg{&arr}.can_cast_to()); - CHECK(arg{&arr}.can_cast_to()); - CHECK(arg{&arr}.can_cast_to()); + CHECK(uarg{arr}.can_cast_to()); + CHECK(uarg{arr}.can_cast_to()); + CHECK(uarg{&arr}.can_cast_to()); + CHECK(uarg{&arr}.can_cast_to()); + CHECK(uarg{&arr}.can_cast_to()); + CHECK(uarg{&arr}.can_cast_to()); - CHECK(&arg{arr}.cast() == &arr); - CHECK(&arg{arr}.cast() == &arr); - CHECK(arg{&arr}.cast() == &arr); - CHECK(arg{&arr}.cast() == &arr); - CHECK(arg{&arr}.cast() == &arr); - CHECK(arg{&arr}.cast() == &arr); + CHECK(&uarg{arr}.cast() == &arr); + CHECK(&uarg{arr}.cast() == &arr); + CHECK(uarg{&arr}.cast() == &arr); + CHECK(uarg{&arr}.cast() == &arr); + CHECK(uarg{&arr}.cast() == &arr); + CHECK(uarg{&arr}.cast() == &arr); } { @@ -236,19 +236,19 @@ TEST_CASE("meta/meta_utilities/arg5/cast") { static_assert(!std::is_invocable_v); static_assert(std::is_invocable_v); - CHECK_FALSE(arg{arr}.can_cast_to()); - CHECK(arg{arr}.can_cast_to()); - CHECK_FALSE(arg{&arr}.can_cast_to()); - CHECK(arg{&arr}.can_cast_to()); - CHECK_FALSE(arg{&arr}.can_cast_to()); - CHECK(arg{&arr}.can_cast_to()); + CHECK_FALSE(uarg{arr}.can_cast_to()); + CHECK(uarg{arr}.can_cast_to()); + CHECK_FALSE(uarg{&arr}.can_cast_to()); + CHECK(uarg{&arr}.can_cast_to()); + CHECK_FALSE(uarg{&arr}.can_cast_to()); + CHECK(uarg{&arr}.can_cast_to()); - CHECK_THROWS(std::ignore = &arg{arr}.cast()); - CHECK(&arg{arr}.cast() == &arr); - CHECK_THROWS(std::ignore = arg{&arr}.cast()); - CHECK(arg{&arr}.cast() == &arr); - CHECK_THROWS(std::ignore = arg{&arr}.cast()); - CHECK(arg{&arr}.cast() == &arr); + CHECK_THROWS(std::ignore = &uarg{arr}.cast()); + CHECK(&uarg{arr}.cast() == &arr); + CHECK_THROWS(std::ignore = uarg{&arr}.cast()); + CHECK(uarg{&arr}.cast() == &arr); + CHECK_THROWS(std::ignore = uarg{&arr}.cast()); + CHECK(uarg{&arr}.cast() == &arr); } } } diff --git a/untests/meta_utilities/arg6_tests.cpp b/untests/meta_utilities/arg6_tests.cpp index 67c09da..a7ff536 100644 --- a/untests/meta_utilities/arg6_tests.cpp +++ b/untests/meta_utilities/arg6_tests.cpp @@ -32,7 +32,7 @@ namespace TEST_CASE("meta/meta_utilities/arg6") { namespace meta = meta_hpp; - using meta::detail::arg; + using meta::detail::uarg; const meta::scope scope = meta::local_scope_("scope") .function_("func_with_member", &func_with_member) @@ -48,8 +48,8 @@ TEST_CASE("meta/meta_utilities/arg6") { CHECK(f.is_invocable_with(cl, &clazz::int_member)); CHECK(f.invoke(cl, &clazz::int_member) == 42); - CHECK(f.is_invocable_with(meta::value{cl}, meta::value{&clazz::int_member})); - CHECK(f.invoke(meta::value{cl}, meta::value{&clazz::int_member}) == 42); + CHECK(f.is_invocable_with(meta::uvalue{cl}, meta::uvalue{&clazz::int_member})); + CHECK(f.invoke(meta::uvalue{cl}, meta::uvalue{&clazz::int_member}) == 42); } SUBCASE("int_method") { @@ -62,7 +62,7 @@ TEST_CASE("meta/meta_utilities/arg6") { CHECK(f.is_invocable_with(cl, &clazz::int_method)); CHECK(f.invoke(cl, &clazz::int_method) == 42); - CHECK(f.is_invocable_with(meta::value{cl}, meta::value{&clazz::int_method})); - CHECK(f.invoke(meta::value{cl}, meta::value{&clazz::int_method}) == 42); + CHECK(f.is_invocable_with(meta::uvalue{cl}, meta::uvalue{&clazz::int_method})); + CHECK(f.invoke(meta::uvalue{cl}, meta::uvalue{&clazz::int_method}) == 42); } } diff --git a/untests/meta_utilities/arg7_tests.cpp b/untests/meta_utilities/arg7_tests.cpp index 0cc6239..5001b49 100644 --- a/untests/meta_utilities/arg7_tests.cpp +++ b/untests/meta_utilities/arg7_tests.cpp @@ -48,7 +48,7 @@ TEST_CASE("meta/meta_utilities/arg7") { TEST_CASE("meta/meta_utilities/arg7/cast/to_void") { namespace meta = meta_hpp; - using meta::detail::arg; + using meta::detail::uarg; SUBCASE("int* -> void*") { int i{42}; @@ -56,11 +56,11 @@ TEST_CASE("meta/meta_utilities/arg7/cast/to_void") { static_assert(std::is_invocable_v); static_assert(std::is_invocable_v); - CHECK(arg{&i}.can_cast_to()); - CHECK(arg{&i}.can_cast_to()); + CHECK(uarg{&i}.can_cast_to()); + CHECK(uarg{&i}.can_cast_to()); - CHECK(arg{&i}.cast() == &i); - CHECK(arg{&i}.cast() == &i); + CHECK(uarg{&i}.cast() == &i); + CHECK(uarg{&i}.cast() == &i); } SUBCASE("const int* -> void*") { @@ -69,11 +69,11 @@ TEST_CASE("meta/meta_utilities/arg7/cast/to_void") { static_assert(!std::is_invocable_v); static_assert(std::is_invocable_v); - CHECK_FALSE(arg{&i}.can_cast_to()); - CHECK(arg{&i}.can_cast_to()); + CHECK_FALSE(uarg{&i}.can_cast_to()); + CHECK(uarg{&i}.can_cast_to()); - CHECK_THROWS(std::ignore = arg{&i}.cast()); - CHECK(arg{&i}.cast() == &i); + CHECK_THROWS(std::ignore = uarg{&i}.cast()); + CHECK(uarg{&i}.cast() == &i); } SUBCASE("D* -> void*") { @@ -82,11 +82,11 @@ TEST_CASE("meta/meta_utilities/arg7/cast/to_void") { static_assert(std::is_invocable_v); static_assert(std::is_invocable_v); - CHECK(arg{&d}.can_cast_to()); - CHECK(arg{&d}.can_cast_to()); + CHECK(uarg{&d}.can_cast_to()); + CHECK(uarg{&d}.can_cast_to()); - CHECK(arg{&d}.cast() == &d); - CHECK(arg{&d}.cast() == &d); + CHECK(uarg{&d}.cast() == &d); + CHECK(uarg{&d}.cast() == &d); } SUBCASE("const D* -> void*") { @@ -95,11 +95,11 @@ TEST_CASE("meta/meta_utilities/arg7/cast/to_void") { static_assert(!std::is_invocable_v); static_assert(std::is_invocable_v); - CHECK_FALSE(arg{&d}.can_cast_to()); - CHECK(arg{&d}.can_cast_to()); + CHECK_FALSE(uarg{&d}.can_cast_to()); + CHECK(uarg{&d}.can_cast_to()); - CHECK_THROWS(std::ignore = arg{&d}.cast()); - CHECK(arg{&d}.cast() == &d); + CHECK_THROWS(std::ignore = uarg{&d}.cast()); + CHECK(uarg{&d}.cast() == &d); } SUBCASE("D[2] -> void*") { @@ -108,11 +108,11 @@ TEST_CASE("meta/meta_utilities/arg7/cast/to_void") { static_assert(std::is_invocable_v); static_assert(std::is_invocable_v); - CHECK(arg{arr}.can_cast_to()); - CHECK(arg{arr}.can_cast_to()); + CHECK(uarg{arr}.can_cast_to()); + CHECK(uarg{arr}.can_cast_to()); - CHECK(arg{arr}.cast() == &arr); - CHECK(arg{arr}.cast() == &arr); + CHECK(uarg{arr}.cast() == &arr); + CHECK(uarg{arr}.cast() == &arr); } SUBCASE("const D[2] -> void*") { @@ -121,17 +121,17 @@ TEST_CASE("meta/meta_utilities/arg7/cast/to_void") { static_assert(!std::is_invocable_v); static_assert(std::is_invocable_v); - CHECK_FALSE(arg{arr}.can_cast_to()); - CHECK(arg{arr}.can_cast_to()); + CHECK_FALSE(uarg{arr}.can_cast_to()); + CHECK(uarg{arr}.can_cast_to()); - CHECK_THROWS(std::ignore = arg{arr}.cast()); - CHECK(arg{arr}.cast() == &arr); + CHECK_THROWS(std::ignore = uarg{arr}.cast()); + CHECK(uarg{arr}.cast() == &arr); } } TEST_CASE("meta/meta_utilities/arg7/cast/from_nullptr") { namespace meta = meta_hpp; - using meta::detail::arg; + using meta::detail::uarg; SUBCASE("nullptr -> *") { static_assert(std::is_invocable_v); @@ -151,46 +151,46 @@ TEST_CASE("meta/meta_utilities/arg7/cast/from_nullptr") { std::nullptr_t n1{nullptr}; const std::nullptr_t n2{nullptr}; - CHECK(arg{n1}.can_cast_to()); - CHECK(arg{std::move(n1)}.can_cast_to()); - CHECK(arg{n2}.can_cast_to()); - CHECK(arg{std::move(n2)}.can_cast_to()); + CHECK(uarg{n1}.can_cast_to()); + CHECK(uarg{std::move(n1)}.can_cast_to()); + CHECK(uarg{n2}.can_cast_to()); + CHECK(uarg{std::move(n2)}.can_cast_to()); - CHECK(arg{n1}.can_cast_to()); - CHECK(arg{std::move(n1)}.can_cast_to()); - CHECK(arg{n2}.can_cast_to()); - CHECK(arg{std::move(n2)}.can_cast_to()); + CHECK(uarg{n1}.can_cast_to()); + CHECK(uarg{std::move(n1)}.can_cast_to()); + CHECK(uarg{n2}.can_cast_to()); + CHECK(uarg{std::move(n2)}.can_cast_to()); - CHECK(arg{n1}.can_cast_to()); - CHECK(arg{std::move(n1)}.can_cast_to()); - CHECK(arg{n2}.can_cast_to()); - CHECK(arg{std::move(n2)}.can_cast_to()); + CHECK(uarg{n1}.can_cast_to()); + CHECK(uarg{std::move(n1)}.can_cast_to()); + CHECK(uarg{n2}.can_cast_to()); + CHECK(uarg{std::move(n2)}.can_cast_to()); - CHECK(arg{n1}.can_cast_to()); - CHECK(arg{std::move(n1)}.can_cast_to()); - CHECK(arg{n2}.can_cast_to()); - CHECK(arg{std::move(n2)}.can_cast_to()); + CHECK(uarg{n1}.can_cast_to()); + CHECK(uarg{std::move(n1)}.can_cast_to()); + CHECK(uarg{n2}.can_cast_to()); + CHECK(uarg{std::move(n2)}.can_cast_to()); // - CHECK(arg{n1}.cast() == nullptr); - CHECK(arg{std::move(n1)}.cast() == nullptr); - CHECK(arg{n2}.cast() == nullptr); - CHECK(arg{std::move(n2)}.cast() == nullptr); + CHECK(uarg{n1}.cast() == nullptr); + CHECK(uarg{std::move(n1)}.cast() == nullptr); + CHECK(uarg{n2}.cast() == nullptr); + CHECK(uarg{std::move(n2)}.cast() == nullptr); - CHECK(arg{n1}.cast() == nullptr); - CHECK(arg{std::move(n1)}.cast() == nullptr); - CHECK(arg{n2}.cast() == nullptr); - CHECK(arg{std::move(n2)}.cast() == nullptr); + CHECK(uarg{n1}.cast() == nullptr); + CHECK(uarg{std::move(n1)}.cast() == nullptr); + CHECK(uarg{n2}.cast() == nullptr); + CHECK(uarg{std::move(n2)}.cast() == nullptr); - CHECK(arg{n1}.cast() == nullptr); - CHECK(arg{std::move(n1)}.cast() == nullptr); - CHECK(arg{n2}.cast() == nullptr); - CHECK(arg{std::move(n2)}.cast() == nullptr); + CHECK(uarg{n1}.cast() == nullptr); + CHECK(uarg{std::move(n1)}.cast() == nullptr); + CHECK(uarg{n2}.cast() == nullptr); + CHECK(uarg{std::move(n2)}.cast() == nullptr); - CHECK(arg{n1}.cast() == nullptr); - CHECK(arg{std::move(n1)}.cast() == nullptr); - CHECK(arg{n2}.cast() == nullptr); - CHECK(arg{std::move(n2)}.cast() == nullptr); + CHECK(uarg{n1}.cast() == nullptr); + CHECK(uarg{std::move(n1)}.cast() == nullptr); + CHECK(uarg{n2}.cast() == nullptr); + CHECK(uarg{std::move(n2)}.cast() == nullptr); } } diff --git a/untests/meta_utilities/arg_tests.cpp b/untests/meta_utilities/arg_tests.cpp index efa1d40..eabcd78 100644 --- a/untests/meta_utilities/arg_tests.cpp +++ b/untests/meta_utilities/arg_tests.cpp @@ -73,16 +73,16 @@ namespace meta::function f_state{function_state::make("", function_ptr)};\ \ if ( std::is_invocable_v ) {\ - CHECK(arg{FromValue}.can_cast_to());\ - CHECK(arg_base{type_list{}}.can_cast_to());\ - CHECK_NOTHROW(std::ignore = arg{FromValue}.cast());\ + CHECK(uarg{FromValue}.can_cast_to());\ + CHECK(uarg_base{type_list{}}.can_cast_to());\ + CHECK_NOTHROW(std::ignore = uarg{FromValue}.cast());\ \ CHECK(f_state.is_invocable_with());\ CHECK(f_state.invoke(FromValue) == 1);\ } else {\ - CHECK_FALSE(arg{FromValue}.can_cast_to());\ - CHECK_FALSE(arg_base{type_list{}}.can_cast_to());\ - CHECK_THROWS(std::ignore = arg{FromValue}.cast());\ + CHECK_FALSE(uarg{FromValue}.can_cast_to());\ + CHECK_FALSE(uarg_base{type_list{}}.can_cast_to());\ + CHECK_THROWS(std::ignore = uarg{FromValue}.cast());\ \ CHECK_FALSE(f_state.is_invocable_with());\ CHECK_THROWS(f_state.invoke(FromValue));\ @@ -124,9 +124,9 @@ TEST_CASE("meta/meta_utilities/arg/refs") { auto LV2 = []() -> dclazz& { static dclazz v; return v; }; auto LV3 = []() -> int& { static int v{1}; return v; }; - meta::detail::arg a{LV()}; + meta::detail::uarg a{LV()}; CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::lvalue); + CHECK(a.get_ref_type() == meta::detail::uarg::ref_types::lvalue); META_HPP_CHECK_INVOCABLE(LV(), f1, clazz) META_HPP_CHECK_INVOCABLE(LV(), f2, const clazz) @@ -156,9 +156,9 @@ TEST_CASE("meta/meta_utilities/arg/refs") { auto CLV2 = []() -> const dclazz& { static dclazz v; return v; }; auto CLV3 = []() -> const int& { static int v{1}; return v; }; - meta::detail::arg a{CLV()}; + meta::detail::uarg a{CLV()}; CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::const_lvalue); + CHECK(a.get_ref_type() == meta::detail::uarg::ref_types::const_lvalue); META_HPP_CHECK_INVOCABLE(CLV(), f1, clazz) META_HPP_CHECK_INVOCABLE(CLV(), f2, const clazz) @@ -188,9 +188,9 @@ TEST_CASE("meta/meta_utilities/arg/refs") { auto XV2 = []() -> dclazz&& { static dclazz v; return std::move(v); }; auto XV3 = []() -> int&& { static int v{1}; return std::move(v); }; - meta::detail::arg a{XV()}; + meta::detail::uarg a{XV()}; CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::rvalue); + CHECK(a.get_ref_type() == meta::detail::uarg::ref_types::rvalue); META_HPP_CHECK_INVOCABLE(XV(), f1, clazz) META_HPP_CHECK_INVOCABLE(XV(), f2, const clazz) @@ -220,9 +220,9 @@ TEST_CASE("meta/meta_utilities/arg/refs") { auto CXV2 = []() -> const dclazz&& { static dclazz v; return std::move(v); }; auto CXV3 = []() -> const int&& { static int v{1}; return std::move(v); }; - meta::detail::arg a{CXV()}; + meta::detail::uarg a{CXV()}; CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::const_rvalue); + CHECK(a.get_ref_type() == meta::detail::uarg::ref_types::const_rvalue); META_HPP_CHECK_INVOCABLE(CXV(), f1, clazz) META_HPP_CHECK_INVOCABLE(CXV(), f2, const clazz) @@ -252,9 +252,9 @@ TEST_CASE("meta/meta_utilities/arg/refs") { auto PRV2 = []() -> dclazz { return dclazz{}; }; auto PRV3 = []() -> int { return int{1}; }; - meta::detail::arg a{PRV()}; + meta::detail::uarg a{PRV()}; CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::rvalue); + CHECK(a.get_ref_type() == meta::detail::uarg::ref_types::rvalue); META_HPP_CHECK_INVOCABLE(PRV(), f1, clazz) META_HPP_CHECK_INVOCABLE(PRV(), f2, const clazz) @@ -283,9 +283,9 @@ TEST_CASE("meta/meta_utilities/arg/refs") { auto CPRV = []() -> const clazz { return clazz{}; }; auto CPRV2 = []() -> const dclazz { return dclazz{}; }; - meta::detail::arg a{CPRV()}; + meta::detail::uarg a{CPRV()}; CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::const_rvalue); + CHECK(a.get_ref_type() == meta::detail::uarg::ref_types::const_rvalue); META_HPP_CHECK_INVOCABLE(CPRV(), f1, clazz) META_HPP_CHECK_INVOCABLE(CPRV(), f2, const clazz) @@ -313,9 +313,9 @@ TEST_CASE("meta/meta_utilities/arg/ptrs") { auto LV2_PTR = []() -> dclazz*& { static dclazz v; static dclazz* p{&v}; return p; }; auto LV3_PTR = []() -> int*& { static int v{1}; static int* p{&v}; return p; }; - meta::detail::arg a{LV_PTR()}; + meta::detail::uarg a{LV_PTR()}; CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::lvalue); + CHECK(a.get_ref_type() == meta::detail::uarg::ref_types::lvalue); META_HPP_CHECK_INVOCABLE(LV_PTR(), f1, clazz*) META_HPP_CHECK_INVOCABLE(LV_PTR(), f2, clazz* const) @@ -364,9 +364,9 @@ TEST_CASE("meta/meta_utilities/arg/ptrs") { auto LV2_CPTR = []() -> const dclazz*& { static dclazz v; static const dclazz* p{&v}; return p; }; auto LV3_CPTR = []() -> const int*& { static int v{1}; static const int* p{&v}; return p; }; - meta::detail::arg a{LV_CPTR()}; + meta::detail::uarg a{LV_CPTR()}; CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::lvalue); + CHECK(a.get_ref_type() == meta::detail::uarg::ref_types::lvalue); META_HPP_CHECK_INVOCABLE(LV_CPTR(), f1, clazz*) META_HPP_CHECK_INVOCABLE(LV_CPTR(), f2, clazz* const) @@ -419,9 +419,9 @@ TEST_CASE("meta/meta_utilities/arg/ptrs") { auto CLV2_PTR = []() -> dclazz* const& { static dclazz v; static dclazz* p{&v}; return p; }; auto CLV3_PTR = []() -> int* const& { static int v{1}; static int* p{&v}; return p; }; - meta::detail::arg a{CLV_PTR()}; + meta::detail::uarg a{CLV_PTR()}; CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::const_lvalue); + CHECK(a.get_ref_type() == meta::detail::uarg::ref_types::const_lvalue); META_HPP_CHECK_INVOCABLE(CLV_PTR(), f1, clazz*) META_HPP_CHECK_INVOCABLE(CLV_PTR(), f2, clazz* const) @@ -470,9 +470,9 @@ TEST_CASE("meta/meta_utilities/arg/ptrs") { auto CLV2_CPTR = []() -> const dclazz* const& { static dclazz v; static const dclazz* p{&v}; return p; }; auto CLV3_CPTR = []() -> const int* const& { static int v{1}; static const int* p{&v}; return p; }; - meta::detail::arg a{CLV_CPTR()}; + meta::detail::uarg a{CLV_CPTR()}; CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::const_lvalue); + CHECK(a.get_ref_type() == meta::detail::uarg::ref_types::const_lvalue); META_HPP_CHECK_INVOCABLE(CLV_CPTR(), f1, clazz*) META_HPP_CHECK_INVOCABLE(CLV_CPTR(), f2, clazz* const) @@ -525,9 +525,9 @@ TEST_CASE("meta/meta_utilities/arg/ptrs") { auto XV2_PTR = []() -> dclazz*&& { static dclazz v; static dclazz* p{&v}; return std::move(p); }; auto XV3_PTR = []() -> int*&& { static int v{1}; static int* p{&v}; return std::move(p); }; - meta::detail::arg a{XV_PTR()}; + meta::detail::uarg a{XV_PTR()}; CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::rvalue); + CHECK(a.get_ref_type() == meta::detail::uarg::ref_types::rvalue); META_HPP_CHECK_INVOCABLE(XV_PTR(), f1, clazz*) META_HPP_CHECK_INVOCABLE(XV_PTR(), f2, clazz* const) @@ -576,9 +576,9 @@ TEST_CASE("meta/meta_utilities/arg/ptrs") { auto XV2_CPTR = []() -> const dclazz*&& { static dclazz v; static const dclazz* p{&v}; return std::move(p); }; auto XV3_CPTR = []() -> const int*&& { static int v{1}; static const int* p{&v}; return std::move(p); }; - meta::detail::arg a{XV_CPTR()}; + meta::detail::uarg a{XV_CPTR()}; CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::rvalue); + CHECK(a.get_ref_type() == meta::detail::uarg::ref_types::rvalue); META_HPP_CHECK_INVOCABLE(XV_CPTR(), f1, clazz*) META_HPP_CHECK_INVOCABLE(XV_CPTR(), f2, clazz* const) @@ -631,9 +631,9 @@ TEST_CASE("meta/meta_utilities/arg/ptrs") { auto CXV2_PTR = []() -> dclazz* const&& { static dclazz v; static dclazz* p{&v}; return std::move(p); }; auto CXV3_PTR = []() -> int* const&& { static int v{1}; static int* p{&v}; return std::move(p); }; - meta::detail::arg a{CXV_PTR()}; + meta::detail::uarg a{CXV_PTR()}; CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::const_rvalue); + CHECK(a.get_ref_type() == meta::detail::uarg::ref_types::const_rvalue); META_HPP_CHECK_INVOCABLE(CXV_PTR(), f1, clazz*) META_HPP_CHECK_INVOCABLE(CXV_PTR(), f2, clazz* const) @@ -682,9 +682,9 @@ TEST_CASE("meta/meta_utilities/arg/ptrs") { auto CXV2_CPTR = []() -> const dclazz* const&& { static dclazz v; static const dclazz* p{&v}; return std::move(p); }; auto CXV3_CPTR = []() -> const int* const&& { static int v{1}; static const int* p{&v}; return std::move(p); }; - meta::detail::arg a{CXV_CPTR()}; + meta::detail::uarg a{CXV_CPTR()}; CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::const_rvalue); + CHECK(a.get_ref_type() == meta::detail::uarg::ref_types::const_rvalue); META_HPP_CHECK_INVOCABLE(CXV_CPTR(), f1, clazz*) META_HPP_CHECK_INVOCABLE(CXV_CPTR(), f2, clazz* const) @@ -737,9 +737,9 @@ TEST_CASE("meta/meta_utilities/arg/ptrs") { auto PRV2_PTR = []() -> dclazz* { static dclazz v; static dclazz* p{&v}; return p; }; auto PRV3_PTR = []() -> int* { static int v{1}; static int* p{&v}; return p; }; - meta::detail::arg a{PRV_PTR()}; + meta::detail::uarg a{PRV_PTR()}; CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::rvalue); + CHECK(a.get_ref_type() == meta::detail::uarg::ref_types::rvalue); META_HPP_CHECK_INVOCABLE(PRV_PTR(), f1, clazz*) META_HPP_CHECK_INVOCABLE(PRV_PTR(), f2, clazz* const) @@ -788,9 +788,9 @@ TEST_CASE("meta/meta_utilities/arg/ptrs") { auto PRV2_CPTR = []() -> const dclazz* { static dclazz v; static const dclazz* p{&v}; return p; }; auto PRV3_CPTR = []() -> const int* { static int v{1}; static const int* p{&v}; return p; }; - meta::detail::arg a{PRV_CPTR()}; + meta::detail::uarg a{PRV_CPTR()}; CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::rvalue); + CHECK(a.get_ref_type() == meta::detail::uarg::ref_types::rvalue); META_HPP_CHECK_INVOCABLE(PRV_CPTR(), f1, clazz*) META_HPP_CHECK_INVOCABLE(PRV_CPTR(), f2, clazz* const) @@ -841,13 +841,13 @@ TEST_CASE("meta/meta_utilities/arg/values") { namespace meta = meta_hpp; { - auto LV = []() -> meta::value& { static meta::value v{clazz{}}; return v; }; - auto LV2 = []() -> meta::value& { static meta::value v{dclazz{}}; return v; }; - auto LV3 = []() -> meta::value& { static meta::value v{int{1}}; return v; }; + auto LV = []() -> meta::uvalue& { static meta::uvalue v{clazz{}}; return v; }; + auto LV2 = []() -> meta::uvalue& { static meta::uvalue v{dclazz{}}; return v; }; + auto LV3 = []() -> meta::uvalue& { static meta::uvalue v{int{1}}; return v; }; - meta::detail::arg a{LV()}; + meta::detail::uarg a{LV()}; CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::lvalue); + CHECK(a.get_ref_type() == meta::detail::uarg::ref_types::lvalue); META_HPP_CHECK_INVOCABLE_2(LV(), f1, clazz&, clazz) META_HPP_CHECK_INVOCABLE_2(LV(), f2, clazz&, const clazz) @@ -872,13 +872,13 @@ TEST_CASE("meta/meta_utilities/arg/values") { } { - auto CLV = []() -> const meta::value& { static meta::value v{clazz{}}; return v; }; - auto CLV2 = []() -> const meta::value& { static meta::value v{dclazz{}}; return v; }; - auto CLV3 = []() -> const meta::value& { static meta::value v{int{1}}; return v; }; + auto CLV = []() -> const meta::uvalue& { static meta::uvalue v{clazz{}}; return v; }; + auto CLV2 = []() -> const meta::uvalue& { static meta::uvalue v{dclazz{}}; return v; }; + auto CLV3 = []() -> const meta::uvalue& { static meta::uvalue v{int{1}}; return v; }; - meta::detail::arg a{CLV()}; + meta::detail::uarg a{CLV()}; CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::const_lvalue); + CHECK(a.get_ref_type() == meta::detail::uarg::ref_types::const_lvalue); META_HPP_CHECK_INVOCABLE_2(CLV(), f1, const clazz&, clazz) META_HPP_CHECK_INVOCABLE_2(CLV(), f2, const clazz&, const clazz) @@ -903,13 +903,13 @@ TEST_CASE("meta/meta_utilities/arg/values") { } { - auto XV = []() -> meta::value&& { static meta::value v{clazz{}}; return std::move(v); }; - auto XV2 = []() -> meta::value&& { static meta::value v{dclazz{}}; return std::move(v); }; - auto XV3 = []() -> meta::value&& { static meta::value v{int{1}}; return std::move(v); }; + auto XV = []() -> meta::uvalue&& { static meta::uvalue v{clazz{}}; return std::move(v); }; + auto XV2 = []() -> meta::uvalue&& { static meta::uvalue v{dclazz{}}; return std::move(v); }; + auto XV3 = []() -> meta::uvalue&& { static meta::uvalue v{int{1}}; return std::move(v); }; - meta::detail::arg a{XV()}; + meta::detail::uarg a{XV()}; CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::rvalue); + CHECK(a.get_ref_type() == meta::detail::uarg::ref_types::rvalue); META_HPP_CHECK_INVOCABLE_2(XV(), f1, clazz&&, clazz) META_HPP_CHECK_INVOCABLE_2(XV(), f2, clazz&&, const clazz) @@ -934,13 +934,13 @@ TEST_CASE("meta/meta_utilities/arg/values") { } { - auto CXV = []() -> const meta::value&& { static meta::value v{clazz{}}; return std::move(v); }; - auto CXV2 = []() -> const meta::value&& { static meta::value v{dclazz{}}; return std::move(v); }; - auto CXV3 = []() -> const meta::value&& { static meta::value v{int{1}}; return std::move(v); }; + auto CXV = []() -> const meta::uvalue&& { static meta::uvalue v{clazz{}}; return std::move(v); }; + auto CXV2 = []() -> const meta::uvalue&& { static meta::uvalue v{dclazz{}}; return std::move(v); }; + auto CXV3 = []() -> const meta::uvalue&& { static meta::uvalue v{int{1}}; return std::move(v); }; - meta::detail::arg a{CXV()}; + meta::detail::uarg a{CXV()}; CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::const_rvalue); + CHECK(a.get_ref_type() == meta::detail::uarg::ref_types::const_rvalue); META_HPP_CHECK_INVOCABLE_2(CXV(), f1, const clazz&&, clazz) META_HPP_CHECK_INVOCABLE_2(CXV(), f2, const clazz&&, const clazz) @@ -965,13 +965,13 @@ TEST_CASE("meta/meta_utilities/arg/values") { } { - auto PRV = []() -> meta::value { return meta::value{clazz{}}; }; - auto PRV2 = []() -> meta::value { return meta::value{dclazz{}}; }; - auto PRV3 = []() -> meta::value { return meta::value{int{1}}; }; + auto PRV = []() -> meta::uvalue { return meta::uvalue{clazz{}}; }; + auto PRV2 = []() -> meta::uvalue { return meta::uvalue{dclazz{}}; }; + auto PRV3 = []() -> meta::uvalue { return meta::uvalue{int{1}}; }; - meta::detail::arg a{PRV()}; + meta::detail::uarg a{PRV()}; CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::rvalue); + CHECK(a.get_ref_type() == meta::detail::uarg::ref_types::rvalue); META_HPP_CHECK_INVOCABLE_2(PRV(), f1, clazz, clazz) META_HPP_CHECK_INVOCABLE_2(PRV(), f2, clazz, const clazz) @@ -996,13 +996,13 @@ TEST_CASE("meta/meta_utilities/arg/values") { } { - auto CPRV = []() -> const meta::value { return meta::value{clazz{}}; }; - auto CPRV2 = []() -> const meta::value { return meta::value{dclazz{}}; }; - auto CPRV3 = []() -> const meta::value { return meta::value{int{1}}; }; + auto CPRV = []() -> const meta::uvalue { return meta::uvalue{clazz{}}; }; + auto CPRV2 = []() -> const meta::uvalue { return meta::uvalue{dclazz{}}; }; + auto CPRV3 = []() -> const meta::uvalue { return meta::uvalue{int{1}}; }; - meta::detail::arg a{CPRV()}; + meta::detail::uarg a{CPRV()}; CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::const_rvalue); + CHECK(a.get_ref_type() == meta::detail::uarg::ref_types::const_rvalue); META_HPP_CHECK_INVOCABLE_2(CPRV(), f1, const clazz, clazz) META_HPP_CHECK_INVOCABLE_2(CPRV(), f2, const clazz, const clazz) @@ -1031,12 +1031,12 @@ TEST_CASE("meta/meta_utilities/arg/ptr_values") { namespace meta = meta_hpp; { - auto LV_PTR = []() -> meta::value& { static clazz v; static clazz* p{&v}; static meta::value vv{p}; return vv; }; - auto LV2_PTR = []() -> meta::value& { static dclazz v; static dclazz* p{&v}; static meta::value vv{p}; return vv; }; + auto LV_PTR = []() -> meta::uvalue& { static clazz v; static clazz* p{&v}; static meta::uvalue vv{p}; return vv; }; + auto LV2_PTR = []() -> meta::uvalue& { static dclazz v; static dclazz* p{&v}; static meta::uvalue vv{p}; return vv; }; - meta::detail::arg a{LV_PTR()}; + meta::detail::uarg a{LV_PTR()}; CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::lvalue); + CHECK(a.get_ref_type() == meta::detail::uarg::ref_types::lvalue); META_HPP_CHECK_INVOCABLE_2(LV_PTR(), f1, clazz*&, clazz*) META_HPP_CHECK_INVOCABLE_2(LV_PTR(), f2, clazz*&, clazz* const) @@ -1068,12 +1068,12 @@ TEST_CASE("meta/meta_utilities/arg/ptr_values") { } { - auto LV_CPTR = []() -> meta::value& { static clazz v; static const clazz* p{&v}; static meta::value vv{p}; return vv; }; - auto LV2_CPTR = []() -> meta::value& { static dclazz v; static const dclazz* p{&v}; static meta::value vv{p}; return vv; }; + auto LV_CPTR = []() -> meta::uvalue& { static clazz v; static const clazz* p{&v}; static meta::uvalue vv{p}; return vv; }; + auto LV2_CPTR = []() -> meta::uvalue& { static dclazz v; static const dclazz* p{&v}; static meta::uvalue vv{p}; return vv; }; - meta::detail::arg a{LV_CPTR()}; + meta::detail::uarg a{LV_CPTR()}; CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::lvalue); + CHECK(a.get_ref_type() == meta::detail::uarg::ref_types::lvalue); META_HPP_CHECK_INVOCABLE_2(LV_CPTR(), f1, const clazz*&, clazz*) META_HPP_CHECK_INVOCABLE_2(LV_CPTR(), f2, const clazz*&, clazz* const) @@ -1105,12 +1105,12 @@ TEST_CASE("meta/meta_utilities/arg/ptr_values") { } { - auto CLV_PTR = []() -> const meta::value& { static clazz v; static clazz* p{&v}; static meta::value vv{p}; return vv; }; - auto CLV2_PTR = []() -> const meta::value& { static dclazz v; static dclazz* p{&v}; static meta::value vv{p}; return vv; }; + auto CLV_PTR = []() -> const meta::uvalue& { static clazz v; static clazz* p{&v}; static meta::uvalue vv{p}; return vv; }; + auto CLV2_PTR = []() -> const meta::uvalue& { static dclazz v; static dclazz* p{&v}; static meta::uvalue vv{p}; return vv; }; - meta::detail::arg a{CLV_PTR()}; + meta::detail::uarg a{CLV_PTR()}; CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::const_lvalue); + CHECK(a.get_ref_type() == meta::detail::uarg::ref_types::const_lvalue); META_HPP_CHECK_INVOCABLE_2(CLV_PTR(), f1, clazz* const&, clazz*) META_HPP_CHECK_INVOCABLE_2(CLV_PTR(), f2, clazz* const&, clazz* const) @@ -1142,12 +1142,12 @@ TEST_CASE("meta/meta_utilities/arg/ptr_values") { } { - auto CLV_CPTR = []() -> const meta::value& { static clazz v; static const clazz* p{&v}; static meta::value vv{p}; return vv; }; - auto CLV2_CPTR = []() -> const meta::value& { static dclazz v; static const dclazz* p{&v}; static meta::value vv{p}; return vv; }; + auto CLV_CPTR = []() -> const meta::uvalue& { static clazz v; static const clazz* p{&v}; static meta::uvalue vv{p}; return vv; }; + auto CLV2_CPTR = []() -> const meta::uvalue& { static dclazz v; static const dclazz* p{&v}; static meta::uvalue vv{p}; return vv; }; - meta::detail::arg a{CLV_CPTR()}; + meta::detail::uarg a{CLV_CPTR()}; CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::const_lvalue); + CHECK(a.get_ref_type() == meta::detail::uarg::ref_types::const_lvalue); META_HPP_CHECK_INVOCABLE_2(CLV_CPTR(), f1, const clazz* const&, clazz*) META_HPP_CHECK_INVOCABLE_2(CLV_CPTR(), f2, const clazz* const&, clazz* const) @@ -1179,12 +1179,12 @@ TEST_CASE("meta/meta_utilities/arg/ptr_values") { } { - auto XV_PTR = []() -> meta::value&& { static clazz v; static clazz* p{&v}; static meta::value vv{std::move(p)}; return std::move(vv); }; - auto XV2_PTR = []() -> meta::value&& { static dclazz v; static dclazz* p{&v}; static meta::value vv{std::move(p)}; return std::move(vv); }; + auto XV_PTR = []() -> meta::uvalue&& { static clazz v; static clazz* p{&v}; static meta::uvalue vv{std::move(p)}; return std::move(vv); }; + auto XV2_PTR = []() -> meta::uvalue&& { static dclazz v; static dclazz* p{&v}; static meta::uvalue vv{std::move(p)}; return std::move(vv); }; - meta::detail::arg a{XV_PTR()}; + meta::detail::uarg a{XV_PTR()}; CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::rvalue); + CHECK(a.get_ref_type() == meta::detail::uarg::ref_types::rvalue); META_HPP_CHECK_INVOCABLE_2(XV_PTR(), f1, clazz*&&, clazz*) META_HPP_CHECK_INVOCABLE_2(XV_PTR(), f2, clazz*&&, clazz* const) @@ -1216,12 +1216,12 @@ TEST_CASE("meta/meta_utilities/arg/ptr_values") { } { - auto XV_CPTR = []() -> meta::value&& { static clazz v; static const clazz* p{&v}; static meta::value vv{std::move(p)}; return std::move(vv); }; - auto XV2_CPTR = []() -> meta::value&& { static dclazz v; static const dclazz* p{&v}; static meta::value vv{std::move(p)}; return std::move(vv); }; + auto XV_CPTR = []() -> meta::uvalue&& { static clazz v; static const clazz* p{&v}; static meta::uvalue vv{std::move(p)}; return std::move(vv); }; + auto XV2_CPTR = []() -> meta::uvalue&& { static dclazz v; static const dclazz* p{&v}; static meta::uvalue vv{std::move(p)}; return std::move(vv); }; - meta::detail::arg a{XV_CPTR()}; + meta::detail::uarg a{XV_CPTR()}; CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::rvalue); + CHECK(a.get_ref_type() == meta::detail::uarg::ref_types::rvalue); META_HPP_CHECK_INVOCABLE_2(XV_CPTR(), f1, const clazz*&&, clazz*) META_HPP_CHECK_INVOCABLE_2(XV_CPTR(), f2, const clazz*&&, clazz* const) @@ -1253,12 +1253,12 @@ TEST_CASE("meta/meta_utilities/arg/ptr_values") { } { - auto CXV_PTR = []() -> const meta::value&& { static clazz v; static clazz* p{&v}; static meta::value vv{std::move(p)}; return std::move(vv); }; - auto CXV2_PTR = []() -> const meta::value&& { static dclazz v; static dclazz* p{&v}; static meta::value vv{std::move(p)}; return std::move(vv); }; + auto CXV_PTR = []() -> const meta::uvalue&& { static clazz v; static clazz* p{&v}; static meta::uvalue vv{std::move(p)}; return std::move(vv); }; + auto CXV2_PTR = []() -> const meta::uvalue&& { static dclazz v; static dclazz* p{&v}; static meta::uvalue vv{std::move(p)}; return std::move(vv); }; - meta::detail::arg a{CXV_PTR()}; + meta::detail::uarg a{CXV_PTR()}; CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::const_rvalue); + CHECK(a.get_ref_type() == meta::detail::uarg::ref_types::const_rvalue); META_HPP_CHECK_INVOCABLE_2(CXV_PTR(), f1, clazz* const&&, clazz*) META_HPP_CHECK_INVOCABLE_2(CXV_PTR(), f2, clazz* const&&, clazz* const) @@ -1290,12 +1290,12 @@ TEST_CASE("meta/meta_utilities/arg/ptr_values") { } { - auto CXV_CPTR = []() -> const meta::value&& { static clazz v; static const clazz* p{&v}; static meta::value vv{std::move(p)}; return std::move(vv); }; - auto CXV2_CPTR = []() -> const meta::value&& { static dclazz v; static const dclazz* p{&v}; static meta::value vv{std::move(p)}; return std::move(vv); }; + auto CXV_CPTR = []() -> const meta::uvalue&& { static clazz v; static const clazz* p{&v}; static meta::uvalue vv{std::move(p)}; return std::move(vv); }; + auto CXV2_CPTR = []() -> const meta::uvalue&& { static dclazz v; static const dclazz* p{&v}; static meta::uvalue vv{std::move(p)}; return std::move(vv); }; - meta::detail::arg a{CXV_CPTR()}; + meta::detail::uarg a{CXV_CPTR()}; CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::const_rvalue); + CHECK(a.get_ref_type() == meta::detail::uarg::ref_types::const_rvalue); META_HPP_CHECK_INVOCABLE_2(CXV_CPTR(), f1, const clazz* const&&, clazz*) META_HPP_CHECK_INVOCABLE_2(CXV_CPTR(), f2, const clazz* const&&, clazz* const) @@ -1327,12 +1327,12 @@ TEST_CASE("meta/meta_utilities/arg/ptr_values") { } { - auto PRV_PTR = []() -> meta::value { static clazz v; static clazz* p{&v}; static meta::value vv{p}; return vv; }; - auto PRV2_PTR = []() -> meta::value { static dclazz v; static dclazz* p{&v}; static meta::value vv{p}; return vv; }; + auto PRV_PTR = []() -> meta::uvalue { static clazz v; static clazz* p{&v}; static meta::uvalue vv{p}; return vv; }; + auto PRV2_PTR = []() -> meta::uvalue { static dclazz v; static dclazz* p{&v}; static meta::uvalue vv{p}; return vv; }; - meta::detail::arg a{PRV_PTR()}; + meta::detail::uarg a{PRV_PTR()}; CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::rvalue); + CHECK(a.get_ref_type() == meta::detail::uarg::ref_types::rvalue); META_HPP_CHECK_INVOCABLE_2(PRV_PTR(), f1, clazz*, clazz*) META_HPP_CHECK_INVOCABLE_2(PRV_PTR(), f2, clazz*, clazz* const) @@ -1364,12 +1364,12 @@ TEST_CASE("meta/meta_utilities/arg/ptr_values") { } { - auto PRV_CPTR = []() -> meta::value { static clazz v; static const clazz* p{&v}; static meta::value vv{p}; return vv; }; - auto PRV2_CPTR = []() -> meta::value { static dclazz v; static const dclazz* p{&v}; static meta::value vv{p}; return vv; }; + auto PRV_CPTR = []() -> meta::uvalue { static clazz v; static const clazz* p{&v}; static meta::uvalue vv{p}; return vv; }; + auto PRV2_CPTR = []() -> meta::uvalue { static dclazz v; static const dclazz* p{&v}; static meta::uvalue vv{p}; return vv; }; - meta::detail::arg a{PRV_CPTR()}; + meta::detail::uarg a{PRV_CPTR()}; CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::rvalue); + CHECK(a.get_ref_type() == meta::detail::uarg::ref_types::rvalue); META_HPP_CHECK_INVOCABLE_2(PRV_CPTR(), f1, const clazz*, clazz*) META_HPP_CHECK_INVOCABLE_2(PRV_CPTR(), f2, const clazz*, clazz* const) @@ -1401,12 +1401,12 @@ TEST_CASE("meta/meta_utilities/arg/ptr_values") { } { - auto CPRV_PTR = []() -> const meta::value { static clazz v; static clazz* p{&v}; static meta::value vv{p}; return vv; }; - auto CPRV2_PTR = []() -> const meta::value { static dclazz v; static dclazz* p{&v}; static meta::value vv{p}; return vv; }; + auto CPRV_PTR = []() -> const meta::uvalue { static clazz v; static clazz* p{&v}; static meta::uvalue vv{p}; return vv; }; + auto CPRV2_PTR = []() -> const meta::uvalue { static dclazz v; static dclazz* p{&v}; static meta::uvalue vv{p}; return vv; }; - meta::detail::arg a{CPRV_PTR()}; + meta::detail::uarg a{CPRV_PTR()}; CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::const_rvalue); + CHECK(a.get_ref_type() == meta::detail::uarg::ref_types::const_rvalue); META_HPP_CHECK_INVOCABLE_2(CPRV_PTR(), f1, clazz* const, clazz*) META_HPP_CHECK_INVOCABLE_2(CPRV_PTR(), f2, clazz* const, clazz* const) @@ -1438,12 +1438,12 @@ TEST_CASE("meta/meta_utilities/arg/ptr_values") { } { - auto CPRV_CPTR = []() -> const meta::value { static clazz v; static const clazz* p{&v}; static meta::value vv{p}; return vv; }; - auto CPRV2_CPTR = []() -> const meta::value { static dclazz v; static const dclazz* p{&v}; static meta::value vv{p}; return vv; }; + auto CPRV_CPTR = []() -> const meta::uvalue { static clazz v; static const clazz* p{&v}; static meta::uvalue vv{p}; return vv; }; + auto CPRV2_CPTR = []() -> const meta::uvalue { static dclazz v; static const dclazz* p{&v}; static meta::uvalue vv{p}; return vv; }; - meta::detail::arg a{CPRV_CPTR()}; + meta::detail::uarg a{CPRV_CPTR()}; CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::const_rvalue); + CHECK(a.get_ref_type() == meta::detail::uarg::ref_types::const_rvalue); META_HPP_CHECK_INVOCABLE_2(CPRV_CPTR(), f1, const clazz* const, clazz*) META_HPP_CHECK_INVOCABLE_2(CPRV_CPTR(), f2, const clazz* const, clazz* const) diff --git a/untests/meta_utilities/inst_tests.cpp b/untests/meta_utilities/inst_tests.cpp index 5c4c859..ed46b5a 100644 --- a/untests/meta_utilities/inst_tests.cpp +++ b/untests/meta_utilities/inst_tests.cpp @@ -33,16 +33,16 @@ namespace meta::method m_state{method_state::make("", method_ptr)};\ \ if ( std::is_invocable_v ) {\ - CHECK(inst{Inst}.can_cast_to());\ - CHECK(inst_base{type_list{}}.can_cast_to());\ - CHECK_NOTHROW(std::ignore = inst{Inst}.cast());\ + CHECK(uinst{Inst}.can_cast_to());\ + CHECK(uinst_base{type_list{}}.can_cast_to());\ + CHECK_NOTHROW(std::ignore = uinst{Inst}.cast());\ \ CHECK(m_state.is_invocable_with());\ CHECK(m_state.invoke(Inst) == 1);\ } else {\ - CHECK_FALSE(inst{Inst}.can_cast_to());\ - CHECK_FALSE(inst_base{type_list{}}.can_cast_to());\ - CHECK_THROWS(std::ignore = inst{Inst}.cast());\ + CHECK_FALSE(uinst{Inst}.can_cast_to());\ + CHECK_FALSE(uinst_base{type_list{}}.can_cast_to());\ + CHECK_THROWS(std::ignore = uinst{Inst}.cast());\ \ CHECK_FALSE(m_state.is_invocable_with());\ CHECK_THROWS(m_state.invoke(Inst));\ @@ -84,9 +84,9 @@ TEST_CASE("meta/meta_utilities/inst2/refs") { auto LV2 = []() -> dclazz& { static dclazz v; return v; }; { - meta::detail::inst i{LV()}; + meta::detail::uinst i{LV()}; CHECK(i.get_raw_type() == meta::resolve_type()); - CHECK(i.get_ref_type() == meta::detail::inst::ref_types::lvalue); + CHECK(i.get_ref_type() == meta::detail::uinst::ref_types::lvalue); } META_HPP_CHECK_INVOCABLE(LV(), m1, ) @@ -110,9 +110,9 @@ TEST_CASE("meta/meta_utilities/inst2/refs") { auto CLV2 = []() -> const dclazz& { static dclazz v; return v; }; { - meta::detail::inst i{CLV()}; + meta::detail::uinst i{CLV()}; CHECK(i.get_raw_type() == meta::resolve_type()); - CHECK(i.get_ref_type() == meta::detail::inst::ref_types::const_lvalue); + CHECK(i.get_ref_type() == meta::detail::uinst::ref_types::const_lvalue); } META_HPP_CHECK_INVOCABLE(CLV(), m1, ) @@ -136,9 +136,9 @@ TEST_CASE("meta/meta_utilities/inst2/refs") { auto XV2 = []() -> dclazz&& { static dclazz v; return std::move(v); }; { - meta::detail::inst i{XV()}; + meta::detail::uinst i{XV()}; CHECK(i.get_raw_type() == meta::resolve_type()); - CHECK(i.get_ref_type() == meta::detail::inst::ref_types::rvalue); + CHECK(i.get_ref_type() == meta::detail::uinst::ref_types::rvalue); } META_HPP_CHECK_INVOCABLE(XV(), m1, ) @@ -162,9 +162,9 @@ TEST_CASE("meta/meta_utilities/inst2/refs") { auto CXV2 = []() -> const dclazz&& { static dclazz v; return std::move(v); }; { - meta::detail::inst i{CXV()}; + meta::detail::uinst i{CXV()}; CHECK(i.get_raw_type() == meta::resolve_type()); - CHECK(i.get_ref_type() == meta::detail::inst::ref_types::const_rvalue); + CHECK(i.get_ref_type() == meta::detail::uinst::ref_types::const_rvalue); } META_HPP_CHECK_INVOCABLE(CXV(), m1, ) @@ -188,9 +188,9 @@ TEST_CASE("meta/meta_utilities/inst2/refs") { auto PRV2 = []() -> dclazz { return dclazz{}; }; { - meta::detail::inst i{PRV()}; + meta::detail::uinst i{PRV()}; CHECK(i.get_raw_type() == meta::resolve_type()); - CHECK(i.get_ref_type() == meta::detail::inst::ref_types::rvalue); + CHECK(i.get_ref_type() == meta::detail::uinst::ref_types::rvalue); } META_HPP_CHECK_INVOCABLE(PRV(), m1, ) @@ -214,9 +214,9 @@ TEST_CASE("meta/meta_utilities/inst2/refs") { auto CPRV2 = []() -> const dclazz { return dclazz{}; }; { - meta::detail::inst i{CPRV()}; + meta::detail::uinst i{CPRV()}; CHECK(i.get_raw_type() == meta::resolve_type()); - CHECK(i.get_ref_type() == meta::detail::inst::ref_types::const_rvalue); + CHECK(i.get_ref_type() == meta::detail::uinst::ref_types::const_rvalue); } META_HPP_CHECK_INVOCABLE(CPRV(), m1, ) @@ -240,12 +240,12 @@ TEST_CASE("meta/meta_utilities/inst2/values") { { // lvalue - auto LV = []() -> meta::value& { static meta::value v{clazz{}}; return v; }; - auto LV2 = []() -> meta::value& { static meta::value v{dclazz{}}; return v; }; + auto LV = []() -> meta::uvalue& { static meta::uvalue v{clazz{}}; return v; }; + auto LV2 = []() -> meta::uvalue& { static meta::uvalue v{dclazz{}}; return v; }; - meta::detail::arg a{LV()}; + meta::detail::uarg a{LV()}; CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::lvalue); + CHECK(a.get_ref_type() == meta::detail::uarg::ref_types::lvalue); META_HPP_CHECK_INVOCABLE_2(LV(), m1, clazz&, ) META_HPP_CHECK_INVOCABLE_2(LV(), m2, clazz&, &) @@ -264,12 +264,12 @@ TEST_CASE("meta/meta_utilities/inst2/values") { { // const lvalue - auto CLV = []() -> const meta::value& { static meta::value v{clazz{}}; return v; }; - auto CLV2 = []() -> const meta::value& { static meta::value v{dclazz{}}; return v; }; + auto CLV = []() -> const meta::uvalue& { static meta::uvalue v{clazz{}}; return v; }; + auto CLV2 = []() -> const meta::uvalue& { static meta::uvalue v{dclazz{}}; return v; }; - meta::detail::arg a{CLV()}; + meta::detail::uarg a{CLV()}; CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::const_lvalue); + CHECK(a.get_ref_type() == meta::detail::uarg::ref_types::const_lvalue); META_HPP_CHECK_INVOCABLE_2(CLV(), m1, const clazz&, ) META_HPP_CHECK_INVOCABLE_2(CLV(), m2, const clazz&, &) @@ -288,12 +288,12 @@ TEST_CASE("meta/meta_utilities/inst2/values") { { // xvalue - auto XV = []() -> meta::value&& { static meta::value v{clazz{}}; return std::move(v); }; - auto XV2 = []() -> meta::value&& { static meta::value v{dclazz{}}; return std::move(v); }; + auto XV = []() -> meta::uvalue&& { static meta::uvalue v{clazz{}}; return std::move(v); }; + auto XV2 = []() -> meta::uvalue&& { static meta::uvalue v{dclazz{}}; return std::move(v); }; - meta::detail::arg a{XV()}; + meta::detail::uarg a{XV()}; CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::rvalue); + CHECK(a.get_ref_type() == meta::detail::uarg::ref_types::rvalue); META_HPP_CHECK_INVOCABLE_2(XV(), m1, clazz&&, ) META_HPP_CHECK_INVOCABLE_2(XV(), m2, clazz&&, &) @@ -312,12 +312,12 @@ TEST_CASE("meta/meta_utilities/inst2/values") { { // const xvalue - auto CXV = []() -> const meta::value&& { static meta::value v{clazz{}}; return std::move(v); }; - auto CXV2 = []() -> const meta::value&& { static meta::value v{dclazz{}}; return std::move(v); }; + auto CXV = []() -> const meta::uvalue&& { static meta::uvalue v{clazz{}}; return std::move(v); }; + auto CXV2 = []() -> const meta::uvalue&& { static meta::uvalue v{dclazz{}}; return std::move(v); }; - meta::detail::arg a{CXV()}; + meta::detail::uarg a{CXV()}; CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::const_rvalue); + CHECK(a.get_ref_type() == meta::detail::uarg::ref_types::const_rvalue); META_HPP_CHECK_INVOCABLE_2(CXV(), m1, const clazz&&, ) META_HPP_CHECK_INVOCABLE_2(CXV(), m2, const clazz&&, &) @@ -336,12 +336,12 @@ TEST_CASE("meta/meta_utilities/inst2/values") { { // prvalue - auto PRV = []() -> meta::value { return meta::value{clazz{}}; }; - auto PRV2 = []() -> meta::value { return meta::value{dclazz{}}; }; + auto PRV = []() -> meta::uvalue { return meta::uvalue{clazz{}}; }; + auto PRV2 = []() -> meta::uvalue { return meta::uvalue{dclazz{}}; }; - meta::detail::arg a{PRV()}; + meta::detail::uarg a{PRV()}; CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::rvalue); + CHECK(a.get_ref_type() == meta::detail::uarg::ref_types::rvalue); META_HPP_CHECK_INVOCABLE_2(PRV(), m1, clazz, ) META_HPP_CHECK_INVOCABLE_2(PRV(), m2, clazz, &) @@ -360,12 +360,12 @@ TEST_CASE("meta/meta_utilities/inst2/values") { { // const prvalue - auto CPRV = []() -> const meta::value { return meta::value{clazz{}}; }; - auto CPRV2 = []() -> const meta::value { return meta::value{dclazz{}}; }; + auto CPRV = []() -> const meta::uvalue { return meta::uvalue{clazz{}}; }; + auto CPRV2 = []() -> const meta::uvalue { return meta::uvalue{dclazz{}}; }; - meta::detail::arg a{CPRV()}; + meta::detail::uarg a{CPRV()}; CHECK(a.get_raw_type() == meta::resolve_type()); - CHECK(a.get_ref_type() == meta::detail::arg::ref_types::const_rvalue); + CHECK(a.get_ref_type() == meta::detail::uarg::ref_types::const_rvalue); META_HPP_CHECK_INVOCABLE_2(CPRV(), m1, const clazz, ) META_HPP_CHECK_INVOCABLE_2(CPRV(), m2, const clazz, &) diff --git a/untests/meta_utilities/invoke_tests.cpp b/untests/meta_utilities/invoke_tests.cpp index f13e07b..330f525 100644 --- a/untests/meta_utilities/invoke_tests.cpp +++ b/untests/meta_utilities/invoke_tests.cpp @@ -33,17 +33,17 @@ TEST_CASE("meta/meta_utilities/invoke") { { CHECK(meta::invoke(&clazz::function, 3) == 3); - CHECK(meta::invoke(&clazz::function, meta::value(3)) == 3); + CHECK(meta::invoke(&clazz::function, meta::uvalue(3)) == 3); CHECK(meta::invoke(clazz_function, 3) == 3); - CHECK(meta::invoke(clazz_function, meta::value(3)) == 3); + CHECK(meta::invoke(clazz_function, meta::uvalue(3)) == 3); CHECK(meta::is_invocable_with(clazz_function, 3)); - CHECK(meta::is_invocable_with(clazz_function, meta::value(3))); + CHECK(meta::is_invocable_with(clazz_function, meta::uvalue(3))); CHECK(meta::is_invocable_with(clazz_function)); using function_t = decltype(&clazz::function); CHECK(meta::is_invocable_with(3)); - CHECK(meta::is_invocable_with(meta::value(3))); + CHECK(meta::is_invocable_with(meta::uvalue(3))); CHECK(meta::is_invocable_with()); } @@ -51,17 +51,17 @@ TEST_CASE("meta/meta_utilities/invoke") { clazz cl; CHECK(meta::invoke(&clazz::member, cl) == 1); - CHECK(meta::invoke(&clazz::member, meta::value{cl}) == 1); + CHECK(meta::invoke(&clazz::member, meta::uvalue{cl}) == 1); CHECK(meta::invoke(clazz_member, cl) == 1); - CHECK(meta::invoke(clazz_member, meta::value{cl}) == 1); + CHECK(meta::invoke(clazz_member, meta::uvalue{cl}) == 1); CHECK(meta::is_invocable_with(clazz_member, cl)); - CHECK(meta::is_invocable_with(clazz_member, meta::value{cl})); + CHECK(meta::is_invocable_with(clazz_member, meta::uvalue{cl})); CHECK(meta::is_invocable_with(clazz_member)); using member_t = decltype(&clazz::member); CHECK(meta::is_invocable_with(cl)); - CHECK(meta::is_invocable_with(meta::value{cl})); + CHECK(meta::is_invocable_with(meta::uvalue{cl})); CHECK(meta::is_invocable_with()); } @@ -69,17 +69,17 @@ TEST_CASE("meta/meta_utilities/invoke") { clazz cl; CHECK(meta::invoke(&clazz::method, cl, 2) == 2); - CHECK(meta::invoke(&clazz::method, meta::value{cl}, meta::value(2)) == 2); + CHECK(meta::invoke(&clazz::method, meta::uvalue{cl}, meta::uvalue(2)) == 2); CHECK(meta::invoke(clazz_method, cl, 2) == 2); - CHECK(meta::invoke(clazz_method, meta::value{cl}, meta::value(2)) == 2); + CHECK(meta::invoke(clazz_method, meta::uvalue{cl}, meta::uvalue(2)) == 2); CHECK(meta::is_invocable_with(clazz_method, cl, 2)); - CHECK(meta::is_invocable_with(clazz_method, meta::value{cl}, meta::value(2))); + CHECK(meta::is_invocable_with(clazz_method, meta::uvalue{cl}, meta::uvalue(2))); CHECK(meta::is_invocable_with(clazz_method)); using method_t = decltype(&clazz::method); CHECK(meta::is_invocable_with(cl, 2)); - CHECK(meta::is_invocable_with(meta::value{cl}, meta::value(2))); + CHECK(meta::is_invocable_with(meta::uvalue{cl}, meta::uvalue(2))); CHECK(meta::is_invocable_with()); } } diff --git a/untests/meta_utilities/value2_tests.cpp b/untests/meta_utilities/value2_tests.cpp index 58588bc..d98d9dc 100644 --- a/untests/meta_utilities/value2_tests.cpp +++ b/untests/meta_utilities/value2_tests.cpp @@ -124,7 +124,7 @@ TEST_CASE("meta/meta_utilities/value2/counters/small") { SUBCASE("def ctor") { { - meta::value v{}; + meta::uvalue v{}; CHECK(ivec2::dtor_counter == 0); CHECK(ivec2::move_ctor_counter == 0); CHECK(ivec2::copy_ctor_counter == 0); @@ -136,7 +136,7 @@ TEST_CASE("meta/meta_utilities/value2/counters/small") { SUBCASE("val ctor") { { - meta::value v{ivec2{1,2}}; + meta::uvalue v{ivec2{1,2}}; CHECK(ivec2::dtor_counter == 1); CHECK(ivec2::move_ctor_counter == 1); CHECK(ivec2::copy_ctor_counter == 0); @@ -148,8 +148,8 @@ TEST_CASE("meta/meta_utilities/value2/counters/small") { SUBCASE("move ctor") { { - meta::value v1{ivec2{1,2}}; - meta::value v2{std::move(v1)}; + meta::uvalue v1{ivec2{1,2}}; + meta::uvalue v2{std::move(v1)}; CHECK_FALSE(v1); CHECK(v2.cast().x == 1); @@ -165,8 +165,8 @@ TEST_CASE("meta/meta_utilities/value2/counters/small") { SUBCASE("copy ctor") { { - meta::value v1{ivec2{1,2}}; - meta::value v2{std::as_const(v1)}; + meta::uvalue v1{ivec2{1,2}}; + meta::uvalue v2{std::as_const(v1)}; CHECK(v1.cast().x == 1); CHECK(v2.cast().y == 2); @@ -182,8 +182,8 @@ TEST_CASE("meta/meta_utilities/value2/counters/small") { SUBCASE("swap") { { - meta::value v1{ivec2{1,2}}; - meta::value v2{ivec2{3,4}}; + meta::uvalue v1{ivec2{1,2}}; + meta::uvalue v2{ivec2{3,4}}; CHECK(ivec2::dtor_counter == 2); CHECK(ivec2::move_ctor_counter == 2); CHECK(ivec2::copy_ctor_counter == 0); @@ -211,7 +211,7 @@ TEST_CASE("meta/meta_utilities/value2/counters/big") { SUBCASE("def ctor") { { - meta::value v{}; + meta::uvalue v{}; CHECK(ivec2_big::dtor_counter == 0); CHECK(ivec2_big::move_ctor_counter == 0); CHECK(ivec2_big::copy_ctor_counter == 0); @@ -223,7 +223,7 @@ TEST_CASE("meta/meta_utilities/value2/counters/big") { SUBCASE("val ctor") { { - meta::value v{ivec2_big{1,2}}; + meta::uvalue v{ivec2_big{1,2}}; CHECK(ivec2_big::dtor_counter == 1); CHECK(ivec2_big::move_ctor_counter == 1); CHECK(ivec2_big::copy_ctor_counter == 0); @@ -235,8 +235,8 @@ TEST_CASE("meta/meta_utilities/value2/counters/big") { SUBCASE("move ctor") { { - meta::value v1{ivec2_big{1,2}}; - meta::value v2{std::move(v1)}; + meta::uvalue v1{ivec2_big{1,2}}; + meta::uvalue v2{std::move(v1)}; CHECK_FALSE(v1); CHECK(v2.cast().x == 1); @@ -252,8 +252,8 @@ TEST_CASE("meta/meta_utilities/value2/counters/big") { SUBCASE("copy ctor") { { - meta::value v1{ivec2_big{1,2}}; - meta::value v2{std::as_const(v1)}; + meta::uvalue v1{ivec2_big{1,2}}; + meta::uvalue v2{std::as_const(v1)}; CHECK(v1.cast().x == 1); CHECK(v2.cast().y == 2); @@ -269,8 +269,8 @@ TEST_CASE("meta/meta_utilities/value2/counters/big") { SUBCASE("swap") { { - meta::value v1{ivec2_big{1,2}}; - meta::value v2{ivec2_big{3,4}}; + meta::uvalue v1{ivec2_big{1,2}}; + meta::uvalue v2{ivec2_big{3,4}}; CHECK(ivec2_big::dtor_counter == 2); CHECK(ivec2_big::move_ctor_counter == 2); CHECK(ivec2_big::copy_ctor_counter == 0); @@ -302,8 +302,8 @@ TEST_CASE("meta/meta_utilities/value2/counters/swap") { SUBCASE("empty/small") { { - meta::value v1{}; - meta::value v2{ivec2{1,2}}; + meta::uvalue v1{}; + meta::uvalue v2{ivec2{1,2}}; CHECK(ivec2::dtor_counter == 1); CHECK(ivec2::move_ctor_counter == 1); @@ -333,8 +333,8 @@ TEST_CASE("meta/meta_utilities/value2/counters/swap") { SUBCASE("empty/big") { { - meta::value v1{}; - meta::value v2{ivec2_big{3,4}}; + meta::uvalue v1{}; + meta::uvalue v2{ivec2_big{3,4}}; CHECK(ivec2_big::dtor_counter == 1); CHECK(ivec2_big::move_ctor_counter == 1); @@ -364,8 +364,8 @@ TEST_CASE("meta/meta_utilities/value2/counters/swap") { SUBCASE("small/big") { { - meta::value v1{ivec2{1,2}}; - meta::value v2{ivec2_big{3,4}}; + meta::uvalue v1{ivec2{1,2}}; + meta::uvalue v2{ivec2_big{3,4}}; CHECK(ivec2::dtor_counter == 1); CHECK(ivec2::move_ctor_counter == 1); diff --git a/untests/meta_utilities/value_tests.cpp b/untests/meta_utilities/value_tests.cpp index 88f2239..920e894 100644 --- a/untests/meta_utilities/value_tests.cpp +++ b/untests/meta_utilities/value_tests.cpp @@ -103,31 +103,31 @@ TEST_CASE("meta/meta_utilities/value") { SUBCASE("cast types") { static_assert(std::is_same_v< - decltype(std::declval().cast()), + decltype(std::declval().cast()), ivec2&>); static_assert(std::is_same_v< - decltype(std::declval().cast()), + decltype(std::declval().cast()), ivec2&&>); static_assert(std::is_same_v< - decltype(std::declval().cast()), + decltype(std::declval().cast()), const ivec2&>); static_assert(std::is_same_v< - decltype(std::declval().cast()), + decltype(std::declval().cast()), const ivec2&&>); } SUBCASE("try_cast types") { static_assert(std::is_same_v< - decltype(std::declval().try_cast()), + decltype(std::declval().try_cast()), ivec2*>); static_assert(std::is_same_v< - decltype(std::declval().try_cast()), + decltype(std::declval().try_cast()), const ivec2*>); } SUBCASE("ivec2{}") { { - meta::value val{}; + meta::uvalue val{}; CHECK(!val); CHECK_FALSE(val); @@ -150,45 +150,45 @@ TEST_CASE("meta/meta_utilities/value") { } { - CHECK_FALSE(meta::value{1} < meta::value{}); - CHECK(meta::value{} < meta::value{1}); - CHECK_FALSE(meta::value{} < meta::value{}); + CHECK_FALSE(meta::uvalue{1} < meta::uvalue{}); + CHECK(meta::uvalue{} < meta::uvalue{1}); + CHECK_FALSE(meta::uvalue{} < meta::uvalue{}); - CHECK_FALSE(1 < meta::value{}); - CHECK(meta::value{} < 1); - CHECK_FALSE(meta::value{} < meta::value{}); + CHECK_FALSE(1 < meta::uvalue{}); + CHECK(meta::uvalue{} < 1); + CHECK_FALSE(meta::uvalue{} < meta::uvalue{}); } { - CHECK_FALSE(meta::value{1} == meta::value{}); - CHECK_FALSE(meta::value{} == meta::value{1}); - CHECK(meta::value{} == meta::value{}); + CHECK_FALSE(meta::uvalue{1} == meta::uvalue{}); + CHECK_FALSE(meta::uvalue{} == meta::uvalue{1}); + CHECK(meta::uvalue{} == meta::uvalue{}); - CHECK_FALSE(1 == meta::value{}); - CHECK_FALSE(meta::value{} == 1); - CHECK(meta::value{} == meta::value{}); + CHECK_FALSE(1 == meta::uvalue{}); + CHECK_FALSE(meta::uvalue{} == 1); + CHECK(meta::uvalue{} == meta::uvalue{}); } { - CHECK(meta::value{1} != meta::value{}); - CHECK(meta::value{} != meta::value{1}); - CHECK_FALSE(meta::value{} != meta::value{}); + CHECK(meta::uvalue{1} != meta::uvalue{}); + CHECK(meta::uvalue{} != meta::uvalue{1}); + CHECK_FALSE(meta::uvalue{} != meta::uvalue{}); - CHECK(1 != meta::value{}); - CHECK(meta::value{} != 1); - CHECK_FALSE(meta::value{} != meta::value{}); + CHECK(1 != meta::uvalue{}); + CHECK(meta::uvalue{} != 1); + CHECK_FALSE(meta::uvalue{} != meta::uvalue{}); } - CHECK_FALSE(meta::value{} == 0); - CHECK_FALSE(meta::value{} == nullptr); - CHECK(meta::value{}.get_type() == meta::resolve_type()); + CHECK_FALSE(meta::uvalue{} == 0); + CHECK_FALSE(meta::uvalue{} == nullptr); + CHECK(meta::uvalue{}.get_type() == meta::resolve_type()); } SUBCASE("ivec2&") { ivec2 v{1,2}; ivec2& vr = v; - meta::value val{vr}; + meta::uvalue val{vr}; CHECK(ivec2::move_ctor_counter == 0); CHECK(ivec2::copy_ctor_counter == 1); @@ -200,7 +200,7 @@ TEST_CASE("meta/meta_utilities/value") { CHECK(*static_cast(std::as_const(val).cdata()) == vr); CHECK(val == ivec2{1,2}); - CHECK(val == meta::value{ivec2{1,2}}); + CHECK(val == meta::uvalue{ivec2{1,2}}); CHECK(val.cast() == ivec2{1,2}); CHECK(std::as_const(val).cast() == ivec2{1,2}); @@ -222,7 +222,7 @@ TEST_CASE("meta/meta_utilities/value") { const ivec2 v{1,2}; const ivec2& vr = v; - meta::value val{vr}; + meta::uvalue val{vr}; CHECK(ivec2::move_ctor_counter == 0); CHECK(ivec2::copy_ctor_counter == 1); @@ -234,7 +234,7 @@ TEST_CASE("meta/meta_utilities/value") { CHECK(*static_cast(std::as_const(val).cdata()) == vr); CHECK(val == ivec2{1,2}); - CHECK(val == meta::value{ivec2{1,2}}); + CHECK(val == meta::uvalue{ivec2{1,2}}); CHECK(val.cast() == ivec2{1,2}); CHECK(std::as_const(val).cast() == ivec2{1,2}); @@ -255,14 +255,14 @@ TEST_CASE("meta/meta_utilities/value") { SUBCASE("ivec2&&") { ivec2 v{1,2}; - meta::value val{std::move(v)}; + meta::uvalue val{std::move(v)}; CHECK(ivec2::move_ctor_counter == 1); CHECK(ivec2::copy_ctor_counter == 0); CHECK(val.get_type() == meta::resolve_type()); CHECK(val == ivec2{1,2}); - CHECK(val == meta::value{ivec2{1,2}}); + CHECK(val == meta::uvalue{ivec2{1,2}}); CHECK(val.cast() == ivec2{1,2}); CHECK(std::as_const(val).cast() == ivec2{1,2}); @@ -283,14 +283,14 @@ TEST_CASE("meta/meta_utilities/value") { SUBCASE("const ivec2&&") { const ivec2 v{1,2}; - meta::value val{std::move(v)}; + meta::uvalue val{std::move(v)}; CHECK(ivec2::move_ctor_counter == 0); CHECK(ivec2::copy_ctor_counter == 1); CHECK(val.get_type() == meta::resolve_type()); CHECK(val == ivec2{1,2}); - CHECK(val == meta::value{ivec2{1,2}}); + CHECK(val == meta::uvalue{ivec2{1,2}}); CHECK(val.cast() == ivec2{1,2}); CHECK(std::as_const(val).cast() == ivec2{1,2}); @@ -310,11 +310,11 @@ TEST_CASE("meta/meta_utilities/value") { SUBCASE("value(value&&)") { ivec2 v{1,2}; - meta::value val_src{std::move(v)}; + meta::uvalue val_src{std::move(v)}; CHECK(ivec2::move_ctor_counter == 1); CHECK(ivec2::copy_ctor_counter == 0); - meta::value val_dst{std::move(val_src)}; + meta::uvalue val_dst{std::move(val_src)}; CHECK(val_dst == ivec2{1,2}); CHECK(ivec2::move_ctor_counter == 2); CHECK(ivec2::copy_ctor_counter == 0); @@ -322,11 +322,11 @@ TEST_CASE("meta/meta_utilities/value") { SUBCASE("value(const meta::value&)") { const ivec2 v{1,2}; - meta::value val_src{v}; + meta::uvalue val_src{v}; CHECK(ivec2::move_ctor_counter == 0); CHECK(ivec2::copy_ctor_counter == 1); - meta::value val_dst{val_src}; + meta::uvalue val_dst{val_src}; CHECK(val_dst == ivec2{1,2}); CHECK(ivec2::move_ctor_counter == 0); CHECK(ivec2::copy_ctor_counter == 2); @@ -336,7 +336,7 @@ TEST_CASE("meta/meta_utilities/value") { } SUBCASE("value& operator=(T&&)") { - meta::value val{10}; + meta::uvalue val{10}; val = 20; CHECK(val == 20); @@ -346,12 +346,12 @@ TEST_CASE("meta/meta_utilities/value") { } SUBCASE("value& operator=(value&&)") { - meta::value val_src1{"world"s}; - meta::value val_src2{ivec2{1,2}}; + meta::uvalue val_src1{"world"s}; + meta::uvalue val_src2{ivec2{1,2}}; CHECK(ivec2::move_ctor_counter == 1); CHECK(ivec2::copy_ctor_counter == 0); - meta::value val_dst{"hello"s}; + meta::uvalue val_dst{"hello"s}; val_dst = std::move(val_src1); CHECK(val_dst == "world"s); @@ -365,12 +365,12 @@ TEST_CASE("meta/meta_utilities/value") { } SUBCASE("value& operator=(const meta::value&)") { - meta::value val_src1{"world"s}; - meta::value val_src2{ivec2{1,2}}; + meta::uvalue val_src1{"world"s}; + meta::uvalue val_src2{ivec2{1,2}}; CHECK(ivec2::move_ctor_counter == 1); CHECK(ivec2::copy_ctor_counter == 0); - meta::value val_dst{"hello"s}; + meta::uvalue val_dst{"hello"s}; val_dst = val_src1; CHECK(val_dst == "world"s); @@ -387,8 +387,8 @@ TEST_CASE("meta/meta_utilities/value") { } SUBCASE("swap") { - meta::value val1{"world"s}; - meta::value val2{ivec2{1,2}}; + meta::uvalue val1{"world"s}; + meta::uvalue val2{ivec2{1,2}}; CHECK(ivec2::move_ctor_counter == 1); CHECK(ivec2::copy_ctor_counter == 0); @@ -405,18 +405,18 @@ TEST_CASE("meta/meta_utilities/value") { SUBCASE("ostream") { std::stringstream str_stream; - CHECK_NOTHROW(str_stream << meta::value{21} << " " << meta::value{42}); - CHECK_THROWS((str_stream << meta::value{ivec2{1,2}})); + CHECK_NOTHROW(str_stream << meta::uvalue{21} << " " << meta::uvalue{42}); + CHECK_THROWS((str_stream << meta::uvalue{ivec2{1,2}})); REQUIRE(str_stream.str() == "21 42"); } SUBCASE("istream") { std::stringstream str_stream{"21 42"}; - meta::value v{ivec2{1,2}}; + meta::uvalue v{ivec2{1,2}}; CHECK_THROWS(str_stream >> v); - v = meta::value{0}; + v = meta::uvalue{0}; CHECK_NOTHROW(str_stream >> v); CHECK(v == 21); CHECK_NOTHROW(str_stream >> v); @@ -424,61 +424,61 @@ TEST_CASE("meta/meta_utilities/value") { } SUBCASE("operator<") { - CHECK(meta::value{ivec2{1,2}} < ivec2{1,3}); - CHECK_FALSE(meta::value{ivec2{1,3}} < ivec2{1,2}); + CHECK(meta::uvalue{ivec2{1,2}} < ivec2{1,3}); + CHECK_FALSE(meta::uvalue{ivec2{1,3}} < ivec2{1,2}); - CHECK(ivec2{1,2} < meta::value{ivec2{1,3}}); - CHECK_FALSE(ivec2{1,3} < meta::value{ivec2{1,2}}); + CHECK(ivec2{1,2} < meta::uvalue{ivec2{1,3}}); + CHECK_FALSE(ivec2{1,3} < meta::uvalue{ivec2{1,2}}); - CHECK(meta::value{ivec2{1,2}} < meta::value{ivec2{1,3}}); - CHECK_FALSE(meta::value{ivec2{1,3}} < meta::value{ivec2{1,2}}); + CHECK(meta::uvalue{ivec2{1,2}} < meta::uvalue{ivec2{1,3}}); + CHECK_FALSE(meta::uvalue{ivec2{1,3}} < meta::uvalue{ivec2{1,2}}); { class empty_class1 {}; class empty_class2 {}; - CHECK((operator<(meta::value{empty_class1{}}, meta::value{empty_class2{}}) - || operator<(meta::value{empty_class2{}}, meta::value{empty_class1{}}))); - CHECK_THROWS(std::ignore = operator<(meta::value{empty_class1{}}, meta::value{empty_class1{}})); + CHECK((operator<(meta::uvalue{empty_class1{}}, meta::uvalue{empty_class2{}}) + || operator<(meta::uvalue{empty_class2{}}, meta::uvalue{empty_class1{}}))); + CHECK_THROWS(std::ignore = operator<(meta::uvalue{empty_class1{}}, meta::uvalue{empty_class1{}})); } } SUBCASE("operator==") { - CHECK(meta::value{ivec2{1,2}} == ivec2{1,2}); - CHECK_FALSE(meta::value{ivec2{1,2}} == ivec2{1,3}); + CHECK(meta::uvalue{ivec2{1,2}} == ivec2{1,2}); + CHECK_FALSE(meta::uvalue{ivec2{1,2}} == ivec2{1,3}); - CHECK(ivec2{1,2} == meta::value{ivec2{1,2}}); - CHECK_FALSE(ivec2{1,3} == meta::value{ivec2{1,2}}); + CHECK(ivec2{1,2} == meta::uvalue{ivec2{1,2}}); + CHECK_FALSE(ivec2{1,3} == meta::uvalue{ivec2{1,2}}); - CHECK(meta::value{ivec2{1,2}} == meta::value{ivec2{1,2}}); - CHECK_FALSE(meta::value{ivec2{1,2}} == meta::value{ivec2{1,3}}); + CHECK(meta::uvalue{ivec2{1,2}} == meta::uvalue{ivec2{1,2}}); + CHECK_FALSE(meta::uvalue{ivec2{1,2}} == meta::uvalue{ivec2{1,3}}); { class empty_class1 {}; class empty_class2 {}; - CHECK_FALSE(operator==(meta::value{empty_class1{}}, meta::value{empty_class2{}})); - CHECK_THROWS(std::ignore = operator==(meta::value{empty_class1{}}, meta::value{empty_class1{}})); + CHECK_FALSE(operator==(meta::uvalue{empty_class1{}}, meta::uvalue{empty_class2{}})); + CHECK_THROWS(std::ignore = operator==(meta::uvalue{empty_class1{}}, meta::uvalue{empty_class1{}})); } } SUBCASE("deref") { { int i{42}; - const meta::value v{*meta::value{&i}}; + const meta::uvalue v{*meta::uvalue{&i}}; CHECK(v.get_type() == meta::resolve_type()); CHECK(v.data() != &i); } { const char i{42}; - const meta::value v{*meta::value{&i}}; + const meta::uvalue v{*meta::uvalue{&i}}; CHECK(v.get_type() == meta::resolve_type()); CHECK(v.data() != &i); } { const int i{42}; const int* const pi = &i; - const meta::value v{*meta::value{&pi}}; + const meta::uvalue v{*meta::uvalue{&pi}}; CHECK(v.get_type() == meta::resolve_type() ); CHECK(v.cast() == pi); } @@ -490,31 +490,31 @@ TEST_CASE("meta/meta_utilities/value") { void* const& p3 = &i; const void* const& p4 = &i; - CHECK_THROWS(std::ignore = *meta::value(p1)); - CHECK_THROWS(std::ignore = *meta::value(p2)); - CHECK_THROWS(std::ignore = *meta::value(p3)); - CHECK_THROWS(std::ignore = *meta::value(p4)); + CHECK_THROWS(std::ignore = *meta::uvalue(p1)); + CHECK_THROWS(std::ignore = *meta::uvalue(p2)); + CHECK_THROWS(std::ignore = *meta::uvalue(p3)); + CHECK_THROWS(std::ignore = *meta::uvalue(p4)); } { ivec2 v{1,2}; - meta::value vp{&v}; + meta::uvalue vp{&v}; CHECK(ivec2::move_ctor_counter == 0); CHECK(ivec2::copy_ctor_counter == 0); - [[maybe_unused]] meta::value vv1{*vp}; + [[maybe_unused]] meta::uvalue vv1{*vp}; CHECK((ivec2::move_ctor_counter == 0 || ivec2::move_ctor_counter == 2)); CHECK(ivec2::copy_ctor_counter == 1); - [[maybe_unused]] meta::value vv2{*std::move(vp)}; + [[maybe_unused]] meta::uvalue vv2{*std::move(vp)}; CHECK((ivec2::move_ctor_counter == 0 || ivec2::move_ctor_counter == 4)); CHECK(ivec2::copy_ctor_counter == 2); - [[maybe_unused]] meta::value vv3{*std::as_const(vp)}; + [[maybe_unused]] meta::uvalue vv3{*std::as_const(vp)}; CHECK((ivec2::move_ctor_counter == 0 || ivec2::move_ctor_counter == 6)); CHECK(ivec2::copy_ctor_counter == 3); } { - meta::value v{std::make_shared(42)}; + meta::uvalue v{std::make_shared(42)}; CHECK(*v == 42); } } @@ -525,7 +525,7 @@ TEST_CASE("meta/meta_utilities/value/arrays") { SUBCASE("int[3]") { int arr[3]{1,2,3}; - meta::value v{arr}; + meta::uvalue v{arr}; CHECK(v.get_type() == meta::resolve_type()); CHECK(v[0] == 1); CHECK(v[1] == 2); @@ -534,7 +534,7 @@ TEST_CASE("meta/meta_utilities/value/arrays") { SUBCASE("const int[3]") { const int arr[3]{1,2,3}; - meta::value v{arr}; + meta::uvalue v{arr}; CHECK(v.get_type() == meta::resolve_type()); CHECK(v[0] == 1); CHECK(v[1] == 2); @@ -542,7 +542,7 @@ TEST_CASE("meta/meta_utilities/value/arrays") { } SUBCASE("std::array") { - meta::value v{std::array{1,2,3}}; + meta::uvalue v{std::array{1,2,3}}; CHECK(v.get_type() == meta::resolve_type>()); CHECK(v[0] == 1); CHECK(v[1] == 2); @@ -550,7 +550,7 @@ TEST_CASE("meta/meta_utilities/value/arrays") { } SUBCASE("std::string") { - meta::value v{std::string{"hi!"}}; + meta::uvalue v{std::string{"hi!"}}; CHECK(v.get_type() == meta::resolve_type()); CHECK(v[0] == 'h'); CHECK(v[1] == 'i'); @@ -559,7 +559,7 @@ TEST_CASE("meta/meta_utilities/value/arrays") { SUBCASE("std::span") { std::vector arr{1,2,3}; - meta::value v{std::span{arr}}; + meta::uvalue v{std::span{arr}}; CHECK(v.get_type() == meta::resolve_type>()); CHECK(v[0] == 1); CHECK(v[1] == 2); @@ -567,7 +567,7 @@ TEST_CASE("meta/meta_utilities/value/arrays") { } SUBCASE("std::vector") { - const meta::value v{std::vector{1,2,3}}; + const meta::uvalue v{std::vector{1,2,3}}; CHECK(v.get_type() == meta::resolve_type>()); CHECK(v[0] == 1); CHECK(v[1] == 2); @@ -580,7 +580,7 @@ TEST_CASE("meta/meta_utilities/value/functions") { SUBCASE("add") { { - const meta::value v{&ivec2::add}; + const meta::uvalue v{&ivec2::add}; CHECK(v.get_type() == meta::resolve_type()); CHECK(std::invoke(v.cast(), ivec2{1,2}, ivec2{3,4}) == ivec2{4,6}); CHECK(std::invoke(*v.try_cast(), ivec2{1,2}, ivec2{3,4}) == ivec2{4,6}); @@ -589,13 +589,13 @@ TEST_CASE("meta/meta_utilities/value/functions") { SUBCASE("iadd2") { { - const meta::value v{iadd2}; + const meta::uvalue v{iadd2}; CHECK(v.get_type() == meta::resolve_type()); CHECK(std::invoke(v.cast(), ivec2{1,2}, ivec2{3,4}) == ivec2{4,6}); CHECK(std::invoke(*v.try_cast(), ivec2{1,2}, ivec2{3,4}) == ivec2{4,6}); } { - const meta::value v{&iadd2}; + const meta::uvalue v{&iadd2}; CHECK(v.get_type() == meta::resolve_type()); CHECK(std::invoke(v.cast(), ivec2{1,2}, ivec2{3,4}) == ivec2{4,6}); CHECK(std::invoke(*v.try_cast(), ivec2{1,2}, ivec2{3,4}) == ivec2{4,6}); From 04fd737d6222647e53623633139090ad4718b361 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Tue, 8 Feb 2022 23:36:20 +0700 Subject: [PATCH 219/233] rename: ctor -> constructor, dtor -> destructor, parameter -> argument --- headers/meta.hpp/meta_all.hpp | 16 +- headers/meta.hpp/meta_base.hpp | 44 +-- headers/meta.hpp/meta_base/type_kinds.hpp | 4 +- headers/meta.hpp/meta_binds.hpp | 28 +- headers/meta.hpp/meta_binds/class_bind.hpp | 62 ++-- headers/meta.hpp/meta_binds/scope_bind.hpp | 12 +- headers/meta.hpp/meta_detail/state_family.hpp | 6 +- headers/meta.hpp/meta_detail/type_family.hpp | 4 +- .../meta.hpp/meta_detail/type_registry.hpp | 20 +- ...ctor_traits.hpp => constructor_traits.hpp} | 14 +- ...{dtor_traits.hpp => destructor_traits.hpp} | 14 +- headers/meta.hpp/meta_indices.hpp | 74 ++--- ...parameter_index.hpp => argument_index.hpp} | 16 +- .../{ctor_index.hpp => constructor_index.hpp} | 12 +- .../{dtor_index.hpp => destructor_index.hpp} | 12 +- headers/meta.hpp/meta_states.hpp | 114 +++---- .../{parameter.hpp => argument.hpp} | 22 +- .../meta_states/{ctor.hpp => constructor.hpp} | 84 ++--- .../meta_states/{dtor.hpp => destructor.hpp} | 46 +-- headers/meta.hpp/meta_states/function.hpp | 24 +- headers/meta.hpp/meta_states/method.hpp | 24 +- headers/meta.hpp/meta_types.hpp | 76 ++--- headers/meta.hpp/meta_types/any_type.hpp | 28 +- headers/meta.hpp/meta_types/class_type.hpp | 34 +- .../meta.hpp/meta_types/constructor_type.hpp | 65 ++++ headers/meta.hpp/meta_types/ctor_type.hpp | 65 ---- .../{dtor_type.hpp => destructor_type.hpp} | 24 +- manuals/meta_examples/classes_example.cpp | 2 +- manuals/meta_examples/functions_example.cpp | 2 +- manuals/meta_examples/methods_example.cpp | 2 +- untests/meta_states/ctor_tests.cpp | 84 ++--- untests/meta_states/function2_tests.cpp | 40 +-- untests/meta_states/method2_tests.cpp | 12 +- untests/meta_states/scope_tests.cpp | 40 +-- untests/meta_types/any_type_tests.cpp | 16 +- untests/meta_types/class_type_tests.cpp | 32 +- untests/meta_utilities/value2_tests.cpp | 304 +++++++++--------- untests/meta_utilities/value_tests.cpp | 112 +++---- 38 files changed, 795 insertions(+), 795 deletions(-) rename headers/meta.hpp/meta_detail/type_traits/{ctor_traits.hpp => constructor_traits.hpp} (69%) rename headers/meta.hpp/meta_detail/type_traits/{dtor_traits.hpp => destructor_traits.hpp} (66%) rename headers/meta.hpp/meta_indices/{parameter_index.hpp => argument_index.hpp} (58%) rename headers/meta.hpp/meta_indices/{ctor_index.hpp => constructor_index.hpp} (61%) rename headers/meta.hpp/meta_indices/{dtor_index.hpp => destructor_index.hpp} (61%) rename headers/meta.hpp/meta_states/{parameter.hpp => argument.hpp} (53%) rename headers/meta.hpp/meta_states/{ctor.hpp => constructor.hpp} (61%) rename headers/meta.hpp/meta_states/{dtor.hpp => destructor.hpp} (60%) create mode 100644 headers/meta.hpp/meta_types/constructor_type.hpp delete mode 100644 headers/meta.hpp/meta_types/ctor_type.hpp rename headers/meta.hpp/meta_types/{dtor_type.hpp => destructor_type.hpp} (52%) diff --git a/headers/meta.hpp/meta_all.hpp b/headers/meta.hpp/meta_all.hpp index 45fe3a7..8936e65 100644 --- a/headers/meta.hpp/meta_all.hpp +++ b/headers/meta.hpp/meta_all.hpp @@ -14,24 +14,24 @@ #include "meta_binds/scope_bind.hpp" #include "meta_indices.hpp" -#include "meta_indices/ctor_index.hpp" -#include "meta_indices/dtor_index.hpp" +#include "meta_indices/argument_index.hpp" +#include "meta_indices/constructor_index.hpp" +#include "meta_indices/destructor_index.hpp" #include "meta_indices/evalue_index.hpp" #include "meta_indices/function_index.hpp" #include "meta_indices/member_index.hpp" #include "meta_indices/method_index.hpp" -#include "meta_indices/parameter_index.hpp" #include "meta_indices/scope_index.hpp" #include "meta_indices/variable_index.hpp" #include "meta_states.hpp" -#include "meta_states/ctor.hpp" -#include "meta_states/dtor.hpp" +#include "meta_states/argument.hpp" +#include "meta_states/constructor.hpp" +#include "meta_states/destructor.hpp" #include "meta_states/evalue.hpp" #include "meta_states/function.hpp" #include "meta_states/member.hpp" #include "meta_states/method.hpp" -#include "meta_states/parameter.hpp" #include "meta_states/scope.hpp" #include "meta_states/variable.hpp" @@ -39,8 +39,8 @@ #include "meta_types/any_type.hpp" #include "meta_types/array_type.hpp" #include "meta_types/class_type.hpp" -#include "meta_types/ctor_type.hpp" -#include "meta_types/dtor_type.hpp" +#include "meta_types/constructor_type.hpp" +#include "meta_types/destructor_type.hpp" #include "meta_types/enum_type.hpp" #include "meta_types/function_type.hpp" #include "meta_types/member_type.hpp" diff --git a/headers/meta.hpp/meta_base.hpp b/headers/meta.hpp/meta_base.hpp index 4921cd8..6819a7b 100644 --- a/headers/meta.hpp/meta_base.hpp +++ b/headers/meta.hpp/meta_base.hpp @@ -103,35 +103,35 @@ namespace meta_hpp namespace meta_hpp { - class ctor; - class dtor; + class argument; + class constructor; + class destructor; class evalue; class function; class member; class method; - class parameter; class scope; class variable; namespace detail { - struct ctor_state; - struct dtor_state; + struct argument_state; + struct constructor_state; + struct destructor_state; struct evalue_state; struct function_state; struct member_state; struct method_state; - struct parameter_state; struct scope_state; struct variable_state; - using ctor_state_ptr = std::shared_ptr; - using dtor_state_ptr = std::shared_ptr; + using argument_state_ptr = std::shared_ptr; + using constructor_state_ptr = std::shared_ptr; + using destructor_state_ptr = std::shared_ptr; using evalue_state_ptr = std::shared_ptr; using function_state_ptr = std::shared_ptr; using member_state_ptr = std::shared_ptr; using method_state_ptr = std::shared_ptr; - using parameter_state_ptr = std::shared_ptr; using scope_state_ptr = std::shared_ptr; using variable_state_ptr = std::shared_ptr; } @@ -142,8 +142,8 @@ namespace meta_hpp class any_type; class array_type; class class_type; - class ctor_type; - class dtor_type; + class constructor_type; + class destructor_type; class enum_type; class function_type; class member_type; @@ -159,8 +159,8 @@ namespace meta_hpp struct type_data_base; struct array_type_data; struct class_type_data; - struct ctor_type_data; - struct dtor_type_data; + struct constructor_type_data; + struct destructor_type_data; struct enum_type_data; struct function_type_data; struct member_type_data; @@ -174,8 +174,8 @@ namespace meta_hpp using type_data_base_ptr = std::shared_ptr; using array_type_data_ptr = std::shared_ptr; using class_type_data_ptr = std::shared_ptr; - using ctor_type_data_ptr = std::shared_ptr; - using dtor_type_data_ptr = std::shared_ptr; + using constructor_type_data_ptr = std::shared_ptr; + using destructor_type_data_ptr = std::shared_ptr; using enum_type_data_ptr = std::shared_ptr; using function_type_data_ptr = std::shared_ptr; using member_type_data_ptr = std::shared_ptr; @@ -190,33 +190,33 @@ namespace meta_hpp namespace meta_hpp { - class ctor_index; - class dtor_index; + class argument_index; + class constructor_index; + class destructor_index; class evalue_index; class function_index; class member_index; class method_index; - class parameter_index; class scope_index; class variable_index; } namespace meta_hpp { + using argument_list = std::vector; + using class_set = std::set>; using class_map = std::map>; using enum_set = std::set>; using enum_map = std::map>; - using ctor_map = std::map>; - using dtor_map = std::map>; + using constructor_map = std::map>; + using destructor_map = std::map>; using evalue_map = std::map>; using function_map = std::map>; using member_map = std::map>; using method_map = std::map>; using scope_map = std::map>; using variable_map = std::map>; - - using parameter_list = std::vector; } diff --git a/headers/meta.hpp/meta_base/type_kinds.hpp b/headers/meta.hpp/meta_base/type_kinds.hpp index dd39caf..c0ea70e 100644 --- a/headers/meta.hpp/meta_base/type_kinds.hpp +++ b/headers/meta.hpp/meta_base/type_kinds.hpp @@ -50,8 +50,8 @@ namespace meta_hpp::detail enum class type_kind : std::uint32_t { array_, class_, - ctor_, - dtor_, + constructor_, + destructor_, enum_, function_, member_, diff --git a/headers/meta.hpp/meta_binds.hpp b/headers/meta.hpp/meta_binds.hpp index 272e08b..2ec5a53 100644 --- a/headers/meta.hpp/meta_binds.hpp +++ b/headers/meta.hpp/meta_binds.hpp @@ -14,12 +14,12 @@ namespace meta_hpp namespace detail { template < typename Class, typename... Args > - concept class_bind_ctor_kind = + concept class_bind_constructor_kind = class_kind && requires(Args&&... args) { { Class{std::forward(args)...} }; }; template < typename Class > - concept class_bind_dtor_kind = + concept class_bind_destructor_kind = class_kind && requires(Class&& inst) { { inst.~Class() }; }; @@ -46,19 +46,19 @@ namespace meta_hpp operator class_type() const noexcept; template < typename... Args - , ctor_policy_kind Policy = ctor_policy::as_object > - class_bind& ctor_(Policy = Policy{}) - requires detail::class_bind_ctor_kind; + , constructor_policy_kind Policy = constructor_policy::as_object > + class_bind& constructor_(Policy = Policy{}) + requires detail::class_bind_constructor_kind; template < typename... Args - , ctor_policy_kind Policy = ctor_policy::as_object > - class_bind& ctor_( - std::initializer_list pnames, + , constructor_policy_kind Policy = constructor_policy::as_object > + class_bind& constructor_( + std::initializer_list anames, Policy = Policy{}) - requires detail::class_bind_ctor_kind; + requires detail::class_bind_constructor_kind; - class_bind& dtor_() - requires detail::class_bind_dtor_kind; + class_bind& destructor_() + requires detail::class_bind_destructor_kind; template < detail::class_kind Base > class_bind& base_() @@ -73,7 +73,7 @@ namespace meta_hpp class_bind& function_( std::string name, Function function, - std::initializer_list pnames, + std::initializer_list anames, Policy = Policy{}); template < detail::member_kind Member @@ -91,7 +91,7 @@ namespace meta_hpp class_bind& method_( std::string name, Method method, - std::initializer_list pnames, + std::initializer_list anames, Policy = Policy{}) requires detail::class_bind_method_kind; @@ -143,7 +143,7 @@ namespace meta_hpp scope_bind& function_( std::string name, Function function, - std::initializer_list pnames, + std::initializer_list anames, Policy = Policy{}); template < detail::pointer_kind Pointer diff --git a/headers/meta.hpp/meta_binds/class_bind.hpp b/headers/meta.hpp/meta_binds/class_bind.hpp index b6254c4..e6cb114 100644 --- a/headers/meta.hpp/meta_binds/class_bind.hpp +++ b/headers/meta.hpp/meta_binds/class_bind.hpp @@ -23,41 +23,41 @@ namespace meta_hpp } template < detail::class_kind Class > - template < typename... Args, ctor_policy_kind Policy > - class_bind& class_bind::ctor_(Policy policy) - requires detail::class_bind_ctor_kind + template < typename... Args, constructor_policy_kind Policy > + class_bind& class_bind::constructor_(Policy policy) + requires detail::class_bind_constructor_kind { - return ctor_({}, policy); + return constructor_({}, policy); } template < detail::class_kind Class > - template < typename... Args, ctor_policy_kind Policy > - class_bind& class_bind::ctor_( - std::initializer_list pnames, + template < typename... Args, constructor_policy_kind Policy > + class_bind& class_bind::constructor_( + std::initializer_list anames, [[maybe_unused]] Policy policy) - requires detail::class_bind_ctor_kind + requires detail::class_bind_constructor_kind { - auto ctor_state = detail::ctor_state::make(); + auto constructor_state = detail::constructor_state::make(); - if ( pnames.size() > ctor_state->parameters.size() ) { - detail::throw_exception_with("provided parameter names don't match constructor argument count"); + if ( anames.size() > constructor_state->arguments.size() ) { + detail::throw_exception_with("provided argument names don't match constructor argument count"); } - for ( std::size_t i = 0; i < pnames.size(); ++i ) { - parameter& param = ctor_state->parameters[i]; - detail::state_access(param)->name = std::string{std::data(pnames)[i]}; + for ( std::size_t i = 0; i < anames.size(); ++i ) { + argument& arg = constructor_state->arguments[i]; + detail::state_access(arg)->name = std::string{std::data(anames)[i]}; } - data_->ctors.emplace(ctor_state->index, std::move(ctor_state)); + data_->constructors.emplace(constructor_state->index, std::move(constructor_state)); return *this; } template < detail::class_kind Class > - class_bind& class_bind::dtor_() - requires detail::class_bind_dtor_kind + class_bind& class_bind::destructor_() + requires detail::class_bind_destructor_kind { - auto dtor_state = detail::dtor_state::make(); - data_->dtors.emplace(dtor_state->index, std::move(dtor_state)); + auto destructor_state = detail::destructor_state::make(); + data_->destructors.emplace(destructor_state->index, std::move(destructor_state)); return *this; } @@ -86,18 +86,18 @@ namespace meta_hpp class_bind& class_bind::function_( std::string name, Function function, - std::initializer_list pnames, + std::initializer_list anames, [[maybe_unused]] Policy policy) { auto function_state = detail::function_state::make(std::move(name), std::move(function)); - if ( pnames.size() > function_state->parameters.size() ) { - detail::throw_exception_with("provided parameter names don't match function argument count"); + if ( anames.size() > function_state->arguments.size() ) { + detail::throw_exception_with("provided argument names don't match function argument count"); } - for ( std::size_t i = 0; i < pnames.size(); ++i ) { - parameter& param = function_state->parameters[i]; - detail::state_access(param)->name = std::string{std::data(pnames)[i]}; + for ( std::size_t i = 0; i < anames.size(); ++i ) { + argument& arg = function_state->arguments[i]; + detail::state_access(arg)->name = std::string{std::data(anames)[i]}; } data_->functions.emplace(function_state->index, std::move(function_state)); @@ -127,19 +127,19 @@ namespace meta_hpp class_bind& class_bind::method_( std::string name, Method method, - std::initializer_list pnames, + std::initializer_list anames, [[maybe_unused]] Policy policy) requires detail::class_bind_method_kind { auto method_state = detail::method_state::make(std::move(name), std::move(method)); - if ( pnames.size() > method_state->parameters.size() ) { - detail::throw_exception_with("provided parameter names don't match method argument count"); + if ( anames.size() > method_state->arguments.size() ) { + detail::throw_exception_with("provided argument names don't match method argument count"); } - for ( std::size_t i = 0; i < pnames.size(); ++i ) { - parameter& param = method_state->parameters[i]; - detail::state_access(param)->name = std::string{std::data(pnames)[i]}; + for ( std::size_t i = 0; i < anames.size(); ++i ) { + argument& arg = method_state->arguments[i]; + detail::state_access(arg)->name = std::string{std::data(anames)[i]}; } data_->methods.emplace(method_state->index, std::move(method_state)); diff --git a/headers/meta.hpp/meta_binds/scope_bind.hpp b/headers/meta.hpp/meta_binds/scope_bind.hpp index 1f00cd9..93eb02b 100644 --- a/headers/meta.hpp/meta_binds/scope_bind.hpp +++ b/headers/meta.hpp/meta_binds/scope_bind.hpp @@ -47,18 +47,18 @@ namespace meta_hpp scope_bind& scope_bind::function_( std::string name, Function function, - std::initializer_list pnames, + std::initializer_list anames, [[maybe_unused]] Policy policy) { auto function_state = detail::function_state::make(std::move(name), std::move(function)); - if ( pnames.size() > function_state->parameters.size() ) { - detail::throw_exception_with("provided parameter names don't match function argument count"); + if ( anames.size() > function_state->arguments.size() ) { + detail::throw_exception_with("provided argument names don't match function argument count"); } - for ( std::size_t i = 0; i < pnames.size(); ++i ) { - parameter& param = function_state->parameters[i]; - detail::state_access(param)->name = std::string{std::data(pnames)[i]}; + for ( std::size_t i = 0; i < anames.size(); ++i ) { + argument& arg = function_state->arguments[i]; + detail::state_access(arg)->name = std::string{std::data(anames)[i]}; } state_->functions.emplace(function_state->index, std::move(function_state)); diff --git a/headers/meta.hpp/meta_detail/state_family.hpp b/headers/meta.hpp/meta_detail/state_family.hpp index 18c4865..114caab 100644 --- a/headers/meta.hpp/meta_detail/state_family.hpp +++ b/headers/meta.hpp/meta_detail/state_family.hpp @@ -12,13 +12,13 @@ namespace meta_hpp::detail { template < typename T > inline constexpr bool is_state_family_v = - std::is_same_v || - std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v || - std::is_same_v || std::is_same_v || std::is_same_v; diff --git a/headers/meta.hpp/meta_detail/type_family.hpp b/headers/meta.hpp/meta_detail/type_family.hpp index 66764e5..8655d3b 100644 --- a/headers/meta.hpp/meta_detail/type_family.hpp +++ b/headers/meta.hpp/meta_detail/type_family.hpp @@ -15,8 +15,8 @@ namespace meta_hpp::detail std::is_same_v || std::is_same_v || std::is_same_v || - std::is_same_v || - std::is_same_v || + std::is_same_v || + std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v || diff --git a/headers/meta.hpp/meta_detail/type_registry.hpp b/headers/meta.hpp/meta_detail/type_registry.hpp index 763e166..9f63b31 100644 --- a/headers/meta.hpp/meta_detail/type_registry.hpp +++ b/headers/meta.hpp/meta_detail/type_registry.hpp @@ -82,10 +82,10 @@ namespace meta_hpp::detail [[nodiscard]] class_type resolve_class_type() { return class_type{resolve_class_type_data()}; } template < class_kind Class, typename... Args > - [[nodiscard]] ctor_type resolve_ctor_type() { return ctor_type{resolve_ctor_type_data()}; } + [[nodiscard]] constructor_type resolve_constructor_type() { return constructor_type{resolve_constructor_type_data()}; } template < class_kind Class > - [[nodiscard]] dtor_type resolve_dtor_type() { return dtor_type{resolve_dtor_type_data()}; } + [[nodiscard]] destructor_type resolve_destructor_type() { return destructor_type{resolve_destructor_type_data()}; } template < enum_kind Enum > [[nodiscard]] enum_type resolve_enum_type() { return enum_type{resolve_enum_type_data()}; } @@ -131,14 +131,14 @@ namespace meta_hpp::detail } template < class_kind Class, typename... Args > - [[nodiscard]] ctor_type_data_ptr resolve_ctor_type_data() { - static ctor_type_data_ptr data{std::make_shared(type_list{}, type_list{})}; + [[nodiscard]] constructor_type_data_ptr resolve_constructor_type_data() { + static constructor_type_data_ptr data{std::make_shared(type_list{}, type_list{})}; return data; } template < class_kind Class > - [[nodiscard]] dtor_type_data_ptr resolve_dtor_type_data() { - static dtor_type_data_ptr data{std::make_shared(type_list{})}; + [[nodiscard]] destructor_type_data_ptr resolve_destructor_type_data() { + static destructor_type_data_ptr data{std::make_shared(type_list{})}; return data; } @@ -234,15 +234,15 @@ namespace meta_hpp::detail namespace meta_hpp::detail { template < class_kind Class, typename... Args > - ctor_type resolve_ctor_type() { + constructor_type resolve_constructor_type() { type_registry& registry = type_registry::instance(); - return registry.resolve_ctor_type(); + return registry.resolve_constructor_type(); } template < class_kind Class > - dtor_type resolve_dtor_type() { + destructor_type resolve_destructor_type() { type_registry& registry = type_registry::instance(); - return registry.resolve_dtor_type(); + return registry.resolve_destructor_type(); } } diff --git a/headers/meta.hpp/meta_detail/type_traits/ctor_traits.hpp b/headers/meta.hpp/meta_detail/type_traits/constructor_traits.hpp similarity index 69% rename from headers/meta.hpp/meta_detail/type_traits/ctor_traits.hpp rename to headers/meta.hpp/meta_detail/type_traits/constructor_traits.hpp index 9c8eedd..2d4e9ee 100644 --- a/headers/meta.hpp/meta_detail/type_traits/ctor_traits.hpp +++ b/headers/meta.hpp/meta_detail/type_traits/constructor_traits.hpp @@ -10,28 +10,28 @@ namespace meta_hpp::detail { - enum class ctor_flags : std::uint32_t { + enum class constructor_flags : std::uint32_t { is_noexcept = 1 << 0, }; - ENUM_HPP_OPERATORS_DECL(ctor_flags) - using ctor_bitflags = bitflags; + ENUM_HPP_OPERATORS_DECL(constructor_flags) + using constructor_bitflags = bitflags; } namespace meta_hpp::detail { template < class_kind Class, typename... Args > - struct ctor_traits { + struct constructor_traits { static constexpr std::size_t arity{sizeof...(Args)}; using class_type = Class; using argument_types = type_list; - [[nodiscard]] static constexpr ctor_bitflags make_flags() noexcept { - ctor_bitflags flags{}; + [[nodiscard]] static constexpr constructor_bitflags make_flags() noexcept { + constructor_bitflags flags{}; if constexpr ( std::is_nothrow_constructible_v ) { - flags.set(ctor_flags::is_noexcept); + flags.set(constructor_flags::is_noexcept); } return flags; diff --git a/headers/meta.hpp/meta_detail/type_traits/dtor_traits.hpp b/headers/meta.hpp/meta_detail/type_traits/destructor_traits.hpp similarity index 66% rename from headers/meta.hpp/meta_detail/type_traits/dtor_traits.hpp rename to headers/meta.hpp/meta_detail/type_traits/destructor_traits.hpp index 759cdd5..e7ad092 100644 --- a/headers/meta.hpp/meta_detail/type_traits/dtor_traits.hpp +++ b/headers/meta.hpp/meta_detail/type_traits/destructor_traits.hpp @@ -10,25 +10,25 @@ namespace meta_hpp::detail { - enum class dtor_flags : std::uint32_t { + enum class destructor_flags : std::uint32_t { is_noexcept = 1 << 0, }; - ENUM_HPP_OPERATORS_DECL(dtor_flags) - using dtor_bitflags = bitflags; + ENUM_HPP_OPERATORS_DECL(destructor_flags) + using destructor_bitflags = bitflags; } namespace meta_hpp::detail { template < class_kind Class > - struct dtor_traits { + struct destructor_traits { using class_type = Class; - [[nodiscard]] static constexpr dtor_bitflags make_flags() noexcept { - dtor_bitflags flags{}; + [[nodiscard]] static constexpr destructor_bitflags make_flags() noexcept { + destructor_bitflags flags{}; if constexpr ( std::is_nothrow_destructible_v ) { - flags.set(dtor_flags::is_noexcept); + flags.set(destructor_flags::is_noexcept); } return flags; diff --git a/headers/meta.hpp/meta_indices.hpp b/headers/meta.hpp/meta_indices.hpp index 7033a92..fc0a38b 100644 --- a/headers/meta.hpp/meta_indices.hpp +++ b/headers/meta.hpp/meta_indices.hpp @@ -11,36 +11,54 @@ namespace meta_hpp { - class ctor_index final { + class argument_index final { public: - ctor_index() = delete; - [[nodiscard]] const ctor_type& get_type() const noexcept; + argument_index() = delete; + [[nodiscard]] const any_type& get_type() const noexcept; + [[nodiscard]] std::size_t get_position() const noexcept; private: - friend detail::ctor_state; - template < detail::class_kind Class, typename... Args > - [[nodiscard]] static ctor_index make(); + friend detail::argument_state; + template < typename Argument > + [[nodiscard]] static argument_index make(std::size_t position); private: - explicit ctor_index(ctor_type type); - friend bool operator<(const ctor_index& l, const ctor_index& r) noexcept; - friend bool operator==(const ctor_index& l, const ctor_index& r) noexcept; + explicit argument_index(any_type type, std::size_t position); + friend bool operator<(const argument_index& l, const argument_index& r) noexcept; + friend bool operator==(const argument_index& l, const argument_index& r) noexcept; private: - ctor_type type_; + any_type type_; + std::size_t position_{}; }; - class dtor_index final { + class constructor_index final { public: - dtor_index() = delete; - [[nodiscard]] const dtor_type& get_type() const noexcept; + constructor_index() = delete; + [[nodiscard]] const constructor_type& get_type() const noexcept; private: - friend detail::dtor_state; + friend detail::constructor_state; + template < detail::class_kind Class, typename... Args > + [[nodiscard]] static constructor_index make(); + private: + explicit constructor_index(constructor_type type); + friend bool operator<(const constructor_index& l, const constructor_index& r) noexcept; + friend bool operator==(const constructor_index& l, const constructor_index& r) noexcept; + private: + constructor_type type_; + }; + + class destructor_index final { + public: + destructor_index() = delete; + [[nodiscard]] const destructor_type& get_type() const noexcept; + private: + friend detail::destructor_state; template < detail::class_kind Class > - [[nodiscard]] static dtor_index make(); + [[nodiscard]] static destructor_index make(); private: - explicit dtor_index(dtor_type type); - friend bool operator<(const dtor_index& l, const dtor_index& r) noexcept; - friend bool operator==(const dtor_index& l, const dtor_index& r) noexcept; + explicit destructor_index(destructor_type type); + friend bool operator<(const destructor_index& l, const destructor_index& r) noexcept; + friend bool operator==(const destructor_index& l, const destructor_index& r) noexcept; private: - dtor_type type_; + destructor_type type_; }; class evalue_index final { @@ -115,24 +133,6 @@ namespace meta_hpp std::string name_; }; - class parameter_index final { - public: - parameter_index() = delete; - [[nodiscard]] const any_type& get_type() const noexcept; - [[nodiscard]] std::size_t get_position() const noexcept; - private: - friend detail::parameter_state; - template < typename Parameter > - [[nodiscard]] static parameter_index make(std::size_t position); - private: - explicit parameter_index(any_type type, std::size_t position); - friend bool operator<(const parameter_index& l, const parameter_index& r) noexcept; - friend bool operator==(const parameter_index& l, const parameter_index& r) noexcept; - private: - any_type type_; - std::size_t position_{}; - }; - class scope_index final { public: scope_index() = delete; diff --git a/headers/meta.hpp/meta_indices/parameter_index.hpp b/headers/meta.hpp/meta_indices/argument_index.hpp similarity index 58% rename from headers/meta.hpp/meta_indices/parameter_index.hpp rename to headers/meta.hpp/meta_indices/argument_index.hpp index 00b9d48..7cb3ef3 100644 --- a/headers/meta.hpp/meta_indices/parameter_index.hpp +++ b/headers/meta.hpp/meta_indices/argument_index.hpp @@ -14,28 +14,28 @@ namespace meta_hpp { - inline parameter_index::parameter_index(any_type type, std::size_t position) + inline argument_index::argument_index(any_type type, std::size_t position) : type_{std::move(type)} , position_{position} {} - template < typename Parameter > - inline parameter_index parameter_index::make(std::size_t position) { - return parameter_index{detail::resolve_type(), position}; + template < typename Argument > + inline argument_index argument_index::make(std::size_t position) { + return argument_index{detail::resolve_type(), position}; } - inline const any_type& parameter_index::get_type() const noexcept { + inline const any_type& argument_index::get_type() const noexcept { return type_; } - inline std::size_t parameter_index::get_position() const noexcept { + inline std::size_t argument_index::get_position() const noexcept { return position_; } - inline bool operator<(const parameter_index& l, const parameter_index& r) noexcept { + inline bool operator<(const argument_index& l, const argument_index& r) noexcept { return l.type_ < r.type_ || (l.type_ == r.type_ && l.position_ < r.position_); } - inline bool operator==(const parameter_index& l, const parameter_index& r) noexcept { + inline bool operator==(const argument_index& l, const argument_index& r) noexcept { return l.type_ == r.type_ && l.position_ == r.position_; } } diff --git a/headers/meta.hpp/meta_indices/ctor_index.hpp b/headers/meta.hpp/meta_indices/constructor_index.hpp similarity index 61% rename from headers/meta.hpp/meta_indices/ctor_index.hpp rename to headers/meta.hpp/meta_indices/constructor_index.hpp index 0d83eb6..9ab13b6 100644 --- a/headers/meta.hpp/meta_indices/ctor_index.hpp +++ b/headers/meta.hpp/meta_indices/constructor_index.hpp @@ -14,23 +14,23 @@ namespace meta_hpp { - inline ctor_index::ctor_index(ctor_type type) + inline constructor_index::constructor_index(constructor_type type) : type_{std::move(type)} {} template < detail::class_kind Class, typename... Args > - ctor_index ctor_index::make() { - return ctor_index{detail::resolve_ctor_type()}; + constructor_index constructor_index::make() { + return constructor_index{detail::resolve_constructor_type()}; } - inline const ctor_type& ctor_index::get_type() const noexcept { + inline const constructor_type& constructor_index::get_type() const noexcept { return type_; } - inline bool operator<(const ctor_index& l, const ctor_index& r) noexcept { + inline bool operator<(const constructor_index& l, const constructor_index& r) noexcept { return l.type_ < r.type_; } - inline bool operator==(const ctor_index& l, const ctor_index& r) noexcept { + inline bool operator==(const constructor_index& l, const constructor_index& r) noexcept { return l.type_ == r.type_; } } diff --git a/headers/meta.hpp/meta_indices/dtor_index.hpp b/headers/meta.hpp/meta_indices/destructor_index.hpp similarity index 61% rename from headers/meta.hpp/meta_indices/dtor_index.hpp rename to headers/meta.hpp/meta_indices/destructor_index.hpp index e62828d..2207b85 100644 --- a/headers/meta.hpp/meta_indices/dtor_index.hpp +++ b/headers/meta.hpp/meta_indices/destructor_index.hpp @@ -14,23 +14,23 @@ namespace meta_hpp { - inline dtor_index::dtor_index(dtor_type type) + inline destructor_index::destructor_index(destructor_type type) : type_{std::move(type)} {} template < detail::class_kind Class > - dtor_index dtor_index::make() { - return dtor_index{detail::resolve_dtor_type()}; + destructor_index destructor_index::make() { + return destructor_index{detail::resolve_destructor_type()}; } - inline const dtor_type& dtor_index::get_type() const noexcept { + inline const destructor_type& destructor_index::get_type() const noexcept { return type_; } - inline bool operator<(const dtor_index& l, const dtor_index& r) noexcept { + inline bool operator<(const destructor_index& l, const destructor_index& r) noexcept { return l.type_ < r.type_; } - inline bool operator==(const dtor_index& l, const dtor_index& r) noexcept { + inline bool operator==(const destructor_index& l, const destructor_index& r) noexcept { return l.type_ == r.type_; } } diff --git a/headers/meta.hpp/meta_states.hpp b/headers/meta.hpp/meta_states.hpp index 3e4d3d3..f238b80 100644 --- a/headers/meta.hpp/meta_states.hpp +++ b/headers/meta.hpp/meta_states.hpp @@ -15,7 +15,7 @@ namespace meta_hpp { - namespace ctor_policy + namespace constructor_policy { struct as_object final {}; struct as_raw_pointer final {}; @@ -51,10 +51,10 @@ namespace meta_hpp } template < typename Policy > - inline constexpr bool is_ctor_policy_v = - std::is_same_v || - std::is_same_v || - std::is_same_v; + inline constexpr bool is_constructor_policy_v = + std::is_same_v || + std::is_same_v || + std::is_same_v; template < typename Policy > inline constexpr bool is_function_policy_v = @@ -81,7 +81,7 @@ namespace meta_hpp std::is_same_v; template < typename Policy > - concept ctor_policy_kind = is_ctor_policy_v; + concept constructor_policy_kind = is_constructor_policy_v; template < typename Policy > concept function_policy_kind = is_function_policy_v; @@ -98,16 +98,33 @@ namespace meta_hpp namespace meta_hpp { - class ctor final { + class argument final { public: - explicit ctor() = default; - explicit ctor(detail::ctor_state_ptr state); + explicit argument() = default; + explicit argument(detail::argument_state_ptr state); [[nodiscard]] bool is_valid() const noexcept; [[nodiscard]] explicit operator bool() const noexcept; - [[nodiscard]] const ctor_index& get_index() const noexcept; - [[nodiscard]] const ctor_type& get_type() const noexcept; + [[nodiscard]] const argument_index& get_index() const noexcept; + [[nodiscard]] const any_type& get_type() const noexcept; + [[nodiscard]] std::size_t get_position() const noexcept; + [[nodiscard]] const std::string& get_name() const noexcept; + private: + detail::argument_state_ptr state_; + friend auto detail::state_access(const argument&); + }; + + class constructor final { + public: + explicit constructor() = default; + explicit constructor(detail::constructor_state_ptr state); + + [[nodiscard]] bool is_valid() const noexcept; + [[nodiscard]] explicit operator bool() const noexcept; + + [[nodiscard]] const constructor_index& get_index() const noexcept; + [[nodiscard]] const constructor_type& get_type() const noexcept; template < typename... Args > uvalue invoke(Args&&... args) const; @@ -121,23 +138,23 @@ namespace meta_hpp template < typename... Args > [[nodiscard]] bool is_invocable_with(Args&&... args) const noexcept; - [[nodiscard]] parameter get_parameter(std::size_t position) const noexcept; - [[nodiscard]] const parameter_list& get_parameters() const noexcept; + [[nodiscard]] argument get_argument(std::size_t position) const noexcept; + [[nodiscard]] const argument_list& get_arguments() const noexcept; private: - detail::ctor_state_ptr state_; - friend auto detail::state_access(const ctor&); + detail::constructor_state_ptr state_; + friend auto detail::state_access(const constructor&); }; - class dtor final { + class destructor final { public: - explicit dtor() = default; - explicit dtor(detail::dtor_state_ptr state); + explicit destructor() = default; + explicit destructor(detail::destructor_state_ptr state); [[nodiscard]] bool is_valid() const noexcept; [[nodiscard]] explicit operator bool() const noexcept; - [[nodiscard]] const dtor_index& get_index() const noexcept; - [[nodiscard]] const dtor_type& get_type() const noexcept; + [[nodiscard]] const destructor_index& get_index() const noexcept; + [[nodiscard]] const destructor_type& get_type() const noexcept; template < typename Arg > void invoke(Arg&& ptr) const; @@ -151,8 +168,8 @@ namespace meta_hpp template < typename Arg > [[nodiscard]] bool is_invocable_with(Arg&& ptr) const noexcept; private: - detail::dtor_state_ptr state_; - friend auto detail::state_access(const dtor&); + detail::destructor_state_ptr state_; + friend auto detail::state_access(const destructor&); }; class evalue final { @@ -198,8 +215,8 @@ namespace meta_hpp template < typename... Args > [[nodiscard]] bool is_invocable_with(Args&&... args) const noexcept; - [[nodiscard]] parameter get_parameter(std::size_t position) const noexcept; - [[nodiscard]] const parameter_list& get_parameters() const noexcept; + [[nodiscard]] argument get_argument(std::size_t position) const noexcept; + [[nodiscard]] const argument_list& get_arguments() const noexcept; private: detail::function_state_ptr state_; friend auto detail::state_access(const function&); @@ -269,30 +286,13 @@ namespace meta_hpp template < typename Instance, typename... Args > [[nodiscard]] bool is_invocable_with(Instance&& instance, Args&&... args) const noexcept; - [[nodiscard]] parameter get_parameter(std::size_t position) const noexcept; - [[nodiscard]] const parameter_list& get_parameters() const noexcept; + [[nodiscard]] argument get_argument(std::size_t position) const noexcept; + [[nodiscard]] const argument_list& get_arguments() const noexcept; private: detail::method_state_ptr state_; friend auto detail::state_access(const method&); }; - class parameter final { - public: - explicit parameter() = default; - explicit parameter(detail::parameter_state_ptr state); - - [[nodiscard]] bool is_valid() const noexcept; - [[nodiscard]] explicit operator bool() const noexcept; - - [[nodiscard]] const parameter_index& get_index() const noexcept; - [[nodiscard]] const any_type& get_type() const noexcept; - [[nodiscard]] std::size_t get_position() const noexcept; - [[nodiscard]] const std::string& get_name() const noexcept; - private: - detail::parameter_state_ptr state_; - friend auto detail::state_access(const parameter&); - }; - class scope final { public: explicit scope() = default; @@ -394,30 +394,30 @@ namespace meta_hpp namespace meta_hpp::detail { - struct ctor_state final { + struct constructor_state final { using invoke_impl = fixed_function)>; using is_invocable_with_impl = fixed_function)>; - ctor_index index; + constructor_index index; invoke_impl invoke; is_invocable_with_impl is_invocable_with; - parameter_list parameters; + argument_list arguments; - template < ctor_policy_kind Policy, class_kind Class, typename... Args > - [[nodiscard]] static ctor_state_ptr make(); + template < constructor_policy_kind Policy, class_kind Class, typename... Args > + [[nodiscard]] static constructor_state_ptr make(); }; - struct dtor_state final { + struct destructor_state final { using invoke_impl = fixed_function; using is_invocable_with_impl = fixed_function; - dtor_index index; + destructor_index index; invoke_impl invoke; is_invocable_with_impl is_invocable_with; template < class_kind Class > - [[nodiscard]] static dtor_state_ptr make(); + [[nodiscard]] static destructor_state_ptr make(); }; struct evalue_state final { @@ -437,7 +437,7 @@ namespace meta_hpp::detail invoke_impl invoke; is_invocable_with_impl is_invocable_with; - parameter_list parameters; + argument_list arguments; template < function_policy_kind Policy, function_kind Function > [[nodiscard]] static function_state_ptr make(std::string name, Function function); @@ -468,19 +468,19 @@ namespace meta_hpp::detail invoke_impl invoke; is_invocable_with_impl is_invocable_with; - parameter_list parameters; + argument_list arguments; template < method_policy_kind Policy, method_kind Method > [[nodiscard]] static method_state_ptr make(std::string name, Method method); }; - struct parameter_state final { - parameter_index index; + struct argument_state final { + argument_index index; std::string name{}; - template < typename Parameter > - [[nodiscard]] static parameter_state_ptr make(std::size_t position); + template < typename Argument > + [[nodiscard]] static argument_state_ptr make(std::size_t position); }; struct scope_state final { diff --git a/headers/meta.hpp/meta_states/parameter.hpp b/headers/meta.hpp/meta_states/argument.hpp similarity index 53% rename from headers/meta.hpp/meta_states/parameter.hpp rename to headers/meta.hpp/meta_states/argument.hpp index e0cad8d..4d47d9f 100644 --- a/headers/meta.hpp/meta_states/parameter.hpp +++ b/headers/meta.hpp/meta_states/argument.hpp @@ -11,10 +11,10 @@ namespace meta_hpp::detail { - template < typename Parameter > - inline parameter_state_ptr parameter_state::make(std::size_t position) { - return std::make_shared(parameter_state{ - .index{parameter_index::make(position)}, + template < typename Argument > + inline argument_state_ptr argument_state::make(std::size_t position) { + return std::make_shared(argument_state{ + .index{argument_index::make(position)}, }); } } @@ -22,30 +22,30 @@ namespace meta_hpp::detail namespace meta_hpp { - inline parameter::parameter(detail::parameter_state_ptr state) + inline argument::argument(detail::argument_state_ptr state) : state_{std::move(state)} {} - inline bool parameter::is_valid() const noexcept { + inline bool argument::is_valid() const noexcept { return !!state_; } - inline parameter::operator bool() const noexcept { + inline argument::operator bool() const noexcept { return is_valid(); } - inline const parameter_index& parameter::get_index() const noexcept { + inline const argument_index& argument::get_index() const noexcept { return state_->index; } - inline const any_type& parameter::get_type() const noexcept { + inline const any_type& argument::get_type() const noexcept { return state_->index.get_type(); } - inline std::size_t parameter::get_position() const noexcept { + inline std::size_t argument::get_position() const noexcept { return state_->index.get_position(); } - inline const std::string& parameter::get_name() const noexcept { + inline const std::string& argument::get_name() const noexcept { return state_->name; } } diff --git a/headers/meta.hpp/meta_states/ctor.hpp b/headers/meta.hpp/meta_states/constructor.hpp similarity index 61% rename from headers/meta.hpp/meta_states/ctor.hpp rename to headers/meta.hpp/meta_states/constructor.hpp index 432d665..fade6dc 100644 --- a/headers/meta.hpp/meta_states/ctor.hpp +++ b/headers/meta.hpp/meta_states/constructor.hpp @@ -9,26 +9,26 @@ #include "../meta_base.hpp" #include "../meta_states.hpp" -#include "../meta_types/ctor_type.hpp" +#include "../meta_types/constructor_type.hpp" #include "../meta_detail/value_utilities/uarg.hpp" namespace meta_hpp::detail { - template < ctor_policy_kind Policy, class_kind Class, typename... Args > - uvalue raw_ctor_invoke(std::span args) { - using ct = ctor_traits; + template < constructor_policy_kind Policy, class_kind Class, typename... Args > + uvalue raw_constructor_invoke(std::span args) { + using ct = constructor_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; + stdex::same_as; constexpr bool as_raw_ptr = - stdex::same_as; + stdex::same_as; constexpr bool as_shared_ptr = - stdex::same_as; + stdex::same_as; static_assert(as_object || as_raw_ptr || as_shared_ptr); @@ -62,8 +62,8 @@ namespace meta_hpp::detail } template < class_kind Class, typename... Args > - bool raw_ctor_is_invocable_with(std::span args) { - using ct = ctor_traits; + bool raw_constructor_is_invocable_with(std::span args) { + using ct = constructor_traits; using argument_types = typename ct::argument_types; if ( args.size() != ct::arity ) { @@ -79,71 +79,71 @@ namespace meta_hpp::detail namespace meta_hpp::detail { - template < ctor_policy_kind Policy, class_kind Class, typename... Args > - ctor_state::invoke_impl make_ctor_invoke() { - return &raw_ctor_invoke; + template < constructor_policy_kind Policy, class_kind Class, typename... Args > + constructor_state::invoke_impl make_constructor_invoke() { + return &raw_constructor_invoke; } template < class_kind Class, typename... Args > - ctor_state::is_invocable_with_impl make_ctor_is_invocable_with() { - return &raw_ctor_is_invocable_with; + constructor_state::is_invocable_with_impl make_constructor_is_invocable_with() { + return &raw_constructor_is_invocable_with; } template < class_kind Class, typename... Args > - parameter_list make_ctor_parameters() { - using ct = detail::ctor_traits; + argument_list make_constructor_arguments() { + using ct = detail::constructor_traits; - parameter_list parameters; - parameters.reserve(ct::arity); + argument_list arguments; + arguments.reserve(ct::arity); // NOLINTNEXTLINE(readability-named-parameter) - [¶meters](std::index_sequence) mutable { - (parameters.push_back([](){ + [&arguments](std::index_sequence) mutable { + (arguments.push_back([](){ using P = detail::type_list_at_t; - return parameter{detail::parameter_state::make