You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
from_number meaning, you pass the underlying value of the enum?
For ostream, are you saying that operator<< does something to to_string, i.e. "Bar(1)" instead of "Bar"? That seems a bit surprising that ostream wouldn't be consistent with to_string don't you think?
In both cases, why an abort call? Seems like returning an empty optional is much better; it allows for proper error handling and the user is free to call abort if the optional is empty.
I decided to make istream operator >> permissive in that it understands text or numbers, on the basis that with IO it's helpful to be strict when writing and permissive when reading.
namespace quoine::wrap::wise_enum
{
using namespace ::wise_enum;
template < class T, std::enable_if_t< wise_enum::is_wise_enum_v< T > > * = nullptr >
void wise_enum_from_stream(std::istream &is, T &arg)
{
auto buffer = std::string();
is >> buffer;
if (is)
{
auto o = wise_enum::from_string< T >(buffer);
if (o.has_value())
arg = *o;
else
{
using int_type = std::underlying_type_t< T >;
auto num = static_cast< int_type >(std::atoll(buffer.c_str()));
bool found = false;
for (auto e : wise_enum::range< T >)
{
if (static_cast< int_type >(e.value) == num)
{
arg = e.value;
found = true;
break;
}
}
if (not found)
is.setstate(std::ios::failbit);
}
}
}
} // namespace quoine::wrap::wise_enum
#define WISE_ENUM_ENABLE_IO(Enum) \
inline auto operator<<(std::ostream &os, Enum e)->std::ostream & { return os << ::quoine::wrap::wise_enum::to_string(e); } \
inline auto operator>>(std::istream &is, Enum &e)->std::istream & \
{ \
::quoine::wrap::wise_enum::wise_enum_from_stream(is, e); \
return is; \
}
#define WISE_ENUM_MEMBER_ENABLE_IO(Enum) \
friend auto operator<<(std::ostream &os, Enum e)->std::ostream & { return os << ::quoine::wrap::wise_enum::to_string(e); } \
friend auto operator>>(std::istream &is, Enum &e)->std::istream & \
{ \
::quoine::wrap::wise_enum::wise_enum_from_stream(is, e); \
return is; \
}
@karol-koczwara-ig @madmongo1 I kind of want to be careful here because obviously there are infinite things that could be added. My main goal is to keep a relatively small set of basis functions that you should be able to implement other things "on top of", non-intrusively (so you can use wise_enum the way you want without needing to fork it).
Right now, I think I will do from_integer with similar API to from_string. It will be implemented using another public function, verify_enum, which takes an enum and returns a bool, and simply verify that the value passed in is actually a valid value (which users might find useful for other things).
I'm not really sure about the stream operators. Using operator<< as the debug representation doesn't seem like a very standard thing to do. Different people might want different debug representations too (and not everyone even uses/likes streams), so I think maybe it's just better to let users do what they want on top of to_string. Again, as @madmongo1 's code snippet shows, it's not necessary to modify wise_enum itself to get the desired behavior.
I'm not really sure why to_string would abort for an invalid argument. Currently it returns an empty string; some people may want to do something other than abort with this. If you want to abort, then you can wrap that function with my_to_string, do the if check and abort yourself. I don't really want to have lots of #defines that switch behaviors between incompatible states.
Activity
quicknir commentedon Apr 4, 2019
from_number meaning, you pass the underlying value of the enum?
For ostream, are you saying that operator<< does something to to_string, i.e. "Bar(1)" instead of "Bar"? That seems a bit surprising that ostream wouldn't be consistent with to_string don't you think?
In both cases, why an abort call? Seems like returning an empty optional is much better; it allows for proper error handling and the user is free to call abort if the optional is empty.
koczwak commentedon Apr 4, 2019
madmongo1 commentedon May 18, 2019
I did a similar thing. very useful.
I decided to make
istream operator >>permissive in that it understands text or numbers, on the basis that with IO it's helpful to be strict when writing and permissive when reading.quicknir commentedon May 18, 2019
@karol-koczwara-ig @madmongo1 I kind of want to be careful here because obviously there are infinite things that could be added. My main goal is to keep a relatively small set of basis functions that you should be able to implement other things "on top of", non-intrusively (so you can use wise_enum the way you want without needing to fork it).
Right now, I think I will do from_integer with similar API to from_string. It will be implemented using another public function, verify_enum, which takes an enum and returns a bool, and simply verify that the value passed in is actually a valid value (which users might find useful for other things).
I'm not really sure about the stream operators. Using operator<< as the debug representation doesn't seem like a very standard thing to do. Different people might want different debug representations too (and not everyone even uses/likes streams), so I think maybe it's just better to let users do what they want on top of to_string. Again, as @madmongo1 's code snippet shows, it's not necessary to modify wise_enum itself to get the desired behavior.
I'm not really sure why to_string would abort for an invalid argument. Currently it returns an empty string; some people may want to do something other than abort with this. If you want to abort, then you can wrap that function with
my_to_string, do the if check and abort yourself. I don't really want to have lots of #defines that switch behaviors between incompatible states.