From 9ab065b8f3ad83d90ad2d173ff106237cae9b9fc Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Tue, 14 Mar 2023 16:28:05 +0700 Subject: [PATCH 1/2] for_each_type for specific kind of types --- ROADMAP.md | 1 - develop/singles/headers/meta.hpp/meta_all.hpp | 16 +++++-- .../meta_features/for_each_type_tests.cpp | 46 +++++++++++++++++++ headers/meta.hpp/meta_registry.hpp | 8 +++- headers/meta.hpp/meta_types.hpp | 1 + headers/meta.hpp/meta_types/any_type.hpp | 7 ++- 6 files changed, 70 insertions(+), 9 deletions(-) create mode 100644 develop/untests/meta_features/for_each_type_tests.cpp diff --git a/ROADMAP.md b/ROADMAP.md index 747762f..fb1ed31 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -17,7 +17,6 @@ - `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 diff --git a/develop/singles/headers/meta.hpp/meta_all.hpp b/develop/singles/headers/meta.hpp/meta_all.hpp index 6a105cc..bd60bc9 100644 --- a/develop/singles/headers/meta.hpp/meta_all.hpp +++ b/develop/singles/headers/meta.hpp/meta_all.hpp @@ -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)); + registry.for_each_type([&f](const any_type& type) { + if ( type.is() ) { + std::invoke(f, type.as()); + } + }); } template < typename T > @@ -8766,11 +8771,14 @@ namespace meta_hpp if constexpr ( std::is_same_v ) { return data_ != nullptr; } else { - constexpr type_kind is_kind{detail::type_traits::kind}; - return data_ != nullptr && data_->kind == is_kind; + return is(detail::type_traits::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 ) { diff --git a/develop/untests/meta_features/for_each_type_tests.cpp b/develop/untests/meta_features/for_each_type_tests.cpp new file mode 100644 index 0000000..5e62bbd --- /dev/null +++ b/develop/untests/meta_features/for_each_type_tests.cpp @@ -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 +#include + +namespace +{ + class A{}; + class B{}; +} + +TEST_CASE("meta/meta_features/for_each_type") { + namespace meta = meta_hpp; + + SUBCASE("any_type") { + std::set 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())); + + meta::for_each_type([&all_types](const meta::any_type& type){ + all_types.insert(type); + }); + CHECK(all_types.contains(meta::resolve_type())); + + } + + SUBCASE("specific_type") { + std::set all_types; + + meta::for_each_type([&all_types](const meta::array_type& type){ + all_types.insert(type); + }); + CHECK_FALSE(all_types.contains(meta::resolve_type())); + + meta::for_each_type([&all_types](const meta::array_type& type){ + all_types.insert(type); + }); + CHECK(all_types.contains(meta::resolve_type())); + } +} diff --git a/headers/meta.hpp/meta_registry.hpp b/headers/meta.hpp/meta_registry.hpp index 62a7ac3..05f62b6 100644 --- a/headers/meta.hpp/meta_registry.hpp +++ b/headers/meta.hpp/meta_registry.hpp @@ -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)); + registry.for_each_type([&f](const any_type& type) { + if ( type.is() ) { + std::invoke(f, type.as()); + } + }); } template < typename T > diff --git a/headers/meta.hpp/meta_types.hpp b/headers/meta.hpp/meta_types.hpp index bf40c54..55bb8ad 100644 --- a/headers/meta.hpp/meta_types.hpp +++ b/headers/meta.hpp/meta_types.hpp @@ -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; diff --git a/headers/meta.hpp/meta_types/any_type.hpp b/headers/meta.hpp/meta_types/any_type.hpp index bd0c252..c5aed8a 100644 --- a/headers/meta.hpp/meta_types/any_type.hpp +++ b/headers/meta.hpp/meta_types/any_type.hpp @@ -20,11 +20,14 @@ namespace meta_hpp if constexpr ( std::is_same_v ) { return data_ != nullptr; } else { - constexpr type_kind is_kind{detail::type_traits::kind}; - return data_ != nullptr && data_->kind == is_kind; + return is(detail::type_traits::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 ) { From 0688faa825d304c7a4366eff24a90dbf876a469e Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Wed, 15 Mar 2023 00:33:28 +0700 Subject: [PATCH 2/2] add conditions to compiler specific flags --- ROADMAP.md | 18 +++++++++++------- develop/cmake/DisableExceptions.cmake | 3 ++- develop/cmake/DisableRTTI.cmake | 3 ++- develop/cmake/EnableASan.cmake | 18 ++++++++++-------- develop/cmake/EnableGCov.cmake | 6 ++++-- develop/cmake/EnableUBSan.cmake | 10 ++++++---- 6 files changed, 35 insertions(+), 23 deletions(-) diff --git a/ROADMAP.md b/ROADMAP.md index fb1ed31..9456ccd 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -2,20 +2,13 @@ ## 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 ## Thoughts @@ -23,3 +16,14 @@ - 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) diff --git a/develop/cmake/DisableExceptions.cmake b/develop/cmake/DisableExceptions.cmake index a61354a..615e2b4 100644 --- a/develop/cmake/DisableExceptions.cmake +++ b/develop/cmake/DisableExceptions.cmake @@ -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) + $<$,$>: + -fno-exceptions>) diff --git a/develop/cmake/DisableRTTI.cmake b/develop/cmake/DisableRTTI.cmake index 1bdcecf..e87a9a2 100644 --- a/develop/cmake/DisableRTTI.cmake +++ b/develop/cmake/DisableRTTI.cmake @@ -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) + $<$,$>: + -fno-rtti>) diff --git a/develop/cmake/EnableASan.cmake b/develop/cmake/EnableASan.cmake index 1af49c9..4540388 100644 --- a/develop/cmake/EnableASan.cmake +++ b/develop/cmake/EnableASan.cmake @@ -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) + $<$,$>: + -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) + $<$,$>: + -fsanitize=address + -fno-omit-frame-pointer + -fsanitize-address-use-after-scope + -fsanitize-address-use-after-return=always>) diff --git a/develop/cmake/EnableGCov.cmake b/develop/cmake/EnableGCov.cmake index e98ea88..26bd865 100644 --- a/develop/cmake/EnableGCov.cmake +++ b/develop/cmake/EnableGCov.cmake @@ -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) + $<$,$>: + --coverage>) target_link_options(${PROJECT_NAME}.enable_gcov INTERFACE - --coverage) + $<$,$>: + --coverage>) diff --git a/develop/cmake/EnableUBSan.cmake b/develop/cmake/EnableUBSan.cmake index 358b14d..d1a0ec2 100644 --- a/develop/cmake/EnableUBSan.cmake +++ b/develop/cmake/EnableUBSan.cmake @@ -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) + $<$,$>: + -fsanitize=undefined + -fno-omit-frame-pointer>) target_link_options(${PROJECT_NAME}.enable_ubsan INTERFACE - -fsanitize=undefined - -fno-omit-frame-pointer) + $<$,$>: + -fsanitize=undefined + -fno-omit-frame-pointer>)