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()); +}