mirror of
https://github.com/BlackMATov/meta.hpp.git
synced 2025-12-16 14:09:02 +07:00
for_each_type for specific kind of types
This commit is contained in:
@@ -17,7 +17,6 @@
|
|||||||
- `try_invoke`/`is_invocable` should return error codes
|
- `try_invoke`/`is_invocable` should return error codes
|
||||||
- conan package config
|
- conan package config
|
||||||
- test and support shared libraries
|
- test and support shared libraries
|
||||||
- add `for_each_type` for specific kind of types
|
|
||||||
|
|
||||||
## Thoughts
|
## Thoughts
|
||||||
|
|
||||||
|
|||||||
@@ -2556,6 +2556,7 @@ namespace meta_hpp
|
|||||||
|
|
||||||
template < detail::type_family Type >
|
template < detail::type_family Type >
|
||||||
[[nodiscard]] bool is() const noexcept;
|
[[nodiscard]] bool is() const noexcept;
|
||||||
|
[[nodiscard]] bool is(type_kind kind) const noexcept;
|
||||||
|
|
||||||
template < detail::type_family Type >
|
template < detail::type_family Type >
|
||||||
[[nodiscard]] Type as() const noexcept;
|
[[nodiscard]] Type as() const noexcept;
|
||||||
@@ -4395,11 +4396,15 @@ namespace meta_hpp::detail
|
|||||||
|
|
||||||
namespace meta_hpp
|
namespace meta_hpp
|
||||||
{
|
{
|
||||||
template < typename F >
|
template < detail::type_family Type = any_type, typename F >
|
||||||
void for_each_type(F&& f) {
|
void for_each_type(F&& f) {
|
||||||
using namespace detail;
|
using namespace detail;
|
||||||
type_registry& registry = type_registry::instance();
|
type_registry& registry = type_registry::instance();
|
||||||
registry.for_each_type(std::forward<F>(f));
|
registry.for_each_type([&f](const any_type& type) {
|
||||||
|
if ( type.is<Type>() ) {
|
||||||
|
std::invoke(f, type.as<Type>());
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
@@ -8766,11 +8771,14 @@ namespace meta_hpp
|
|||||||
if constexpr ( std::is_same_v<Type, any_type> ) {
|
if constexpr ( std::is_same_v<Type, any_type> ) {
|
||||||
return data_ != nullptr;
|
return data_ != nullptr;
|
||||||
} else {
|
} else {
|
||||||
constexpr type_kind is_kind{detail::type_traits<Type>::kind};
|
return is(detail::type_traits<Type>::kind);
|
||||||
return data_ != nullptr && data_->kind == is_kind;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] inline bool any_type::is(type_kind kind) const noexcept {
|
||||||
|
return data_ != nullptr && data_->kind == kind;
|
||||||
|
}
|
||||||
|
|
||||||
template < detail::type_family Type >
|
template < detail::type_family Type >
|
||||||
Type any_type::as() const noexcept {
|
Type any_type::as() const noexcept {
|
||||||
if constexpr ( std::is_same_v<Type, any_type> ) {
|
if constexpr ( std::is_same_v<Type, any_type> ) {
|
||||||
|
|||||||
46
develop/untests/meta_features/for_each_type_tests.cpp
Normal file
46
develop/untests/meta_features/for_each_type_tests.cpp
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* 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
|
||||||
|
{
|
||||||
|
class A{};
|
||||||
|
class B{};
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("meta/meta_features/for_each_type") {
|
||||||
|
namespace meta = meta_hpp;
|
||||||
|
|
||||||
|
SUBCASE("any_type") {
|
||||||
|
std::set<meta_hpp::any_type> all_types;
|
||||||
|
meta::for_each_type([&all_types](const meta::any_type& type){
|
||||||
|
all_types.insert(type);
|
||||||
|
});
|
||||||
|
CHECK_FALSE(all_types.contains(meta::resolve_type<A>()));
|
||||||
|
|
||||||
|
meta::for_each_type([&all_types](const meta::any_type& type){
|
||||||
|
all_types.insert(type);
|
||||||
|
});
|
||||||
|
CHECK(all_types.contains(meta::resolve_type<A>()));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
SUBCASE("specific_type") {
|
||||||
|
std::set<meta_hpp::array_type> all_types;
|
||||||
|
|
||||||
|
meta::for_each_type<meta::array_type>([&all_types](const meta::array_type& type){
|
||||||
|
all_types.insert(type);
|
||||||
|
});
|
||||||
|
CHECK_FALSE(all_types.contains(meta::resolve_type<A[]>()));
|
||||||
|
|
||||||
|
meta::for_each_type<meta::array_type>([&all_types](const meta::array_type& type){
|
||||||
|
all_types.insert(type);
|
||||||
|
});
|
||||||
|
CHECK(all_types.contains(meta::resolve_type<A[]>()));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,11 +16,15 @@
|
|||||||
|
|
||||||
namespace meta_hpp
|
namespace meta_hpp
|
||||||
{
|
{
|
||||||
template < typename F >
|
template < detail::type_family Type = any_type, typename F >
|
||||||
void for_each_type(F&& f) {
|
void for_each_type(F&& f) {
|
||||||
using namespace detail;
|
using namespace detail;
|
||||||
type_registry& registry = type_registry::instance();
|
type_registry& registry = type_registry::instance();
|
||||||
registry.for_each_type(std::forward<F>(f));
|
registry.for_each_type([&f](const any_type& type) {
|
||||||
|
if ( type.is<Type>() ) {
|
||||||
|
std::invoke(f, type.as<Type>());
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
|
|||||||
@@ -151,6 +151,7 @@ namespace meta_hpp
|
|||||||
|
|
||||||
template < detail::type_family Type >
|
template < detail::type_family Type >
|
||||||
[[nodiscard]] bool is() const noexcept;
|
[[nodiscard]] bool is() const noexcept;
|
||||||
|
[[nodiscard]] bool is(type_kind kind) const noexcept;
|
||||||
|
|
||||||
template < detail::type_family Type >
|
template < detail::type_family Type >
|
||||||
[[nodiscard]] Type as() const noexcept;
|
[[nodiscard]] Type as() const noexcept;
|
||||||
|
|||||||
@@ -20,11 +20,14 @@ namespace meta_hpp
|
|||||||
if constexpr ( std::is_same_v<Type, any_type> ) {
|
if constexpr ( std::is_same_v<Type, any_type> ) {
|
||||||
return data_ != nullptr;
|
return data_ != nullptr;
|
||||||
} else {
|
} else {
|
||||||
constexpr type_kind is_kind{detail::type_traits<Type>::kind};
|
return is(detail::type_traits<Type>::kind);
|
||||||
return data_ != nullptr && data_->kind == is_kind;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] inline bool any_type::is(type_kind kind) const noexcept {
|
||||||
|
return data_ != nullptr && data_->kind == kind;
|
||||||
|
}
|
||||||
|
|
||||||
template < detail::type_family Type >
|
template < detail::type_family Type >
|
||||||
Type any_type::as() const noexcept {
|
Type any_type::as() const noexcept {
|
||||||
if constexpr ( std::is_same_v<Type, any_type> ) {
|
if constexpr ( std::is_same_v<Type, any_type> ) {
|
||||||
|
|||||||
Reference in New Issue
Block a user