any_type::match function

This commit is contained in:
BlackMATov
2023-08-11 07:02:44 +07:00
parent 03fbc72400
commit d4185e738d
6 changed files with 226 additions and 1 deletions

View File

@@ -8,7 +8,6 @@
- fix all includes to work with the library more flexible
- test and support shared libraries
- remove `resolve_poly_type`, use `resolve_type(T&&)` instead
- add `match` function to `any_type` class
## Thoughts

View File

@@ -1534,6 +1534,8 @@ namespace meta_hpp
using detail::hashed_string;
using detail::memory_buffer;
using detail::overloaded;
using detail::select_const;
using detail::select_non_const;
using detail::select_overload;
@@ -2615,6 +2617,9 @@ namespace meta_hpp
template < type_family Type >
[[nodiscard]] Type as() const noexcept;
template < typename F >
bool match(F&& f) const;
[[nodiscard]] bool is_array() const noexcept;
[[nodiscard]] bool is_class() const noexcept;
[[nodiscard]] bool is_constructor() const noexcept;
@@ -9275,6 +9280,58 @@ namespace meta_hpp
}
}
template < typename F >
bool any_type::match(F&& f) const {
if ( !is_valid() ) {
return false;
}
switch ( get_kind() ) {
case type_kind::array_:
std::invoke(std::forward<F>(f), as_array());
return true;
case type_kind::class_:
std::invoke(std::forward<F>(f), as_class());
return true;
case type_kind::constructor_:
std::invoke(std::forward<F>(f), as_constructor());
return true;
case type_kind::destructor_:
std::invoke(std::forward<F>(f), as_destructor());
return true;
case type_kind::enum_:
std::invoke(std::forward<F>(f), as_enum());
return true;
case type_kind::function_:
std::invoke(std::forward<F>(f), as_function());
return true;
case type_kind::member_:
std::invoke(std::forward<F>(f), as_member());
return true;
case type_kind::method_:
std::invoke(std::forward<F>(f), as_method());
return true;
case type_kind::nullptr_:
std::invoke(std::forward<F>(f), as_nullptr());
return true;
case type_kind::number_:
std::invoke(std::forward<F>(f), as_number());
return true;
case type_kind::pointer_:
std::invoke(std::forward<F>(f), as_pointer());
return true;
case type_kind::reference_:
std::invoke(std::forward<F>(f), as_reference());
return true;
case type_kind::void_:
std::invoke(std::forward<F>(f), as_void());
return true;
}
META_HPP_ASSERT(false);
return false;
}
inline bool any_type::is_array() const noexcept {
return is<array_type>();
}

View File

@@ -43,6 +43,10 @@ TEST_CASE("meta/meta_types/any_type") {
CHECK_FALSE(type.is_array());
CHECK_FALSE(type.as_array());
CHECK_FALSE(type.match(meta::overloaded{
[](auto&&){}
}));
}
SUBCASE("array") {
@@ -61,6 +65,15 @@ TEST_CASE("meta/meta_types/any_type") {
const meta::array_type& specific_type = type.as_array();
REQUIRE(specific_type);
CHECK(specific_type.get_id() == type.get_id());
{
bool match_called = false;
CHECK(type.match(meta::overloaded{
[&type, &match_called](meta::array_type t){ CHECK(t == type); match_called = true; },
[](auto&&){}
}));
CHECK(match_called);
}
}
SUBCASE("class") {
@@ -79,6 +92,15 @@ TEST_CASE("meta/meta_types/any_type") {
const meta::class_type& specific_type = type.as_class();
REQUIRE(specific_type);
CHECK(specific_type.get_id() == type.get_id());
{
bool match_called = false;
CHECK(type.match(meta::overloaded{
[&type, &match_called](meta::class_type t){ CHECK(t == type); match_called = true; },
[](auto&&){}
}));
CHECK(match_called);
}
}
SUBCASE("ctor") {
@@ -97,6 +119,15 @@ TEST_CASE("meta/meta_types/any_type") {
const meta::constructor_type& specific_type = type.as_constructor();
REQUIRE(specific_type);
CHECK(specific_type.get_id() == type.get_id());
{
bool match_called = false;
CHECK(type.match(meta::overloaded{
[&type, &match_called](meta::constructor_type t){ CHECK(t == type); match_called = true; },
[](auto&&){}
}));
CHECK(match_called);
}
}
SUBCASE("enum") {
@@ -115,6 +146,15 @@ TEST_CASE("meta/meta_types/any_type") {
const meta::enum_type& specific_type = type.as_enum();
REQUIRE(specific_type);
CHECK(specific_type.get_id() == type.get_id());
{
bool match_called = false;
CHECK(type.match(meta::overloaded{
[&type, &match_called](meta::enum_type t){ CHECK(t == type); match_called = true; },
[](auto&&){}
}));
CHECK(match_called);
}
}
SUBCASE("function") {
@@ -133,6 +173,15 @@ TEST_CASE("meta/meta_types/any_type") {
const meta::function_type& specific_type = type.as_function();
REQUIRE(specific_type);
CHECK(specific_type.get_id() == type.get_id());
{
bool match_called = false;
CHECK(type.match(meta::overloaded{
[&type, &match_called](meta::function_type t){ CHECK(t == type); match_called = true; },
[](auto&&){}
}));
CHECK(match_called);
}
}
SUBCASE("member") {
@@ -151,6 +200,15 @@ TEST_CASE("meta/meta_types/any_type") {
const meta::member_type& specific_type = type.as_member();
REQUIRE(specific_type);
CHECK(specific_type.get_id() == type.get_id());
{
bool match_called = false;
CHECK(type.match(meta::overloaded{
[&type, &match_called](meta::member_type t){ CHECK(t == type); match_called = true; },
[](auto&&){}
}));
CHECK(match_called);
}
}
SUBCASE("method") {
@@ -169,6 +227,15 @@ TEST_CASE("meta/meta_types/any_type") {
const meta::method_type& specific_type = type.as_method();
REQUIRE(specific_type);
CHECK(specific_type.get_id() == type.get_id());
{
bool match_called = false;
CHECK(type.match(meta::overloaded{
[&type, &match_called](meta::method_type t){ CHECK(t == type); match_called = true; },
[](auto&&){}
}));
CHECK(match_called);
}
}
SUBCASE("nullptr") {
@@ -187,6 +254,15 @@ TEST_CASE("meta/meta_types/any_type") {
const meta::nullptr_type& specific_type = type.as_nullptr();
REQUIRE(specific_type);
CHECK(specific_type.get_id() == type.get_id());
{
bool match_called = false;
CHECK(type.match(meta::overloaded{
[&type, &match_called](meta::nullptr_type t){ CHECK(t == type); match_called = true; },
[](auto&&){}
}));
CHECK(match_called);
}
}
SUBCASE("number") {
@@ -205,6 +281,15 @@ TEST_CASE("meta/meta_types/any_type") {
const meta::number_type& specific_type = type.as_number();
REQUIRE(specific_type);
CHECK(specific_type.get_id() == type.get_id());
{
bool match_called = false;
CHECK(type.match(meta::overloaded{
[&type, &match_called](meta::number_type t){ CHECK(t == type); match_called = true; },
[](auto&&){}
}));
CHECK(match_called);
}
}
SUBCASE("pointer") {
@@ -223,6 +308,15 @@ TEST_CASE("meta/meta_types/any_type") {
const meta::pointer_type& specific_type = type.as_pointer();
REQUIRE(specific_type);
CHECK(specific_type.get_id() == type.get_id());
{
bool match_called = false;
CHECK(type.match(meta::overloaded{
[&type, &match_called](meta::pointer_type t){ CHECK(t == type); match_called = true; },
[](auto&&){}
}));
CHECK(match_called);
}
}
SUBCASE("reference") {
@@ -239,6 +333,15 @@ TEST_CASE("meta/meta_types/any_type") {
const meta::reference_type& specific_type = type.as_reference();
REQUIRE(specific_type);
CHECK(specific_type.get_id() == type.get_id());
{
bool match_called = false;
CHECK(type.match(meta::overloaded{
[&type, &match_called](meta::reference_type t){ CHECK(t == type); match_called = true; },
[](auto&&){}
}));
CHECK(match_called);
}
}
SUBCASE("void") {
@@ -255,6 +358,15 @@ TEST_CASE("meta/meta_types/any_type") {
const meta::void_type& specific_type = type.as_void();
REQUIRE(specific_type);
CHECK(specific_type.get_id() == type.get_id());
{
bool match_called = false;
CHECK(type.match(meta::overloaded{
[&type, &match_called](meta::void_type t){ CHECK(t == type); match_called = true; },
[](auto&&){}
}));
CHECK(match_called);
}
}
SUBCASE("is/as") {

View File

@@ -38,6 +38,8 @@ namespace meta_hpp
using detail::hashed_string;
using detail::memory_buffer;
using detail::overloaded;
using detail::select_const;
using detail::select_non_const;
using detail::select_overload;

View File

@@ -157,6 +157,9 @@ namespace meta_hpp
template < type_family Type >
[[nodiscard]] Type as() const noexcept;
template < typename F >
bool match(F&& f) const;
[[nodiscard]] bool is_array() const noexcept;
[[nodiscard]] bool is_class() const noexcept;
[[nodiscard]] bool is_constructor() const noexcept;

View File

@@ -38,6 +38,58 @@ namespace meta_hpp
}
}
template < typename F >
bool any_type::match(F&& f) const {
if ( !is_valid() ) {
return false;
}
switch ( get_kind() ) {
case type_kind::array_:
std::invoke(std::forward<F>(f), as_array());
return true;
case type_kind::class_:
std::invoke(std::forward<F>(f), as_class());
return true;
case type_kind::constructor_:
std::invoke(std::forward<F>(f), as_constructor());
return true;
case type_kind::destructor_:
std::invoke(std::forward<F>(f), as_destructor());
return true;
case type_kind::enum_:
std::invoke(std::forward<F>(f), as_enum());
return true;
case type_kind::function_:
std::invoke(std::forward<F>(f), as_function());
return true;
case type_kind::member_:
std::invoke(std::forward<F>(f), as_member());
return true;
case type_kind::method_:
std::invoke(std::forward<F>(f), as_method());
return true;
case type_kind::nullptr_:
std::invoke(std::forward<F>(f), as_nullptr());
return true;
case type_kind::number_:
std::invoke(std::forward<F>(f), as_number());
return true;
case type_kind::pointer_:
std::invoke(std::forward<F>(f), as_pointer());
return true;
case type_kind::reference_:
std::invoke(std::forward<F>(f), as_reference());
return true;
case type_kind::void_:
std::invoke(std::forward<F>(f), as_void());
return true;
}
META_HPP_ASSERT(false);
return false;
}
inline bool any_type::is_array() const noexcept {
return is<array_type>();
}