base type for classes

This commit is contained in:
BlackMATov
2021-08-10 03:38:39 +07:00
parent 18ffff8ea0
commit 2f4d33d24a
15 changed files with 607 additions and 20 deletions

View File

@@ -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<K, V, std::less<>>;
using base_info_map = info_map<type_id, base_info>;
using class_info_map = info_map<std::string, class_info>;
using ctor_info_map = info_map<type_id, ctor_info>;
using data_info_map = info_map<std::string, data_info>;

View File

@@ -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"

View File

@@ -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<Base>, typename_arg_t<Derived>);
private:
struct state;
std::shared_ptr<state> 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<Base>, typename_arg_t<Derived>)
: state_{std::make_shared<state>(state{
base_type{typename_arg<Base>, typename_arg<Derived>},
{}
})} {}
}

View File

@@ -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<any_type, Args>& args) const noexcept;
ctor_info get_ctor_by_args(const std::vector<any_type>& 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<Base>());
}
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<any_type, sizeof...(Args)> args{type_db::get<Args>()...};
return get_ctor_by_args(args);
}
template < std::size_t Args >
ctor_info class_info::get_ctor_by_args(const std::array<any_type, Args>& args) const noexcept {
for ( auto&& id_info : state_->ctors ) {
const std::vector<any_type>& 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<any_type>& args) const noexcept {
for ( auto&& id_info : state_->ctors ) {
const std::vector<any_type>& 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>(state{
std::move(name),
type_db::get<Class>().template as<class_type>(),
{}, {}, {}, {}, {}, {}, {}
{}, {}, {}, {}, {}, {}, {}, {}
})} {}
}

View File

@@ -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));

View File

@@ -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_<Base>::make_info() const {
base_info info{typename_arg<Base>, typename_arg<Derived>};
info.state_->datas.insert(datas_.begin(), datas_.end());
return info;
}
template < typename Base >
template < typename... Internals >
base_<Base>& base_<Base>::operator()(Internals&&...internals) {
(add_(std::forward<Internals>(internals)), ...);
return *this;
}
}
namespace meta_hpp
{
template < typename Base >
void base_<Base>::add_(const data_& internal) {
auto info = internal.make_info();
detail::merge_with(datas_, info.name(), info, &data_info::merge);
}
}

View File

@@ -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_<Base>& internal);
template < typename Class2 >
void add_(const class_<Class2>& 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_<Class>::make_info() const {
class_info info{typename_arg<Class>, 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_<Class>::add_(const base_<Base>& internal) {
auto info = internal.template make_info<Class>();
detail::merge_with(bases_, info.type().id(), info, &base_info::merge);
}
template < typename Class >
template < typename Class2 >
void class_<Class>::add_(const class_<Class2>& internal) {

View File

@@ -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"

View File

@@ -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*,

View File

@@ -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<Base>, typename_arg_t<Derived>);
any_type base_class_type() const noexcept;
any_type derived_class_type() const noexcept;
private:
struct state;
std::shared_ptr<state> state_;
};
}
namespace meta_hpp::detail
{
template < typename Base, typename Derived >
struct base_traits {
static_assert(std::is_base_of_v<Base, Derived>);
using base_class_type = Base;
using derived_class_type = Derived;
static any_type make_base_class_type() {
return type_db::get<base_class_type>();
}
static any_type make_derived_class_type() {
return type_db::get<derived_class_type>();
}
};
}
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<Base>, typename_arg_t<Derived>)
: type_base{typename_arg<struct base_type_tag, Base, Derived>}
, state_{std::make_shared<state>(state{
detail::base_traits<Base, Derived>::make_base_class_type(),
detail::base_traits<Base, Derived>::make_derived_class_type(),
})} {
static_assert(std::is_base_of_v<Base, Derived>);
}
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;
}
}

View File

@@ -59,16 +59,16 @@ namespace meta_hpp
template < typename T
, std::enable_if_t<!std::is_reference_v<T>, int> >
inline arg::arg(T&& v)
: data_{const_cast<add_ptr_t<remove_cvref_t<T>>>(std::addressof(v))}
, raw_type_{type_db::get<remove_cvref_t<T>>()}
: data_{const_cast<std::add_pointer_t<stdex::remove_cvref_t<T>>>(std::addressof(v))}
, raw_type_{type_db::get<stdex::remove_cvref_t<T>>()}
, ref_type_{std::is_const_v<T> ? ref_types::crref : ref_types::rref} {}
template < typename T
, std::enable_if_t<std::is_lvalue_reference_v<T>, int> >
inline arg::arg(T&& v)
: data_{const_cast<add_ptr_t<remove_cvref_t<T>>>(std::addressof(v))}
, raw_type_{type_db::get<remove_cvref_t<T>>()}
, ref_type_{std::is_const_v<remove_ref_t<T>> ? ref_types::cref : ref_types::ref} {}
: data_{const_cast<std::add_pointer_t<stdex::remove_cvref_t<T>>>(std::addressof(v))}
, raw_type_{type_db::get<stdex::remove_cvref_t<T>>()}
, ref_type_{std::is_const_v<std::remove_reference_t<T>> ? 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<To> ) {
using raw_type = remove_cvref_t<To>;
using raw_type = stdex::remove_cvref_t<To>;
if constexpr ( std::is_lvalue_reference_v<To> ) {
return *static_cast<raw_type*>(data_);
@@ -93,7 +93,7 @@ namespace meta_hpp
}
if constexpr ( !std::is_pointer_v<To> && !std::is_reference_v<To> ) {
using raw_type = remove_cvref_t<To>;
using raw_type = stdex::remove_cvref_t<To>;
if ( ref_type() == ref_types::ref ) {
if constexpr ( std::is_constructible_v<To, raw_type&> ) {
@@ -126,14 +126,14 @@ namespace meta_hpp
template < typename To >
inline bool arg::can_cast() const noexcept {
if constexpr ( std::is_pointer_v<To> ) {
using to_raw_type = remove_cv_t<To>;
using to_raw_ptr_type = remove_cv_t<std::remove_pointer_t<to_raw_type>>;
using to_raw_type = std::remove_cv_t<To>;
using to_raw_ptr_type = std::remove_cv_t<std::remove_pointer_t<to_raw_type>>;
return raw_type().id() == type_db::get<to_raw_type>().id()
|| raw_type().id() == type_db::get<add_ptr_t<to_raw_ptr_type>>().id();
|| raw_type().id() == type_db::get<std::add_pointer_t<to_raw_ptr_type>>().id();
}
if constexpr ( std::is_lvalue_reference_v<To> ) {
constexpr bool to_const = std::is_const_v<remove_ref_t<To>>;
constexpr bool to_const = std::is_const_v<std::remove_reference_t<To>>;
if ( !to_const && is_rvalue() ) {
return false;
@@ -143,21 +143,21 @@ namespace meta_hpp
return false;
}
using to_raw_type = remove_cvref_t<To>;
using to_raw_type = stdex::remove_cvref_t<To>;
if ( raw_type().id() == type_db::get<to_raw_type>().id() ) {
return true;
}
if constexpr ( to_const && std::is_pointer_v<to_raw_type> ) {
using to_raw_ptr_type = remove_cv_t<std::remove_pointer_t<to_raw_type>>;
return raw_type().id() == type_db::get<add_ptr_t<to_raw_ptr_type>>().id();
using to_raw_ptr_type = std::remove_cv_t<std::remove_pointer_t<to_raw_type>>;
return raw_type().id() == type_db::get<std::add_pointer_t<to_raw_ptr_type>>().id();
}
return false;
}
if constexpr ( std::is_rvalue_reference_v<To> ) {
constexpr bool to_const = std::is_const_v<remove_ref_t<To>>;
constexpr bool to_const = std::is_const_v<std::remove_reference_t<To>>;
if ( !is_rvalue() ) {
return false;
@@ -167,21 +167,21 @@ namespace meta_hpp
return false;
}
using to_raw_type = remove_cvref_t<To>;
using to_raw_type = stdex::remove_cvref_t<To>;
if ( raw_type().id() == type_db::get<to_raw_type>().id() ) {
return true;
}
if constexpr ( to_const && std::is_pointer_v<to_raw_type> ) {
using to_raw_ptr_type = remove_cv_t<std::remove_pointer_t<to_raw_type>>;
return raw_type().id() == type_db::get<add_ptr_t<to_raw_ptr_type>>().id();
using to_raw_ptr_type = std::remove_cv_t<std::remove_pointer_t<to_raw_type>>;
return raw_type().id() == type_db::get<std::add_pointer_t<to_raw_ptr_type>>().id();
}
return false;
}
if constexpr ( !std::is_pointer_v<To> && !std::is_reference_v<To> ) {
using to_raw_type = remove_cv_t<To>;
using to_raw_type = std::remove_cv_t<To>;
if ( raw_type().id() != type_db::get<to_raw_type>().id() ) {
return false;
}

View File

@@ -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>{"base"},
class_<derived>{"derived"}(
base_<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<base>());
CHECK_FALSE(derived_info.is_derived_from<empty>());
}

View File

@@ -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>{"shape"}(
method_{"area", &shape::area}
),
class_<rectangle>{"rectangle"}(
base_<shape>{},
ctor_<int, int>{},
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<shape>().id());
CHECK_FALSE(shape_info.is_derived_from<shape>());
CHECK_FALSE(shape_info.is_derived_from<rectangle>());
}
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<rectangle>().id());
CHECK(rectangle_info.is_derived_from<shape>());
CHECK_FALSE(rectangle_info.is_derived_from<rectangle>());
}
}

View File

@@ -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>{"ivec2"}(
ctor_<>{}(data_{"info", "void ctor"s}),
ctor_<const ivec2&>{}(data_{"info", "copy ctor"s}),
ctor_<int>{}(data_{"info", "int ctor"s}),
ctor_<int, int>{}(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<any_type, 0>{});
const ctor_info ci3 = ivec2_info.get_ctor_by_args(std::vector<any_type>{});
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<int>();
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<any_type, 1>{
type_db::get<int>()});
const ctor_info ci3 = ivec2_info.get_ctor_by_args(std::vector<any_type>{
type_db::get<int>()});
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<const ivec2&>();
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<any_type, 1>{
type_db::get<const ivec2&>()});
const ctor_info ci3 = ivec2_info.get_ctor_by_args(std::vector<any_type>{
type_db::get<const ivec2&>()});
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<int,int>();
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<any_type, 2>{
type_db::get<int>(),
type_db::get<int>()});
const ctor_info ci3 = ivec2_info.get_ctor_by_args(std::vector<any_type>{
type_db::get<int>(),
type_db::get<int>()});
REQUIRE(ci2);
REQUIRE(ci3);
CHECK(ci.type().id() == ci2.type().id());
CHECK(ci.type().id() == ci2.type().id());
}
}
}

View File

@@ -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<base>, typename_arg<derived>};
CHECK(bt.base_class_type().id() == type_db::get<base>().id());
CHECK(bt.derived_class_type().id() == type_db::get<derived>().id());
}