mirror of
https://github.com/aantron/better-enums.git
synced 2025-12-06 16:56:42 +08:00
Merge pull request #1 from Shelim/indexable
Added indexable properties on enums
This commit is contained in:
commit
e3898a835f
55
enum.h
55
enum.h
@ -343,6 +343,12 @@ BETTER_ENUMS_CONSTEXPR_ static T* _or_null(optional<T*> maybe)
|
||||
return maybe ? *maybe : BETTER_ENUMS_NULLPTR;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
BETTER_ENUMS_CONSTEXPR_ static T _or_zero(optional<T> maybe)
|
||||
{
|
||||
return maybe ? *maybe : static_cast<T>(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Functional sequencing. This is essentially a comma operator wrapped in a
|
||||
@ -615,6 +621,15 @@ class Enum { \
|
||||
_from_integral_unchecked(_integral value); \
|
||||
BETTER_ENUMS_CONSTEXPR_ static _optional \
|
||||
_from_integral_nothrow(_integral value); \
|
||||
\
|
||||
BETTER_ENUMS_CONSTEXPR_ _integral _to_index() const; \
|
||||
BETTER_ENUMS_IF_EXCEPTIONS( \
|
||||
BETTER_ENUMS_CONSTEXPR_ static Enum _from_index(_integral value); \
|
||||
) \
|
||||
BETTER_ENUMS_CONSTEXPR_ static Enum \
|
||||
_from_index_unchecked(_integral value); \
|
||||
BETTER_ENUMS_CONSTEXPR_ static _optional \
|
||||
_from_index_nothrow(_integral value); \
|
||||
\
|
||||
ToStringConstexpr const char* _to_string() const; \
|
||||
BETTER_ENUMS_IF_EXCEPTIONS( \
|
||||
@ -661,6 +676,8 @@ class Enum { \
|
||||
BETTER_ENUMS_CONSTEXPR_ static _optional_index \
|
||||
_from_value_loop(_integral value, std::size_t index = 0); \
|
||||
BETTER_ENUMS_CONSTEXPR_ static _optional_index \
|
||||
_from_index_loop(_integral value, std::size_t index = 0); \
|
||||
BETTER_ENUMS_CONSTEXPR_ static _optional_index \
|
||||
_from_string_loop(const char *name, std::size_t index = 0); \
|
||||
BETTER_ENUMS_CONSTEXPR_ static _optional_index \
|
||||
_from_string_nocase_loop(const char *name, std::size_t index = 0); \
|
||||
@ -700,6 +717,17 @@ Enum::_from_value_loop(Enum::_integral value, std::size_t index) \
|
||||
_from_value_loop(value, index + 1); \
|
||||
} \
|
||||
\
|
||||
BETTER_ENUMS_CONSTEXPR_ inline Enum::_optional \
|
||||
Enum::_from_index_loop(Enum::_integral value, std::size_t index) \
|
||||
{ \
|
||||
return \
|
||||
index == _size() ? \
|
||||
_optional() : \
|
||||
BETTER_ENUMS_NS(Enum)::index == value ? \
|
||||
_optional(_value_array[index]) : \
|
||||
_from_value_loop(value, index + 1); \
|
||||
} \
|
||||
\
|
||||
BETTER_ENUMS_CONSTEXPR_ inline Enum::_optional_index \
|
||||
Enum::_from_string_loop(const char *name, std::size_t index) \
|
||||
{ \
|
||||
@ -727,6 +755,33 @@ BETTER_ENUMS_CONSTEXPR_ inline Enum::_integral Enum::_to_integral() const \
|
||||
return _integral(_value); \
|
||||
} \
|
||||
\
|
||||
BETTER_ENUMS_CONSTEXPR_ inline Enum::_integral Enum::_to_index() const \
|
||||
{ \
|
||||
return _from_value_loop(value) \
|
||||
} \
|
||||
\
|
||||
BETTER_ENUMS_CONSTEXPR_ inline Enum \
|
||||
Enum::_from_index_unchecked(_integral value) \
|
||||
{ \
|
||||
return \
|
||||
::better_enums::_or_zero(_from_index_nothrow(value)); \
|
||||
} \
|
||||
\
|
||||
BETTER_ENUMS_CONSTEXPR_ inline Enum::_optional \
|
||||
Enum::_from_index_nothrow(_integral value) \
|
||||
{ \
|
||||
return _from_index_loop(value); \
|
||||
} \
|
||||
\
|
||||
BETTER_ENUMS_IF_EXCEPTIONS( \
|
||||
BETTER_ENUMS_CONSTEXPR_ inline Enum Enum::_from_index(_integral value) \
|
||||
{ \
|
||||
return \
|
||||
::better_enums::_or_throw(_from_index_nothrow(value), \
|
||||
#Enum "::_from_index: invalid argument"); \
|
||||
} \
|
||||
) \
|
||||
\
|
||||
BETTER_ENUMS_CONSTEXPR_ inline Enum \
|
||||
Enum::_from_integral_unchecked(_integral value) \
|
||||
{ \
|
||||
|
||||
@ -313,6 +313,103 @@ class EnumTests : public CxxTest::TestSuite {
|
||||
+test::Namespaced::One);
|
||||
TS_ASSERT_EQUALS(strcmp(*test::Namespaced::_names().begin(), "One"), 0);
|
||||
}
|
||||
|
||||
void test_to_index()
|
||||
{
|
||||
TS_ASSERT_EQUALS((+Channel::Red)._to_index(), 0);
|
||||
TS_ASSERT_EQUALS((+Channel::Green)._to_index(), 1);
|
||||
TS_ASSERT_EQUALS((+Channel::Blue)._to_index(), 2);
|
||||
|
||||
TS_ASSERT_EQUALS((+Depth::HighColor)._to_index(), 0);
|
||||
TS_ASSERT_EQUALS((+Depth::TrueColor)._to_index(), 1);
|
||||
|
||||
TS_ASSERT_EQUALS((+Compression::None)._to_index(), 0);
|
||||
TS_ASSERT_EQUALS((+Compression::Huffman)._to_index(), 1);
|
||||
TS_ASSERT_EQUALS((+Compression::Default)._to_index(), 2);
|
||||
}
|
||||
|
||||
void test_from_index()
|
||||
{
|
||||
TS_ASSERT_EQUALS((+Channel::Red)), Depth::_from_index(0));
|
||||
TS_ASSERT_EQUALS((+Channel::Green), Depth::_from_index(1));
|
||||
TS_ASSERT_EQUALS((+Channel::Blue), Depth::_from_index(1));
|
||||
TS_ASSERT_THROWS(Channel::_from_index(42), std::runtime_error);
|
||||
|
||||
TS_ASSERT_EQUALS((+Depth::HighColor)), Depth::_from_index(0));
|
||||
TS_ASSERT_EQUALS((+Depth::TrueColor), Depth::_from_index(1));
|
||||
TS_ASSERT_THROWS(Depth::_from_index(42), std::runtime_error);
|
||||
|
||||
TS_ASSERT_EQUALS((+Compression::None), Compression::_from_index(0));
|
||||
TS_ASSERT_EQUALS((+Compression::Huffman), Compression::_from_index(1));
|
||||
TS_ASSERT_EQUALS((+Compression::Default), Compression::_from_index(2));
|
||||
TS_ASSERT_THROWS(Compression::_from_index(42), std::runtime_error);
|
||||
}
|
||||
|
||||
void test_from_index_nothrow()
|
||||
{
|
||||
better_enums::optional<Channel> maybe_channel = Channel::_from_index(0);
|
||||
TS_ASSERT(maybe_channel);
|
||||
TS_ASSERT_EQUALS(*maybe_channel, +Channel::Red);
|
||||
|
||||
maybe_channel = Channel::_from_index(1);
|
||||
TS_ASSERT(maybe_channel);
|
||||
TS_ASSERT_EQUALS(*maybe_channel, +Channel::Green);
|
||||
|
||||
maybe_channel = Channel::_from_index(2);
|
||||
TS_ASSERT(maybe_channel);
|
||||
TS_ASSERT_EQUALS(*maybe_channel, +Channel::Blue);
|
||||
TS_ASSERT(!Channel::_from_index(45));
|
||||
|
||||
better_enums::optional<Depth> maybe_depth = Depth::_from_index(0);
|
||||
TS_ASSERT(maybe_depth);
|
||||
TS_ASSERT_EQUALS(*maybe_depth, +Depth::HighColor);
|
||||
|
||||
maybe_depth = Depth::_from_index(1);
|
||||
TS_ASSERT(maybe_depth);
|
||||
TS_ASSERT_EQUALS(*maybe_depth, +Depth::TrueColor);
|
||||
TS_ASSERT(!Channel::_from_index(45));
|
||||
|
||||
better_enums::optional<Depth> maybe_depth = Depth::_from_index(0);
|
||||
TS_ASSERT(maybe_depth);
|
||||
TS_ASSERT_EQUALS(*maybe_depth, +Depth::HighColor);
|
||||
|
||||
maybe_depth = Depth::_from_index(1);
|
||||
TS_ASSERT(maybe_depth);
|
||||
TS_ASSERT_EQUALS(*maybe_depth, +Depth::TrueColor);
|
||||
TS_ASSERT(!Channel::_from_index(45));
|
||||
|
||||
better_enums::optional<Depth> maybe_depth = Depth::_from_index(0);
|
||||
TS_ASSERT(maybe_depth);
|
||||
TS_ASSERT_EQUALS(*maybe_depth, +Depth::HighColor);
|
||||
|
||||
better_enums::optional<Compression> maybe_compression = Compression::_from_index(0);
|
||||
TS_ASSERT(maybe_compression);
|
||||
TS_ASSERT_EQUALS(*maybe_compression, +Compression::None);
|
||||
|
||||
maybe_compression = Compression::_from_index(1);
|
||||
TS_ASSERT(maybe_compression);
|
||||
TS_ASSERT_EQUALS(*maybe_compression, +Compression::Huffman);
|
||||
|
||||
maybe_compression = Compression::_from_index(2);
|
||||
TS_ASSERT(maybe_compression);
|
||||
TS_ASSERT_EQUALS(*maybe_compression, +Compression::Default);
|
||||
TS_ASSERT(!Compression::_from_index(45));
|
||||
}
|
||||
|
||||
void test_from_index_unchecked()
|
||||
{
|
||||
|
||||
TS_ASSERT_EQUALS((+Channel::Red), Channel::_from_index_unchecked(0));
|
||||
TS_ASSERT_EQUALS((+Channel::Green), Channel::_from_index_unchecked(1));
|
||||
TS_ASSERT_EQUALS((+Channel::Blue), Channel::_from_index_unchecked(2));
|
||||
|
||||
TS_ASSERT_EQUALS((+Depth::HighColor)), Depth::_from_index_unchecked(0));
|
||||
TS_ASSERT_EQUALS((+Depth::TrueColor), Depth::_from_index_unchecked(1));
|
||||
|
||||
TS_ASSERT_EQUALS((+Compression::None), Compression::_from_index_unchecked(0));
|
||||
TS_ASSERT_EQUALS((+Compression::Huffman), Compression::_from_index_unchecked(1));
|
||||
TS_ASSERT_EQUALS((+Compression::Default), Compression::_from_index_unchecked(2));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user