From 43bcc14c1a3139ca912fd9b834f283ed9a4a10af Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 20 Jan 2023 17:55:24 +0700 Subject: [PATCH] types with type_id compare operators --- develop/singles/headers/meta.hpp/meta_all.hpp | 59 ++++- develop/untests/meta_types/ops_tests.cpp | 203 ++++++++++++++++++ headers/meta.hpp/meta_binds/class_bind.hpp | 5 +- .../meta.hpp/meta_detail/state_registry.hpp | 4 +- .../meta.hpp/meta_detail/type_registry.hpp | 17 +- headers/meta.hpp/meta_types.hpp | 33 +++ 6 files changed, 301 insertions(+), 20 deletions(-) create mode 100644 develop/untests/meta_types/ops_tests.cpp diff --git a/develop/singles/headers/meta.hpp/meta_all.hpp b/develop/singles/headers/meta.hpp/meta_all.hpp index 4e5a019..9357235 100644 --- a/develop/singles/headers/meta.hpp/meta_all.hpp +++ b/develop/singles/headers/meta.hpp/meta_all.hpp @@ -2121,6 +2121,39 @@ namespace meta_hpp } } +namespace meta_hpp +{ + template < detail::type_family T > + [[nodiscard]] bool operator<(const T& l, type_id r) noexcept { + return !static_cast(l) || l.get_id() < r; + } + + template < detail::type_family U > + [[nodiscard]] bool operator<(type_id l, const U& r) noexcept { + return static_cast(r) && l < r.get_id(); + } + + template < detail::type_family T > + [[nodiscard]] bool operator==(const T& l, type_id r) noexcept { + return static_cast(l) || l.get_id() == r; + } + + template < detail::type_family U > + [[nodiscard]] bool operator==(type_id l, const U& r) noexcept { + return static_cast(r) && l == r.get_id(); + } + + template < detail::type_family T > + [[nodiscard]] bool operator!=(const T& l, type_id r) noexcept { + return !(l == r); + } + + template < detail::type_family U > + [[nodiscard]] bool operator!=(type_id l, const U& r) noexcept { + return !(l == r); + } +} + namespace meta_hpp::detail { struct type_data_base { @@ -3264,7 +3297,7 @@ namespace meta_hpp::detail [[nodiscard]] scope get_scope_by_name(std::string_view name) const noexcept { const locker lock; - if ( auto iter = scopes_.find(name); iter != scopes_.end() ) { + if ( auto iter{scopes_.find(name)}; iter != scopes_.end() ) { return iter->second; } @@ -3274,7 +3307,7 @@ namespace meta_hpp::detail [[nodiscard]] scope resolve_scope(std::string_view name) { const locker lock; - if ( auto iter = scopes_.find(name); iter != scopes_.end() ) { + if ( auto iter{scopes_.find(name)}; iter != scopes_.end() ) { return iter->second; } @@ -3318,8 +3351,8 @@ namespace meta_hpp::detail [[nodiscard]] any_type get_type_by_id(type_id id) const noexcept { const locker lock; - if ( auto iter = type_by_id_.find(id); iter != type_by_id_.end() ) { - return iter->second; + if ( auto iter{type_by_id_.find(id)}; iter != type_by_id_.end() ) { + return *iter; } return any_type{}; @@ -3328,7 +3361,7 @@ namespace meta_hpp::detail [[nodiscard]] any_type get_type_by_rtti(const std::type_index& index) const noexcept { const locker lock; - if ( auto iter = type_by_rtti_.find(index); iter != type_by_rtti_.end() ) { + if ( auto iter{type_by_rtti_.find(index)}; iter != type_by_rtti_.end() ) { return iter->second; } @@ -3504,12 +3537,17 @@ namespace meta_hpp::detail static std::once_flag init_flag{}; std::call_once(init_flag, [this, &type_data](){ const locker lock; - type_by_id_.emplace(type_data.id, any_type{&type_data}); + + auto&& [position, emplaced] = type_by_id_.emplace(any_type{&type_data}); + if ( !emplaced ) { + return; + } + #if !defined(META_HPP_NO_RTTI) META_HPP_TRY { type_by_rtti_.emplace(typeid(Type), any_type{&type_data}); } META_HPP_CATCH(...) { - type_by_id_.erase(type_data.id); + type_by_id_.erase(position); META_HPP_RETHROW(); } #endif @@ -3517,7 +3555,7 @@ namespace meta_hpp::detail } private: std::recursive_mutex mutex_; - std::map> type_by_id_; + std::set> type_by_id_; #if !defined(META_HPP_NO_RTTI) std::map> type_by_rtti_; #endif @@ -4092,7 +4130,8 @@ namespace meta_hpp ([this](std::in_place_type_t) { const class_type& base_type = resolve_type(); - if ( auto&& [_, emplaced] = get_data().bases.emplace(base_type); !emplaced ) { + auto&& [position, emplaced] = get_data().bases.emplace(base_type); + if ( !emplaced ) { return; } @@ -4103,7 +4142,7 @@ namespace meta_hpp } }); } META_HPP_CATCH(...) { - get_data().bases.erase(base_type); + get_data().bases.erase(position); META_HPP_RETHROW(); } }(std::in_place_type), ...); diff --git a/develop/untests/meta_types/ops_tests.cpp b/develop/untests/meta_types/ops_tests.cpp new file mode 100644 index 0000000..1ec9f37 --- /dev/null +++ b/develop/untests/meta_types/ops_tests.cpp @@ -0,0 +1,203 @@ +/******************************************************************************* + * 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_untests.hpp" + +namespace +{ + +} + +TEST_CASE("meta/meta_types/ops") { + namespace meta = meta_hpp; + + SUBCASE("operator<") { + // NOLINTBEGIN(*-redundant-expression) + static_assert(std::is_same_v() < std::declval())>); + static_assert(std::is_same_v() < std::declval())>); + static_assert(std::is_same_v() < std::declval())>); + static_assert(std::is_same_v() < std::declval())>); + static_assert(std::is_same_v() < std::declval())>); + static_assert(std::is_same_v() < std::declval())>); + static_assert(std::is_same_v() < std::declval())>); + static_assert(std::is_same_v() < std::declval())>); + static_assert(std::is_same_v() < std::declval())>); + static_assert(std::is_same_v() < std::declval())>); + static_assert(std::is_same_v() < std::declval())>); + static_assert(std::is_same_v() < std::declval())>); + static_assert(std::is_same_v() < std::declval())>); + static_assert(std::is_same_v() < std::declval())>); + + static_assert(std::is_same_v() < std::declval())>); + static_assert(std::is_same_v() < std::declval())>); + static_assert(std::is_same_v() < std::declval())>); + static_assert(std::is_same_v() < std::declval())>); + static_assert(std::is_same_v() < std::declval())>); + static_assert(std::is_same_v() < std::declval())>); + static_assert(std::is_same_v() < std::declval())>); + static_assert(std::is_same_v() < std::declval())>); + static_assert(std::is_same_v() < std::declval())>); + static_assert(std::is_same_v() < std::declval())>); + static_assert(std::is_same_v() < std::declval())>); + static_assert(std::is_same_v() < std::declval())>); + static_assert(std::is_same_v() < std::declval())>); + static_assert(std::is_same_v() < std::declval())>); + static_assert(std::is_same_v() < std::declval())>); + static_assert(std::is_same_v() < std::declval())>); + static_assert(std::is_same_v() < std::declval())>); + static_assert(std::is_same_v() < std::declval())>); + static_assert(std::is_same_v() < std::declval())>); + + static_assert(std::is_same_v() < std::declval())>); + static_assert(std::is_same_v() < std::declval())>); + static_assert(std::is_same_v() < std::declval())>); + static_assert(std::is_same_v() < std::declval())>); + static_assert(std::is_same_v() < std::declval())>); + static_assert(std::is_same_v() < std::declval())>); + static_assert(std::is_same_v() < std::declval())>); + static_assert(std::is_same_v() < std::declval())>); + static_assert(std::is_same_v() < std::declval())>); + static_assert(std::is_same_v() < std::declval())>); + static_assert(std::is_same_v() < std::declval())>); + static_assert(std::is_same_v() < std::declval())>); + static_assert(std::is_same_v() < std::declval())>); + static_assert(std::is_same_v() < std::declval())>); + static_assert(std::is_same_v() < std::declval())>); + static_assert(std::is_same_v() < std::declval())>); + static_assert(std::is_same_v() < std::declval())>); + static_assert(std::is_same_v() < std::declval())>); + static_assert(std::is_same_v() < std::declval())>); + // NOLINTEND(*-redundant-expression) + } + + SUBCASE("operator==") { + // NOLINTBEGIN(*-redundant-expression) + static_assert(std::is_same_v() == std::declval())>); + static_assert(std::is_same_v() == std::declval())>); + static_assert(std::is_same_v() == std::declval())>); + static_assert(std::is_same_v() == std::declval())>); + static_assert(std::is_same_v() == std::declval())>); + static_assert(std::is_same_v() == std::declval())>); + static_assert(std::is_same_v() == std::declval())>); + static_assert(std::is_same_v() == std::declval())>); + static_assert(std::is_same_v() == std::declval())>); + static_assert(std::is_same_v() == std::declval())>); + static_assert(std::is_same_v() == std::declval())>); + static_assert(std::is_same_v() == std::declval())>); + static_assert(std::is_same_v() == std::declval())>); + static_assert(std::is_same_v() == std::declval())>); + static_assert(std::is_same_v() == std::declval())>); + static_assert(std::is_same_v() == std::declval())>); + static_assert(std::is_same_v() == std::declval())>); + static_assert(std::is_same_v() == std::declval())>); + static_assert(std::is_same_v() == std::declval())>); + + static_assert(std::is_same_v() == std::declval())>); + static_assert(std::is_same_v() == std::declval())>); + static_assert(std::is_same_v() == std::declval())>); + static_assert(std::is_same_v() == std::declval())>); + static_assert(std::is_same_v() == std::declval())>); + static_assert(std::is_same_v() == std::declval())>); + static_assert(std::is_same_v() == std::declval())>); + static_assert(std::is_same_v() == std::declval())>); + static_assert(std::is_same_v() == std::declval())>); + static_assert(std::is_same_v() == std::declval())>); + static_assert(std::is_same_v() == std::declval())>); + static_assert(std::is_same_v() == std::declval())>); + static_assert(std::is_same_v() == std::declval())>); + static_assert(std::is_same_v() == std::declval())>); + static_assert(std::is_same_v() == std::declval())>); + static_assert(std::is_same_v() == std::declval())>); + static_assert(std::is_same_v() == std::declval())>); + static_assert(std::is_same_v() == std::declval())>); + static_assert(std::is_same_v() == std::declval())>); + + static_assert(std::is_same_v() == std::declval())>); + static_assert(std::is_same_v() == std::declval())>); + static_assert(std::is_same_v() == std::declval())>); + static_assert(std::is_same_v() == std::declval())>); + static_assert(std::is_same_v() == std::declval())>); + static_assert(std::is_same_v() == std::declval())>); + static_assert(std::is_same_v() == std::declval())>); + static_assert(std::is_same_v() == std::declval())>); + static_assert(std::is_same_v() == std::declval())>); + static_assert(std::is_same_v() == std::declval())>); + static_assert(std::is_same_v() == std::declval())>); + static_assert(std::is_same_v() == std::declval())>); + static_assert(std::is_same_v() == std::declval())>); + static_assert(std::is_same_v() == std::declval())>); + static_assert(std::is_same_v() == std::declval())>); + static_assert(std::is_same_v() == std::declval())>); + static_assert(std::is_same_v() == std::declval())>); + static_assert(std::is_same_v() == std::declval())>); + static_assert(std::is_same_v() == std::declval())>); + // NOLINTEND(*-redundant-expression) + } + + SUBCASE("operator!=") { + // NOLINTBEGIN(*-redundant-expression) + static_assert(std::is_same_v() != std::declval())>); + static_assert(std::is_same_v() != std::declval())>); + static_assert(std::is_same_v() != std::declval())>); + static_assert(std::is_same_v() != std::declval())>); + static_assert(std::is_same_v() != std::declval())>); + static_assert(std::is_same_v() != std::declval())>); + static_assert(std::is_same_v() != std::declval())>); + static_assert(std::is_same_v() != std::declval())>); + static_assert(std::is_same_v() != std::declval())>); + static_assert(std::is_same_v() != std::declval())>); + static_assert(std::is_same_v() != std::declval())>); + static_assert(std::is_same_v() != std::declval())>); + static_assert(std::is_same_v() != std::declval())>); + static_assert(std::is_same_v() != std::declval())>); + static_assert(std::is_same_v() != std::declval())>); + static_assert(std::is_same_v() != std::declval())>); + static_assert(std::is_same_v() != std::declval())>); + static_assert(std::is_same_v() != std::declval())>); + static_assert(std::is_same_v() != std::declval())>); + + static_assert(std::is_same_v() != std::declval())>); + static_assert(std::is_same_v() != std::declval())>); + static_assert(std::is_same_v() != std::declval())>); + static_assert(std::is_same_v() != std::declval())>); + static_assert(std::is_same_v() != std::declval())>); + static_assert(std::is_same_v() != std::declval())>); + static_assert(std::is_same_v() != std::declval())>); + static_assert(std::is_same_v() != std::declval())>); + static_assert(std::is_same_v() != std::declval())>); + static_assert(std::is_same_v() != std::declval())>); + static_assert(std::is_same_v() != std::declval())>); + static_assert(std::is_same_v() != std::declval())>); + static_assert(std::is_same_v() != std::declval())>); + static_assert(std::is_same_v() != std::declval())>); + static_assert(std::is_same_v() != std::declval())>); + static_assert(std::is_same_v() != std::declval())>); + static_assert(std::is_same_v() != std::declval())>); + static_assert(std::is_same_v() != std::declval())>); + static_assert(std::is_same_v() != std::declval())>); + + static_assert(std::is_same_v() != std::declval())>); + static_assert(std::is_same_v() != std::declval())>); + static_assert(std::is_same_v() != std::declval())>); + static_assert(std::is_same_v() != std::declval())>); + static_assert(std::is_same_v() != std::declval())>); + static_assert(std::is_same_v() != std::declval())>); + static_assert(std::is_same_v() != std::declval())>); + static_assert(std::is_same_v() != std::declval())>); + static_assert(std::is_same_v() != std::declval())>); + static_assert(std::is_same_v() != std::declval())>); + static_assert(std::is_same_v() != std::declval())>); + static_assert(std::is_same_v() != std::declval())>); + static_assert(std::is_same_v() != std::declval())>); + static_assert(std::is_same_v() != std::declval())>); + static_assert(std::is_same_v() != std::declval())>); + static_assert(std::is_same_v() != std::declval())>); + static_assert(std::is_same_v() != std::declval())>); + static_assert(std::is_same_v() != std::declval())>); + static_assert(std::is_same_v() != std::declval())>); + // NOLINTEND(*-redundant-expression) + } +} diff --git a/headers/meta.hpp/meta_binds/class_bind.hpp b/headers/meta.hpp/meta_binds/class_bind.hpp index d8b3434..3965da0 100644 --- a/headers/meta.hpp/meta_binds/class_bind.hpp +++ b/headers/meta.hpp/meta_binds/class_bind.hpp @@ -32,7 +32,8 @@ namespace meta_hpp ([this](std::in_place_type_t) { const class_type& base_type = resolve_type(); - if ( auto&& [_, emplaced] = get_data().bases.emplace(base_type); !emplaced ) { + auto&& [position, emplaced] = get_data().bases.emplace(base_type); + if ( !emplaced ) { return; } @@ -43,7 +44,7 @@ namespace meta_hpp } }); } META_HPP_CATCH(...) { - get_data().bases.erase(base_type); + get_data().bases.erase(position); META_HPP_RETHROW(); } }(std::in_place_type), ...); diff --git a/headers/meta.hpp/meta_detail/state_registry.hpp b/headers/meta.hpp/meta_detail/state_registry.hpp index c6cae37..1e60238 100644 --- a/headers/meta.hpp/meta_detail/state_registry.hpp +++ b/headers/meta.hpp/meta_detail/state_registry.hpp @@ -35,7 +35,7 @@ namespace meta_hpp::detail [[nodiscard]] scope get_scope_by_name(std::string_view name) const noexcept { const locker lock; - if ( auto iter = scopes_.find(name); iter != scopes_.end() ) { + if ( auto iter{scopes_.find(name)}; iter != scopes_.end() ) { return iter->second; } @@ -45,7 +45,7 @@ namespace meta_hpp::detail [[nodiscard]] scope resolve_scope(std::string_view name) { const locker lock; - if ( auto iter = scopes_.find(name); iter != scopes_.end() ) { + if ( auto iter{scopes_.find(name)}; iter != scopes_.end() ) { return iter->second; } diff --git a/headers/meta.hpp/meta_detail/type_registry.hpp b/headers/meta.hpp/meta_detail/type_registry.hpp index 67b1c88..af0f4e0 100644 --- a/headers/meta.hpp/meta_detail/type_registry.hpp +++ b/headers/meta.hpp/meta_detail/type_registry.hpp @@ -35,8 +35,8 @@ namespace meta_hpp::detail [[nodiscard]] any_type get_type_by_id(type_id id) const noexcept { const locker lock; - if ( auto iter = type_by_id_.find(id); iter != type_by_id_.end() ) { - return iter->second; + if ( auto iter{type_by_id_.find(id)}; iter != type_by_id_.end() ) { + return *iter; } return any_type{}; @@ -45,7 +45,7 @@ namespace meta_hpp::detail [[nodiscard]] any_type get_type_by_rtti(const std::type_index& index) const noexcept { const locker lock; - if ( auto iter = type_by_rtti_.find(index); iter != type_by_rtti_.end() ) { + if ( auto iter{type_by_rtti_.find(index)}; iter != type_by_rtti_.end() ) { return iter->second; } @@ -221,12 +221,17 @@ namespace meta_hpp::detail static std::once_flag init_flag{}; std::call_once(init_flag, [this, &type_data](){ const locker lock; - type_by_id_.emplace(type_data.id, any_type{&type_data}); + + auto&& [position, emplaced] = type_by_id_.emplace(any_type{&type_data}); + if ( !emplaced ) { + return; + } + #if !defined(META_HPP_NO_RTTI) META_HPP_TRY { type_by_rtti_.emplace(typeid(Type), any_type{&type_data}); } META_HPP_CATCH(...) { - type_by_id_.erase(type_data.id); + type_by_id_.erase(position); META_HPP_RETHROW(); } #endif @@ -234,7 +239,7 @@ namespace meta_hpp::detail } private: std::recursive_mutex mutex_; - std::map> type_by_id_; + std::set> type_by_id_; #if !defined(META_HPP_NO_RTTI) std::map> type_by_rtti_; #endif diff --git a/headers/meta.hpp/meta_types.hpp b/headers/meta.hpp/meta_types.hpp index 6a708d7..2956028 100644 --- a/headers/meta.hpp/meta_types.hpp +++ b/headers/meta.hpp/meta_types.hpp @@ -503,6 +503,39 @@ namespace meta_hpp } } +namespace meta_hpp +{ + template < detail::type_family T > + [[nodiscard]] bool operator<(const T& l, type_id r) noexcept { + return !static_cast(l) || l.get_id() < r; + } + + template < detail::type_family U > + [[nodiscard]] bool operator<(type_id l, const U& r) noexcept { + return static_cast(r) && l < r.get_id(); + } + + template < detail::type_family T > + [[nodiscard]] bool operator==(const T& l, type_id r) noexcept { + return static_cast(l) || l.get_id() == r; + } + + template < detail::type_family U > + [[nodiscard]] bool operator==(type_id l, const U& r) noexcept { + return static_cast(r) && l == r.get_id(); + } + + template < detail::type_family T > + [[nodiscard]] bool operator!=(const T& l, type_id r) noexcept { + return !(l == r); + } + + template < detail::type_family U > + [[nodiscard]] bool operator!=(type_id l, const U& r) noexcept { + return !(l == r); + } +} + namespace meta_hpp::detail { struct type_data_base {