mirror of
https://github.com/aantron/better-enums.git
synced 2025-12-06 08:46:42 +08:00
Added workarounds for VC2008.
VC2008 has two quirks. It generates linking errors if a copy constructor is not explicitly defined on a Better Enum, and it has a buggy interaction between the ternary operator and throw. This change detects VC2008 and generates alternative code for that compiler. Having an explicitly-defined copy constructor in a literal type appears to cause an internal compiler error in g++4.7, and causes a spurious compilation failure in g++4.8. For this reason, the copy constructor generation is conditioned on the compiler. The replacement code for the ternary operator is also generated conditionally, because it uses an if-statement. The normal code has to compile in a constexpr context, and so has to use the ternary operator instead of the if-statement. Resolves #6.
This commit is contained in:
parent
124c09f2f0
commit
6278793a0b
34
enum.h
34
enum.h
@ -54,6 +54,9 @@
|
||||
# ifndef _CPPUNWIND
|
||||
# define BETTER_ENUMS__NO_EXCEPTIONS
|
||||
# endif
|
||||
# if _MSC_VER < 1600
|
||||
# define BETTER_ENUMS__VC2008_WORKAROUNDS
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef BETTER_ENUMS_CONSTEXPR
|
||||
@ -315,12 +318,27 @@ _map_index(const Element *array, optional<std::size_t> index)
|
||||
return index ? (CastTo)array[*index] : optional<CastTo>();
|
||||
}
|
||||
|
||||
#ifdef BETTER_ENUMS__VC2008_WORKAROUNDS
|
||||
|
||||
#define BETTER_ENUMS__OR_THROW \
|
||||
if (!maybe) \
|
||||
throw std::runtime_error(message); \
|
||||
\
|
||||
return *maybe;
|
||||
|
||||
#else
|
||||
|
||||
#define BETTER_ENUMS__OR_THROW \
|
||||
return maybe ? *maybe : throw std::runtime_error(message);
|
||||
|
||||
#endif
|
||||
|
||||
BETTER_ENUMS__IF_EXCEPTIONS(
|
||||
template <typename T>
|
||||
BETTER_ENUMS__CONSTEXPR static T _or_throw(optional<T> maybe,
|
||||
const char *message)
|
||||
{
|
||||
return maybe ? *maybe : throw std::runtime_error(message);
|
||||
BETTER_ENUMS__OR_THROW
|
||||
}
|
||||
)
|
||||
|
||||
@ -609,6 +627,18 @@ constexpr const char *_final_ ## index = \
|
||||
|
||||
#define BETTER_ENUMS__NS(EnumType) better_enums::_data_ ## EnumType
|
||||
|
||||
#ifdef BETTER_ENUMS__VC2008_WORKAROUNDS
|
||||
|
||||
#define BETTER_ENUMS__COPY_CONSTRUCTOR(Enum) \
|
||||
BETTER_ENUMS__CONSTEXPR Enum(const Enum &other) : \
|
||||
_value(other._value) { }
|
||||
|
||||
#else
|
||||
|
||||
#define BETTER_ENUMS__COPY_CONSTRUCTOR(Enum)
|
||||
|
||||
#endif
|
||||
|
||||
#define BETTER_ENUMS__TYPE(SetUnderlyingType, SwitchType, GenerateSwitchType, \
|
||||
GenerateStrings, ToStringConstexpr, \
|
||||
DeclareInitialize, DefineInitialize, CallInitialize,\
|
||||
@ -637,6 +667,8 @@ class Enum { \
|
||||
BETTER_ENUMS__CONSTEXPR Enum(_enumerated value) : \
|
||||
_value(_mapping::from_integral(value)) { } \
|
||||
\
|
||||
BETTER_ENUMS__COPY_CONSTRUCTOR(Enum) \
|
||||
\
|
||||
BETTER_ENUMS__CONSTEXPR operator SwitchType(Enum)() const \
|
||||
{ \
|
||||
return (SwitchType(Enum))_mapping::to_integral(_value); \
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user