diff --git a/enum.h b/enum.h index 2dac25c8..ac8c4956 100644 --- a/enum.h +++ b/enum.h @@ -555,7 +555,7 @@ constexpr const char *_final_ ## index = \ // The enums proper. -#define BETTER_ENUMS_NS(EnumType) better_enums::_data_ ## EnumType +#define BETTER_ENUMS_NS(EnumType) better_enums_data_ ## EnumType #ifdef BETTER_ENUMS_VC2008_WORKAROUNDS @@ -574,12 +574,10 @@ constexpr const char *_final_ ## index = \ DeclareInitialize, DefineInitialize, CallInitialize, \ Enum, Underlying, ...) \ \ -namespace better_enums { \ -namespace _data_ ## Enum { \ +namespace better_enums_data_ ## Enum { \ \ BETTER_ENUMS_ID(GenerateSwitchType(Underlying, __VA_ARGS__)) \ \ -} \ } \ \ class Enum { \ @@ -662,8 +660,7 @@ class Enum { \ friend struct ::better_enums::_initialize_at_program_start; \ }; \ \ -namespace better_enums { \ -namespace _data_ ## Enum { \ +namespace better_enums_data_ ## Enum { \ \ static ::better_enums::_initialize_at_program_start \ _force_initialization; \ @@ -675,7 +672,6 @@ BETTER_ENUMS_CONSTEXPR_ const Enum _value_array[] = \ \ BETTER_ENUMS_ID(GenerateStrings(Enum, __VA_ARGS__)) \ \ -} \ } \ \ BETTER_ENUMS_CONSTEXPR_ inline const Enum \ @@ -834,7 +830,33 @@ BETTER_ENUMS_CONSTEXPR_ inline bool operator <=(const Enum &a, const Enum &b) \ BETTER_ENUMS_CONSTEXPR_ inline bool operator >(const Enum &a, const Enum &b) \ { return a._to_integral() > b._to_integral(); } \ BETTER_ENUMS_CONSTEXPR_ inline bool operator >=(const Enum &a, const Enum &b) \ - { return a._to_integral() >= b._to_integral(); } + { return a._to_integral() >= b._to_integral(); } \ + \ + \ +template \ +std::basic_ostream& \ +operator <<(std::basic_ostream& stream, const Enum &value) \ +{ \ + return stream << value._to_string(); \ +} \ + \ +template \ +std::basic_istream& \ +operator >>(std::basic_istream& stream, Enum &value) \ +{ \ + std::basic_string buffer; \ + \ + stream >> buffer; \ + ::better_enums::optional converted = \ + Enum::_from_string_nothrow(buffer.c_str()); \ + \ + if (converted) \ + value = *converted; \ + else \ + stream.setstate(std::basic_istream::failbit); \ + \ + return stream; \ +} @@ -1140,45 +1162,6 @@ BETTER_ENUMS_CONSTEXPR_ map make_map(T (*f)(Enum)) return map(f); } - - -// Stream I/O operators. - -// This template is used as a sort of enable_if for SFINAE. It should be -// possible to use std::enable_if, however is not available in -// C++98. Non-char streams are currently not supported. -template -struct only_if_enum { typedef T type; }; - } -template -inline typename better_enums::only_if_enum, - typename Enum::_enumerated>::type& -operator <<(std::basic_ostream& stream, const Enum &value) -{ - return stream << value._to_string(); -} - -template -inline typename better_enums::only_if_enum, - typename Enum::_enumerated>::type& -operator >>(std::basic_istream& stream, Enum &value) -{ - std::basic_string buffer; - - stream >> buffer; - better_enums::optional converted = - Enum::_from_string_nothrow(buffer.c_str()); - - if (converted) - value = *converted; - else - stream.setstate(std::basic_istream::failbit); - - return stream; -} - - - #endif // #ifndef BETTER_ENUMS_ENUM_H diff --git a/test/cxxtest/general.h b/test/cxxtest/general.h index a680da51..caa54146 100644 --- a/test/cxxtest/general.h +++ b/test/cxxtest/general.h @@ -1,3 +1,4 @@ +#include #include #include #include @@ -125,6 +126,17 @@ static_assert_1(*Channel::_values().begin() == +Channel::Red); static_assert_1(*(Channel::_values().end() - 1) == +Channel::Blue); static_assert_1(Channel::_values()[1] == +Channel::Green); +namespace name_clash_test { + +struct Foo {}; +std::ostream& operator<<(std::ostream&, Foo); + +BETTER_ENUM(Enum, int, ONE, TWO, THREE) + +static_assert_1((std::is_same() << +Enum::ONE), std::ostream&>())); + +} + #ifdef BETTER_ENUMS_CONSTEXPR_TO_STRING constexpr bool same_string(const char *r, const char *s, size_t index = 0)