mirror of
https://github.com/BlackMATov/meta.hpp.git
synced 2025-12-14 19:41:29 +07:00
new base info wip
This commit is contained in:
@@ -9,6 +9,7 @@
|
|||||||
- test and support shared libraries
|
- test and support shared libraries
|
||||||
- remove `resolve_poly_type`, use `resolve_type(T&&)` instead
|
- remove `resolve_poly_type`, use `resolve_type(T&&)` instead
|
||||||
- add ucast manual
|
- add ucast manual
|
||||||
|
- mark all internal macro with DETAIL prefix
|
||||||
|
|
||||||
## Thoughts
|
## Thoughts
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ namespace
|
|||||||
};
|
};
|
||||||
|
|
||||||
class rectangle : public shape {
|
class rectangle : public shape {
|
||||||
|
META_HPP_ENABLE_BASE_INFO(shape)
|
||||||
public:
|
public:
|
||||||
explicit rectangle(int width, int height)
|
explicit rectangle(int width, int height)
|
||||||
: width_{width}
|
: width_{width}
|
||||||
@@ -52,7 +53,6 @@ TEST_CASE("meta/meta_manuals/class/type") {
|
|||||||
|
|
||||||
// 'rectangle' class type registration
|
// 'rectangle' class type registration
|
||||||
meta::class_<rectangle>()
|
meta::class_<rectangle>()
|
||||||
.base_<shape>()
|
|
||||||
.constructor_<int, int>()
|
.constructor_<int, int>()
|
||||||
.method_("get_width", &rectangle::get_width)
|
.method_("get_width", &rectangle::get_width)
|
||||||
.method_("get_height", &rectangle::get_height);
|
.method_("get_height", &rectangle::get_height);
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ namespace
|
|||||||
};
|
};
|
||||||
|
|
||||||
class rectangle : public shape {
|
class rectangle : public shape {
|
||||||
|
META_HPP_ENABLE_BASE_INFO(shape)
|
||||||
public:
|
public:
|
||||||
explicit rectangle(int width, int height)
|
explicit rectangle(int width, int height)
|
||||||
: width_{width}
|
: width_{width}
|
||||||
@@ -52,7 +53,6 @@ TEST_CASE("meta/meta_manuals/uvalue") {
|
|||||||
|
|
||||||
// 'rectangle' class type registration
|
// 'rectangle' class type registration
|
||||||
meta::class_<rectangle>()
|
meta::class_<rectangle>()
|
||||||
.base_<shape>()
|
|
||||||
.constructor_<int, int>()
|
.constructor_<int, int>()
|
||||||
.method_("get_width", &rectangle::get_width)
|
.method_("get_width", &rectangle::get_width)
|
||||||
.method_("get_height", &rectangle::get_height);
|
.method_("get_height", &rectangle::get_height);
|
||||||
|
|||||||
@@ -2672,7 +2672,6 @@ namespace meta_hpp
|
|||||||
[[nodiscard]] const any_type_list& get_argument_types() const noexcept;
|
[[nodiscard]] const any_type_list& get_argument_types() const noexcept;
|
||||||
|
|
||||||
[[nodiscard]] const class_list& get_base_classes() const noexcept;
|
[[nodiscard]] const class_list& get_base_classes() const noexcept;
|
||||||
[[nodiscard]] const class_list& get_derived_classes() const noexcept;
|
|
||||||
[[nodiscard]] const constructor_list& get_constructors() const noexcept;
|
[[nodiscard]] const constructor_list& get_constructors() const noexcept;
|
||||||
[[nodiscard]] const destructor_list& get_destructors() const noexcept;
|
[[nodiscard]] const destructor_list& get_destructors() const noexcept;
|
||||||
[[nodiscard]] const function_list& get_functions() const noexcept;
|
[[nodiscard]] const function_list& get_functions() const noexcept;
|
||||||
@@ -2965,7 +2964,6 @@ namespace meta_hpp::detail
|
|||||||
// NOLINTEND(*-avoid-const-or-ref-data-members)
|
// NOLINTEND(*-avoid-const-or-ref-data-members)
|
||||||
|
|
||||||
class_list base_classes;
|
class_list base_classes;
|
||||||
class_list derived_classes;
|
|
||||||
constructor_list constructors;
|
constructor_list constructors;
|
||||||
destructor_list destructors;
|
destructor_list destructors;
|
||||||
function_list functions;
|
function_list functions;
|
||||||
@@ -2997,8 +2995,8 @@ namespace meta_hpp::detail
|
|||||||
vbases_t vbases{};
|
vbases_t vbases{};
|
||||||
bool is_ambiguous{};
|
bool is_ambiguous{};
|
||||||
|
|
||||||
upcast_func_list_t(const upcast_func_t& _upcast);
|
upcast_func_list_t(const upcast_func_t& in_upcast);
|
||||||
upcast_func_list_t(upcasts_t _upcasts, vbases_t _vbases);
|
upcast_func_list_t(upcasts_t in_upcasts, vbases_t in_vbases);
|
||||||
|
|
||||||
[[nodiscard]] void* apply(void* ptr) const noexcept;
|
[[nodiscard]] void* apply(void* ptr) const noexcept;
|
||||||
[[nodiscard]] const void* apply(const void* ptr) const noexcept;
|
[[nodiscard]] const void* apply(const void* ptr) const noexcept;
|
||||||
@@ -4312,6 +4310,10 @@ namespace meta_hpp::detail
|
|||||||
class_type type{};
|
class_type type{};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template < typename T >
|
||||||
|
concept check_base_info_enabled //
|
||||||
|
= requires { typename T::meta_base_info; };
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
concept check_poly_info_enabled //
|
concept check_poly_info_enabled //
|
||||||
= requires(type_registry& r, const T& v) {
|
= requires(type_registry& r, const T& v) {
|
||||||
@@ -4319,7 +4321,14 @@ namespace meta_hpp::detail
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#define META_HPP_ENABLE_POLY_INFO() \
|
#define META_HPP_ENABLE_BASE_INFO(...) \
|
||||||
|
public: \
|
||||||
|
using meta_base_info = ::meta_hpp::detail::type_list<__VA_ARGS__>; \
|
||||||
|
\
|
||||||
|
private:
|
||||||
|
|
||||||
|
#define META_HPP_ENABLE_POLY_INFO(...) \
|
||||||
|
META_HPP_ENABLE_BASE_INFO(__VA_ARGS__) \
|
||||||
public: \
|
public: \
|
||||||
META_HPP_IGNORE_OVERRIDE_WARNINGS_PUSH() \
|
META_HPP_IGNORE_OVERRIDE_WARNINGS_PUSH() \
|
||||||
virtual ::meta_hpp::detail::poly_info get_most_derived_poly_info(::meta_hpp::detail::type_registry& registry) const { \
|
virtual ::meta_hpp::detail::poly_info get_most_derived_poly_info(::meta_hpp::detail::type_registry& registry) const { \
|
||||||
@@ -4511,11 +4520,6 @@ namespace meta_hpp::detail
|
|||||||
concept class_bind_destructor_kind //
|
concept class_bind_destructor_kind //
|
||||||
= class_kind<Class> && std::is_destructible_v<Class>; //
|
= class_kind<Class> && std::is_destructible_v<Class>; //
|
||||||
|
|
||||||
template < typename Base, typename Class >
|
|
||||||
concept class_bind_base_kind //
|
|
||||||
= class_kind<Base> && class_kind<Class> //
|
|
||||||
&& std::derived_from<Class, Base>; //
|
|
||||||
|
|
||||||
template < typename Member, typename Class >
|
template < typename Member, typename Class >
|
||||||
concept class_bind_member_kind //
|
concept class_bind_member_kind //
|
||||||
= member_pointer_kind<Member> && class_kind<Class> //
|
= member_pointer_kind<Member> && class_kind<Class> //
|
||||||
@@ -4596,9 +4600,6 @@ namespace meta_hpp
|
|||||||
public:
|
public:
|
||||||
explicit class_bind(metadata_map metadata);
|
explicit class_bind(metadata_map metadata);
|
||||||
|
|
||||||
template < detail::class_bind_base_kind<Class>... Bases >
|
|
||||||
class_bind& base_();
|
|
||||||
|
|
||||||
template < typename... Args, typename... Opts >
|
template < typename... Args, typename... Opts >
|
||||||
requires detail::class_bind_constructor_kind<Class, Args...>
|
requires detail::class_bind_constructor_kind<Class, Args...>
|
||||||
class_bind& constructor_(Opts&&... opts);
|
class_bind& constructor_(Opts&&... opts);
|
||||||
@@ -5023,83 +5024,6 @@ namespace meta_hpp
|
|||||||
: type_bind_base{resolve_type<Array>(), std::move(metadata)} {}
|
: type_bind_base{resolve_type<Array>(), std::move(metadata)} {}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace meta_hpp::detail::class_bind_impl
|
|
||||||
{
|
|
||||||
using base_upcasts_t = class_type_data::base_upcasts_t;
|
|
||||||
using deep_upcasts_t = class_type_data::deep_upcasts_t;
|
|
||||||
|
|
||||||
using upcast_func_t = class_type_data::upcast_func_t;
|
|
||||||
using upcast_func_list_t = class_type_data::upcast_func_list_t;
|
|
||||||
|
|
||||||
using new_bases_db_t = std::vector<std::pair<class_type, upcast_func_t>>;
|
|
||||||
using deep_upcasts_db_t = std::map<class_type, deep_upcasts_t, std::less<>>;
|
|
||||||
using derived_classes_db_t = std::map<class_type, class_list, std::less<>>;
|
|
||||||
|
|
||||||
template < class_kind Class, class_kind Base >
|
|
||||||
requires std::is_base_of_v<Base, Class>
|
|
||||||
void update_new_bases_db( //
|
|
||||||
new_bases_db_t& new_bases_db
|
|
||||||
) {
|
|
||||||
const class_type& new_base = resolve_type<Base>();
|
|
||||||
|
|
||||||
for ( auto&& [db_base, _] : new_bases_db ) {
|
|
||||||
if ( db_base == new_base ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
new_bases_db.emplace_back( //
|
|
||||||
new_base,
|
|
||||||
upcast_func_t{std::in_place_type<Class>, std::in_place_type<Base>}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void update_deep_upcasts_db( //
|
|
||||||
const class_type& derived_class,
|
|
||||||
const class_type& new_base_class,
|
|
||||||
upcast_func_list_t&& derived_to_new_base,
|
|
||||||
deep_upcasts_db_t& deep_upcasts_db
|
|
||||||
) {
|
|
||||||
const class_type_data& derived_class_data = *type_access(derived_class);
|
|
||||||
const class_type_data& new_base_class_data = *type_access(new_base_class);
|
|
||||||
|
|
||||||
const auto [deep_upcasts_db_iter, _] = deep_upcasts_db.try_emplace(derived_class, derived_class_data.deep_upcasts);
|
|
||||||
deep_upcasts_t& derived_deep_upcasts = deep_upcasts_db_iter->second;
|
|
||||||
|
|
||||||
const auto add_derived_deep_upcast = [&derived_deep_upcasts](const class_type& deep_class, upcast_func_list_t&& upcasts) {
|
|
||||||
auto&& [position, emplaced] = derived_deep_upcasts.try_emplace(deep_class, std::move(upcasts));
|
|
||||||
if ( !emplaced ) {
|
|
||||||
position->second.is_ambiguous = is_disjoint(position->second.vbases, upcasts.vbases);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
for ( auto&& [new_deep_class, new_base_to_deep] : new_base_class_data.deep_upcasts ) {
|
|
||||||
upcast_func_list_t derived_to_new_deep = derived_to_new_base + new_base_to_deep;
|
|
||||||
add_derived_deep_upcast(new_deep_class, std::move(derived_to_new_deep));
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( const class_type& subderived_class : derived_class_data.derived_classes ) {
|
|
||||||
const class_type_data& subderived_data = *type_access(subderived_class);
|
|
||||||
upcast_func_t subderived_to_derived = subderived_data.base_upcasts.at(derived_class);
|
|
||||||
upcast_func_list_t subderived_to_new_base = subderived_to_derived + derived_to_new_base;
|
|
||||||
update_deep_upcasts_db(subderived_class, new_base_class, std::move(subderived_to_new_base), deep_upcasts_db);
|
|
||||||
}
|
|
||||||
|
|
||||||
add_derived_deep_upcast(new_base_class, std::move(derived_to_new_base));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void updata_derived_classes_db( //
|
|
||||||
const class_type& self_class,
|
|
||||||
const class_type& new_base_class,
|
|
||||||
derived_classes_db_t& derived_classes_db
|
|
||||||
) {
|
|
||||||
const class_type_data& base_class_data = *type_access(new_base_class);
|
|
||||||
class_list new_derived_classes{base_class_data.derived_classes};
|
|
||||||
insert_or_assign(new_derived_classes, self_class);
|
|
||||||
derived_classes_db.emplace(new_base_class, std::move(new_derived_classes));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace meta_hpp
|
namespace meta_hpp
|
||||||
{
|
{
|
||||||
template < detail::class_kind Class >
|
template < detail::class_kind Class >
|
||||||
@@ -5110,49 +5034,6 @@ namespace meta_hpp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template < detail::class_kind Class >
|
|
||||||
template < detail::class_bind_base_kind<Class>... Bases >
|
|
||||||
class_bind<Class>& class_bind<Class>::base_() {
|
|
||||||
using namespace detail;
|
|
||||||
using namespace detail::class_bind_impl;
|
|
||||||
|
|
||||||
new_bases_db_t new_bases_db;
|
|
||||||
(update_new_bases_db<Class, Bases>(new_bases_db), ...);
|
|
||||||
|
|
||||||
deep_upcasts_db_t deep_upcasts_db;
|
|
||||||
derived_classes_db_t derived_classes_db;
|
|
||||||
|
|
||||||
class_list new_base_classes{get_data().base_classes};
|
|
||||||
base_upcasts_t new_base_upcasts{get_data().base_upcasts};
|
|
||||||
|
|
||||||
for ( auto&& [new_base_class, self_to_new_base] : new_bases_db ) {
|
|
||||||
if ( std::find(new_base_classes.begin(), new_base_classes.end(), new_base_class) != new_base_classes.end() ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
update_deep_upcasts_db(*this, new_base_class, self_to_new_base, deep_upcasts_db);
|
|
||||||
updata_derived_classes_db(*this, new_base_class, derived_classes_db);
|
|
||||||
|
|
||||||
new_base_classes.emplace_back(new_base_class);
|
|
||||||
new_base_upcasts.emplace(new_base_class, self_to_new_base);
|
|
||||||
}
|
|
||||||
|
|
||||||
get_data().base_classes.swap(new_base_classes);
|
|
||||||
get_data().base_upcasts.swap(new_base_upcasts);
|
|
||||||
|
|
||||||
for ( auto&& [derived_class, new_deep_upcasts] : deep_upcasts_db ) {
|
|
||||||
class_type_data& derived_data = *type_access(derived_class);
|
|
||||||
derived_data.deep_upcasts.swap(new_deep_upcasts);
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( auto&& [base_class, new_derived_classes] : derived_classes_db ) {
|
|
||||||
class_type_data& base_data = *type_access(base_class);
|
|
||||||
base_data.derived_classes.swap(new_derived_classes);
|
|
||||||
}
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template < detail::class_kind Class >
|
template < detail::class_kind Class >
|
||||||
template < typename... Args, typename... Opts >
|
template < typename... Args, typename... Opts >
|
||||||
requires detail::class_bind_constructor_kind<Class, Args...>
|
requires detail::class_bind_constructor_kind<Class, Args...>
|
||||||
@@ -8476,7 +8357,48 @@ namespace meta_hpp::detail
|
|||||||
, flags{class_traits<Class>::make_flags()}
|
, flags{class_traits<Class>::make_flags()}
|
||||||
, size{class_traits<Class>::size}
|
, size{class_traits<Class>::size}
|
||||||
, align{class_traits<Class>::align}
|
, align{class_traits<Class>::align}
|
||||||
, argument_types{resolve_types(typename class_traits<Class>::argument_types{})} {}
|
, argument_types{resolve_types(typename class_traits<Class>::argument_types{})} {
|
||||||
|
if constexpr ( check_base_info_enabled<Class> ) {
|
||||||
|
using meta_base_info = typename Class::meta_base_info;
|
||||||
|
|
||||||
|
[this]<std::size_t... Is>(std::index_sequence<Is...>) {
|
||||||
|
struct {
|
||||||
|
class_list base_classes;
|
||||||
|
base_upcasts_t base_upcasts;
|
||||||
|
deep_upcasts_t deep_upcasts;
|
||||||
|
} new_base_data;
|
||||||
|
|
||||||
|
const auto add_new_base_class = [&new_base_data]<class_kind Base>(std::in_place_type_t<Base>) {
|
||||||
|
const class_type& base_class = resolve_type<Base>();
|
||||||
|
const class_type_data& base_class_data = *type_access(base_class);
|
||||||
|
|
||||||
|
upcast_func_t self_to_base{std::in_place_type<Class>, std::in_place_type<Base>};
|
||||||
|
|
||||||
|
new_base_data.base_classes.emplace_back(base_class);
|
||||||
|
new_base_data.base_upcasts.emplace(base_class, self_to_base);
|
||||||
|
|
||||||
|
for ( const auto& [deep_class, base_to_deep] : base_class_data.deep_upcasts ) {
|
||||||
|
upcast_func_list_t self_to_deep = self_to_base + base_to_deep;
|
||||||
|
|
||||||
|
const auto& [position, emplaced] = new_base_data.deep_upcasts.try_emplace(
|
||||||
|
deep_class, std::move(self_to_deep)
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( !emplaced ) {
|
||||||
|
position->second.is_ambiguous = is_disjoint(position->second.vbases, self_to_deep.vbases);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
new_base_data.deep_upcasts.emplace(base_class, upcast_func_list_t{self_to_base});
|
||||||
|
};
|
||||||
|
(add_new_base_class(std::in_place_type<type_list_at_t<Is, meta_base_info>>), ...);
|
||||||
|
|
||||||
|
base_classes.swap(new_base_data.base_classes);
|
||||||
|
base_upcasts.swap(new_base_data.base_upcasts);
|
||||||
|
deep_upcasts.swap(new_base_data.deep_upcasts);
|
||||||
|
}(std::make_index_sequence<type_list_arity_v<meta_base_info>>());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace meta_hpp::detail
|
namespace meta_hpp::detail
|
||||||
@@ -8500,8 +8422,8 @@ namespace meta_hpp::detail
|
|||||||
|
|
||||||
namespace meta_hpp::detail
|
namespace meta_hpp::detail
|
||||||
{
|
{
|
||||||
inline class_type_data::upcast_func_list_t::upcast_func_list_t(const upcast_func_t& _upcast)
|
inline class_type_data::upcast_func_list_t::upcast_func_list_t(const upcast_func_t& in_upcast)
|
||||||
: upcasts{_upcast} {
|
: upcasts{in_upcast} {
|
||||||
for ( const upcast_func_t& upcast : upcasts ) {
|
for ( const upcast_func_t& upcast : upcasts ) {
|
||||||
if ( upcast.is_virtual ) {
|
if ( upcast.is_virtual ) {
|
||||||
vbases.emplace(upcast.target);
|
vbases.emplace(upcast.target);
|
||||||
@@ -8509,9 +8431,9 @@ namespace meta_hpp::detail
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline class_type_data::upcast_func_list_t::upcast_func_list_t(upcasts_t _upcasts, vbases_t _vbases)
|
inline class_type_data::upcast_func_list_t::upcast_func_list_t(upcasts_t in_upcasts, vbases_t in_vbases)
|
||||||
: upcasts{std::move(_upcasts)}
|
: upcasts{std::move(in_upcasts)}
|
||||||
, vbases{std::move(_vbases)} {}
|
, vbases{std::move(in_vbases)} {}
|
||||||
|
|
||||||
inline void* class_type_data::upcast_func_list_t::apply(void* ptr) const noexcept {
|
inline void* class_type_data::upcast_func_list_t::apply(void* ptr) const noexcept {
|
||||||
for ( const upcast_func_t& upcast : upcasts ) {
|
for ( const upcast_func_t& upcast : upcasts ) {
|
||||||
@@ -8538,7 +8460,9 @@ namespace meta_hpp::detail
|
|||||||
new_vbases.insert(l.vbases.begin(), l.vbases.end());
|
new_vbases.insert(l.vbases.begin(), l.vbases.end());
|
||||||
new_vbases.insert(r.vbases.begin(), r.vbases.end());
|
new_vbases.insert(r.vbases.begin(), r.vbases.end());
|
||||||
|
|
||||||
return class_type_data::upcast_func_list_t{std::move(new_upcasts), std::move(new_vbases)};
|
class_type_data::upcast_func_list_t result{std::move(new_upcasts), std::move(new_vbases)};
|
||||||
|
result.is_ambiguous = l.is_ambiguous || r.is_ambiguous;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -8572,10 +8496,6 @@ namespace meta_hpp
|
|||||||
return data_->base_classes;
|
return data_->base_classes;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const class_list& class_type::get_derived_classes() const noexcept {
|
|
||||||
return data_->derived_classes;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const constructor_list& class_type::get_constructors() const noexcept {
|
inline const constructor_list& class_type::get_constructors() const noexcept {
|
||||||
return data_->constructors;
|
return data_->constructors;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,14 +28,17 @@ namespace
|
|||||||
|
|
||||||
struct base2 : base1 {
|
struct base2 : base1 {
|
||||||
unsigned b2{2};
|
unsigned b2{2};
|
||||||
|
META_HPP_ENABLE_BASE_INFO(base1)
|
||||||
};
|
};
|
||||||
|
|
||||||
struct base3 : base2 {
|
struct base3 : base2 {
|
||||||
unsigned b3{3};
|
unsigned b3{3};
|
||||||
|
META_HPP_ENABLE_BASE_INFO(base2)
|
||||||
};
|
};
|
||||||
|
|
||||||
struct base4 : base3 {
|
struct base4 : base3 {
|
||||||
unsigned b4{4};
|
unsigned b4{4};
|
||||||
|
META_HPP_ENABLE_BASE_INFO(base3)
|
||||||
};
|
};
|
||||||
|
|
||||||
unsigned static_function_1(base1* b1) {
|
unsigned static_function_1(base1* b1) {
|
||||||
@@ -67,14 +70,6 @@ namespace
|
|||||||
static_acc = 0;
|
static_acc = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool registered = [](){
|
|
||||||
meta::class_<base1>();
|
|
||||||
meta::class_<base2>().base_<base1>();
|
|
||||||
meta::class_<base3>().base_<base2>();
|
|
||||||
meta::class_<base4>().base_<base3>();
|
|
||||||
return true;
|
|
||||||
}();
|
|
||||||
|
|
||||||
meta::scope meta_bench_scope = meta::local_scope_("")
|
meta::scope meta_bench_scope = meta::local_scope_("")
|
||||||
.function_("cast_function_1", &static_function_1)
|
.function_("cast_function_1", &static_function_1)
|
||||||
.function_("cast_function_2", &static_function_2)
|
.function_("cast_function_2", &static_function_2)
|
||||||
|
|||||||
@@ -28,17 +28,17 @@ namespace
|
|||||||
|
|
||||||
struct base2 : base1 {
|
struct base2 : base1 {
|
||||||
unsigned b2{2};
|
unsigned b2{2};
|
||||||
META_HPP_ENABLE_POLY_INFO()
|
META_HPP_ENABLE_POLY_INFO(base1)
|
||||||
};
|
};
|
||||||
|
|
||||||
struct base3 : base2 {
|
struct base3 : base2 {
|
||||||
unsigned b3{3};
|
unsigned b3{3};
|
||||||
META_HPP_ENABLE_POLY_INFO()
|
META_HPP_ENABLE_POLY_INFO(base2)
|
||||||
};
|
};
|
||||||
|
|
||||||
struct base4 : base3 {
|
struct base4 : base3 {
|
||||||
unsigned b4{4};
|
unsigned b4{4};
|
||||||
META_HPP_ENABLE_POLY_INFO()
|
META_HPP_ENABLE_POLY_INFO(base3)
|
||||||
};
|
};
|
||||||
|
|
||||||
base4* dynamic_cast_1(base1* b1) {
|
base4* dynamic_cast_1(base1* b1) {
|
||||||
@@ -56,14 +56,6 @@ namespace
|
|||||||
base4* dynamic_cast_4(base4* b4) {
|
base4* dynamic_cast_4(base4* b4) {
|
||||||
return dynamic_cast<base4*>(b4);
|
return dynamic_cast<base4*>(b4);
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool registered = [](){
|
|
||||||
meta::class_<base1>();
|
|
||||||
meta::class_<base2>().base_<base1>();
|
|
||||||
meta::class_<base3>().base_<base2>();
|
|
||||||
meta::class_<base4>().base_<base3>();
|
|
||||||
return true;
|
|
||||||
}();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -10,29 +10,25 @@
|
|||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
struct A1 { std::string a1{"a1"}; };
|
struct A1 { std::string a1{"a1"}; };
|
||||||
struct B1 : A1 { std::string b1{"b1"}; };
|
struct B1 : A1 { std::string b1{"b1"}; META_HPP_ENABLE_BASE_INFO(A1) };
|
||||||
struct C1 : A1 { std::string c1{"c1"}; };
|
struct C1 : A1 { std::string c1{"c1"}; META_HPP_ENABLE_BASE_INFO(A1) };
|
||||||
struct D1 : B1, C1 { std::string d1{"d1"}; };
|
struct D1 : B1, C1 { std::string d1{"d1"}; META_HPP_ENABLE_BASE_INFO(B1, C1) };
|
||||||
|
|
||||||
struct A2 { std::string a2{"a2"}; };
|
struct A2 { std::string a2{"a2"}; };
|
||||||
struct B2 : virtual A2 { std::string b2{"b2"}; };
|
struct B2 : virtual A2 { std::string b2{"b2"}; META_HPP_ENABLE_BASE_INFO(A2) };
|
||||||
struct C2 : virtual A2 { std::string c2{"c2"}; };
|
struct C2 : virtual A2 { std::string c2{"c2"}; META_HPP_ENABLE_BASE_INFO(A2) };
|
||||||
struct D2 : B2, C2 { std::string d2{"d2"}; };
|
struct D2 : B2, C2 { std::string d2{"d2"}; META_HPP_ENABLE_BASE_INFO(B2, C2) };
|
||||||
|
|
||||||
struct A3 { std::string a3{"a3"}; };
|
struct A3 { std::string a3{"a3"}; };
|
||||||
struct B3 : virtual A3 { std::string b3{"b3"}; };
|
struct B3 : virtual A3 { std::string b3{"b3"}; META_HPP_ENABLE_BASE_INFO(A3) };
|
||||||
struct C3 : A3 { std::string c3{"c3"}; };
|
struct C3 : A3 { std::string c3{"c3"}; META_HPP_ENABLE_BASE_INFO(A3) };
|
||||||
struct D3 : B3, C3 { std::string d3{"d3"}; };
|
struct D3 : B3, C3 { std::string d3{"d3"}; META_HPP_ENABLE_BASE_INFO(B3, C3) };
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("meta/meta_features/ambiguous") {
|
TEST_CASE("meta/meta_features/ambiguous") {
|
||||||
namespace meta = meta_hpp;
|
namespace meta = meta_hpp;
|
||||||
|
|
||||||
{
|
{
|
||||||
meta::class_<B1>().base_<A1>();
|
|
||||||
meta::class_<C1>().base_<A1>();
|
|
||||||
meta::class_<D1>().base_<B1, C1>();
|
|
||||||
|
|
||||||
// A1 < B1
|
// A1 < B1
|
||||||
// < D1
|
// < D1
|
||||||
// A1 < C1
|
// A1 < C1
|
||||||
@@ -56,10 +52,6 @@ TEST_CASE("meta/meta_features/ambiguous") {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
meta::class_<B2>().base_<A2>();
|
|
||||||
meta::class_<C2>().base_<A2>();
|
|
||||||
meta::class_<D2>().base_<B2, C2>();
|
|
||||||
|
|
||||||
// A2 <= B2
|
// A2 <= B2
|
||||||
// < D2
|
// < D2
|
||||||
// A2 <= C2
|
// A2 <= C2
|
||||||
@@ -83,10 +75,6 @@ TEST_CASE("meta/meta_features/ambiguous") {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
meta::class_<B3>().base_<A3>();
|
|
||||||
meta::class_<C3>().base_<A3>();
|
|
||||||
meta::class_<D3>().base_<B3, C3>();
|
|
||||||
|
|
||||||
// A3 <= B3
|
// A3 <= B3
|
||||||
// < D3
|
// < D3
|
||||||
// A3 < C3
|
// A3 < C3
|
||||||
|
|||||||
@@ -22,9 +22,9 @@ namespace
|
|||||||
META_HPP_ENABLE_POLY_INFO()
|
META_HPP_ENABLE_POLY_INFO()
|
||||||
};
|
};
|
||||||
|
|
||||||
struct B : virtual A { META_HPP_ENABLE_POLY_INFO() };
|
struct B : virtual A { META_HPP_ENABLE_POLY_INFO(A) };
|
||||||
struct C : virtual A { META_HPP_ENABLE_POLY_INFO() };
|
struct C : virtual A { META_HPP_ENABLE_POLY_INFO(A) };
|
||||||
struct D : B, C { META_HPP_ENABLE_POLY_INFO() };
|
struct D : B, C { META_HPP_ENABLE_POLY_INFO(B, C) };
|
||||||
struct E {};
|
struct E {};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,12 +35,6 @@ TEST_CASE("meta/meta_features/diamond") {
|
|||||||
using meta::detail::type_registry;
|
using meta::detail::type_registry;
|
||||||
type_registry& r{type_registry::instance()};
|
type_registry& r{type_registry::instance()};
|
||||||
|
|
||||||
meta::class_<A>();
|
|
||||||
meta::class_<B>().base_<A>();
|
|
||||||
meta::class_<C>().base_<A>();
|
|
||||||
meta::class_<D>().base_<B>().base_<C>();
|
|
||||||
meta::class_<E>();
|
|
||||||
|
|
||||||
// * <- B <- *
|
// * <- B <- *
|
||||||
// A D
|
// A D
|
||||||
// * <- C <- *
|
// * <- C <- *
|
||||||
|
|||||||
@@ -10,31 +10,21 @@
|
|||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
struct A { std::string a{"a"}; };
|
struct A { std::string a{"a"}; };
|
||||||
struct B0 : virtual A { std::string b0{"b0"}; };
|
struct B0 : virtual A { std::string b0{"b0"}; META_HPP_ENABLE_BASE_INFO(A) };
|
||||||
struct B1 : virtual A { std::string b1{"b1"}; };
|
struct B1 : virtual A { std::string b1{"b1"}; META_HPP_ENABLE_BASE_INFO(A) };
|
||||||
|
|
||||||
struct C : B0, B1 { std::string c{"c"}; };
|
struct C : B0, B1 { std::string c{"c"}; META_HPP_ENABLE_BASE_INFO(B0, B1) };
|
||||||
|
|
||||||
struct D0 : C { std::string d0{"d0"}; };
|
struct D0 : C { std::string d0{"d0"}; META_HPP_ENABLE_BASE_INFO(C) };
|
||||||
struct E0 : D0 { std::string e0{"e0"}; };
|
struct E0 : D0 { std::string e0{"e0"}; META_HPP_ENABLE_BASE_INFO(D0) };
|
||||||
|
|
||||||
struct D1 : C { std::string d1{"d1"}; };
|
struct D1 : C { std::string d1{"d1"}; META_HPP_ENABLE_BASE_INFO(C) };
|
||||||
struct E1 : D1 { std::string e1{"e1"}; };
|
struct E1 : D1 { std::string e1{"e1"}; META_HPP_ENABLE_BASE_INFO(D1) };
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("meta/meta_features/multiple2/_") {
|
TEST_CASE("meta/meta_features/multiple2/_") {
|
||||||
namespace meta = meta_hpp;
|
namespace meta = meta_hpp;
|
||||||
|
|
||||||
meta::class_<C>().base_<B0, B1>();
|
|
||||||
meta::class_<B0>().base_<A>();
|
|
||||||
meta::class_<B1>().base_<A>();
|
|
||||||
|
|
||||||
meta::class_<E0>().base_<D0>();
|
|
||||||
meta::class_<E1>().base_<D1>();
|
|
||||||
|
|
||||||
meta::class_<D0>().base_<C>();
|
|
||||||
meta::class_<D1>().base_<C>();
|
|
||||||
|
|
||||||
// * <- B0 <- * * <- D0 * <- E0
|
// * <- B0 <- * * <- D0 * <- E0
|
||||||
// A C
|
// A C
|
||||||
// * <- B1 <- * * <- D1 * <- E1
|
// * <- B1 <- * * <- D1 * <- E1
|
||||||
|
|||||||
@@ -21,22 +21,16 @@ namespace
|
|||||||
virtual ~A() = default;
|
virtual ~A() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct B : A {};
|
struct B : A { META_HPP_ENABLE_BASE_INFO(A) };
|
||||||
struct C : A {};
|
struct C : A { META_HPP_ENABLE_BASE_INFO(A) };
|
||||||
struct D : B, C {};
|
struct D : B, C { META_HPP_ENABLE_BASE_INFO(B, C) };
|
||||||
struct E : D {};
|
struct E : D { META_HPP_ENABLE_BASE_INFO(D) };
|
||||||
struct F {};
|
struct F {};
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("meta/meta_features/multiple/_") {
|
TEST_CASE("meta/meta_features/multiple/_") {
|
||||||
namespace meta = meta_hpp;
|
namespace meta = meta_hpp;
|
||||||
|
|
||||||
meta::class_<D>().base_<B, C>();
|
|
||||||
meta::class_<E>().base_<D>();
|
|
||||||
|
|
||||||
meta::class_<B>().base_<A>();
|
|
||||||
meta::class_<C>().base_<A>();
|
|
||||||
|
|
||||||
// A * <- B <- *
|
// A * <- B <- *
|
||||||
// D * <- E
|
// D * <- E
|
||||||
// A * <- C <- *
|
// A * <- C <- *
|
||||||
|
|||||||
@@ -10,43 +10,38 @@
|
|||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
struct A1 {};
|
struct A1 {};
|
||||||
struct B1 : A1 {};
|
struct B1 : A1 { META_HPP_ENABLE_BASE_INFO(A1) };
|
||||||
struct C1 : A1 {};
|
struct C1 : A1 { META_HPP_ENABLE_BASE_INFO(A1) };
|
||||||
struct D1 : B1, C1 {};
|
struct D1 : B1, C1 { META_HPP_ENABLE_BASE_INFO(B1, C1) };
|
||||||
|
|
||||||
// A1 <- B1 <- *
|
// A1 <- B1 <- *
|
||||||
// D1
|
// D1
|
||||||
// A1 <- C1 <- *
|
// A1 <- C1 <- *
|
||||||
|
|
||||||
struct A2 {};
|
struct A2 {};
|
||||||
struct B2 : virtual A2 {};
|
struct B2 : virtual A2 { META_HPP_ENABLE_BASE_INFO(A2) };
|
||||||
struct C2 : virtual B2 {};
|
struct C2 : virtual B2 { META_HPP_ENABLE_BASE_INFO(B2) };
|
||||||
struct D2 : virtual B2 {};
|
struct D2 : virtual B2 { META_HPP_ENABLE_BASE_INFO(B2) };
|
||||||
struct E2 : C2, D2 {};
|
struct E2 : C2, D2 { META_HPP_ENABLE_BASE_INFO(C2, D2) };
|
||||||
|
|
||||||
// A2 <= B2 <= C2 <- *
|
// A2 <= B2 <= C2 <- *
|
||||||
// E2
|
// E2
|
||||||
// A2 <= B2 <= D2 <- *
|
// A2 <= B2 <= D2 <- *
|
||||||
|
|
||||||
struct A3 {};
|
struct A3 {};
|
||||||
struct B3 : virtual A3 {};
|
struct B3 : virtual A3 { META_HPP_ENABLE_BASE_INFO(A3) };
|
||||||
struct C3 : A3 {};
|
struct C3 : A3 { META_HPP_ENABLE_BASE_INFO(A3) };
|
||||||
struct D3 : B3, C3 {};
|
struct D3 : B3, C3 { META_HPP_ENABLE_BASE_INFO(B3, C3) };
|
||||||
|
|
||||||
// A3 <= B3 <- *
|
// A3 <= B3 <- *
|
||||||
// D3
|
// D3
|
||||||
// A3 <- C3 <- *
|
// A3 <- C3 <- *
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("meta/meta_issues/random/1") {
|
TEST_CASE("meta/meta_issues/random/1") {
|
||||||
namespace meta = meta_hpp;
|
namespace meta = meta_hpp;
|
||||||
|
|
||||||
{
|
{
|
||||||
meta::class_<B1>().base_<A1>();
|
|
||||||
meta::class_<C1>().base_<A1>();
|
|
||||||
meta::class_<D1>().base_<B1, C1>();
|
|
||||||
|
|
||||||
CHECK(meta::is_invocable_with(+[](const D1&){ return true; }, D1{}));
|
CHECK(meta::is_invocable_with(+[](const D1&){ return true; }, D1{}));
|
||||||
CHECK(meta::is_invocable_with(+[](const C1&){ return true; }, D1{}));
|
CHECK(meta::is_invocable_with(+[](const C1&){ return true; }, D1{}));
|
||||||
CHECK(meta::is_invocable_with(+[](const B1&){ return true; }, D1{}));
|
CHECK(meta::is_invocable_with(+[](const B1&){ return true; }, D1{}));
|
||||||
@@ -61,11 +56,6 @@ TEST_CASE("meta/meta_issues/random/1") {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
meta::class_<B2>().base_<A2>();
|
|
||||||
meta::class_<C2>().base_<B2>();
|
|
||||||
meta::class_<D2>().base_<B2>();
|
|
||||||
meta::class_<E2>().base_<C2, D2>();
|
|
||||||
|
|
||||||
CHECK(meta::is_invocable_with(+[](const A2&){ return true; }, E2{}));
|
CHECK(meta::is_invocable_with(+[](const A2&){ return true; }, E2{}));
|
||||||
CHECK(meta::is_invocable_with(+[](const B2&){ return true; }, E2{}));
|
CHECK(meta::is_invocable_with(+[](const B2&){ return true; }, E2{}));
|
||||||
CHECK(meta::is_invocable_with(+[](const C2&){ return true; }, E2{}));
|
CHECK(meta::is_invocable_with(+[](const C2&){ return true; }, E2{}));
|
||||||
@@ -80,10 +70,6 @@ TEST_CASE("meta/meta_issues/random/1") {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
meta::class_<B3>().base_<A3>();
|
|
||||||
meta::class_<C3>().base_<A3>();
|
|
||||||
meta::class_<D3>().base_<B3, C3>();
|
|
||||||
|
|
||||||
static_assert(std::is_invocable_v<void(A3*), A3*>);
|
static_assert(std::is_invocable_v<void(A3*), A3*>);
|
||||||
static_assert(std::is_invocable_v<void(A3*), B3*>);
|
static_assert(std::is_invocable_v<void(A3*), B3*>);
|
||||||
static_assert(std::is_invocable_v<void(A3*), C3*>);
|
static_assert(std::is_invocable_v<void(A3*), C3*>);
|
||||||
|
|||||||
@@ -53,10 +53,15 @@ namespace
|
|||||||
//
|
//
|
||||||
|
|
||||||
int ii = 0;
|
int ii = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
META_HPP_ENABLE_BASE_INFO(base)
|
||||||
};
|
};
|
||||||
|
|
||||||
struct derived_clazz : fake, clazz {
|
struct derived_clazz : fake, clazz {
|
||||||
int pure_virtual_method() override { return -2; }
|
int pure_virtual_method() override { return -2; }
|
||||||
|
META_HPP_ENABLE_BASE_INFO(fake, clazz)
|
||||||
};
|
};
|
||||||
|
|
||||||
struct clazz2 {};
|
struct clazz2 {};
|
||||||
@@ -69,8 +74,6 @@ TEST_CASE("meta/meta_states/method/_") {
|
|||||||
.method_("pure_virtual_method", &base::pure_virtual_method);
|
.method_("pure_virtual_method", &base::pure_virtual_method);
|
||||||
|
|
||||||
meta::class_<clazz>()
|
meta::class_<clazz>()
|
||||||
.base_<base>()
|
|
||||||
|
|
||||||
.method_("non_const_method", &clazz::non_const_method)
|
.method_("non_const_method", &clazz::non_const_method)
|
||||||
.method_("non_const_method_noexcept", &clazz::non_const_method_noexcept)
|
.method_("non_const_method_noexcept", &clazz::non_const_method_noexcept)
|
||||||
|
|
||||||
@@ -88,9 +91,6 @@ TEST_CASE("meta/meta_states/method/_") {
|
|||||||
|
|
||||||
.method_("const_method_rref", &clazz::const_method_rref)
|
.method_("const_method_rref", &clazz::const_method_rref)
|
||||||
.method_("const_method_noexcept_rref", &clazz::const_method_noexcept_rref);
|
.method_("const_method_noexcept_rref", &clazz::const_method_noexcept_rref);
|
||||||
|
|
||||||
meta::class_<derived_clazz>()
|
|
||||||
.base_<clazz>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("meta/meta_states/method") {
|
TEST_CASE("meta/meta_states/method") {
|
||||||
|
|||||||
@@ -49,10 +49,12 @@ namespace
|
|||||||
static double derived_function() { return 3.0; }
|
static double derived_function() { return 3.0; }
|
||||||
|
|
||||||
static constexpr double derived_variable = 3.0;
|
static constexpr double derived_variable = 3.0;
|
||||||
|
META_HPP_ENABLE_BASE_INFO(base_clazz_1, base_clazz_2)
|
||||||
};
|
};
|
||||||
|
|
||||||
struct final_derived_clazz final : derived_clazz {
|
struct final_derived_clazz final : derived_clazz {
|
||||||
using derived_clazz::derived_clazz;
|
using derived_clazz::derived_clazz;
|
||||||
|
META_HPP_ENABLE_BASE_INFO(derived_clazz)
|
||||||
};
|
};
|
||||||
|
|
||||||
template < typename... Args >
|
template < typename... Args >
|
||||||
@@ -64,7 +66,6 @@ TEST_CASE("meta/meta_types/class_type/_") {
|
|||||||
|
|
||||||
meta::class_<base_clazz_1>()
|
meta::class_<base_clazz_1>()
|
||||||
.constructor_<int>()
|
.constructor_<int>()
|
||||||
.base_<>()
|
|
||||||
.member_("base_member_1", &base_clazz_1::base_member_1)
|
.member_("base_member_1", &base_clazz_1::base_member_1)
|
||||||
.method_("base_method_1", &base_clazz_1::base_method_1)
|
.method_("base_method_1", &base_clazz_1::base_method_1)
|
||||||
.function_("base_function_1", &base_clazz_1::base_function_1)
|
.function_("base_function_1", &base_clazz_1::base_function_1)
|
||||||
@@ -83,15 +84,13 @@ TEST_CASE("meta/meta_types/class_type/_") {
|
|||||||
|
|
||||||
meta::class_<derived_clazz>()
|
meta::class_<derived_clazz>()
|
||||||
.constructor_<int, float>()
|
.constructor_<int, float>()
|
||||||
.base_<base_clazz_1, base_clazz_2>()
|
|
||||||
.member_("derived_member", &derived_clazz::derived_member)
|
.member_("derived_member", &derived_clazz::derived_member)
|
||||||
.method_("derived_method", &derived_clazz::derived_method)
|
.method_("derived_method", &derived_clazz::derived_method)
|
||||||
.function_("derived_function", &derived_clazz::derived_function)
|
.function_("derived_function", &derived_clazz::derived_function)
|
||||||
.variable_("derived_variable", &derived_clazz::derived_variable);
|
.variable_("derived_variable", &derived_clazz::derived_variable);
|
||||||
|
|
||||||
meta::class_<final_derived_clazz>()
|
meta::class_<final_derived_clazz>()
|
||||||
.constructor_<int, float>()
|
.constructor_<int, float>();
|
||||||
.base_<derived_clazz>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("meta/meta_types/class_type") {
|
TEST_CASE("meta/meta_types/class_type") {
|
||||||
@@ -209,13 +208,6 @@ TEST_CASE("meta/meta_types/class_type") {
|
|||||||
CHECK(final_derived_clazz_type.get_base_classes() == meta::class_list{derived_clazz_type});
|
CHECK(final_derived_clazz_type.get_base_classes() == meta::class_list{derived_clazz_type});
|
||||||
}
|
}
|
||||||
|
|
||||||
SUBCASE("get_derived_classes") {
|
|
||||||
CHECK(base_clazz_1_type.get_derived_classes() == meta::class_list{derived_clazz_type});
|
|
||||||
CHECK(base_clazz_2_type.get_derived_classes() == meta::class_list{derived_clazz_type});
|
|
||||||
CHECK(derived_clazz_type.get_derived_classes() == meta::class_list{final_derived_clazz_type});
|
|
||||||
CHECK(final_derived_clazz_type.get_derived_classes() == meta::class_list{});
|
|
||||||
}
|
|
||||||
|
|
||||||
SUBCASE("get_functions") {
|
SUBCASE("get_functions") {
|
||||||
CHECK(base_clazz_1_type.get_functions().size() == 3);
|
CHECK(base_clazz_1_type.get_functions().size() == 3);
|
||||||
CHECK(base_clazz_2_type.get_functions().size() == 1);
|
CHECK(base_clazz_2_type.get_functions().size() == 1);
|
||||||
|
|||||||
@@ -32,16 +32,19 @@ namespace
|
|||||||
struct B : virtual A {
|
struct B : virtual A {
|
||||||
int bi = 2;
|
int bi = 2;
|
||||||
[[nodiscard]] int f() const { return bi; }
|
[[nodiscard]] int f() const { return bi; }
|
||||||
|
META_HPP_ENABLE_BASE_INFO(A)
|
||||||
};
|
};
|
||||||
|
|
||||||
struct C : virtual A {
|
struct C : virtual A {
|
||||||
int ci = 3;
|
int ci = 3;
|
||||||
[[nodiscard]] int f() const { return ci; }
|
[[nodiscard]] int f() const { return ci; }
|
||||||
|
META_HPP_ENABLE_BASE_INFO(A)
|
||||||
};
|
};
|
||||||
|
|
||||||
struct D : B, C {
|
struct D : B, C {
|
||||||
int di = 4;
|
int di = 4;
|
||||||
[[nodiscard]] int f() const { return di; }
|
[[nodiscard]] int f() const { return di; }
|
||||||
|
META_HPP_ENABLE_BASE_INFO(B, C)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,11 +54,6 @@ TEST_CASE("meta/meta_utilities/arg2") {
|
|||||||
// * <- B <- *
|
// * <- B <- *
|
||||||
// A D
|
// A D
|
||||||
// * <- C <- *
|
// * <- C <- *
|
||||||
|
|
||||||
meta::class_<A>();
|
|
||||||
meta::class_<B>().base_<A>();
|
|
||||||
meta::class_<C>().base_<A>();
|
|
||||||
meta::class_<D>().base_<B>().base_<C>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("meta/meta_utilities/arg2/cast") {
|
TEST_CASE("meta/meta_utilities/arg2/cast") {
|
||||||
|
|||||||
@@ -25,16 +25,19 @@ namespace
|
|||||||
struct B : virtual A {
|
struct B : virtual A {
|
||||||
int bi = 2;
|
int bi = 2;
|
||||||
[[nodiscard]] int f() const { return bi; }
|
[[nodiscard]] int f() const { return bi; }
|
||||||
|
META_HPP_ENABLE_BASE_INFO(A)
|
||||||
};
|
};
|
||||||
|
|
||||||
struct C : virtual A {
|
struct C : virtual A {
|
||||||
int ci = 3;
|
int ci = 3;
|
||||||
[[nodiscard]] int f() const { return ci; }
|
[[nodiscard]] int f() const { return ci; }
|
||||||
|
META_HPP_ENABLE_BASE_INFO(A)
|
||||||
};
|
};
|
||||||
|
|
||||||
struct D : B, C {
|
struct D : B, C {
|
||||||
int di = 4;
|
int di = 4;
|
||||||
[[nodiscard]] int f() const { return di; }
|
[[nodiscard]] int f() const { return di; }
|
||||||
|
META_HPP_ENABLE_BASE_INFO(B, C)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,11 +47,6 @@ TEST_CASE("meta/meta_utilities/arg3") {
|
|||||||
// * <- B <- *
|
// * <- B <- *
|
||||||
// A D
|
// A D
|
||||||
// * <- C <- *
|
// * <- C <- *
|
||||||
|
|
||||||
meta::class_<A>();
|
|
||||||
meta::class_<B>().base_<A>();
|
|
||||||
meta::class_<C>().base_<A>();
|
|
||||||
meta::class_<D>().base_<B>().base_<C>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("meta/meta_utilities/arg3/cast") {
|
TEST_CASE("meta/meta_utilities/arg3/cast") {
|
||||||
|
|||||||
@@ -23,14 +23,17 @@ namespace
|
|||||||
|
|
||||||
struct B : virtual A {
|
struct B : virtual A {
|
||||||
int bi = 2;
|
int bi = 2;
|
||||||
|
META_HPP_ENABLE_BASE_INFO(A)
|
||||||
};
|
};
|
||||||
|
|
||||||
struct C : virtual A {
|
struct C : virtual A {
|
||||||
int ci = 3;
|
int ci = 3;
|
||||||
|
META_HPP_ENABLE_BASE_INFO(A)
|
||||||
};
|
};
|
||||||
|
|
||||||
struct D : B, C {
|
struct D : B, C {
|
||||||
int di = 4;
|
int di = 4;
|
||||||
|
META_HPP_ENABLE_BASE_INFO(B, C)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,11 +43,6 @@ TEST_CASE("meta/meta_utilities/arg5") {
|
|||||||
// * <- B <- *
|
// * <- B <- *
|
||||||
// A D
|
// A D
|
||||||
// * <- C <- *
|
// * <- C <- *
|
||||||
|
|
||||||
meta::class_<A>();
|
|
||||||
meta::class_<B>().base_<A>();
|
|
||||||
meta::class_<C>().base_<A>();
|
|
||||||
meta::class_<D>().base_<B>().base_<C>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("meta/meta_utilities/arg5/cast") {
|
TEST_CASE("meta/meta_utilities/arg5/cast") {
|
||||||
|
|||||||
@@ -40,11 +40,6 @@ TEST_CASE("meta/meta_utilities/arg7") {
|
|||||||
// * <- B <- *
|
// * <- B <- *
|
||||||
// A D
|
// A D
|
||||||
// * <- C <- *
|
// * <- C <- *
|
||||||
|
|
||||||
meta::class_<A>();
|
|
||||||
meta::class_<B>().base_<A>();
|
|
||||||
meta::class_<C>().base_<A>();
|
|
||||||
meta::class_<D>().base_<B>().base_<C>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("meta/meta_utilities/arg7/cast/to_void") {
|
TEST_CASE("meta/meta_utilities/arg7/cast/to_void") {
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ namespace
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct dclazz : fake, clazz {
|
struct dclazz : fake, clazz {
|
||||||
|
META_HPP_ENABLE_BASE_INFO(fake, clazz)
|
||||||
};
|
};
|
||||||
|
|
||||||
int f1(int v) { return v; }
|
int f1(int v) { return v; }
|
||||||
@@ -110,14 +111,6 @@ namespace
|
|||||||
}\
|
}\
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("meta/meta_utilities/arg") {
|
|
||||||
namespace meta = meta_hpp;
|
|
||||||
|
|
||||||
meta::class_<fake>();
|
|
||||||
meta::class_<clazz>();
|
|
||||||
meta::class_<dclazz>().base_<fake>().base_<clazz>();
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("meta/meta_utilities/arg/refs") {
|
TEST_CASE("meta/meta_utilities/arg/refs") {
|
||||||
namespace meta = meta_hpp;
|
namespace meta = meta_hpp;
|
||||||
using meta::detail::uarg;
|
using meta::detail::uarg;
|
||||||
|
|||||||
@@ -21,14 +21,14 @@ namespace
|
|||||||
B1() = default;
|
B1() = default;
|
||||||
B1(const B1&) = default;
|
B1(const B1&) = default;
|
||||||
char b{'b'};
|
char b{'b'};
|
||||||
META_HPP_ENABLE_POLY_INFO()
|
META_HPP_ENABLE_POLY_INFO(A1)
|
||||||
};
|
};
|
||||||
|
|
||||||
struct C1 : B1 {
|
struct C1 : B1 {
|
||||||
C1() = default;
|
C1() = default;
|
||||||
C1(const C1&) = default;
|
C1(const C1&) = default;
|
||||||
char c{'c'};
|
char c{'c'};
|
||||||
META_HPP_ENABLE_POLY_INFO()
|
META_HPP_ENABLE_POLY_INFO(B1)
|
||||||
};
|
};
|
||||||
|
|
||||||
// A1 <- B1 <- C1
|
// A1 <- B1 <- C1
|
||||||
@@ -45,14 +45,14 @@ namespace
|
|||||||
B2() = default;
|
B2() = default;
|
||||||
B2(const B2&) = default;
|
B2(const B2&) = default;
|
||||||
char b{'b'};
|
char b{'b'};
|
||||||
META_HPP_ENABLE_POLY_INFO()
|
META_HPP_ENABLE_POLY_INFO(A2)
|
||||||
};
|
};
|
||||||
|
|
||||||
struct C2 : virtual A2 {
|
struct C2 : virtual A2 {
|
||||||
C2() = default;
|
C2() = default;
|
||||||
C2(const C2&) = default;
|
C2(const C2&) = default;
|
||||||
char c{'c'};
|
char c{'c'};
|
||||||
META_HPP_ENABLE_POLY_INFO()
|
META_HPP_ENABLE_POLY_INFO(A2)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -68,14 +68,14 @@ namespace
|
|||||||
E2() = default;
|
E2() = default;
|
||||||
E2(const E2&) = default;
|
E2(const E2&) = default;
|
||||||
char e{'e'};
|
char e{'e'};
|
||||||
META_HPP_ENABLE_POLY_INFO()
|
META_HPP_ENABLE_POLY_INFO(D2)
|
||||||
};
|
};
|
||||||
|
|
||||||
struct F2 : B2, C2, E2 {
|
struct F2 : B2, C2, E2 {
|
||||||
F2() = default;
|
F2() = default;
|
||||||
F2(const F2&) = default;
|
F2(const F2&) = default;
|
||||||
char f{'f'};
|
char f{'f'};
|
||||||
META_HPP_ENABLE_POLY_INFO()
|
META_HPP_ENABLE_POLY_INFO(B2, C2, E2)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -119,21 +119,6 @@ namespace
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("meta/meta_utilities/ucast/_") {
|
|
||||||
namespace meta = meta_hpp;
|
|
||||||
|
|
||||||
meta::class_<A1>();
|
|
||||||
meta::class_<B1>().base_<A1>();
|
|
||||||
meta::class_<C1>().base_<B1>();
|
|
||||||
|
|
||||||
meta::class_<A2>();
|
|
||||||
meta::class_<B2>().base_<A2>();
|
|
||||||
meta::class_<C2>().base_<A2>();
|
|
||||||
meta::class_<D2>();
|
|
||||||
meta::class_<E2>().base_<D2>();
|
|
||||||
meta::class_<F2>().base_<B2, C2, E2>();
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("meta/meta_utilities/ucast") {
|
TEST_CASE("meta/meta_utilities/ucast") {
|
||||||
namespace meta = meta_hpp;
|
namespace meta = meta_hpp;
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,9 @@ namespace
|
|||||||
[[nodiscard]] int m6() const && { return ii; }
|
[[nodiscard]] int m6() const && { return ii; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dclazz : fake, clazz {};
|
struct dclazz : fake, clazz {
|
||||||
|
META_HPP_ENABLE_BASE_INFO(fake, clazz)
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOLINTNEXTLINE(*-macro-usage)
|
// NOLINTNEXTLINE(*-macro-usage)
|
||||||
@@ -70,14 +72,6 @@ namespace
|
|||||||
}\
|
}\
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("meta/meta_utilities/inst2") {
|
|
||||||
namespace meta = meta_hpp;
|
|
||||||
|
|
||||||
meta::class_<fake>();
|
|
||||||
meta::class_<clazz>();
|
|
||||||
meta::class_<dclazz>().base_<fake>().base_<clazz>();
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("meta/meta_utilities/inst2/refs") {
|
TEST_CASE("meta/meta_utilities/inst2/refs") {
|
||||||
namespace meta = meta_hpp;
|
namespace meta = meta_hpp;
|
||||||
using meta::detail::uarg;
|
using meta::detail::uarg;
|
||||||
|
|||||||
@@ -15,41 +15,25 @@ namespace
|
|||||||
|
|
||||||
struct base1 : virtual base0 {
|
struct base1 : virtual base0 {
|
||||||
int j{42};
|
int j{42};
|
||||||
|
META_HPP_ENABLE_BASE_INFO(base0)
|
||||||
};
|
};
|
||||||
|
|
||||||
struct base2 : virtual base0 {
|
struct base2 : virtual base0 {
|
||||||
int k{84};
|
int k{84};
|
||||||
|
META_HPP_ENABLE_BASE_INFO(base0)
|
||||||
};
|
};
|
||||||
|
|
||||||
struct derived : base1, base2 {
|
struct derived : base1, base2 {
|
||||||
int l{168};
|
int l{168};
|
||||||
|
META_HPP_ENABLE_BASE_INFO(base1, base2)
|
||||||
};
|
};
|
||||||
|
|
||||||
struct derived2 : base1, base2 {
|
struct derived2 : base1, base2 {
|
||||||
int m{336};
|
int m{336};
|
||||||
|
META_HPP_ENABLE_BASE_INFO(base1, base2)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("meta/meta_utilities/value3") {
|
|
||||||
namespace meta = meta_hpp;
|
|
||||||
|
|
||||||
meta::class_<base0>();
|
|
||||||
|
|
||||||
meta::class_<base1>()
|
|
||||||
.base_<base0>();
|
|
||||||
|
|
||||||
meta::class_<base2>()
|
|
||||||
.base_<base0>();
|
|
||||||
|
|
||||||
meta::class_<derived>()
|
|
||||||
.base_<base1>()
|
|
||||||
.base_<base2>();
|
|
||||||
|
|
||||||
meta::class_<derived2>()
|
|
||||||
.base_<base1>()
|
|
||||||
.base_<base2>();
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("meta/meta_utilities/value3/get_type") {
|
TEST_CASE("meta/meta_utilities/value3/get_type") {
|
||||||
namespace meta = meta_hpp;
|
namespace meta = meta_hpp;
|
||||||
|
|
||||||
|
|||||||
3
develop/vendors/CMakeLists.txt
vendored
3
develop/vendors/CMakeLists.txt
vendored
@@ -54,6 +54,9 @@ target_include_directories(${PROJECT_NAME}.gbench SYSTEM
|
|||||||
target_compile_definitions(${PROJECT_NAME}.gbench
|
target_compile_definitions(${PROJECT_NAME}.gbench
|
||||||
PUBLIC BENCHMARK_STATIC_DEFINE)
|
PUBLIC BENCHMARK_STATIC_DEFINE)
|
||||||
|
|
||||||
|
target_link_libraries(${PROJECT_NAME}.gbench
|
||||||
|
PRIVATE $<$<PLATFORM_ID:Windows>:shlwapi>)
|
||||||
|
|
||||||
#
|
#
|
||||||
# vmath.hpp
|
# vmath.hpp
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -22,11 +22,6 @@ namespace meta_hpp::detail
|
|||||||
concept class_bind_destructor_kind //
|
concept class_bind_destructor_kind //
|
||||||
= class_kind<Class> && std::is_destructible_v<Class>; //
|
= class_kind<Class> && std::is_destructible_v<Class>; //
|
||||||
|
|
||||||
template < typename Base, typename Class >
|
|
||||||
concept class_bind_base_kind //
|
|
||||||
= class_kind<Base> && class_kind<Class> //
|
|
||||||
&& std::derived_from<Class, Base>; //
|
|
||||||
|
|
||||||
template < typename Member, typename Class >
|
template < typename Member, typename Class >
|
||||||
concept class_bind_member_kind //
|
concept class_bind_member_kind //
|
||||||
= member_pointer_kind<Member> && class_kind<Class> //
|
= member_pointer_kind<Member> && class_kind<Class> //
|
||||||
@@ -107,9 +102,6 @@ namespace meta_hpp
|
|||||||
public:
|
public:
|
||||||
explicit class_bind(metadata_map metadata);
|
explicit class_bind(metadata_map metadata);
|
||||||
|
|
||||||
template < detail::class_bind_base_kind<Class>... Bases >
|
|
||||||
class_bind& base_();
|
|
||||||
|
|
||||||
template < typename... Args, typename... Opts >
|
template < typename... Args, typename... Opts >
|
||||||
requires detail::class_bind_constructor_kind<Class, Args...>
|
requires detail::class_bind_constructor_kind<Class, Args...>
|
||||||
class_bind& constructor_(Opts&&... opts);
|
class_bind& constructor_(Opts&&... opts);
|
||||||
|
|||||||
@@ -10,83 +10,6 @@
|
|||||||
#include "../meta_binds.hpp"
|
#include "../meta_binds.hpp"
|
||||||
#include "../meta_registry.hpp"
|
#include "../meta_registry.hpp"
|
||||||
|
|
||||||
namespace meta_hpp::detail::class_bind_impl
|
|
||||||
{
|
|
||||||
using base_upcasts_t = class_type_data::base_upcasts_t;
|
|
||||||
using deep_upcasts_t = class_type_data::deep_upcasts_t;
|
|
||||||
|
|
||||||
using upcast_func_t = class_type_data::upcast_func_t;
|
|
||||||
using upcast_func_list_t = class_type_data::upcast_func_list_t;
|
|
||||||
|
|
||||||
using new_bases_db_t = std::vector<std::pair<class_type, upcast_func_t>>;
|
|
||||||
using deep_upcasts_db_t = std::map<class_type, deep_upcasts_t, std::less<>>;
|
|
||||||
using derived_classes_db_t = std::map<class_type, class_list, std::less<>>;
|
|
||||||
|
|
||||||
template < class_kind Class, class_kind Base >
|
|
||||||
requires std::is_base_of_v<Base, Class>
|
|
||||||
void update_new_bases_db( //
|
|
||||||
new_bases_db_t& new_bases_db
|
|
||||||
) {
|
|
||||||
const class_type& new_base = resolve_type<Base>();
|
|
||||||
|
|
||||||
for ( auto&& [db_base, _] : new_bases_db ) {
|
|
||||||
if ( db_base == new_base ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
new_bases_db.emplace_back( //
|
|
||||||
new_base,
|
|
||||||
upcast_func_t{std::in_place_type<Class>, std::in_place_type<Base>}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void update_deep_upcasts_db( //
|
|
||||||
const class_type& derived_class,
|
|
||||||
const class_type& new_base_class,
|
|
||||||
upcast_func_list_t&& derived_to_new_base,
|
|
||||||
deep_upcasts_db_t& deep_upcasts_db
|
|
||||||
) {
|
|
||||||
const class_type_data& derived_class_data = *type_access(derived_class);
|
|
||||||
const class_type_data& new_base_class_data = *type_access(new_base_class);
|
|
||||||
|
|
||||||
const auto [deep_upcasts_db_iter, _] = deep_upcasts_db.try_emplace(derived_class, derived_class_data.deep_upcasts);
|
|
||||||
deep_upcasts_t& derived_deep_upcasts = deep_upcasts_db_iter->second;
|
|
||||||
|
|
||||||
const auto add_derived_deep_upcast = [&derived_deep_upcasts](const class_type& deep_class, upcast_func_list_t&& upcasts) {
|
|
||||||
auto&& [position, emplaced] = derived_deep_upcasts.try_emplace(deep_class, std::move(upcasts));
|
|
||||||
if ( !emplaced ) {
|
|
||||||
position->second.is_ambiguous = is_disjoint(position->second.vbases, upcasts.vbases);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
for ( auto&& [new_deep_class, new_base_to_deep] : new_base_class_data.deep_upcasts ) {
|
|
||||||
upcast_func_list_t derived_to_new_deep = derived_to_new_base + new_base_to_deep;
|
|
||||||
add_derived_deep_upcast(new_deep_class, std::move(derived_to_new_deep));
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( const class_type& subderived_class : derived_class_data.derived_classes ) {
|
|
||||||
const class_type_data& subderived_data = *type_access(subderived_class);
|
|
||||||
upcast_func_t subderived_to_derived = subderived_data.base_upcasts.at(derived_class);
|
|
||||||
upcast_func_list_t subderived_to_new_base = subderived_to_derived + derived_to_new_base;
|
|
||||||
update_deep_upcasts_db(subderived_class, new_base_class, std::move(subderived_to_new_base), deep_upcasts_db);
|
|
||||||
}
|
|
||||||
|
|
||||||
add_derived_deep_upcast(new_base_class, std::move(derived_to_new_base));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void updata_derived_classes_db( //
|
|
||||||
const class_type& self_class,
|
|
||||||
const class_type& new_base_class,
|
|
||||||
derived_classes_db_t& derived_classes_db
|
|
||||||
) {
|
|
||||||
const class_type_data& base_class_data = *type_access(new_base_class);
|
|
||||||
class_list new_derived_classes{base_class_data.derived_classes};
|
|
||||||
insert_or_assign(new_derived_classes, self_class);
|
|
||||||
derived_classes_db.emplace(new_base_class, std::move(new_derived_classes));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace meta_hpp
|
namespace meta_hpp
|
||||||
{
|
{
|
||||||
template < detail::class_kind Class >
|
template < detail::class_kind Class >
|
||||||
@@ -97,49 +20,6 @@ namespace meta_hpp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template < detail::class_kind Class >
|
|
||||||
template < detail::class_bind_base_kind<Class>... Bases >
|
|
||||||
class_bind<Class>& class_bind<Class>::base_() {
|
|
||||||
using namespace detail;
|
|
||||||
using namespace detail::class_bind_impl;
|
|
||||||
|
|
||||||
new_bases_db_t new_bases_db;
|
|
||||||
(update_new_bases_db<Class, Bases>(new_bases_db), ...);
|
|
||||||
|
|
||||||
deep_upcasts_db_t deep_upcasts_db;
|
|
||||||
derived_classes_db_t derived_classes_db;
|
|
||||||
|
|
||||||
class_list new_base_classes{get_data().base_classes};
|
|
||||||
base_upcasts_t new_base_upcasts{get_data().base_upcasts};
|
|
||||||
|
|
||||||
for ( auto&& [new_base_class, self_to_new_base] : new_bases_db ) {
|
|
||||||
if ( std::find(new_base_classes.begin(), new_base_classes.end(), new_base_class) != new_base_classes.end() ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
update_deep_upcasts_db(*this, new_base_class, self_to_new_base, deep_upcasts_db);
|
|
||||||
updata_derived_classes_db(*this, new_base_class, derived_classes_db);
|
|
||||||
|
|
||||||
new_base_classes.emplace_back(new_base_class);
|
|
||||||
new_base_upcasts.emplace(new_base_class, self_to_new_base);
|
|
||||||
}
|
|
||||||
|
|
||||||
get_data().base_classes.swap(new_base_classes);
|
|
||||||
get_data().base_upcasts.swap(new_base_upcasts);
|
|
||||||
|
|
||||||
for ( auto&& [derived_class, new_deep_upcasts] : deep_upcasts_db ) {
|
|
||||||
class_type_data& derived_data = *type_access(derived_class);
|
|
||||||
derived_data.deep_upcasts.swap(new_deep_upcasts);
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( auto&& [base_class, new_derived_classes] : derived_classes_db ) {
|
|
||||||
class_type_data& base_data = *type_access(base_class);
|
|
||||||
base_data.derived_classes.swap(new_derived_classes);
|
|
||||||
}
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template < detail::class_kind Class >
|
template < detail::class_kind Class >
|
||||||
template < typename... Args, typename... Opts >
|
template < typename... Args, typename... Opts >
|
||||||
requires detail::class_bind_constructor_kind<Class, Args...>
|
requires detail::class_bind_constructor_kind<Class, Args...>
|
||||||
|
|||||||
@@ -18,6 +18,10 @@ namespace meta_hpp::detail
|
|||||||
class_type type{};
|
class_type type{};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template < typename T >
|
||||||
|
concept check_base_info_enabled //
|
||||||
|
= requires { typename T::meta_base_info; };
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
concept check_poly_info_enabled //
|
concept check_poly_info_enabled //
|
||||||
= requires(type_registry& r, const T& v) {
|
= requires(type_registry& r, const T& v) {
|
||||||
@@ -25,7 +29,14 @@ namespace meta_hpp::detail
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#define META_HPP_ENABLE_POLY_INFO() \
|
#define META_HPP_ENABLE_BASE_INFO(...) \
|
||||||
|
public: \
|
||||||
|
using meta_base_info = ::meta_hpp::detail::type_list<__VA_ARGS__>; \
|
||||||
|
\
|
||||||
|
private:
|
||||||
|
|
||||||
|
#define META_HPP_ENABLE_POLY_INFO(...) \
|
||||||
|
META_HPP_ENABLE_BASE_INFO(__VA_ARGS__) \
|
||||||
public: \
|
public: \
|
||||||
META_HPP_IGNORE_OVERRIDE_WARNINGS_PUSH() \
|
META_HPP_IGNORE_OVERRIDE_WARNINGS_PUSH() \
|
||||||
virtual ::meta_hpp::detail::poly_info get_most_derived_poly_info(::meta_hpp::detail::type_registry& registry) const { \
|
virtual ::meta_hpp::detail::poly_info get_most_derived_poly_info(::meta_hpp::detail::type_registry& registry) const { \
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
#include "meta_states.hpp"
|
#include "meta_states.hpp"
|
||||||
#include "meta_types.hpp"
|
#include "meta_types.hpp"
|
||||||
|
|
||||||
#include "meta_detail/poly_info.hpp"
|
#include "meta_detail/base_info.hpp"
|
||||||
#include "meta_detail/state_registry.hpp"
|
#include "meta_detail/state_registry.hpp"
|
||||||
#include "meta_detail/type_registry.hpp"
|
#include "meta_detail/type_registry.hpp"
|
||||||
|
|
||||||
|
|||||||
@@ -211,7 +211,6 @@ namespace meta_hpp
|
|||||||
[[nodiscard]] const any_type_list& get_argument_types() const noexcept;
|
[[nodiscard]] const any_type_list& get_argument_types() const noexcept;
|
||||||
|
|
||||||
[[nodiscard]] const class_list& get_base_classes() const noexcept;
|
[[nodiscard]] const class_list& get_base_classes() const noexcept;
|
||||||
[[nodiscard]] const class_list& get_derived_classes() const noexcept;
|
|
||||||
[[nodiscard]] const constructor_list& get_constructors() const noexcept;
|
[[nodiscard]] const constructor_list& get_constructors() const noexcept;
|
||||||
[[nodiscard]] const destructor_list& get_destructors() const noexcept;
|
[[nodiscard]] const destructor_list& get_destructors() const noexcept;
|
||||||
[[nodiscard]] const function_list& get_functions() const noexcept;
|
[[nodiscard]] const function_list& get_functions() const noexcept;
|
||||||
@@ -504,7 +503,6 @@ namespace meta_hpp::detail
|
|||||||
// NOLINTEND(*-avoid-const-or-ref-data-members)
|
// NOLINTEND(*-avoid-const-or-ref-data-members)
|
||||||
|
|
||||||
class_list base_classes;
|
class_list base_classes;
|
||||||
class_list derived_classes;
|
|
||||||
constructor_list constructors;
|
constructor_list constructors;
|
||||||
destructor_list destructors;
|
destructor_list destructors;
|
||||||
function_list functions;
|
function_list functions;
|
||||||
@@ -536,8 +534,8 @@ namespace meta_hpp::detail
|
|||||||
vbases_t vbases{};
|
vbases_t vbases{};
|
||||||
bool is_ambiguous{};
|
bool is_ambiguous{};
|
||||||
|
|
||||||
upcast_func_list_t(const upcast_func_t& _upcast);
|
upcast_func_list_t(const upcast_func_t& in_upcast);
|
||||||
upcast_func_list_t(upcasts_t _upcasts, vbases_t _vbases);
|
upcast_func_list_t(upcasts_t in_upcasts, vbases_t in_vbases);
|
||||||
|
|
||||||
[[nodiscard]] void* apply(void* ptr) const noexcept;
|
[[nodiscard]] void* apply(void* ptr) const noexcept;
|
||||||
[[nodiscard]] const void* apply(const void* ptr) const noexcept;
|
[[nodiscard]] const void* apply(const void* ptr) const noexcept;
|
||||||
|
|||||||
@@ -26,7 +26,48 @@ namespace meta_hpp::detail
|
|||||||
, flags{class_traits<Class>::make_flags()}
|
, flags{class_traits<Class>::make_flags()}
|
||||||
, size{class_traits<Class>::size}
|
, size{class_traits<Class>::size}
|
||||||
, align{class_traits<Class>::align}
|
, align{class_traits<Class>::align}
|
||||||
, argument_types{resolve_types(typename class_traits<Class>::argument_types{})} {}
|
, argument_types{resolve_types(typename class_traits<Class>::argument_types{})} {
|
||||||
|
if constexpr ( check_base_info_enabled<Class> ) {
|
||||||
|
using meta_base_info = typename Class::meta_base_info;
|
||||||
|
|
||||||
|
[this]<std::size_t... Is>(std::index_sequence<Is...>) {
|
||||||
|
struct {
|
||||||
|
class_list base_classes;
|
||||||
|
base_upcasts_t base_upcasts;
|
||||||
|
deep_upcasts_t deep_upcasts;
|
||||||
|
} new_base_data;
|
||||||
|
|
||||||
|
const auto add_new_base_class = [&new_base_data]<class_kind Base>(std::in_place_type_t<Base>) {
|
||||||
|
const class_type& base_class = resolve_type<Base>();
|
||||||
|
const class_type_data& base_class_data = *type_access(base_class);
|
||||||
|
|
||||||
|
upcast_func_t self_to_base{std::in_place_type<Class>, std::in_place_type<Base>};
|
||||||
|
|
||||||
|
new_base_data.base_classes.emplace_back(base_class);
|
||||||
|
new_base_data.base_upcasts.emplace(base_class, self_to_base);
|
||||||
|
|
||||||
|
for ( const auto& [deep_class, base_to_deep] : base_class_data.deep_upcasts ) {
|
||||||
|
upcast_func_list_t self_to_deep = self_to_base + base_to_deep;
|
||||||
|
|
||||||
|
const auto& [position, emplaced] = new_base_data.deep_upcasts.try_emplace(
|
||||||
|
deep_class, std::move(self_to_deep)
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( !emplaced ) {
|
||||||
|
position->second.is_ambiguous = is_disjoint(position->second.vbases, self_to_deep.vbases);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
new_base_data.deep_upcasts.emplace(base_class, upcast_func_list_t{self_to_base});
|
||||||
|
};
|
||||||
|
(add_new_base_class(std::in_place_type<type_list_at_t<Is, meta_base_info>>), ...);
|
||||||
|
|
||||||
|
base_classes.swap(new_base_data.base_classes);
|
||||||
|
base_upcasts.swap(new_base_data.base_upcasts);
|
||||||
|
deep_upcasts.swap(new_base_data.deep_upcasts);
|
||||||
|
}(std::make_index_sequence<type_list_arity_v<meta_base_info>>());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace meta_hpp::detail
|
namespace meta_hpp::detail
|
||||||
@@ -50,8 +91,8 @@ namespace meta_hpp::detail
|
|||||||
|
|
||||||
namespace meta_hpp::detail
|
namespace meta_hpp::detail
|
||||||
{
|
{
|
||||||
inline class_type_data::upcast_func_list_t::upcast_func_list_t(const upcast_func_t& _upcast)
|
inline class_type_data::upcast_func_list_t::upcast_func_list_t(const upcast_func_t& in_upcast)
|
||||||
: upcasts{_upcast} {
|
: upcasts{in_upcast} {
|
||||||
for ( const upcast_func_t& upcast : upcasts ) {
|
for ( const upcast_func_t& upcast : upcasts ) {
|
||||||
if ( upcast.is_virtual ) {
|
if ( upcast.is_virtual ) {
|
||||||
vbases.emplace(upcast.target);
|
vbases.emplace(upcast.target);
|
||||||
@@ -59,9 +100,9 @@ namespace meta_hpp::detail
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline class_type_data::upcast_func_list_t::upcast_func_list_t(upcasts_t _upcasts, vbases_t _vbases)
|
inline class_type_data::upcast_func_list_t::upcast_func_list_t(upcasts_t in_upcasts, vbases_t in_vbases)
|
||||||
: upcasts{std::move(_upcasts)}
|
: upcasts{std::move(in_upcasts)}
|
||||||
, vbases{std::move(_vbases)} {}
|
, vbases{std::move(in_vbases)} {}
|
||||||
|
|
||||||
inline void* class_type_data::upcast_func_list_t::apply(void* ptr) const noexcept {
|
inline void* class_type_data::upcast_func_list_t::apply(void* ptr) const noexcept {
|
||||||
for ( const upcast_func_t& upcast : upcasts ) {
|
for ( const upcast_func_t& upcast : upcasts ) {
|
||||||
@@ -88,7 +129,9 @@ namespace meta_hpp::detail
|
|||||||
new_vbases.insert(l.vbases.begin(), l.vbases.end());
|
new_vbases.insert(l.vbases.begin(), l.vbases.end());
|
||||||
new_vbases.insert(r.vbases.begin(), r.vbases.end());
|
new_vbases.insert(r.vbases.begin(), r.vbases.end());
|
||||||
|
|
||||||
return class_type_data::upcast_func_list_t{std::move(new_upcasts), std::move(new_vbases)};
|
class_type_data::upcast_func_list_t result{std::move(new_upcasts), std::move(new_vbases)};
|
||||||
|
result.is_ambiguous = l.is_ambiguous || r.is_ambiguous;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,10 +165,6 @@ namespace meta_hpp
|
|||||||
return data_->base_classes;
|
return data_->base_classes;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const class_list& class_type::get_derived_classes() const noexcept {
|
|
||||||
return data_->derived_classes;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const constructor_list& class_type::get_constructors() const noexcept {
|
inline const constructor_list& class_type::get_constructors() const noexcept {
|
||||||
return data_->constructors;
|
return data_->constructors;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
#include "../meta_base.hpp"
|
#include "../meta_base.hpp"
|
||||||
#include "../meta_ucast.hpp"
|
#include "../meta_ucast.hpp"
|
||||||
|
|
||||||
#include "../meta_detail/poly_info.hpp"
|
#include "../meta_detail/base_info.hpp"
|
||||||
#include "../meta_detail/type_registry.hpp"
|
#include "../meta_detail/type_registry.hpp"
|
||||||
#include "../meta_detail/value_utilities/utraits.hpp"
|
#include "../meta_detail/value_utilities/utraits.hpp"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user