From 571f1419c73ad4ecd8e5f80f6655fde0a3bc1d3b Mon Sep 17 00:00:00 2001 From: Anton Bachin Date: Sun, 3 May 2015 05:43:29 -0400 Subject: [PATCH] Flattened class hierarchy. --- Enum.h | 12 ++---- EnumInternal.h | 108 +++++++++++++++++++++++++------------------------ 2 files changed, 59 insertions(+), 61 deletions(-) diff --git a/Enum.h b/Enum.h index 1f3bed3..5653638 100644 --- a/Enum.h +++ b/Enum.h @@ -22,13 +22,7 @@ // TODO Try to make names and values into values instead of functions. #define ENUM(EnumType, UnderlyingType, ...) \ - _ENUM_ARRAYS(EnumType, UnderlyingType, __VA_ARGS__); \ - \ - class EnumType : public _enum::_Implementation { \ - using _Super = _enum::_Implementation; \ - using _Super::_Super; \ - friend _Super; \ - friend _Super::_ValueIterable; \ - }; \ - \ + _ENUM_TAG_DECLARATION(EnumType); \ + _ENUM_ARRAYS(EnumType, UnderlyingType, _ENUM_TAG(EnumType), __VA_ARGS__); \ + using EnumType = _enum::_Enum<_enum::_ENUM_TAG(EnumType)>; \ _ENUM_STATIC_DEFINITIONS(EnumType); diff --git a/EnumInternal.h b/EnumInternal.h index 0526057..a0a64b4 100644 --- a/EnumInternal.h +++ b/EnumInternal.h @@ -68,7 +68,7 @@ namespace _enum { // Forward declaration of _Internal, for use in a friend declation in _Iterable. -template class _Implementation; +template class _Enum; // TODO Make these standard-compliant. /// Template for iterable objects over enum names and values. @@ -205,7 +205,7 @@ class _Iterable { private: constexpr _Iterable() { }; - friend _Implementation; + friend EnumType; }; @@ -488,17 +488,21 @@ static inline const char * const* _processNames(const char * const *rawNames, return processedNames; } -template class _GeneratedArrays; +#define _ENUM_TAG(EnumType) _tag_ ## EnumType +#define _ENUM_TAG_DECLARATION(EnumType) \ + namespace _enum { \ + struct _ENUM_TAG(EnumType); \ + } + +template class _GeneratedArrays; // TODO Move definitions to last macro. -#define _ENUM_ARRAYS(EnumType, UnderlyingType, ...) \ - class EnumType; \ - \ +#define _ENUM_ARRAYS(EnumType, UnderlyingType, Tag, ...) \ namespace _enum { \ \ template <> \ - class _GeneratedArrays { \ + class _GeneratedArrays { \ protected: \ using _Integral = UnderlyingType; \ \ @@ -518,22 +522,22 @@ template class _GeneratedArrays; _ENUM_PP_COUNT(__VA_ARGS__); \ }; \ \ - constexpr _GeneratedArrays::_Enumerated _ENUM_WEAK \ - _GeneratedArrays::_value_array[]; \ + constexpr _GeneratedArrays::_Enumerated _ENUM_WEAK \ + _GeneratedArrays::_value_array[]; \ \ constexpr const char * _ENUM_WEAK \ - _GeneratedArrays::_name_array[]; \ + _GeneratedArrays::_name_array[]; \ \ template <> \ const char * const * _ENUM_WEAK \ - _Implementation::_processedNames = nullptr; \ + _Enum::_processedNames = nullptr; \ \ } -template -class _Implementation : public _GeneratedArrays { +template +class _Enum : public _GeneratedArrays { protected: - using _arrays = _GeneratedArrays; + using _arrays = _GeneratedArrays; using _arrays::_value_array; using _arrays::_name_array; @@ -544,27 +548,27 @@ class _Implementation : public _GeneratedArrays { using _arrays::_size; static_assert(_size > 0, "no constants defined in enum type"); - static const EnumType _first; - static const EnumType _last; - static const EnumType _min; - static const EnumType _max; + static const _Enum _first; + static const _Enum _last; + static const _Enum _min; + static const _Enum _max; static const size_t _span; - _Implementation() = delete; - constexpr _Implementation(_Enumerated constant) : _value(constant) { } + _Enum() = delete; + constexpr _Enum(_Enumerated constant) : _value(constant) { } constexpr _Integral to_int() const { return _value; } - constexpr static EnumType _from_int(_Integral value) + constexpr static _Enum _from_int(_Integral value) { return _value_array[_from_int_loop(value, true)]; } - constexpr static EnumType _from_int_unchecked(_Integral value) + constexpr static _Enum _from_int_unchecked(_Integral value) { return (_Enumerated)value; } @@ -581,12 +585,12 @@ class _Implementation : public _GeneratedArrays { throw std::domain_error("Enum::_to_string: invalid enum value"); } - constexpr static EnumType _from_string(const char *name) + constexpr static _Enum _from_string(const char *name) { return _value_array[_from_string_loop(name, true)]; } - constexpr static EnumType _from_string_nocase(const char *name) + constexpr static _Enum _from_string_nocase(const char *name) { return _value_array[_from_string_nocase_loop(name, true)]; } @@ -625,11 +629,11 @@ class _Implementation : public _GeneratedArrays { return _processedNames[index]; } - using _ValueIterable = _Iterable>; - using _NameIterable = _Iterable>; + using _ValueIterable = _Iterable<_Enum, _ValueIterator<_Enum>>; + using _NameIterable = _Iterable<_Enum, _NameIterator<_Enum>>; - friend _ValueIterator; - friend _NameIterator; + friend _ValueIterator<_Enum>; + friend _NameIterator<_Enum>; public: static const _ValueIterable _values; @@ -678,43 +682,43 @@ class _Implementation : public _GeneratedArrays { _from_string_nocase_loop(name, throw_exception, index + 1); } - // TODO Remove static casts wherever reasonable. // TODO Make many of these constexpr. + // TODO Review which operators should be present. public: - bool operator ==(const EnumType &other) const - { return static_cast(*this)._value == other._value; } + bool operator ==(const _Enum &other) const + { return _value == other._value; } bool operator ==(const _Enumerated value) const - { return static_cast(*this)._value == value; } + { return _value == value; } template bool operator ==(T other) const = delete; - bool operator !=(const EnumType &other) const + bool operator !=(const _Enum &other) const { return !(*this == other); } bool operator !=(const _Enumerated value) const { return !(*this == value); } template bool operator !=(T other) const = delete; - bool operator <(const EnumType &other) const - { return static_cast(*this)._value < other._value; } + bool operator <(const _Enum &other) const + { return _value < other._value; } bool operator <(const _Enumerated value) const - { return static_cast(*this)._value < value; } + { return _value < value; } template bool operator <(T other) const = delete; - bool operator <=(const EnumType &other) const - { return static_cast(*this)._value <= other._value; } + bool operator <=(const _Enum &other) const + { return _value <= other._value; } bool operator <=(const _Enumerated value) const - { return static_cast(*this)._value <= value; } + { return _value <= value; } template bool operator <=(T other) const = delete; - bool operator >(const EnumType &other) const - { return static_cast(*this)._value > other._value; } + bool operator >(const _Enum &other) const + { return _value > other._value; } bool operator >(const _Enumerated value) const - { return static_cast(*this)._value > value; } + { return _value > value; } template bool operator >(T other) const = delete; - bool operator >=(const EnumType &other) const - { return static_cast(*this)._value >= other._value; } + bool operator >=(const _Enum &other) const + { return _value >= other._value; } bool operator >=(const _Enumerated value) const - { return static_cast(*this)._value >= value; } + { return _value >= value; } template bool operator >=(T other) const = delete; int operator -() const = delete; @@ -742,29 +746,29 @@ class _Implementation : public _GeneratedArrays { namespace _enum { \ \ template <> \ - constexpr EnumType::_ValueIterable _Implementation::_values{}; \ + constexpr EnumType::_ValueIterable EnumType::_values{}; \ \ template <> \ - constexpr EnumType::_NameIterable _Implementation::_names{}; \ + constexpr EnumType::_NameIterable EnumType::_names{}; \ \ template <> \ - constexpr EnumType _Implementation::_first = \ + constexpr EnumType EnumType::_first = \ EnumType::_from_int(EnumType::_value_array[0]); \ \ template <> \ - constexpr EnumType _Implementation::_last = \ + constexpr EnumType EnumType::_last = \ EnumType::_from_int(EnumType::_value_array[EnumType::_size - 1]); \ \ template <> \ - constexpr EnumType _Implementation::_min = \ + constexpr EnumType EnumType::_min = \ _range::_findMin(EnumType::_value_array, EnumType::_size); \ \ template <> \ - constexpr EnumType _Implementation::_max = \ + constexpr EnumType EnumType::_max = \ _range::_findMax(EnumType::_value_array, EnumType::_size); \ \ template <> \ - constexpr size_t _Implementation::_span = \ + constexpr size_t EnumType::_span = \ _max.to_int() - _min.to_int() + 1; \ \ }