diff --git a/include/magic_enum.hpp b/include/magic_enum.hpp index fca7f5c..5388f02 100644 --- a/include/magic_enum.hpp +++ b/include/magic_enum.hpp @@ -1336,7 +1336,7 @@ std::basic_ostream& operator<<(std::basic_ostream& o using U = underlying_type_t; if constexpr (detail::supported::value) { - if (const auto name = magic_enum::enum_flags_name(value); !name.empty()) { + if (const auto name = enum_flags_name(value); !name.empty()) { for (const auto c : name) { os.put(c); } @@ -1353,6 +1353,29 @@ std::basic_ostream& operator<<(std::basic_ostream& o } // namespace magic_enum::ostream_operators +namespace istream_operators { + +template = 0> +std::basic_istream& operator>>(std::basic_istream& is, E& value) { + std::basic_string in; + is >> in; + if (const auto v = enum_cast(in)) { + value = *v; + } else { + is.setstate(std::ios::failbit); + } + return is; +} + +} // namespace magic_enum::istream_operators + +namespace iostream_operators { + +using namespace ostream_operators; +using namespace istream_operators; + +} // namespace magic_enum::iostream_operators + namespace bitwise_operators { template = 0> diff --git a/test/test.cpp b/test/test.cpp index 2f995cf..8f5bb8a 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -670,10 +670,11 @@ TEST_CASE("enum_entries") { } TEST_CASE("ostream_operators") { - auto test_ostream = [](auto e, std::string_view name) { + auto test_ostream = [](auto e, std::string name) { using namespace magic_enum::ostream_operators; std::stringstream ss; ss << e; + REQUIRE(ss); REQUIRE(ss.str() == name); }; @@ -714,6 +715,36 @@ TEST_CASE("ostream_operators") { test_ostream(std::make_optional(static_cast(0)), "0"); } +TEST_CASE("istream_operators") { + auto test_istream = [](const auto e, std::string name) { + using namespace magic_enum::istream_operators; + std::istringstream ss(name); + std::decay_t v; + ss >> v; + REQUIRE(ss); + REQUIRE(v == e); + }; + + test_istream(Color::GREEN, "GREEN"); + test_istream(Color::BLUE, "BLUE"); + + test_istream(Numbers::two, "two"); + test_istream(Numbers::three, "three"); + + test_istream(Directions::Down, "Down"); + test_istream(Directions::Right, "Right"); + test_istream(Directions::Left, "Left"); + +#if defined(MAGIC_ENUM_ENABLE_NONASCII) + test_istream(Language::한국어, "한국어"); + test_istream(Language::English, "English"); + test_istream(Language::😃, "😃"); +#endif + + test_istream(number::two, "two"); + test_istream(number::three, "three"); +} + TEST_CASE("bitwise_operators") { using namespace magic_enum::bitwise_operators; diff --git a/test/test_flags.cpp b/test/test_flags.cpp index 07f5a7c..aa7a9bc 100644 --- a/test/test_flags.cpp +++ b/test/test_flags.cpp @@ -598,7 +598,7 @@ TEST_CASE("enum_entries") { } TEST_CASE("ostream_operators") { - auto test_ostream = [](auto e, std::string_view name) { + auto test_ostream = [](auto e, std::string name) { using namespace magic_enum::ostream_operators; std::stringstream ss; ss << e; @@ -646,6 +646,42 @@ TEST_CASE("ostream_operators") { test_ostream(std::make_optional(static_cast(0)), "0"); } +TEST_CASE("istream_operators") { + auto test_istream = [](const auto e, std::string name) { + using namespace magic_enum::istream_operators; + std::istringstream ss(name); + std::decay_t v; + ss >> v; + REQUIRE(v == e); + REQUIRE(ss); + }; + + test_istream(Color::GREEN, "GREEN"); + test_istream(Color::BLUE, "BLUE"); + test_istream(Color::BLUE | Color::RED, "RED|BLUE"); + test_istream(Color::BLUE | Color::RED | Color::RED, "RED|BLUE"); + + test_istream(Numbers::two, "two"); + test_istream(Numbers::three, "three"); + test_istream(Numbers::many, "many"); + + test_istream(Directions::Down, "Down"); + test_istream(Directions::Right, "Right"); + test_istream(Directions::Left, "Left"); + test_istream(Directions::Right | Directions::Left, "Left|Right"); + +#if defined(MAGIC_ENUM_ENABLE_NONASCII) + test_istream(Language::한국어, "한국어"); + test_istream(Language::English, "English"); + test_istream(Language::😃, "😃"); +#endif + + test_istream(number::two, "two"); + test_istream(number::three, "three"); + test_istream(number::four, "four"); + test_istream(number::four | number::one, "one|four"); +} + TEST_CASE("bitwise_operators") { SECTION("operator^") { REQUIRE(enum_integer(~Color::RED) == ~enum_integer(Color::RED));