mirror of
https://github.com/BlackMATov/meta.hpp.git
synced 2025-12-16 22:17:02 +07:00
add some random issue with virtual bases
This commit is contained in:
@@ -21,7 +21,7 @@ namespace
|
|||||||
};
|
};
|
||||||
|
|
||||||
class rectangle : public shape {
|
class rectangle : public shape {
|
||||||
META_HPP_ENABLE_BASE_INFO(shape)
|
META_HPP_ENABLE_POLY_INFO(shape)
|
||||||
public:
|
public:
|
||||||
explicit rectangle(int width, int height)
|
explicit rectangle(int width, int height)
|
||||||
: width_{width}
|
: width_{width}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ namespace
|
|||||||
};
|
};
|
||||||
|
|
||||||
class rectangle : public shape {
|
class rectangle : public shape {
|
||||||
META_HPP_ENABLE_BASE_INFO(shape)
|
META_HPP_ENABLE_POLY_INFO(shape)
|
||||||
public:
|
public:
|
||||||
explicit rectangle(int width, int height)
|
explicit rectangle(int width, int height)
|
||||||
: width_{width}
|
: width_{width}
|
||||||
|
|||||||
@@ -2995,7 +2995,7 @@ namespace meta_hpp::detail
|
|||||||
vbases_t vbases{};
|
vbases_t vbases{};
|
||||||
bool is_ambiguous{};
|
bool is_ambiguous{};
|
||||||
|
|
||||||
upcast_func_list_t(const upcast_func_t& in_upcast);
|
explicit upcast_func_list_t(const upcast_func_t& in_upcast);
|
||||||
upcast_func_list_t(upcasts_t in_upcasts, vbases_t in_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;
|
||||||
@@ -8368,17 +8368,18 @@ namespace meta_hpp::detail
|
|||||||
deep_upcasts_t deep_upcasts;
|
deep_upcasts_t deep_upcasts;
|
||||||
} new_base_data;
|
} new_base_data;
|
||||||
|
|
||||||
[[maybe_unused]] const auto add_base_class = [&new_base_data]<class_kind Base>(std::in_place_type_t<Base>) {
|
[[maybe_unused]] const auto add_base_class = [&new_base_data]<class_kind Base>() {
|
||||||
const class_type& base_class = resolve_type<Base>();
|
const class_type& base_class = resolve_type<Base>();
|
||||||
const class_type_data& base_class_data = *type_access(base_class);
|
const class_type_data& base_data = *type_access(base_class);
|
||||||
|
|
||||||
upcast_func_t self_to_base{std::in_place_type<Class>, std::in_place_type<Base>};
|
upcast_func_t self_to_base{std::in_place_type<Class>, std::in_place_type<Base>};
|
||||||
|
upcast_func_list_t self_to_base_list{self_to_base};
|
||||||
|
|
||||||
new_base_data.base_classes.emplace_back(base_class);
|
new_base_data.base_classes.emplace_back(base_class);
|
||||||
new_base_data.base_upcasts.emplace(base_class, self_to_base);
|
new_base_data.base_upcasts.emplace(base_class, self_to_base);
|
||||||
|
|
||||||
for ( const auto& [deep_class, base_to_deep] : base_class_data.deep_upcasts ) {
|
for ( const auto& [deep_class, base_to_deep] : base_data.deep_upcasts ) {
|
||||||
upcast_func_list_t self_to_deep = self_to_base + base_to_deep;
|
upcast_func_list_t self_to_deep = self_to_base_list + base_to_deep;
|
||||||
|
|
||||||
const auto& [position, emplaced] = new_base_data.deep_upcasts.try_emplace(
|
const auto& [position, emplaced] = new_base_data.deep_upcasts.try_emplace(
|
||||||
deep_class, std::move(self_to_deep)
|
deep_class, std::move(self_to_deep)
|
||||||
@@ -8389,9 +8390,9 @@ namespace meta_hpp::detail
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
new_base_data.deep_upcasts.emplace(base_class, upcast_func_list_t{self_to_base});
|
new_base_data.deep_upcasts.emplace(base_class, std::move(self_to_base_list));
|
||||||
};
|
};
|
||||||
(add_base_class(std::in_place_type<type_list_at_t<Is, meta_base_info>>), ...);
|
(add_base_class.template operator()<type_list_at_t<Is, meta_base_info>>(), ...);
|
||||||
|
|
||||||
base_classes.swap(new_base_data.base_classes);
|
base_classes.swap(new_base_data.base_classes);
|
||||||
base_upcasts.swap(new_base_data.base_upcasts);
|
base_upcasts.swap(new_base_data.base_upcasts);
|
||||||
|
|||||||
61
develop/untests/meta_issues/random_issue_5.cpp
Normal file
61
develop/untests/meta_issues/random_issue_5.cpp
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* This file is part of the "https://github.com/blackmatov/meta.hpp"
|
||||||
|
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||||
|
* Copyright (C) 2021-2023, by Matvey Cherevko (blackmatov@gmail.com)
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#include <meta.hpp/meta_all.hpp>
|
||||||
|
#include <doctest/doctest.h>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
struct A1 {};
|
||||||
|
struct B1 : A1 { META_HPP_ENABLE_BASE_INFO(A1) };
|
||||||
|
struct C1 : A1 { META_HPP_ENABLE_BASE_INFO(A1) };
|
||||||
|
struct D1 : B1, C1 { META_HPP_ENABLE_BASE_INFO(B1, C1) };
|
||||||
|
struct E1 : D1 { META_HPP_ENABLE_BASE_INFO(D1) };
|
||||||
|
|
||||||
|
// A1 < B1
|
||||||
|
// < D1 < E1
|
||||||
|
// A1 < C1
|
||||||
|
|
||||||
|
struct A2 {};
|
||||||
|
struct B2 : virtual A2 { META_HPP_ENABLE_BASE_INFO(A2) };
|
||||||
|
struct C2 : virtual A2 { META_HPP_ENABLE_BASE_INFO(A2) };
|
||||||
|
struct D2 : B2, C2 { META_HPP_ENABLE_BASE_INFO(B2, C2) };
|
||||||
|
struct E2 : D2 { META_HPP_ENABLE_BASE_INFO(D2) };
|
||||||
|
|
||||||
|
// A2 <= B2
|
||||||
|
// < D2 < E2
|
||||||
|
// A2 <= C2
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("meta/meta_issues/random/5") {
|
||||||
|
namespace meta = meta_hpp;
|
||||||
|
|
||||||
|
{
|
||||||
|
CHECK(meta::is_invocable_with(+[](const A1&){}, B1{}));
|
||||||
|
CHECK(meta::is_invocable_with(+[](const A1&){}, C1{}));
|
||||||
|
CHECK(meta::is_invocable_with(+[](const B1&){}, D1{}));
|
||||||
|
CHECK(meta::is_invocable_with(+[](const C1&){}, D1{}));
|
||||||
|
CHECK(meta::is_invocable_with(+[](const B1&){}, E1{}));
|
||||||
|
CHECK(meta::is_invocable_with(+[](const C1&){}, E1{}));
|
||||||
|
CHECK(meta::is_invocable_with(+[](const D1&){}, E1{}));
|
||||||
|
|
||||||
|
CHECK_FALSE(meta::is_invocable_with(+[](const A1&){}, D1{}));
|
||||||
|
CHECK_FALSE(meta::is_invocable_with(+[](const A1&){}, E1{}));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
CHECK(meta::is_invocable_with(+[](const A2&){}, B2{}));
|
||||||
|
CHECK(meta::is_invocable_with(+[](const A2&){}, C2{}));
|
||||||
|
CHECK(meta::is_invocable_with(+[](const B2&){}, D2{}));
|
||||||
|
CHECK(meta::is_invocable_with(+[](const C2&){}, D2{}));
|
||||||
|
CHECK(meta::is_invocable_with(+[](const B2&){}, E2{}));
|
||||||
|
CHECK(meta::is_invocable_with(+[](const C2&){}, E2{}));
|
||||||
|
CHECK(meta::is_invocable_with(+[](const D2&){}, E2{}));
|
||||||
|
|
||||||
|
CHECK(meta::is_invocable_with(+[](const A2&){}, D2{}));
|
||||||
|
CHECK(meta::is_invocable_with(+[](const A2&){}, E2{}));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -534,7 +534,7 @@ namespace meta_hpp::detail
|
|||||||
vbases_t vbases{};
|
vbases_t vbases{};
|
||||||
bool is_ambiguous{};
|
bool is_ambiguous{};
|
||||||
|
|
||||||
upcast_func_list_t(const upcast_func_t& in_upcast);
|
explicit upcast_func_list_t(const upcast_func_t& in_upcast);
|
||||||
upcast_func_list_t(upcasts_t in_upcasts, vbases_t in_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;
|
||||||
|
|||||||
@@ -37,17 +37,18 @@ namespace meta_hpp::detail
|
|||||||
deep_upcasts_t deep_upcasts;
|
deep_upcasts_t deep_upcasts;
|
||||||
} new_base_data;
|
} new_base_data;
|
||||||
|
|
||||||
[[maybe_unused]] const auto add_base_class = [&new_base_data]<class_kind Base>(std::in_place_type_t<Base>) {
|
[[maybe_unused]] const auto add_base_class = [&new_base_data]<class_kind Base>() {
|
||||||
const class_type& base_class = resolve_type<Base>();
|
const class_type& base_class = resolve_type<Base>();
|
||||||
const class_type_data& base_class_data = *type_access(base_class);
|
const class_type_data& base_data = *type_access(base_class);
|
||||||
|
|
||||||
upcast_func_t self_to_base{std::in_place_type<Class>, std::in_place_type<Base>};
|
upcast_func_t self_to_base{std::in_place_type<Class>, std::in_place_type<Base>};
|
||||||
|
upcast_func_list_t self_to_base_list{self_to_base};
|
||||||
|
|
||||||
new_base_data.base_classes.emplace_back(base_class);
|
new_base_data.base_classes.emplace_back(base_class);
|
||||||
new_base_data.base_upcasts.emplace(base_class, self_to_base);
|
new_base_data.base_upcasts.emplace(base_class, self_to_base);
|
||||||
|
|
||||||
for ( const auto& [deep_class, base_to_deep] : base_class_data.deep_upcasts ) {
|
for ( const auto& [deep_class, base_to_deep] : base_data.deep_upcasts ) {
|
||||||
upcast_func_list_t self_to_deep = self_to_base + base_to_deep;
|
upcast_func_list_t self_to_deep = self_to_base_list + base_to_deep;
|
||||||
|
|
||||||
const auto& [position, emplaced] = new_base_data.deep_upcasts.try_emplace(
|
const auto& [position, emplaced] = new_base_data.deep_upcasts.try_emplace(
|
||||||
deep_class, std::move(self_to_deep)
|
deep_class, std::move(self_to_deep)
|
||||||
@@ -58,9 +59,9 @@ namespace meta_hpp::detail
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
new_base_data.deep_upcasts.emplace(base_class, upcast_func_list_t{self_to_base});
|
new_base_data.deep_upcasts.emplace(base_class, std::move(self_to_base_list));
|
||||||
};
|
};
|
||||||
(add_base_class(std::in_place_type<type_list_at_t<Is, meta_base_info>>), ...);
|
(add_base_class.template operator()<type_list_at_t<Is, meta_base_info>>(), ...);
|
||||||
|
|
||||||
base_classes.swap(new_base_data.base_classes);
|
base_classes.swap(new_base_data.base_classes);
|
||||||
base_upcasts.swap(new_base_data.base_upcasts);
|
base_upcasts.swap(new_base_data.base_upcasts);
|
||||||
|
|||||||
Reference in New Issue
Block a user