Internal improvements to stream operators.

This commit is contained in:
Anton Bachin 2015-06-12 12:56:51 -05:00
parent 0f63667106
commit 11a1c26494

42
enum.h
View File

@ -1041,49 +1041,37 @@ BETTER_ENUMS__CONSTEXPR inline bool operator !=(const Enum &a, const Enum &b) \
namespace better_enums {
// This template is used both as a sort of enable_if for SFINAE, and to delay
// the compiler from type-checking certain expressions. enum.h does not include
// <iostream> or <string>, because those headers parse very slowly. Therefore,
// it is necessary to prevent the compiler from trying to do anything with types
// from those headers unless the operators <<, >> are actually used, by which
// point the user is expected to have included <iostream> and/or <string>. The
// alternative is to simply move the operator definitions into a separate add-on
// header file.
//
// It should be possible to use std::enable_if, however <type_traits> is not
// available in C++98.
// This template is used as a sort of enable_if for SFINAE. It should be
// possible to use std::enable_if, however <type_traits> is not available in
// C++98. Non-char streams are currently not supported.
template <typename T, typename Enum>
struct hide { typedef T type; };
struct only_if_enum { typedef T type; };
}
template <typename Enum>
inline typename better_enums::hide<std::ostream,
typename Enum::_enumerated>::type&
operator <<(std::ostream& stream, const Enum& value)
template <typename Char, typename Traits, typename Enum>
inline typename better_enums::only_if_enum<std::basic_ostream<Char, Traits>,
typename Enum::_enumerated>::type&
operator <<(std::basic_ostream<Char, Traits>& stream, const Enum &value)
{
return stream << value._to_string();
}
template <typename Enum>
inline typename better_enums::hide<std::istream,
typename Enum::_enumerated>::type&
operator >>(typename better_enums::hide<std::istream, Enum>::type& stream,
Enum& value)
template <typename Char, typename Traits, class Enum>
inline typename better_enums::only_if_enum<std::basic_istream<Char, Traits>,
typename Enum::_enumerated>::type&
operator >>(std::basic_istream<Char, Traits>& stream, Enum &value)
{
typedef typename better_enums::hide<std::ios_base, Enum>::type ios_base;
typedef typename better_enums::hide<std::string, Enum>::type string;
string buffer;
std::basic_string<Char, Traits> buffer;
stream >> buffer;
better_enums::optional<Enum> converted =
better_enums::optional<Enum> converted =
Enum::_from_string_nothrow(buffer.c_str());
if (converted)
value = *converted;
else
stream.setstate(ios_base::failbit);
stream.setstate(std::basic_istream<Char, Traits>::failbit);
return stream;
}