Restored separate compilation support.

This commit is contained in:
Anton Bachin 2015-05-03 20:18:06 -04:00
parent 5e9026c615
commit 8fdaa54e08

60
enum.h
View File

@ -430,14 +430,11 @@ template <typename Tag> class _GeneratedArrays;
enum _Enumerated : _Integral { __VA_ARGS__ }; \ enum _Enumerated : _Integral { __VA_ARGS__ }; \
\ \
protected: \ protected: \
static constexpr _Enumerated _value_array[] = \ constexpr static _Enumerated _value_array[] = \
{ _ENUM_EAT_ASSIGN(_Enumerated, __VA_ARGS__) }; \ { _ENUM_EAT_ASSIGN(_Enumerated, __VA_ARGS__) }; \
\ \
static constexpr const char *_name_array[] = \ constexpr static const char *_name_array[] = \
{ _ENUM_STRINGIZE(__VA_ARGS__) }; \ { _ENUM_STRINGIZE(__VA_ARGS__) }; \
\
static constexpr size_t _size = \
_ENUM_PP_COUNT(__VA_ARGS__); \
}; \ }; \
\ \
} }
@ -453,15 +450,18 @@ class _Enum : public _GeneratedArrays<Tag> {
using typename _arrays::_Enumerated; using typename _arrays::_Enumerated;
using typename _arrays::_Integral; using typename _arrays::_Integral;
using _arrays::_size; constexpr static const size_t _size =
sizeof(_value_array) / sizeof(_Enumerated);
static_assert(_size > 0, "no constants defined in enum type"); static_assert(_size > 0, "no constants defined in enum type");
static const _Enum _first; constexpr static const _Enumerated _first = _value_array[0];
static const _Enum _last; constexpr static const _Enumerated _last = _value_array[_size - 1];
static const _Enum _min; constexpr static const _Enumerated _min =
static const _Enum _max; _range::_findMin(_value_array, _size);
constexpr static const _Enumerated _max =
_range::_findMax(_value_array, _size);
static const size_t _span; constexpr static const size_t _span = _max - _min + 1;
_Enum() = delete; _Enum() = delete;
constexpr _Enum(_Enumerated constant) : _value(constant) { } constexpr _Enum(_Enumerated constant) : _value(constant) { }
@ -471,12 +471,12 @@ class _Enum : public _GeneratedArrays<Tag> {
return _value; return _value;
} }
constexpr static _Enum _from_int(_Integral value) constexpr static const _Enum _from_int(_Integral value)
{ {
return _value_array[_from_int_loop(value, true)]; return _value_array[_from_int_loop(value, true)];
} }
constexpr static _Enum _from_int_unchecked(_Integral value) constexpr static const _Enum _from_int_unchecked(_Integral value)
{ {
return (_Enumerated)value; return (_Enumerated)value;
} }
@ -493,12 +493,12 @@ class _Enum : public _GeneratedArrays<Tag> {
throw std::domain_error("Enum::_to_string: invalid enum value"); throw std::domain_error("Enum::_to_string: invalid enum value");
} }
constexpr static _Enum _from_string(const char *name) constexpr static const _Enum _from_string(const char *name)
{ {
return _value_array[_from_string_loop(name, true)]; return _value_array[_from_string_loop(name, true)];
} }
constexpr static _Enum _from_string_nocase(const char *name) constexpr static const _Enum _from_string_nocase(const char *name)
{ {
return _value_array[_from_string_nocase_loop(name, true)]; return _value_array[_from_string_nocase_loop(name, true)];
} }
@ -647,34 +647,17 @@ class _Enum : public _GeneratedArrays<Tag> {
template <typename T> int operator ||(T other) const = delete; template <typename T> int operator ||(T other) const = delete;
}; };
// TODO Investigate what happens when this is mixed with multiple compilation. #define _ENUM_GLOBALS(EnumType, Tag) \
#define _ENUM_STATIC_DEFINITIONS(EnumType, Tag) \
namespace _enum { \ namespace _enum { \
\ \
template <> \ constexpr const EnumType operator +(EnumType::_Enumerated enumerated) \
constexpr EnumType::_ValueIterable EnumType::_values{}; \ { return (EnumType)enumerated; } \
\ \
template <> \ template <> \
constexpr EnumType::_NameIterable EnumType::_names{}; \ constexpr EnumType::_ValueIterable _ENUM_WEAK EnumType::_values{}; \
\ \
template <> \ template <> \
constexpr EnumType EnumType::_first = \ constexpr EnumType::_NameIterable _ENUM_WEAK EnumType::_names{}; \
EnumType::_from_int(EnumType::_value_array[0]); \
\
template <> \
constexpr EnumType EnumType::_last = \
EnumType::_from_int(EnumType::_value_array[EnumType::_size - 1]); \
\
template <> \
constexpr EnumType EnumType::_min = \
_range::_findMin(EnumType::_value_array, EnumType::_size); \
\
template <> \
constexpr EnumType EnumType::_max = \
_range::_findMax(EnumType::_value_array, EnumType::_size); \
\
template <> \
constexpr size_t EnumType::_span = _max.to_int() - _min.to_int() + 1; \
\ \
constexpr _GeneratedArrays<Tag>::_Enumerated _ENUM_WEAK \ constexpr _GeneratedArrays<Tag>::_Enumerated _ENUM_WEAK \
_GeneratedArrays<Tag>::_value_array[]; \ _GeneratedArrays<Tag>::_value_array[]; \
@ -683,6 +666,7 @@ class _Enum : public _GeneratedArrays<Tag> {
\ \
template <> \ template <> \
const char * const * _ENUM_WEAK EnumType::_processedNames = nullptr; \ const char * const * _ENUM_WEAK EnumType::_processedNames = nullptr; \
\
} }
} }
@ -691,4 +675,4 @@ class _Enum : public _GeneratedArrays<Tag> {
_ENUM_TAG_DECLARATION(EnumType); \ _ENUM_TAG_DECLARATION(EnumType); \
_ENUM_ARRAYS(EnumType, UnderlyingType, _ENUM_TAG(EnumType), __VA_ARGS__); \ _ENUM_ARRAYS(EnumType, UnderlyingType, _ENUM_TAG(EnumType), __VA_ARGS__); \
using EnumType = _enum::_Enum<_enum::_ENUM_TAG(EnumType)>; \ using EnumType = _enum::_Enum<_enum::_ENUM_TAG(EnumType)>; \
_ENUM_STATIC_DEFINITIONS(EnumType, _ENUM_TAG(EnumType)); _ENUM_GLOBALS(EnumType, _ENUM_TAG(EnumType));