mirror of
https://github.com/BlackMATov/meta.hpp.git
synced 2025-12-13 11:17:06 +07:00
19
ROADMAP.md
19
ROADMAP.md
@@ -2,25 +2,28 @@
|
||||
|
||||
## Backlog
|
||||
|
||||
- instance mapper
|
||||
- type conversions
|
||||
- dynamic binds listener
|
||||
- static binds listener
|
||||
- dynamic type visitor
|
||||
- type names by [nameof](https://github.com/Neargye/nameof)
|
||||
- non-linear search of methods/functions/...
|
||||
- register base types by `META_HPP_ENABLE_POLY_INFO`
|
||||
- distinguish between function types and function pointer types
|
||||
- add the library version to sources
|
||||
- fix all includes to work with the library more flexible
|
||||
- build and test on CI with additional flags like no-exception and no-rtti
|
||||
- `try_invoke`/`is_invocable` should return error codes
|
||||
- conan package config
|
||||
- test and support shared libraries
|
||||
- add `for_each_type` for specific kind of types
|
||||
|
||||
## Thoughts
|
||||
|
||||
- should `uvalue` dereference operators return `reference_wrapper`?
|
||||
- `array_view`/`pointer_view` instead `unmap`/`operator[]`/`operator*`?
|
||||
- can we add move-only uvalue analog to return move-only values?
|
||||
|
||||
## Version 1.0
|
||||
|
||||
## Version 2.0
|
||||
|
||||
- instance mapper
|
||||
- dynamic binds listener
|
||||
- static binds listener
|
||||
- dynamic type visitor
|
||||
- conan package config
|
||||
- type names by [nameof](https://github.com/Neargye/nameof)
|
||||
|
||||
@@ -2,4 +2,5 @@ add_library(${PROJECT_NAME}.disable_exceptions INTERFACE)
|
||||
add_library(${PROJECT_NAME}::disable_exceptions ALIAS ${PROJECT_NAME}.disable_exceptions)
|
||||
|
||||
target_compile_options(${PROJECT_NAME}.disable_exceptions INTERFACE
|
||||
-fno-exceptions)
|
||||
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:
|
||||
-fno-exceptions>)
|
||||
|
||||
@@ -2,4 +2,5 @@ add_library(${PROJECT_NAME}.disable_rtti INTERFACE)
|
||||
add_library(${PROJECT_NAME}::disable_rtti ALIAS ${PROJECT_NAME}.disable_rtti)
|
||||
|
||||
target_compile_options(${PROJECT_NAME}.disable_rtti INTERFACE
|
||||
-fno-rtti)
|
||||
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:
|
||||
-fno-rtti>)
|
||||
|
||||
@@ -4,13 +4,15 @@ add_library(${PROJECT_NAME}.enable_asan INTERFACE)
|
||||
add_library(${PROJECT_NAME}::enable_asan ALIAS ${PROJECT_NAME}.enable_asan)
|
||||
|
||||
target_compile_options(${PROJECT_NAME}.enable_asan INTERFACE
|
||||
-fsanitize=address
|
||||
-fno-omit-frame-pointer
|
||||
-fsanitize-address-use-after-scope
|
||||
-fsanitize-address-use-after-return=always)
|
||||
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:
|
||||
-fsanitize=address
|
||||
-fno-omit-frame-pointer
|
||||
-fsanitize-address-use-after-scope
|
||||
-fsanitize-address-use-after-return=always>)
|
||||
|
||||
target_link_options(${PROJECT_NAME}.enable_asan INTERFACE
|
||||
-fsanitize=address
|
||||
-fno-omit-frame-pointer
|
||||
-fsanitize-address-use-after-scope
|
||||
-fsanitize-address-use-after-return=always)
|
||||
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:
|
||||
-fsanitize=address
|
||||
-fno-omit-frame-pointer
|
||||
-fsanitize-address-use-after-scope
|
||||
-fsanitize-address-use-after-return=always>)
|
||||
|
||||
@@ -4,7 +4,9 @@ add_library(${PROJECT_NAME}.enable_gcov INTERFACE)
|
||||
add_library(${PROJECT_NAME}::enable_gcov ALIAS ${PROJECT_NAME}.enable_gcov)
|
||||
|
||||
target_compile_options(${PROJECT_NAME}.enable_gcov INTERFACE
|
||||
--coverage)
|
||||
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:
|
||||
--coverage>)
|
||||
|
||||
target_link_options(${PROJECT_NAME}.enable_gcov INTERFACE
|
||||
--coverage)
|
||||
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:
|
||||
--coverage>)
|
||||
|
||||
@@ -4,9 +4,11 @@ add_library(${PROJECT_NAME}.enable_ubsan INTERFACE)
|
||||
add_library(${PROJECT_NAME}::enable_ubsan ALIAS ${PROJECT_NAME}.enable_ubsan)
|
||||
|
||||
target_compile_options(${PROJECT_NAME}.enable_ubsan INTERFACE
|
||||
-fsanitize=undefined
|
||||
-fno-omit-frame-pointer)
|
||||
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:
|
||||
-fsanitize=undefined
|
||||
-fno-omit-frame-pointer>)
|
||||
|
||||
target_link_options(${PROJECT_NAME}.enable_ubsan INTERFACE
|
||||
-fsanitize=undefined
|
||||
-fno-omit-frame-pointer)
|
||||
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:
|
||||
-fsanitize=undefined
|
||||
-fno-omit-frame-pointer>)
|
||||
|
||||
@@ -2556,6 +2556,7 @@ namespace meta_hpp
|
||||
|
||||
template < detail::type_family Type >
|
||||
[[nodiscard]] bool is() const noexcept;
|
||||
[[nodiscard]] bool is(type_kind kind) const noexcept;
|
||||
|
||||
template < detail::type_family Type >
|
||||
[[nodiscard]] Type as() const noexcept;
|
||||
@@ -4395,11 +4396,15 @@ namespace meta_hpp::detail
|
||||
|
||||
namespace meta_hpp
|
||||
{
|
||||
template < typename F >
|
||||
template < detail::type_family Type = any_type, typename F >
|
||||
void for_each_type(F&& f) {
|
||||
using namespace detail;
|
||||
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 >
|
||||
@@ -8766,11 +8771,14 @@ namespace meta_hpp
|
||||
if constexpr ( std::is_same_v<Type, any_type> ) {
|
||||
return data_ != nullptr;
|
||||
} else {
|
||||
constexpr type_kind is_kind{detail::type_traits<Type>::kind};
|
||||
return data_ != nullptr && data_->kind == is_kind;
|
||||
return is(detail::type_traits<Type>::kind);
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] inline bool any_type::is(type_kind kind) const noexcept {
|
||||
return data_ != nullptr && data_->kind == kind;
|
||||
}
|
||||
|
||||
template < detail::type_family Type >
|
||||
Type any_type::as() const noexcept {
|
||||
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
|
||||
{
|
||||
template < typename F >
|
||||
template < detail::type_family Type = any_type, typename F >
|
||||
void for_each_type(F&& f) {
|
||||
using namespace detail;
|
||||
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 >
|
||||
|
||||
@@ -151,6 +151,7 @@ namespace meta_hpp
|
||||
|
||||
template < detail::type_family Type >
|
||||
[[nodiscard]] bool is() const noexcept;
|
||||
[[nodiscard]] bool is(type_kind kind) const noexcept;
|
||||
|
||||
template < detail::type_family Type >
|
||||
[[nodiscard]] Type as() const noexcept;
|
||||
|
||||
@@ -20,11 +20,14 @@ namespace meta_hpp
|
||||
if constexpr ( std::is_same_v<Type, any_type> ) {
|
||||
return data_ != nullptr;
|
||||
} else {
|
||||
constexpr type_kind is_kind{detail::type_traits<Type>::kind};
|
||||
return data_ != nullptr && data_->kind == is_kind;
|
||||
return is(detail::type_traits<Type>::kind);
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] inline bool any_type::is(type_kind kind) const noexcept {
|
||||
return data_ != nullptr && data_->kind == kind;
|
||||
}
|
||||
|
||||
template < detail::type_family Type >
|
||||
Type any_type::as() const noexcept {
|
||||
if constexpr ( std::is_same_v<Type, any_type> ) {
|
||||
|
||||
Reference in New Issue
Block a user