From eaf84e4ba5a296f70a0fa474c7873205e27a03a6 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 13 Jan 2023 06:50:18 +0700 Subject: [PATCH] states with their indices compare operators --- develop/cmake/SetupTargets.cmake | 1 + develop/singles/headers/meta.hpp/meta_all.hpp | 71 +++++++++-- develop/untests/meta_states/ops_tests.cpp | 118 ++++++++++++++++++ headers/meta.hpp/meta_states.hpp | 71 +++++++++-- 4 files changed, 247 insertions(+), 14 deletions(-) create mode 100644 develop/untests/meta_states/ops_tests.cpp diff --git a/develop/cmake/SetupTargets.cmake b/develop/cmake/SetupTargets.cmake index f03d1e3..57af3fd 100644 --- a/develop/cmake/SetupTargets.cmake +++ b/develop/cmake/SetupTargets.cmake @@ -20,6 +20,7 @@ target_compile_options(${PROJECT_NAME}.setup_targets INTERFACE -Wno-unneeded-member-function -Wno-unused-macros -Wno-weak-vtables + -Wno-zero-as-null-pointer-constant >) if(BUILD_WITH_COVERAGE) diff --git a/develop/singles/headers/meta.hpp/meta_all.hpp b/develop/singles/headers/meta.hpp/meta_all.hpp index e62449a..81dd25f 100644 --- a/develop/singles/headers/meta.hpp/meta_all.hpp +++ b/develop/singles/headers/meta.hpp/meta_all.hpp @@ -2534,6 +2534,8 @@ namespace meta_hpp { class argument final { public: + using index_type = argument_index; + explicit argument() = default; explicit argument(detail::argument_state_ptr state) noexcept; argument& operator=(detail::argument_state_ptr state) noexcept; @@ -2555,8 +2557,10 @@ namespace meta_hpp class constructor final { public: + using index_type = constructor_index; + explicit constructor() = default; - explicit constructor(detail::constructor_state_ptr state) noexcept; + constructor(detail::constructor_state_ptr state) noexcept; constructor& operator=(detail::constructor_state_ptr state) noexcept; [[nodiscard]] bool is_valid() const noexcept; @@ -2588,8 +2592,10 @@ namespace meta_hpp class destructor final { public: + using index_type = destructor_index; + explicit destructor() = default; - explicit destructor(detail::destructor_state_ptr state) noexcept; + destructor(detail::destructor_state_ptr state) noexcept; destructor& operator=(detail::destructor_state_ptr state) noexcept; [[nodiscard]] bool is_valid() const noexcept; @@ -2611,8 +2617,10 @@ namespace meta_hpp class evalue final { public: + using index_type = evalue_index; + explicit evalue() = default; - explicit evalue(detail::evalue_state_ptr state) noexcept; + evalue(detail::evalue_state_ptr state) noexcept; evalue& operator=(detail::evalue_state_ptr state) noexcept; [[nodiscard]] bool is_valid() const noexcept; @@ -2639,8 +2647,10 @@ namespace meta_hpp class function final { public: + using index_type = function_index; + explicit function() = default; - explicit function(detail::function_state_ptr state) noexcept; + function(detail::function_state_ptr state) noexcept; function& operator=(detail::function_state_ptr state) noexcept; [[nodiscard]] bool is_valid() const noexcept; @@ -2673,8 +2683,10 @@ namespace meta_hpp class member final { public: + using index_type = member_index; + explicit member() = default; - explicit member(detail::member_state_ptr state) noexcept; + member(detail::member_state_ptr state) noexcept; member& operator=(detail::member_state_ptr state) noexcept; [[nodiscard]] bool is_valid() const noexcept; @@ -2719,8 +2731,10 @@ namespace meta_hpp class method final { public: + using index_type = method_index; + explicit method() = default; - explicit method(detail::method_state_ptr state) noexcept; + method(detail::method_state_ptr state) noexcept; method& operator=(detail::method_state_ptr state) noexcept; [[nodiscard]] bool is_valid() const noexcept; @@ -2753,6 +2767,8 @@ namespace meta_hpp class scope final { public: + using index_type = scope_index; + explicit scope() = default; explicit scope(detail::scope_state_ptr state) noexcept; scope& operator=(detail::scope_state_ptr state) noexcept; @@ -2786,8 +2802,10 @@ namespace meta_hpp class variable final { public: + using index_type = variable_index; + explicit variable() = default; - explicit variable(detail::variable_state_ptr state) noexcept; + variable(detail::variable_state_ptr state) noexcept; variable& operator=(detail::variable_state_ptr state) noexcept; [[nodiscard]] bool is_valid() const noexcept; @@ -2857,6 +2875,45 @@ namespace meta_hpp } } +namespace meta_hpp +{ + template < detail::state_family T, typename U > + requires std::is_same_v + [[nodiscard]] bool operator<(const T& l, const U& r) noexcept { + return !static_cast(l) || l.get_index() < r; + } + + template < typename T, detail::state_family U > + requires std::is_same_v + [[nodiscard]] bool operator<(const T& l, const U& r) noexcept { + return static_cast(r) && l < r.get_index(); + } + + template < detail::state_family T, typename U > + requires std::is_same_v + [[nodiscard]] bool operator==(const T& l, const U& r) noexcept { + return static_cast(l) || l.get_index() == r; + } + + template < typename T, detail::state_family U > + requires std::is_same_v + [[nodiscard]] bool operator==(const T& l, const U& r) noexcept { + return static_cast(r) && l == r.get_index(); + } + + template < detail::state_family T, typename U > + requires std::is_same_v + [[nodiscard]] bool operator!=(const T& l, const U& r) noexcept { + return !(l == r); + } + + template < typename T, detail::state_family U > + requires std::is_same_v + [[nodiscard]] bool operator!=(const T& l, const U& r) noexcept { + return !(l == r); + } +} + namespace meta_hpp::detail { struct argument_state final { diff --git a/develop/untests/meta_states/ops_tests.cpp b/develop/untests/meta_states/ops_tests.cpp new file mode 100644 index 0000000..a2986dd --- /dev/null +++ b/develop/untests/meta_states/ops_tests.cpp @@ -0,0 +1,118 @@ +/******************************************************************************* + * 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_states/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())>); + // 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())>); + // 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())>); + // NOLINTEND(*-redundant-expression) + } +} diff --git a/headers/meta.hpp/meta_states.hpp b/headers/meta.hpp/meta_states.hpp index eef6da1..2ee2f1d 100644 --- a/headers/meta.hpp/meta_states.hpp +++ b/headers/meta.hpp/meta_states.hpp @@ -105,6 +105,8 @@ namespace meta_hpp { class argument final { public: + using index_type = argument_index; + explicit argument() = default; explicit argument(detail::argument_state_ptr state) noexcept; argument& operator=(detail::argument_state_ptr state) noexcept; @@ -126,8 +128,10 @@ namespace meta_hpp class constructor final { public: + using index_type = constructor_index; + explicit constructor() = default; - explicit constructor(detail::constructor_state_ptr state) noexcept; + constructor(detail::constructor_state_ptr state) noexcept; constructor& operator=(detail::constructor_state_ptr state) noexcept; [[nodiscard]] bool is_valid() const noexcept; @@ -159,8 +163,10 @@ namespace meta_hpp class destructor final { public: + using index_type = destructor_index; + explicit destructor() = default; - explicit destructor(detail::destructor_state_ptr state) noexcept; + destructor(detail::destructor_state_ptr state) noexcept; destructor& operator=(detail::destructor_state_ptr state) noexcept; [[nodiscard]] bool is_valid() const noexcept; @@ -182,8 +188,10 @@ namespace meta_hpp class evalue final { public: + using index_type = evalue_index; + explicit evalue() = default; - explicit evalue(detail::evalue_state_ptr state) noexcept; + evalue(detail::evalue_state_ptr state) noexcept; evalue& operator=(detail::evalue_state_ptr state) noexcept; [[nodiscard]] bool is_valid() const noexcept; @@ -210,8 +218,10 @@ namespace meta_hpp class function final { public: + using index_type = function_index; + explicit function() = default; - explicit function(detail::function_state_ptr state) noexcept; + function(detail::function_state_ptr state) noexcept; function& operator=(detail::function_state_ptr state) noexcept; [[nodiscard]] bool is_valid() const noexcept; @@ -244,8 +254,10 @@ namespace meta_hpp class member final { public: + using index_type = member_index; + explicit member() = default; - explicit member(detail::member_state_ptr state) noexcept; + member(detail::member_state_ptr state) noexcept; member& operator=(detail::member_state_ptr state) noexcept; [[nodiscard]] bool is_valid() const noexcept; @@ -290,8 +302,10 @@ namespace meta_hpp class method final { public: + using index_type = method_index; + explicit method() = default; - explicit method(detail::method_state_ptr state) noexcept; + method(detail::method_state_ptr state) noexcept; method& operator=(detail::method_state_ptr state) noexcept; [[nodiscard]] bool is_valid() const noexcept; @@ -324,6 +338,8 @@ namespace meta_hpp class scope final { public: + using index_type = scope_index; + explicit scope() = default; explicit scope(detail::scope_state_ptr state) noexcept; scope& operator=(detail::scope_state_ptr state) noexcept; @@ -357,8 +373,10 @@ namespace meta_hpp class variable final { public: + using index_type = variable_index; + explicit variable() = default; - explicit variable(detail::variable_state_ptr state) noexcept; + variable(detail::variable_state_ptr state) noexcept; variable& operator=(detail::variable_state_ptr state) noexcept; [[nodiscard]] bool is_valid() const noexcept; @@ -428,6 +446,45 @@ namespace meta_hpp } } +namespace meta_hpp +{ + template < detail::state_family T, typename U > + requires std::is_same_v + [[nodiscard]] bool operator<(const T& l, const U& r) noexcept { + return !static_cast(l) || l.get_index() < r; + } + + template < typename T, detail::state_family U > + requires std::is_same_v + [[nodiscard]] bool operator<(const T& l, const U& r) noexcept { + return static_cast(r) && l < r.get_index(); + } + + template < detail::state_family T, typename U > + requires std::is_same_v + [[nodiscard]] bool operator==(const T& l, const U& r) noexcept { + return static_cast(l) || l.get_index() == r; + } + + template < typename T, detail::state_family U > + requires std::is_same_v + [[nodiscard]] bool operator==(const T& l, const U& r) noexcept { + return static_cast(r) && l == r.get_index(); + } + + template < detail::state_family T, typename U > + requires std::is_same_v + [[nodiscard]] bool operator!=(const T& l, const U& r) noexcept { + return !(l == r); + } + + template < typename T, detail::state_family U > + requires std::is_same_v + [[nodiscard]] bool operator!=(const T& l, const U& r) noexcept { + return !(l == r); + } +} + namespace meta_hpp::detail { struct argument_state final {