mirror of
https://github.com/BlackMATov/meta.hpp.git
synced 2025-12-13 19:18:01 +07:00
Compare commits
6 Commits
523bb59df4
...
8bb1783209
| Author | SHA1 | Date | |
|---|---|---|---|
| 8bb1783209 | |||
|
|
f90e8af84b | ||
|
|
11bc1c23b7 | ||
|
|
e04f8a1fec | ||
|
|
1336ade8b3 | ||
|
|
1390279b63 |
@@ -60,8 +60,8 @@ TEST_CASE("meta/meta_examples/enum/usage") {
|
||||
const meta::enum_type align_type = meta::resolve_type(e);
|
||||
|
||||
// converts the enumerator to its name
|
||||
CHECK(align_type.value_to_name(e) == "center");
|
||||
CHECK(align_type.value_to_evalue(e).get_name() == "center");
|
||||
|
||||
// ... and back again
|
||||
CHECK(align_type.name_to_value("center").as<align>() == e);
|
||||
CHECK(align_type.name_to_evalue("center").get_value().as<align>() == e);
|
||||
}
|
||||
|
||||
@@ -188,6 +188,18 @@
|
||||
|
||||
#define META_HPP_DETAIL_IGNORE_OVERRIDE_WARNINGS_POP() META_HPP_DETAIL_CLANG_IGNORE_WARNINGS_POP()
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
#define META_HPP_DETAIL_IGNORE_COMPARISON_WARNINGS_PUSH() \
|
||||
META_HPP_DETAIL_CLANG_IGNORE_WARNINGS_PUSH() \
|
||||
META_HPP_DETAIL_CLANG_IGNORE_WARNING("-Wunknown-warning-option") \
|
||||
META_HPP_DETAIL_CLANG_IGNORE_WARNING("-Wfloat-equal") \
|
||||
META_HPP_DETAIL_CLANG_IGNORE_WARNING("-Wordered-compare-function-pointers")
|
||||
|
||||
#define META_HPP_DETAIL_IGNORE_COMPARISON_WARNINGS_POP() META_HPP_DETAIL_CLANG_IGNORE_WARNINGS_POP()
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename Enum >
|
||||
@@ -444,6 +456,7 @@ namespace meta_hpp::detail
|
||||
|
||||
bad_const_access,
|
||||
bad_uvalue_access,
|
||||
bad_uvalue_operation,
|
||||
|
||||
bad_argument_cast,
|
||||
bad_instance_cast,
|
||||
@@ -463,6 +476,8 @@ namespace meta_hpp::detail
|
||||
return "bad const access";
|
||||
case error_code::bad_uvalue_access:
|
||||
return "bad uvalue access";
|
||||
case error_code::bad_uvalue_operation:
|
||||
return "bad uvalue operation";
|
||||
case error_code::bad_argument_cast:
|
||||
return "bad argument cast";
|
||||
case error_code::bad_instance_cast:
|
||||
@@ -2755,6 +2770,12 @@ namespace meta_hpp
|
||||
[[nodiscard]] uvalue unmap() const;
|
||||
[[nodiscard]] bool has_unmap_op() const noexcept;
|
||||
|
||||
[[nodiscard]] bool less(const uvalue& other) const;
|
||||
[[nodiscard]] bool has_less_op() const noexcept;
|
||||
|
||||
[[nodiscard]] bool equals(const uvalue& other) const;
|
||||
[[nodiscard]] bool has_equals_op() const noexcept;
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] bool is() const noexcept;
|
||||
|
||||
@@ -3116,11 +3137,10 @@ namespace meta_hpp
|
||||
|
||||
[[nodiscard]] const evalue_list& get_evalues() const noexcept;
|
||||
|
||||
[[nodiscard]] evalue get_evalue(std::string_view name) const noexcept;
|
||||
|
||||
template < enum_kind Enum >
|
||||
[[nodiscard]] std::string_view value_to_name(Enum value) const;
|
||||
[[nodiscard]] const uvalue& name_to_value(std::string_view name) const noexcept;
|
||||
[[nodiscard]] evalue value_to_evalue(Enum value) const;
|
||||
[[nodiscard]] evalue value_to_evalue(const uvalue& value) const;
|
||||
[[nodiscard]] evalue name_to_evalue(std::string_view name) const noexcept;
|
||||
};
|
||||
|
||||
class function_type final : public type_base<function_type> {
|
||||
@@ -9127,7 +9147,36 @@ namespace meta_hpp
|
||||
return data_->evalues;
|
||||
}
|
||||
|
||||
inline evalue enum_type::get_evalue(std::string_view name) const noexcept {
|
||||
template < enum_kind Enum >
|
||||
evalue enum_type::value_to_evalue(Enum value) const {
|
||||
if ( *this != resolve_type<Enum>() ) {
|
||||
return evalue{};
|
||||
}
|
||||
|
||||
for ( const evalue& evalue : data_->evalues ) {
|
||||
if ( evalue.get_value().as<Enum>() == value ) {
|
||||
return evalue;
|
||||
}
|
||||
}
|
||||
|
||||
return evalue{};
|
||||
}
|
||||
|
||||
inline evalue enum_type::value_to_evalue(const uvalue& value) const {
|
||||
if ( *this != value.get_type() ) {
|
||||
return evalue{};
|
||||
}
|
||||
|
||||
for ( const evalue& evalue : data_->evalues ) {
|
||||
if ( evalue.get_value().equals(value) ) {
|
||||
return evalue;
|
||||
}
|
||||
}
|
||||
|
||||
return evalue{};
|
||||
}
|
||||
|
||||
inline evalue enum_type::name_to_evalue(std::string_view name) const noexcept {
|
||||
for ( const evalue& evalue : data_->evalues ) {
|
||||
if ( evalue.get_name() == name ) {
|
||||
return evalue;
|
||||
@@ -9135,29 +9184,6 @@ namespace meta_hpp
|
||||
}
|
||||
return evalue{};
|
||||
}
|
||||
|
||||
template < enum_kind Enum >
|
||||
std::string_view enum_type::value_to_name(Enum value) const {
|
||||
if ( resolve_type<Enum>() != *this ) {
|
||||
return std::string_view{};
|
||||
}
|
||||
|
||||
for ( const evalue& evalue : data_->evalues ) {
|
||||
if ( evalue.get_value().as<Enum>() == value ) {
|
||||
return evalue.get_name();
|
||||
}
|
||||
}
|
||||
|
||||
return std::string_view{};
|
||||
}
|
||||
|
||||
inline const uvalue& enum_type::name_to_value(std::string_view name) const noexcept {
|
||||
if ( const evalue& value = get_evalue(name) ) {
|
||||
return value.get_value();
|
||||
}
|
||||
static const uvalue empty_value;
|
||||
return empty_value;
|
||||
}
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
@@ -10474,6 +10500,120 @@ namespace meta_hpp::detail
|
||||
};
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
struct equals_traits;
|
||||
|
||||
template < typename T >
|
||||
concept has_equals_traits //
|
||||
= requires(const T& v) { equals_traits<T>{}(v, v); };
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
requires requires(const T& v) {
|
||||
{ v == v } -> std::convertible_to<bool>;
|
||||
} && (!class_kind<T> || type_list_arity_v<typename class_traits<T>::argument_types> == 0)
|
||||
struct equals_traits<T> {
|
||||
bool operator()(const T& l, const T& r) const {
|
||||
META_HPP_DETAIL_IGNORE_COMPARISON_WARNINGS_PUSH()
|
||||
return l == r;
|
||||
META_HPP_DETAIL_IGNORE_COMPARISON_WARNINGS_POP()
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
requires has_equals_traits<T>
|
||||
struct equals_traits<std::array<T, Size>> {
|
||||
using value_t = std::array<T, Size>;
|
||||
|
||||
bool operator()(const value_t& l, const value_t& r) const {
|
||||
return l == r;
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T, typename Traits, typename Allocator >
|
||||
requires has_equals_traits<T>
|
||||
struct equals_traits<std::basic_string<T, Traits, Allocator>> {
|
||||
using value_t = std::basic_string<T, Traits, Allocator>;
|
||||
|
||||
bool operator()(const value_t& l, const value_t& r) const {
|
||||
return l == r;
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T, typename Traits >
|
||||
requires has_equals_traits<T>
|
||||
struct equals_traits<std::basic_string_view<T, Traits>> {
|
||||
using value_t = std::basic_string_view<T, Traits>;
|
||||
|
||||
bool operator()(const value_t& l, const value_t& r) const {
|
||||
return l == r;
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T, typename Allocator >
|
||||
requires has_equals_traits<T>
|
||||
struct equals_traits<std::vector<T, Allocator>> {
|
||||
using value_t = std::vector<T, Allocator>;
|
||||
|
||||
bool operator()(const value_t& l, const value_t& r) const {
|
||||
return l == r;
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T >
|
||||
struct equals_traits<std::shared_ptr<T>> {
|
||||
using value_t = std::shared_ptr<T>;
|
||||
|
||||
bool operator()(const value_t& l, const value_t& r) const {
|
||||
return l == r;
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T, typename Deleter >
|
||||
struct equals_traits<std::unique_ptr<T, Deleter>> {
|
||||
using value_t = std::unique_ptr<T, Deleter>;
|
||||
|
||||
bool operator()(const value_t& l, const value_t& r) const {
|
||||
return l == r;
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T >
|
||||
requires has_equals_traits<T>
|
||||
struct equals_traits<std::reference_wrapper<T>> {
|
||||
using value_t = std::reference_wrapper<T>;
|
||||
|
||||
bool operator()(const value_t& l, const value_t& r) const {
|
||||
return l.get() == r.get();
|
||||
}
|
||||
};
|
||||
|
||||
template < typename... Ts >
|
||||
requires(... && has_equals_traits<Ts>)
|
||||
struct equals_traits<std::tuple<Ts...>> {
|
||||
using value_t = std::tuple<Ts...>;
|
||||
|
||||
bool operator()(const value_t& l, const value_t& r) const {
|
||||
return l == r;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#define META_HPP_DECLARE_EQUALS_TRAITS_FOR(T) \
|
||||
namespace meta_hpp::detail \
|
||||
{ \
|
||||
template <> \
|
||||
struct equals_traits<T> { \
|
||||
bool operator()(const T& l, const T& r) const { \
|
||||
return l == r; \
|
||||
} \
|
||||
}; \
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
@@ -10536,6 +10676,120 @@ namespace meta_hpp::detail
|
||||
};
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
struct less_traits;
|
||||
|
||||
template < typename T >
|
||||
concept has_less_traits //
|
||||
= requires(const T& v) { less_traits<T>{}(v, v); };
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
requires requires(const T& v) {
|
||||
{ v < v } -> std::convertible_to<bool>;
|
||||
} && (!class_kind<T> || type_list_arity_v<typename class_traits<T>::argument_types> == 0)
|
||||
struct less_traits<T> {
|
||||
bool operator()(const T& l, const T& r) const {
|
||||
META_HPP_DETAIL_IGNORE_COMPARISON_WARNINGS_PUSH()
|
||||
return l < r;
|
||||
META_HPP_DETAIL_IGNORE_COMPARISON_WARNINGS_POP()
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
requires has_less_traits<T>
|
||||
struct less_traits<std::array<T, Size>> {
|
||||
using value_t = std::array<T, Size>;
|
||||
|
||||
bool operator()(const value_t& l, const value_t& r) const {
|
||||
return l < r;
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T, typename Traits, typename Allocator >
|
||||
requires has_less_traits<T>
|
||||
struct less_traits<std::basic_string<T, Traits, Allocator>> {
|
||||
using value_t = std::basic_string<T, Traits, Allocator>;
|
||||
|
||||
bool operator()(const value_t& l, const value_t& r) const {
|
||||
return l < r;
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T, typename Traits >
|
||||
requires has_less_traits<T>
|
||||
struct less_traits<std::basic_string_view<T, Traits>> {
|
||||
using value_t = std::basic_string_view<T, Traits>;
|
||||
|
||||
bool operator()(const value_t& l, const value_t& r) const {
|
||||
return l < r;
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T, typename Allocator >
|
||||
requires has_less_traits<T>
|
||||
struct less_traits<std::vector<T, Allocator>> {
|
||||
using value_t = std::vector<T, Allocator>;
|
||||
|
||||
bool operator()(const value_t& l, const value_t& r) const {
|
||||
return l < r;
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T >
|
||||
struct less_traits<std::shared_ptr<T>> {
|
||||
using value_t = std::shared_ptr<T>;
|
||||
|
||||
bool operator()(const value_t& l, const value_t& r) const {
|
||||
return l < r;
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T, typename Deleter >
|
||||
struct less_traits<std::unique_ptr<T, Deleter>> {
|
||||
using value_t = std::unique_ptr<T, Deleter>;
|
||||
|
||||
bool operator()(const value_t& l, const value_t& r) const {
|
||||
return l < r;
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T >
|
||||
requires has_less_traits<T>
|
||||
struct less_traits<std::reference_wrapper<T>> {
|
||||
using value_t = std::reference_wrapper<T>;
|
||||
|
||||
bool operator()(const value_t& l, const value_t& r) const {
|
||||
return l.get() < r.get();
|
||||
}
|
||||
};
|
||||
|
||||
template < typename... Ts >
|
||||
requires(... && has_less_traits<Ts>)
|
||||
struct less_traits<std::tuple<Ts...>> {
|
||||
using value_t = std::tuple<Ts...>;
|
||||
|
||||
bool operator()(const value_t& l, const value_t& r) const {
|
||||
return l < r;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#define META_HPP_DECLARE_LESS_TRAITS_FOR(T) \
|
||||
namespace meta_hpp::detail \
|
||||
{ \
|
||||
template <> \
|
||||
struct less_traits<T> { \
|
||||
bool operator()(const T& l, const T& r) const { \
|
||||
return l < r; \
|
||||
} \
|
||||
}; \
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
@@ -10583,6 +10837,9 @@ namespace meta_hpp
|
||||
uvalue (*const deref)(const storage_u& self);
|
||||
uvalue (*const index)(const storage_u& self, std::size_t i);
|
||||
uvalue (*const unmap)(const storage_u& self);
|
||||
|
||||
bool (*const less)(const storage_u& l, const storage_u& r);
|
||||
bool (*const equals)(const storage_u& l, const storage_u& r);
|
||||
// NOLINTEND(*-avoid-const-or-ref-data-members)
|
||||
|
||||
template < typename T >
|
||||
@@ -10785,6 +11042,26 @@ namespace meta_hpp
|
||||
return nullptr;
|
||||
}
|
||||
}()},
|
||||
|
||||
.less{[]() {
|
||||
if constexpr ( detail::has_less_traits<Tp> ) {
|
||||
return +[](const storage_u& l, const storage_u& r) -> bool {
|
||||
return detail::less_traits<Tp>{}(*storage_cast<Tp>(l), *storage_cast<Tp>(r));
|
||||
};
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}()},
|
||||
|
||||
.equals{[]() {
|
||||
if constexpr ( detail::has_equals_traits<Tp> ) {
|
||||
return +[](const storage_u& l, const storage_u& r) -> bool {
|
||||
return detail::equals_traits<Tp>{}(*storage_cast<Tp>(l), *storage_cast<Tp>(r));
|
||||
};
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}()},
|
||||
};
|
||||
|
||||
return &table;
|
||||
@@ -10920,9 +11197,12 @@ namespace meta_hpp
|
||||
|
||||
inline uvalue uvalue::operator*() const {
|
||||
auto&& [tag, vtable] = vtable_t::unpack_vtag(*this);
|
||||
return tag != storage_e::nothing && vtable->deref != nullptr //
|
||||
? vtable->deref(storage_)
|
||||
: uvalue{};
|
||||
|
||||
if ( tag != storage_e::nothing && vtable->deref != nullptr ) {
|
||||
return vtable->deref(storage_);
|
||||
}
|
||||
|
||||
throw_exception(error_code::bad_uvalue_operation);
|
||||
}
|
||||
|
||||
inline bool uvalue::has_deref_op() const noexcept {
|
||||
@@ -10932,9 +11212,12 @@ namespace meta_hpp
|
||||
|
||||
inline uvalue uvalue::operator[](std::size_t index) const {
|
||||
auto&& [tag, vtable] = vtable_t::unpack_vtag(*this);
|
||||
return tag != storage_e::nothing && vtable->index != nullptr //
|
||||
? vtable->index(storage_, index)
|
||||
: uvalue{};
|
||||
|
||||
if ( tag != storage_e::nothing && vtable->index != nullptr ) {
|
||||
return vtable->index(storage_, index);
|
||||
}
|
||||
|
||||
throw_exception(error_code::bad_uvalue_operation);
|
||||
}
|
||||
|
||||
inline bool uvalue::has_index_op() const noexcept {
|
||||
@@ -10944,21 +11227,31 @@ namespace meta_hpp
|
||||
|
||||
inline uvalue uvalue::copy() const {
|
||||
auto&& [tag, vtable] = vtable_t::unpack_vtag(*this);
|
||||
return tag != storage_e::nothing && vtable->copy != nullptr //
|
||||
? vtable->copy(storage_)
|
||||
: uvalue{};
|
||||
|
||||
if ( tag == storage_e::nothing ) {
|
||||
return uvalue{};
|
||||
}
|
||||
|
||||
if ( vtable->copy != nullptr ) {
|
||||
return vtable->copy(storage_);
|
||||
}
|
||||
|
||||
throw_exception(error_code::bad_uvalue_operation);
|
||||
}
|
||||
|
||||
inline bool uvalue::has_copy_op() const noexcept {
|
||||
auto&& [tag, vtable] = vtable_t::unpack_vtag(*this);
|
||||
return tag != storage_e::nothing && vtable->copy != nullptr;
|
||||
return tag == storage_e::nothing || vtable->copy != nullptr;
|
||||
}
|
||||
|
||||
inline uvalue uvalue::unmap() const {
|
||||
auto&& [tag, vtable] = vtable_t::unpack_vtag(*this);
|
||||
return tag != storage_e::nothing && vtable->unmap != nullptr //
|
||||
? vtable->unmap(storage_)
|
||||
: uvalue{};
|
||||
|
||||
if ( tag != storage_e::nothing && vtable->unmap != nullptr ) {
|
||||
return vtable->unmap(storage_);
|
||||
}
|
||||
|
||||
throw_exception(error_code::bad_uvalue_operation);
|
||||
}
|
||||
|
||||
inline bool uvalue::has_unmap_op() const noexcept {
|
||||
@@ -10966,6 +11259,62 @@ namespace meta_hpp
|
||||
return tag != storage_e::nothing && vtable->unmap != nullptr;
|
||||
}
|
||||
|
||||
inline bool uvalue::less(const uvalue& other) const {
|
||||
if ( this == &other ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto&& [l_tag, l_vtable] = vtable_t::unpack_vtag(*this);
|
||||
auto&& [r_tag, r_vtable] = vtable_t::unpack_vtag(other);
|
||||
|
||||
if ( l_tag != r_tag || l_tag == storage_e::nothing ) {
|
||||
return l_tag < r_tag;
|
||||
}
|
||||
|
||||
if ( l_vtable != r_vtable ) {
|
||||
return l_vtable->type < r_vtable->type;
|
||||
}
|
||||
|
||||
if ( l_vtable->less != nullptr ) {
|
||||
return l_vtable->less(storage_, other.storage_);
|
||||
}
|
||||
|
||||
throw_exception(error_code::bad_uvalue_operation);
|
||||
}
|
||||
|
||||
inline bool uvalue::has_less_op() const noexcept {
|
||||
auto&& [tag, vtable] = vtable_t::unpack_vtag(*this);
|
||||
return tag == storage_e::nothing || vtable->less != nullptr;
|
||||
}
|
||||
|
||||
inline bool uvalue::equals(const uvalue& other) const {
|
||||
if ( this == &other ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
auto&& [l_tag, l_vtable] = vtable_t::unpack_vtag(*this);
|
||||
auto&& [r_tag, r_vtable] = vtable_t::unpack_vtag(other);
|
||||
|
||||
if ( l_tag != r_tag || l_tag == storage_e::nothing ) {
|
||||
return l_tag == r_tag;
|
||||
}
|
||||
|
||||
if ( l_vtable != r_vtable ) {
|
||||
return l_vtable->type == r_vtable->type;
|
||||
}
|
||||
|
||||
if ( l_vtable->equals != nullptr ) {
|
||||
return l_vtable->equals(storage_, other.storage_);
|
||||
}
|
||||
|
||||
throw_exception(error_code::bad_uvalue_operation);
|
||||
}
|
||||
|
||||
inline bool uvalue::has_equals_op() const noexcept {
|
||||
auto&& [tag, vtable] = vtable_t::unpack_vtag(*this);
|
||||
return tag == storage_e::nothing || vtable->equals != nullptr;
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
bool uvalue::is() const noexcept {
|
||||
static_assert(std::is_same_v<T, std::decay_t<T>>);
|
||||
|
||||
80
develop/untests/meta_issues/github_discussion_93.cpp
Normal file
80
develop/untests/meta_issues/github_discussion_93.cpp
Normal file
@@ -0,0 +1,80 @@
|
||||
/*******************************************************************************
|
||||
* 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-2024, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#include <meta.hpp/meta_all.hpp>
|
||||
#include <doctest/doctest.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
enum class align {
|
||||
left,
|
||||
right,
|
||||
center,
|
||||
};
|
||||
|
||||
enum class color {
|
||||
red,
|
||||
green,
|
||||
blue,
|
||||
};
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_discussion/93") {
|
||||
namespace meta = meta_hpp;
|
||||
|
||||
meta::enum_<align>()
|
||||
.evalue_("left", align::left)
|
||||
.evalue_("right", align::right)
|
||||
.evalue_("center", align::center);
|
||||
|
||||
const meta::enum_type align_type = meta::resolve_type<align>();
|
||||
|
||||
{
|
||||
CHECK(align_type.name_to_evalue("left").get_name() == "left");
|
||||
CHECK(align_type.name_to_evalue("right").get_name() == "right");
|
||||
CHECK(align_type.name_to_evalue("center").get_name() == "center");
|
||||
}
|
||||
|
||||
{
|
||||
align v = align::right;
|
||||
|
||||
CHECK(align_type.value_to_evalue(v).get_name() == "right");
|
||||
CHECK(align_type.value_to_evalue(std::as_const(v)).get_name() == "right");
|
||||
CHECK(align_type.value_to_evalue(std::move(std::as_const(v))).get_name() == "right");
|
||||
CHECK(align_type.value_to_evalue(std::move(v)).get_name() == "right");
|
||||
|
||||
v = align::center;
|
||||
|
||||
CHECK(align_type.value_to_evalue(v).get_name() == "center");
|
||||
CHECK(align_type.value_to_evalue(std::as_const(v)).get_name() == "center");
|
||||
CHECK(align_type.value_to_evalue(std::move(std::as_const(v))).get_name() == "center");
|
||||
CHECK(align_type.value_to_evalue(std::move(v)).get_name() == "center");
|
||||
}
|
||||
|
||||
{
|
||||
meta::uvalue v = align::right;
|
||||
|
||||
CHECK(align_type.value_to_evalue(v).get_name() == "right");
|
||||
CHECK(align_type.value_to_evalue(std::as_const(v)).get_name() == "right");
|
||||
CHECK(align_type.value_to_evalue(std::move(std::as_const(v))).get_name() == "right");
|
||||
CHECK(align_type.value_to_evalue(std::move(v)).get_name() == "right");
|
||||
|
||||
v = align::center;
|
||||
|
||||
CHECK(align_type.value_to_evalue(v).get_name() == "center");
|
||||
CHECK(align_type.value_to_evalue(std::as_const(v)).get_name() == "center");
|
||||
CHECK(align_type.value_to_evalue(std::move(std::as_const(v))).get_name() == "center");
|
||||
CHECK(align_type.value_to_evalue(std::move(v)).get_name() == "center");
|
||||
}
|
||||
|
||||
{
|
||||
CHECK_FALSE(align_type.name_to_evalue(""));
|
||||
CHECK_FALSE(align_type.name_to_evalue("middle"));
|
||||
|
||||
CHECK_FALSE(align_type.value_to_evalue(color::red));
|
||||
CHECK_FALSE(align_type.value_to_evalue(meta::uvalue{color::red}));
|
||||
}
|
||||
}
|
||||
@@ -35,19 +35,19 @@ TEST_CASE("meta/meta_states/evalue") {
|
||||
const meta::evalue evalue;
|
||||
CHECK_FALSE(evalue);
|
||||
CHECK_FALSE(evalue.is_valid());
|
||||
CHECK(evalue == color_type.get_evalue("non-existent-evalue"));
|
||||
CHECK(evalue == color_type.name_to_evalue("non-existent-evalue"));
|
||||
}
|
||||
|
||||
SUBCASE("operators") {
|
||||
const meta::evalue blue_e = color_type.get_evalue("blue");
|
||||
const meta::evalue white_e = color_type.get_evalue("white");
|
||||
const meta::evalue blue_e = color_type.name_to_evalue("blue");
|
||||
const meta::evalue white_e = color_type.name_to_evalue("white");
|
||||
CHECK(blue_e == blue_e);
|
||||
CHECK(blue_e != white_e);
|
||||
CHECK((blue_e < white_e || white_e < blue_e));
|
||||
}
|
||||
|
||||
SUBCASE("green") {
|
||||
const meta::evalue evalue = color_type.get_evalue("green");
|
||||
const meta::evalue evalue = color_type.name_to_evalue("green");
|
||||
REQUIRE(evalue);
|
||||
|
||||
CHECK(evalue.get_index().get_type() == evalue.get_type());
|
||||
|
||||
@@ -77,7 +77,7 @@ TEST_CASE("meta/meta_states/metadata/enum") {
|
||||
}
|
||||
|
||||
SUBCASE("color::red") {
|
||||
const meta::evalue red_evalue = color_type.get_evalue("red");
|
||||
const meta::evalue red_evalue = color_type.name_to_evalue("red");
|
||||
REQUIRE(red_evalue);
|
||||
CHECK_FALSE(red_evalue.get_metadata().contains("desc1"));
|
||||
CHECK(red_evalue.get_metadata().at("desc2").as<std::string>() == "new-red-color"s);
|
||||
|
||||
@@ -83,12 +83,12 @@ TEST_CASE("meta/meta_types/enum_type") {
|
||||
CHECK(ecolor_type.get_evalues().size() == 4);
|
||||
}
|
||||
|
||||
SUBCASE("color/get_evalue") {
|
||||
SUBCASE("color/name_to_evalue") {
|
||||
const meta::enum_type color_type = meta::resolve_type<color>();
|
||||
REQUIRE(color_type);
|
||||
|
||||
{
|
||||
const meta::evalue green_value = color_type.get_evalue("green");
|
||||
const meta::evalue green_value = color_type.name_to_evalue("green");
|
||||
REQUIRE(green_value);
|
||||
|
||||
CHECK(green_value.get_value().as<color>() == color::green);
|
||||
@@ -96,17 +96,17 @@ TEST_CASE("meta/meta_types/enum_type") {
|
||||
}
|
||||
|
||||
{
|
||||
const meta::evalue yellow_value = color_type.get_evalue("yellow");
|
||||
const meta::evalue yellow_value = color_type.name_to_evalue("yellow");
|
||||
CHECK_FALSE(yellow_value);
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("ecolor/get_evalue") {
|
||||
SUBCASE("ecolor/name_to_evalue") {
|
||||
const meta::enum_type ecolor_type = meta::resolve_type<ecolor>();
|
||||
REQUIRE(ecolor_type);
|
||||
|
||||
{
|
||||
const meta::evalue green_value = ecolor_type.get_evalue("green");
|
||||
const meta::evalue green_value = ecolor_type.name_to_evalue("green");
|
||||
REQUIRE(green_value);
|
||||
|
||||
CHECK(green_value.get_value().as<ecolor>() == ecolor_green);
|
||||
@@ -114,7 +114,7 @@ TEST_CASE("meta/meta_types/enum_type") {
|
||||
}
|
||||
|
||||
{
|
||||
const meta::evalue yellow_value = ecolor_type.get_evalue("yellow");
|
||||
const meta::evalue yellow_value = ecolor_type.name_to_evalue("yellow");
|
||||
CHECK_FALSE(yellow_value);
|
||||
}
|
||||
}
|
||||
@@ -123,18 +123,18 @@ TEST_CASE("meta/meta_types/enum_type") {
|
||||
const meta::enum_type color_type = meta::resolve_type<color>();
|
||||
REQUIRE(color_type);
|
||||
|
||||
CHECK(color_type.value_to_name(color::red) == "red");
|
||||
CHECK(color_type.value_to_name(color::blue) == "blue");
|
||||
CHECK(color_type.value_to_name(color{100500}).empty());
|
||||
CHECK(color_type.value_to_evalue(color::red).get_name() == "red");
|
||||
CHECK(color_type.value_to_evalue(color::blue).get_name() == "blue");
|
||||
CHECK_FALSE(color_type.value_to_evalue(color{100500}));
|
||||
}
|
||||
|
||||
SUBCASE("ecolor/value_to_name") {
|
||||
const meta::enum_type ecolor_type = meta::resolve_type<ecolor>();
|
||||
REQUIRE(ecolor_type);
|
||||
|
||||
CHECK(ecolor_type.value_to_name(ecolor_red) == "red");
|
||||
CHECK(ecolor_type.value_to_name(ecolor_blue) == "blue");
|
||||
CHECK(ecolor_type.value_to_name(ecolor{100500}).empty());
|
||||
CHECK(ecolor_type.value_to_evalue(ecolor_red).get_name() == "red");
|
||||
CHECK(ecolor_type.value_to_evalue(ecolor_blue).get_name() == "blue");
|
||||
CHECK_FALSE(ecolor_type.value_to_evalue(ecolor{100500}));
|
||||
}
|
||||
|
||||
SUBCASE("color/name_to_value") {
|
||||
@@ -142,12 +142,12 @@ TEST_CASE("meta/meta_types/enum_type") {
|
||||
REQUIRE(color_type);
|
||||
|
||||
{
|
||||
REQUIRE(color_type.name_to_value("blue"));
|
||||
CHECK(color_type.name_to_value("blue").as<color>() == color::blue);
|
||||
REQUIRE(color_type.name_to_evalue("blue"));
|
||||
CHECK(color_type.name_to_evalue("blue").get_value().as<color>() == color::blue);
|
||||
}
|
||||
|
||||
{
|
||||
REQUIRE_FALSE(color_type.name_to_value("yellow"));
|
||||
REQUIRE_FALSE(color_type.name_to_evalue("yellow"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,12 +156,12 @@ TEST_CASE("meta/meta_types/enum_type") {
|
||||
REQUIRE(ecolor_type);
|
||||
|
||||
{
|
||||
REQUIRE(ecolor_type.name_to_value("blue"));
|
||||
CHECK(ecolor_type.name_to_value("blue").as<ecolor>() == ecolor_blue);
|
||||
REQUIRE(ecolor_type.name_to_evalue("blue"));
|
||||
CHECK(ecolor_type.name_to_evalue("blue").get_value().as<ecolor>() == ecolor_blue);
|
||||
}
|
||||
|
||||
{
|
||||
REQUIRE_FALSE(ecolor_type.name_to_value("yellow"));
|
||||
REQUIRE_FALSE(ecolor_type.name_to_evalue("yellow"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ TEST_CASE("meta/meta_utilities/hash") {
|
||||
const meta::method ivec2_method = ivec2_type.get_method("add");
|
||||
|
||||
const meta::enum_type color_type = meta::resolve_type<color>();
|
||||
const meta::evalue red_color = color_type.get_evalue("red");
|
||||
const meta::evalue red_color = color_type.name_to_evalue("red");
|
||||
|
||||
const meta::scope local_scope = meta::local_scope_("local-scope")
|
||||
.variable_("pi_v", &pi_v);
|
||||
|
||||
@@ -98,10 +98,12 @@ namespace
|
||||
return {l.x + r.x, l.y + r.y};
|
||||
}
|
||||
|
||||
[[maybe_unused]]
|
||||
bool operator==(const ivec2& l, const ivec2& r) noexcept {
|
||||
return l.x == r.x && l.y == r.y;
|
||||
}
|
||||
|
||||
[[maybe_unused]]
|
||||
bool operator==(const ivec2_big& l, const ivec2_big& r) noexcept {
|
||||
return l.x == r.x && l.y == r.y;
|
||||
}
|
||||
@@ -164,8 +166,8 @@ TEST_CASE("meta/meta_utilities/value") {
|
||||
CHECK(std::as_const(val).get_data() == nullptr);
|
||||
CHECK(std::as_const(val).get_cdata() == nullptr);
|
||||
|
||||
CHECK_FALSE(*val);
|
||||
CHECK_FALSE(val[0]);
|
||||
CHECK_THROWS(std::ignore = *val);
|
||||
CHECK_THROWS(std::ignore = val[0]);
|
||||
|
||||
CHECK_FALSE(val.try_as<ivec2>());
|
||||
CHECK_FALSE(std::as_const(val).try_as<ivec2>());
|
||||
@@ -475,6 +477,13 @@ TEST_CASE("meta/meta_utilities/value") {
|
||||
}
|
||||
|
||||
SUBCASE("copy") {
|
||||
{
|
||||
const meta::uvalue u{};
|
||||
CHECK(u.has_copy_op());
|
||||
|
||||
const meta::uvalue v{u.copy()};
|
||||
CHECK_FALSE(v);
|
||||
}
|
||||
{
|
||||
const meta::uvalue u{42};
|
||||
CHECK(u.has_copy_op());
|
||||
@@ -486,7 +495,7 @@ TEST_CASE("meta/meta_utilities/value") {
|
||||
{
|
||||
const meta::uvalue u{std::unique_ptr<int>{}};
|
||||
CHECK_FALSE(u.has_copy_op());
|
||||
CHECK_FALSE(u.copy());
|
||||
CHECK_THROWS(std::ignore = u.copy());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -494,7 +503,7 @@ TEST_CASE("meta/meta_utilities/value") {
|
||||
{
|
||||
const meta::uvalue u{42};
|
||||
CHECK_FALSE(u.has_unmap_op());
|
||||
CHECK_FALSE(u.unmap());
|
||||
CHECK_THROWS(std::ignore = u.unmap());
|
||||
}
|
||||
{
|
||||
int i{42};
|
||||
@@ -573,10 +582,10 @@ TEST_CASE("meta/meta_utilities/value") {
|
||||
CHECK_FALSE(meta::uvalue(p3).has_deref_op());
|
||||
CHECK_FALSE(meta::uvalue(p4).has_deref_op());
|
||||
|
||||
CHECK_FALSE(*meta::uvalue(p1));
|
||||
CHECK_FALSE(*meta::uvalue(p2));
|
||||
CHECK_FALSE(*meta::uvalue(p3));
|
||||
CHECK_FALSE(*meta::uvalue(p4));
|
||||
CHECK_THROWS(std::ignore = *meta::uvalue(p1));
|
||||
CHECK_THROWS(std::ignore = *meta::uvalue(p2));
|
||||
CHECK_THROWS(std::ignore = *meta::uvalue(p3));
|
||||
CHECK_THROWS(std::ignore = *meta::uvalue(p4));
|
||||
}
|
||||
{
|
||||
int* p1 = nullptr;
|
||||
@@ -615,6 +624,195 @@ TEST_CASE("meta/meta_utilities/value") {
|
||||
CHECK((*v).as<int>() == 42);
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("less/equal") {
|
||||
{
|
||||
meta::uvalue l{};
|
||||
meta::uvalue r{};
|
||||
|
||||
CHECK(l.has_less_op());
|
||||
CHECK(r.has_less_op());
|
||||
CHECK_FALSE(l.less(l));
|
||||
CHECK_FALSE(r.less(r));
|
||||
CHECK_FALSE(l.less(r));
|
||||
CHECK_FALSE(r.less(l));
|
||||
|
||||
CHECK(l.has_equals_op());
|
||||
CHECK(r.has_equals_op());
|
||||
CHECK(l.equals(l));
|
||||
CHECK(r.equals(r));
|
||||
CHECK(l.equals(r));
|
||||
CHECK(r.equals(l));
|
||||
}
|
||||
{
|
||||
meta::uvalue l{};
|
||||
meta::uvalue r{42};
|
||||
|
||||
CHECK(l.has_less_op());
|
||||
CHECK(r.has_less_op());
|
||||
CHECK_FALSE(l.less(l));
|
||||
CHECK_FALSE(r.less(r));
|
||||
CHECK(l.less(r));
|
||||
CHECK_FALSE(r.less(l));
|
||||
|
||||
CHECK(l.has_equals_op());
|
||||
CHECK(r.has_equals_op());
|
||||
CHECK(l.equals(l));
|
||||
CHECK(r.equals(r));
|
||||
CHECK_FALSE(l.equals(r));
|
||||
CHECK_FALSE(r.equals(l));
|
||||
}
|
||||
{
|
||||
meta::uvalue l{21};
|
||||
meta::uvalue r{42};
|
||||
meta::uvalue r2{42};
|
||||
|
||||
CHECK(l.has_less_op());
|
||||
CHECK(r.has_less_op());
|
||||
CHECK_FALSE(l.less(l));
|
||||
CHECK_FALSE(r.less(r));
|
||||
CHECK(l.less(r));
|
||||
CHECK_FALSE(r.less(l));
|
||||
CHECK_FALSE(r.less(r2));
|
||||
|
||||
CHECK(l.has_equals_op());
|
||||
CHECK(r.has_equals_op());
|
||||
CHECK(l.equals(l));
|
||||
CHECK(r.equals(r));
|
||||
CHECK_FALSE(l.equals(r));
|
||||
CHECK_FALSE(r.equals(l));
|
||||
CHECK(r.equals(r2));
|
||||
}
|
||||
{
|
||||
meta::uvalue l{42};
|
||||
meta::uvalue r{'a'};
|
||||
|
||||
CHECK(l.has_less_op());
|
||||
CHECK(r.has_less_op());
|
||||
CHECK_FALSE(l.less(l));
|
||||
CHECK_FALSE(r.less(r));
|
||||
CHECK(l.less(r) == (l.get_type() < r.get_type()));
|
||||
CHECK(r.less(l) == (r.get_type() < l.get_type()));
|
||||
|
||||
CHECK(l.has_equals_op());
|
||||
CHECK(r.has_equals_op());
|
||||
CHECK(l.equals(l));
|
||||
CHECK(r.equals(r));
|
||||
CHECK_FALSE(l.equals(r));
|
||||
CHECK_FALSE(r.equals(l));
|
||||
}
|
||||
{
|
||||
meta::uvalue l{42};
|
||||
meta::uvalue r{ivec2{1,2}};
|
||||
|
||||
CHECK(l.has_less_op());
|
||||
CHECK_FALSE(r.has_less_op());
|
||||
CHECK_FALSE(l.less(l));
|
||||
CHECK_FALSE(r.less(r));
|
||||
CHECK(l.less(r) == (l.get_type() < r.get_type()));
|
||||
CHECK(r.less(l) == (r.get_type() < l.get_type()));
|
||||
|
||||
CHECK(l.has_equals_op());
|
||||
CHECK(r.has_equals_op());
|
||||
CHECK(l.equals(l));
|
||||
CHECK(r.equals(r));
|
||||
CHECK_FALSE(l.equals(r));
|
||||
CHECK_FALSE(r.equals(l));
|
||||
}
|
||||
{
|
||||
meta::uvalue l{ivec2{1,2}};
|
||||
meta::uvalue r{ivec2{1,2}};
|
||||
|
||||
CHECK_FALSE(l.has_less_op());
|
||||
CHECK_FALSE(r.has_less_op());
|
||||
CHECK_FALSE(l.less(l));
|
||||
CHECK_FALSE(r.less(r));
|
||||
CHECK_THROWS(std::ignore = l.less(r));
|
||||
CHECK_THROWS(std::ignore = r.less(l));
|
||||
|
||||
CHECK(l.has_equals_op());
|
||||
CHECK(r.has_equals_op());
|
||||
CHECK(l.equals(l));
|
||||
CHECK(r.equals(r));
|
||||
CHECK(l.equals(r));
|
||||
CHECK(r.equals(l));
|
||||
}
|
||||
{
|
||||
meta::uvalue l{std::vector{1,2}};
|
||||
meta::uvalue r{std::vector{1,3}};
|
||||
|
||||
CHECK(l.has_less_op());
|
||||
CHECK(r.has_less_op());
|
||||
CHECK_FALSE(l.less(l));
|
||||
CHECK_FALSE(r.less(r));
|
||||
CHECK(l.less(r));
|
||||
CHECK_FALSE(r.less(l));
|
||||
|
||||
CHECK(l.has_equals_op());
|
||||
CHECK(r.has_equals_op());
|
||||
CHECK(l.equals(l));
|
||||
CHECK(r.equals(r));
|
||||
CHECK_FALSE(l.equals(r));
|
||||
CHECK_FALSE(r.equals(l));
|
||||
}
|
||||
{
|
||||
meta::uvalue l{std::vector{ivec2{1,2}}};
|
||||
meta::uvalue r{std::vector{ivec2{1,3}}};
|
||||
|
||||
CHECK_FALSE(l.has_less_op());
|
||||
CHECK_FALSE(r.has_less_op());
|
||||
CHECK_FALSE(l.less(l));
|
||||
CHECK_FALSE(r.less(r));
|
||||
CHECK_THROWS(std::ignore = l.less(r));
|
||||
CHECK_THROWS(std::ignore = r.less(l));
|
||||
|
||||
CHECK(l.has_equals_op());
|
||||
CHECK(r.has_equals_op());
|
||||
CHECK(l.equals(l));
|
||||
CHECK(r.equals(r));
|
||||
CHECK_FALSE(l.equals(r));
|
||||
CHECK_FALSE(r.equals(l));
|
||||
}
|
||||
{
|
||||
CHECK(meta::uvalue{std::array<int, 1>{42}}.has_less_op());
|
||||
CHECK(meta::uvalue{std::tuple<std::string>{""}}.has_less_op());
|
||||
CHECK(meta::uvalue{std::vector{std::string_view{""}}}.has_less_op());
|
||||
CHECK(meta::uvalue{std::make_shared<int>(42)}.has_less_op());
|
||||
CHECK(meta::uvalue{std::make_unique<int>(42)}.has_less_op());
|
||||
|
||||
CHECK_FALSE(meta::uvalue{std::array<ivec2, 1>{ivec2{1,2}}}.has_less_op());
|
||||
CHECK_FALSE(meta::uvalue{std::tuple<ivec2>{ivec2{1,2}}}.has_less_op());
|
||||
CHECK_FALSE(meta::uvalue{std::vector{ivec2{1,2}}}.has_less_op());
|
||||
CHECK(meta::uvalue{std::make_shared<ivec2>(1,2)}.has_less_op());
|
||||
CHECK(meta::uvalue{std::make_unique<ivec2>(1,2)}.has_less_op());
|
||||
|
||||
CHECK(meta::uvalue{std::array<int, 1>{42}}.has_equals_op());
|
||||
CHECK(meta::uvalue{std::tuple<std::string>{""}}.has_equals_op());
|
||||
CHECK(meta::uvalue{std::vector{std::string_view{""}}}.has_equals_op());
|
||||
CHECK(meta::uvalue{std::make_shared<int>(42)}.has_equals_op());
|
||||
CHECK(meta::uvalue{std::make_unique<int>(42)}.has_equals_op());
|
||||
|
||||
CHECK(meta::uvalue{std::array<ivec2, 1>{ivec2{1,2}}}.has_equals_op());
|
||||
CHECK(meta::uvalue{std::tuple<ivec2>{ivec2{1,2}}}.has_equals_op());
|
||||
CHECK(meta::uvalue{std::vector{ivec2{1,2}}}.has_equals_op());
|
||||
CHECK(meta::uvalue{std::make_shared<ivec2>(1,2)}.has_equals_op());
|
||||
CHECK(meta::uvalue{std::make_unique<ivec2>(1,2)}.has_equals_op());
|
||||
|
||||
{
|
||||
int v1 = 42;
|
||||
CHECK(meta::uvalue{std::ref(v1)}.has_less_op());
|
||||
CHECK(meta::uvalue{std::cref(v1)}.has_less_op());
|
||||
CHECK(meta::uvalue{std::ref(v1)}.has_equals_op());
|
||||
CHECK(meta::uvalue{std::cref(v1)}.has_equals_op());
|
||||
|
||||
ivec2 v2{1,2};
|
||||
CHECK_FALSE(meta::uvalue{std::ref(v2)}.has_less_op());
|
||||
CHECK_FALSE(meta::uvalue{std::cref(v2)}.has_less_op());
|
||||
CHECK(meta::uvalue{std::ref(v2)}.has_equals_op());
|
||||
CHECK(meta::uvalue{std::cref(v2)}.has_equals_op());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("meta/meta_utilities/value/arrays") {
|
||||
@@ -624,7 +822,7 @@ TEST_CASE("meta/meta_utilities/value/arrays") {
|
||||
meta::uvalue v{42};
|
||||
CHECK(v.get_type() == meta::resolve_type<int>());
|
||||
CHECK_FALSE(v.has_index_op());
|
||||
CHECK_FALSE(v[0]);
|
||||
CHECK_THROWS(std::ignore = v[0]);
|
||||
}
|
||||
|
||||
SUBCASE("void*") {
|
||||
@@ -633,7 +831,7 @@ TEST_CASE("meta/meta_utilities/value/arrays") {
|
||||
meta::uvalue v{p};
|
||||
CHECK(v.get_type() == meta::resolve_type<void*>());
|
||||
CHECK_FALSE(v.has_index_op());
|
||||
CHECK_FALSE(v[0]);
|
||||
CHECK_THROWS(std::ignore = v[0]);
|
||||
}
|
||||
|
||||
SUBCASE("const void*") {
|
||||
@@ -642,7 +840,7 @@ TEST_CASE("meta/meta_utilities/value/arrays") {
|
||||
meta::uvalue v{p};
|
||||
CHECK(v.get_type() == meta::resolve_type<const void*>());
|
||||
CHECK_FALSE(v.has_index_op());
|
||||
CHECK_FALSE(v[0]);
|
||||
CHECK_THROWS(std::ignore = v[0]);
|
||||
}
|
||||
|
||||
SUBCASE("int[3]") {
|
||||
|
||||
@@ -24,5 +24,6 @@ Diagnostics:
|
||||
- readability-identifier-length
|
||||
- readability-named-parameter
|
||||
- readability-redundant-access-specifiers
|
||||
- readability-redundant-member-init
|
||||
- readability-simplify-boolean-expr
|
||||
- readability-use-anyofallof
|
||||
|
||||
@@ -188,3 +188,15 @@
|
||||
META_HPP_DETAIL_CLANG_IGNORE_WARNING("-Wsuggest-override")
|
||||
|
||||
#define META_HPP_DETAIL_IGNORE_OVERRIDE_WARNINGS_POP() META_HPP_DETAIL_CLANG_IGNORE_WARNINGS_POP()
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
#define META_HPP_DETAIL_IGNORE_COMPARISON_WARNINGS_PUSH() \
|
||||
META_HPP_DETAIL_CLANG_IGNORE_WARNINGS_PUSH() \
|
||||
META_HPP_DETAIL_CLANG_IGNORE_WARNING("-Wunknown-warning-option") \
|
||||
META_HPP_DETAIL_CLANG_IGNORE_WARNING("-Wfloat-equal") \
|
||||
META_HPP_DETAIL_CLANG_IGNORE_WARNING("-Wordered-compare-function-pointers")
|
||||
|
||||
#define META_HPP_DETAIL_IGNORE_COMPARISON_WARNINGS_POP() META_HPP_DETAIL_CLANG_IGNORE_WARNINGS_POP()
|
||||
|
||||
@@ -17,6 +17,7 @@ namespace meta_hpp::detail
|
||||
|
||||
bad_const_access,
|
||||
bad_uvalue_access,
|
||||
bad_uvalue_operation,
|
||||
|
||||
bad_argument_cast,
|
||||
bad_instance_cast,
|
||||
@@ -36,6 +37,8 @@ namespace meta_hpp::detail
|
||||
return "bad const access";
|
||||
case error_code::bad_uvalue_access:
|
||||
return "bad uvalue access";
|
||||
case error_code::bad_uvalue_operation:
|
||||
return "bad uvalue operation";
|
||||
case error_code::bad_argument_cast:
|
||||
return "bad argument cast";
|
||||
case error_code::bad_instance_cast:
|
||||
|
||||
124
headers/meta.hpp/meta_detail/value_traits/equals_traits.hpp
Normal file
124
headers/meta.hpp/meta_detail/value_traits/equals_traits.hpp
Normal file
@@ -0,0 +1,124 @@
|
||||
/*******************************************************************************
|
||||
* 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-2024, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../../meta_base.hpp"
|
||||
#include "../../meta_uvalue.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
struct equals_traits;
|
||||
|
||||
template < typename T >
|
||||
concept has_equals_traits //
|
||||
= requires(const T& v) { equals_traits<T>{}(v, v); };
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
requires requires(const T& v) {
|
||||
{ v == v } -> std::convertible_to<bool>;
|
||||
} && (!class_kind<T> || type_list_arity_v<typename class_traits<T>::argument_types> == 0)
|
||||
struct equals_traits<T> {
|
||||
bool operator()(const T& l, const T& r) const {
|
||||
META_HPP_DETAIL_IGNORE_COMPARISON_WARNINGS_PUSH()
|
||||
return l == r;
|
||||
META_HPP_DETAIL_IGNORE_COMPARISON_WARNINGS_POP()
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
requires has_equals_traits<T>
|
||||
struct equals_traits<std::array<T, Size>> {
|
||||
using value_t = std::array<T, Size>;
|
||||
|
||||
bool operator()(const value_t& l, const value_t& r) const {
|
||||
return l == r;
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T, typename Traits, typename Allocator >
|
||||
requires has_equals_traits<T>
|
||||
struct equals_traits<std::basic_string<T, Traits, Allocator>> {
|
||||
using value_t = std::basic_string<T, Traits, Allocator>;
|
||||
|
||||
bool operator()(const value_t& l, const value_t& r) const {
|
||||
return l == r;
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T, typename Traits >
|
||||
requires has_equals_traits<T>
|
||||
struct equals_traits<std::basic_string_view<T, Traits>> {
|
||||
using value_t = std::basic_string_view<T, Traits>;
|
||||
|
||||
bool operator()(const value_t& l, const value_t& r) const {
|
||||
return l == r;
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T, typename Allocator >
|
||||
requires has_equals_traits<T>
|
||||
struct equals_traits<std::vector<T, Allocator>> {
|
||||
using value_t = std::vector<T, Allocator>;
|
||||
|
||||
bool operator()(const value_t& l, const value_t& r) const {
|
||||
return l == r;
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T >
|
||||
struct equals_traits<std::shared_ptr<T>> {
|
||||
using value_t = std::shared_ptr<T>;
|
||||
|
||||
bool operator()(const value_t& l, const value_t& r) const {
|
||||
return l == r;
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T, typename Deleter >
|
||||
struct equals_traits<std::unique_ptr<T, Deleter>> {
|
||||
using value_t = std::unique_ptr<T, Deleter>;
|
||||
|
||||
bool operator()(const value_t& l, const value_t& r) const {
|
||||
return l == r;
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T >
|
||||
requires has_equals_traits<T>
|
||||
struct equals_traits<std::reference_wrapper<T>> {
|
||||
using value_t = std::reference_wrapper<T>;
|
||||
|
||||
bool operator()(const value_t& l, const value_t& r) const {
|
||||
return l.get() == r.get();
|
||||
}
|
||||
};
|
||||
|
||||
template < typename... Ts >
|
||||
requires(... && has_equals_traits<Ts>)
|
||||
struct equals_traits<std::tuple<Ts...>> {
|
||||
using value_t = std::tuple<Ts...>;
|
||||
|
||||
bool operator()(const value_t& l, const value_t& r) const {
|
||||
return l == r;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#define META_HPP_DECLARE_EQUALS_TRAITS_FOR(T) \
|
||||
namespace meta_hpp::detail \
|
||||
{ \
|
||||
template <> \
|
||||
struct equals_traits<T> { \
|
||||
bool operator()(const T& l, const T& r) const { \
|
||||
return l == r; \
|
||||
} \
|
||||
}; \
|
||||
}
|
||||
124
headers/meta.hpp/meta_detail/value_traits/less_traits.hpp
Normal file
124
headers/meta.hpp/meta_detail/value_traits/less_traits.hpp
Normal file
@@ -0,0 +1,124 @@
|
||||
/*******************************************************************************
|
||||
* 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-2024, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../../meta_base.hpp"
|
||||
#include "../../meta_uvalue.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
struct less_traits;
|
||||
|
||||
template < typename T >
|
||||
concept has_less_traits //
|
||||
= requires(const T& v) { less_traits<T>{}(v, v); };
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
requires requires(const T& v) {
|
||||
{ v < v } -> std::convertible_to<bool>;
|
||||
} && (!class_kind<T> || type_list_arity_v<typename class_traits<T>::argument_types> == 0)
|
||||
struct less_traits<T> {
|
||||
bool operator()(const T& l, const T& r) const {
|
||||
META_HPP_DETAIL_IGNORE_COMPARISON_WARNINGS_PUSH()
|
||||
return l < r;
|
||||
META_HPP_DETAIL_IGNORE_COMPARISON_WARNINGS_POP()
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
requires has_less_traits<T>
|
||||
struct less_traits<std::array<T, Size>> {
|
||||
using value_t = std::array<T, Size>;
|
||||
|
||||
bool operator()(const value_t& l, const value_t& r) const {
|
||||
return l < r;
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T, typename Traits, typename Allocator >
|
||||
requires has_less_traits<T>
|
||||
struct less_traits<std::basic_string<T, Traits, Allocator>> {
|
||||
using value_t = std::basic_string<T, Traits, Allocator>;
|
||||
|
||||
bool operator()(const value_t& l, const value_t& r) const {
|
||||
return l < r;
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T, typename Traits >
|
||||
requires has_less_traits<T>
|
||||
struct less_traits<std::basic_string_view<T, Traits>> {
|
||||
using value_t = std::basic_string_view<T, Traits>;
|
||||
|
||||
bool operator()(const value_t& l, const value_t& r) const {
|
||||
return l < r;
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T, typename Allocator >
|
||||
requires has_less_traits<T>
|
||||
struct less_traits<std::vector<T, Allocator>> {
|
||||
using value_t = std::vector<T, Allocator>;
|
||||
|
||||
bool operator()(const value_t& l, const value_t& r) const {
|
||||
return l < r;
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T >
|
||||
struct less_traits<std::shared_ptr<T>> {
|
||||
using value_t = std::shared_ptr<T>;
|
||||
|
||||
bool operator()(const value_t& l, const value_t& r) const {
|
||||
return l < r;
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T, typename Deleter >
|
||||
struct less_traits<std::unique_ptr<T, Deleter>> {
|
||||
using value_t = std::unique_ptr<T, Deleter>;
|
||||
|
||||
bool operator()(const value_t& l, const value_t& r) const {
|
||||
return l < r;
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T >
|
||||
requires has_less_traits<T>
|
||||
struct less_traits<std::reference_wrapper<T>> {
|
||||
using value_t = std::reference_wrapper<T>;
|
||||
|
||||
bool operator()(const value_t& l, const value_t& r) const {
|
||||
return l.get() < r.get();
|
||||
}
|
||||
};
|
||||
|
||||
template < typename... Ts >
|
||||
requires(... && has_less_traits<Ts>)
|
||||
struct less_traits<std::tuple<Ts...>> {
|
||||
using value_t = std::tuple<Ts...>;
|
||||
|
||||
bool operator()(const value_t& l, const value_t& r) const {
|
||||
return l < r;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#define META_HPP_DECLARE_LESS_TRAITS_FOR(T) \
|
||||
namespace meta_hpp::detail \
|
||||
{ \
|
||||
template <> \
|
||||
struct less_traits<T> { \
|
||||
bool operator()(const T& l, const T& r) const { \
|
||||
return l < r; \
|
||||
} \
|
||||
}; \
|
||||
}
|
||||
@@ -291,11 +291,10 @@ namespace meta_hpp
|
||||
|
||||
[[nodiscard]] const evalue_list& get_evalues() const noexcept;
|
||||
|
||||
[[nodiscard]] evalue get_evalue(std::string_view name) const noexcept;
|
||||
|
||||
template < enum_kind Enum >
|
||||
[[nodiscard]] std::string_view value_to_name(Enum value) const;
|
||||
[[nodiscard]] const uvalue& name_to_value(std::string_view name) const noexcept;
|
||||
[[nodiscard]] evalue value_to_evalue(Enum value) const;
|
||||
[[nodiscard]] evalue value_to_evalue(const uvalue& value) const;
|
||||
[[nodiscard]] evalue name_to_evalue(std::string_view name) const noexcept;
|
||||
};
|
||||
|
||||
class function_type final : public type_base<function_type> {
|
||||
|
||||
@@ -39,7 +39,36 @@ namespace meta_hpp
|
||||
return data_->evalues;
|
||||
}
|
||||
|
||||
inline evalue enum_type::get_evalue(std::string_view name) const noexcept {
|
||||
template < enum_kind Enum >
|
||||
evalue enum_type::value_to_evalue(Enum value) const {
|
||||
if ( *this != resolve_type<Enum>() ) {
|
||||
return evalue{};
|
||||
}
|
||||
|
||||
for ( const evalue& evalue : data_->evalues ) {
|
||||
if ( evalue.get_value().as<Enum>() == value ) {
|
||||
return evalue;
|
||||
}
|
||||
}
|
||||
|
||||
return evalue{};
|
||||
}
|
||||
|
||||
inline evalue enum_type::value_to_evalue(const uvalue& value) const {
|
||||
if ( *this != value.get_type() ) {
|
||||
return evalue{};
|
||||
}
|
||||
|
||||
for ( const evalue& evalue : data_->evalues ) {
|
||||
if ( evalue.get_value().equals(value) ) {
|
||||
return evalue;
|
||||
}
|
||||
}
|
||||
|
||||
return evalue{};
|
||||
}
|
||||
|
||||
inline evalue enum_type::name_to_evalue(std::string_view name) const noexcept {
|
||||
for ( const evalue& evalue : data_->evalues ) {
|
||||
if ( evalue.get_name() == name ) {
|
||||
return evalue;
|
||||
@@ -47,27 +76,4 @@ namespace meta_hpp
|
||||
}
|
||||
return evalue{};
|
||||
}
|
||||
|
||||
template < enum_kind Enum >
|
||||
std::string_view enum_type::value_to_name(Enum value) const {
|
||||
if ( resolve_type<Enum>() != *this ) {
|
||||
return std::string_view{};
|
||||
}
|
||||
|
||||
for ( const evalue& evalue : data_->evalues ) {
|
||||
if ( evalue.get_value().as<Enum>() == value ) {
|
||||
return evalue.get_name();
|
||||
}
|
||||
}
|
||||
|
||||
return std::string_view{};
|
||||
}
|
||||
|
||||
inline const uvalue& enum_type::name_to_value(std::string_view name) const noexcept {
|
||||
if ( const evalue& value = get_evalue(name) ) {
|
||||
return value.get_value();
|
||||
}
|
||||
static const uvalue empty_value;
|
||||
return empty_value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,6 +77,12 @@ namespace meta_hpp
|
||||
[[nodiscard]] uvalue unmap() const;
|
||||
[[nodiscard]] bool has_unmap_op() const noexcept;
|
||||
|
||||
[[nodiscard]] bool less(const uvalue& other) const;
|
||||
[[nodiscard]] bool has_less_op() const noexcept;
|
||||
|
||||
[[nodiscard]] bool equals(const uvalue& other) const;
|
||||
[[nodiscard]] bool has_equals_op() const noexcept;
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] bool is() const noexcept;
|
||||
|
||||
|
||||
@@ -12,7 +12,9 @@
|
||||
|
||||
#include "../meta_detail/value_traits/copy_traits.hpp"
|
||||
#include "../meta_detail/value_traits/deref_traits.hpp"
|
||||
#include "../meta_detail/value_traits/equals_traits.hpp"
|
||||
#include "../meta_detail/value_traits/index_traits.hpp"
|
||||
#include "../meta_detail/value_traits/less_traits.hpp"
|
||||
#include "../meta_detail/value_traits/unmap_traits.hpp"
|
||||
|
||||
#include "../meta_detail/value_utilities/uarg.hpp"
|
||||
@@ -31,6 +33,9 @@ namespace meta_hpp
|
||||
uvalue (*const deref)(const storage_u& self);
|
||||
uvalue (*const index)(const storage_u& self, std::size_t i);
|
||||
uvalue (*const unmap)(const storage_u& self);
|
||||
|
||||
bool (*const less)(const storage_u& l, const storage_u& r);
|
||||
bool (*const equals)(const storage_u& l, const storage_u& r);
|
||||
// NOLINTEND(*-avoid-const-or-ref-data-members)
|
||||
|
||||
template < typename T >
|
||||
@@ -233,6 +238,26 @@ namespace meta_hpp
|
||||
return nullptr;
|
||||
}
|
||||
}()},
|
||||
|
||||
.less{[]() {
|
||||
if constexpr ( detail::has_less_traits<Tp> ) {
|
||||
return +[](const storage_u& l, const storage_u& r) -> bool {
|
||||
return detail::less_traits<Tp>{}(*storage_cast<Tp>(l), *storage_cast<Tp>(r));
|
||||
};
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}()},
|
||||
|
||||
.equals{[]() {
|
||||
if constexpr ( detail::has_equals_traits<Tp> ) {
|
||||
return +[](const storage_u& l, const storage_u& r) -> bool {
|
||||
return detail::equals_traits<Tp>{}(*storage_cast<Tp>(l), *storage_cast<Tp>(r));
|
||||
};
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}()},
|
||||
};
|
||||
|
||||
return &table;
|
||||
@@ -368,9 +393,12 @@ namespace meta_hpp
|
||||
|
||||
inline uvalue uvalue::operator*() const {
|
||||
auto&& [tag, vtable] = vtable_t::unpack_vtag(*this);
|
||||
return tag != storage_e::nothing && vtable->deref != nullptr //
|
||||
? vtable->deref(storage_)
|
||||
: uvalue{};
|
||||
|
||||
if ( tag != storage_e::nothing && vtable->deref != nullptr ) {
|
||||
return vtable->deref(storage_);
|
||||
}
|
||||
|
||||
throw_exception(error_code::bad_uvalue_operation);
|
||||
}
|
||||
|
||||
inline bool uvalue::has_deref_op() const noexcept {
|
||||
@@ -380,9 +408,12 @@ namespace meta_hpp
|
||||
|
||||
inline uvalue uvalue::operator[](std::size_t index) const {
|
||||
auto&& [tag, vtable] = vtable_t::unpack_vtag(*this);
|
||||
return tag != storage_e::nothing && vtable->index != nullptr //
|
||||
? vtable->index(storage_, index)
|
||||
: uvalue{};
|
||||
|
||||
if ( tag != storage_e::nothing && vtable->index != nullptr ) {
|
||||
return vtable->index(storage_, index);
|
||||
}
|
||||
|
||||
throw_exception(error_code::bad_uvalue_operation);
|
||||
}
|
||||
|
||||
inline bool uvalue::has_index_op() const noexcept {
|
||||
@@ -392,21 +423,31 @@ namespace meta_hpp
|
||||
|
||||
inline uvalue uvalue::copy() const {
|
||||
auto&& [tag, vtable] = vtable_t::unpack_vtag(*this);
|
||||
return tag != storage_e::nothing && vtable->copy != nullptr //
|
||||
? vtable->copy(storage_)
|
||||
: uvalue{};
|
||||
|
||||
if ( tag == storage_e::nothing ) {
|
||||
return uvalue{};
|
||||
}
|
||||
|
||||
if ( vtable->copy != nullptr ) {
|
||||
return vtable->copy(storage_);
|
||||
}
|
||||
|
||||
throw_exception(error_code::bad_uvalue_operation);
|
||||
}
|
||||
|
||||
inline bool uvalue::has_copy_op() const noexcept {
|
||||
auto&& [tag, vtable] = vtable_t::unpack_vtag(*this);
|
||||
return tag != storage_e::nothing && vtable->copy != nullptr;
|
||||
return tag == storage_e::nothing || vtable->copy != nullptr;
|
||||
}
|
||||
|
||||
inline uvalue uvalue::unmap() const {
|
||||
auto&& [tag, vtable] = vtable_t::unpack_vtag(*this);
|
||||
return tag != storage_e::nothing && vtable->unmap != nullptr //
|
||||
? vtable->unmap(storage_)
|
||||
: uvalue{};
|
||||
|
||||
if ( tag != storage_e::nothing && vtable->unmap != nullptr ) {
|
||||
return vtable->unmap(storage_);
|
||||
}
|
||||
|
||||
throw_exception(error_code::bad_uvalue_operation);
|
||||
}
|
||||
|
||||
inline bool uvalue::has_unmap_op() const noexcept {
|
||||
@@ -414,6 +455,62 @@ namespace meta_hpp
|
||||
return tag != storage_e::nothing && vtable->unmap != nullptr;
|
||||
}
|
||||
|
||||
inline bool uvalue::less(const uvalue& other) const {
|
||||
if ( this == &other ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto&& [l_tag, l_vtable] = vtable_t::unpack_vtag(*this);
|
||||
auto&& [r_tag, r_vtable] = vtable_t::unpack_vtag(other);
|
||||
|
||||
if ( l_tag != r_tag || l_tag == storage_e::nothing ) {
|
||||
return l_tag < r_tag;
|
||||
}
|
||||
|
||||
if ( l_vtable != r_vtable ) {
|
||||
return l_vtable->type < r_vtable->type;
|
||||
}
|
||||
|
||||
if ( l_vtable->less != nullptr ) {
|
||||
return l_vtable->less(storage_, other.storage_);
|
||||
}
|
||||
|
||||
throw_exception(error_code::bad_uvalue_operation);
|
||||
}
|
||||
|
||||
inline bool uvalue::has_less_op() const noexcept {
|
||||
auto&& [tag, vtable] = vtable_t::unpack_vtag(*this);
|
||||
return tag == storage_e::nothing || vtable->less != nullptr;
|
||||
}
|
||||
|
||||
inline bool uvalue::equals(const uvalue& other) const {
|
||||
if ( this == &other ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
auto&& [l_tag, l_vtable] = vtable_t::unpack_vtag(*this);
|
||||
auto&& [r_tag, r_vtable] = vtable_t::unpack_vtag(other);
|
||||
|
||||
if ( l_tag != r_tag || l_tag == storage_e::nothing ) {
|
||||
return l_tag == r_tag;
|
||||
}
|
||||
|
||||
if ( l_vtable != r_vtable ) {
|
||||
return l_vtable->type == r_vtable->type;
|
||||
}
|
||||
|
||||
if ( l_vtable->equals != nullptr ) {
|
||||
return l_vtable->equals(storage_, other.storage_);
|
||||
}
|
||||
|
||||
throw_exception(error_code::bad_uvalue_operation);
|
||||
}
|
||||
|
||||
inline bool uvalue::has_equals_op() const noexcept {
|
||||
auto&& [tag, vtable] = vtable_t::unpack_vtag(*this);
|
||||
return tag == storage_e::nothing || vtable->equals != nullptr;
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
bool uvalue::is() const noexcept {
|
||||
static_assert(std::is_same_v<T, std::decay_t<T>>);
|
||||
|
||||
@@ -191,6 +191,12 @@ public:
|
||||
uvalue unmap() const;
|
||||
bool has_unmap_op() const noexcept;
|
||||
|
||||
bool less(const uvalue& other) const;
|
||||
bool has_less_op() const noexcept;
|
||||
|
||||
bool equals(const uvalue& other) const;
|
||||
bool has_equals_op() const noexcept;
|
||||
|
||||
template < typename T >
|
||||
bool is() const noexcept;
|
||||
|
||||
|
||||
@@ -308,11 +308,10 @@ public:
|
||||
|
||||
const evalue_list& get_evalues() const noexcept;
|
||||
|
||||
evalue get_evalue(std::string_view name) const noexcept;
|
||||
|
||||
template < enum_kind Enum >
|
||||
std::string_view value_to_name(Enum value) const;
|
||||
const uvalue& name_to_value(std::string_view name) const noexcept;
|
||||
evalue value_to_evalue(Enum value) const;
|
||||
evalue value_to_evalue(const uvalue& value) const;
|
||||
evalue name_to_evalue(std::string_view name) const noexcept;
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
Reference in New Issue
Block a user