mirror of
https://github.com/BlackMATov/meta.hpp.git
synced 2025-12-13 19:18:01 +07:00
any_type::match function
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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>();
|
||||
}
|
||||
|
||||
@@ -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") {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user