Support no default value enum_switch
would it be possible to support enum_switch the way that we're used to use overload pattern with std::visit? e.g
return magic_enum::enum_switch( overloaded{
[]( my_enum::val1 arg ) -> int { /* handle val1 enum */ return 1; },
[]( auto arg ) -> int { /* handle the rest */ throw notimplemented; /* or just return sth */ }
});
instead of
return magic_enum::enum_switch( overloaded{
[]( my_enum::val1 arg ) -> int { /* handle val1 enum */ return 1; },
[]( auto arg ) -> int { /* handle the rest */ throw notimplemented; /* or just return sth */ }
}, /*redundant default*/ int(2));
// or probably worse
auto r = magic_enum::enum_switch(
[]( my_enum::val1 arg ) -> int { /* handle val1 enum */ return 1; }
, int(2)
);
if( r == 2 ) throw notimplemented;
I think forcing adding default Result produces boilerplate.
If you need to iterate over all values then use enum_for_each
enum_switch does not take a default value, it takes a value that will be handled in the switch
Yes, sorry I made a mistake in the example above.
return magic_enum::enum_switch( overloaded{
[]( my_enum::val1 arg ) -> int { /* handle val1 enum */ return 1; },
[]( auto arg ) -> int { /* handle the rest */ throw notimplemented; /* or just return sth */ }
}, enumValue);
I'm taking about return value of enum_switch from docs
template <typename Result = void, typename E, typename Lambda>
constexpr Result enum_switch(Lambda&& lambda, E value);
template <typename Result, typename E, typename Lambda>
constexpr Result enum_switch(Lambda&& lambda, E value, Result&& result);
If I want to return a value from enum_switch (Result is not void) I need to pass additional argument and It'd be nice not being forced to do so.
return magic_enum::enum_switch<int>( overloaded{
[]( my_enum::val1 arg ) -> int { /* handle val1 enum */ return 1; },
[]( auto arg ) -> int { /* handle the rest */ throw notimplemented; /* or just return sth */ }
}, enumValue);
see https://github.com/Neargye/magic_enum/blob/master/example/example_switch.cpp
ok, but I still need to specify the return type explicitly.
In case of std::visit as long as all the lambdas in overload return the same value there is no need for additional code.
std::visit( overloaded { []( const Type1 val ) { return int(1); },
[]( const Type2 val ) { return float(2); }
}); // compilation error
std::visit( overloaded { []( const Type1 val ) { return int(1); },
[]( const Type2 val ) -> int { return float(2); }
}); // fine
std::visit( overloaded { []( const Type1 val ) { return int(1); },
[]( const Type2 val ) { return int(2); }
}); // fine
I'll see what i can do
The switch is not required to handle all cases (especially unrecognized values), so when explicitly isn't set the result (or the type) for the magic_enum::enum_switch call, the result type cannot be guessed for all case return value.
What will be the result for example 4 different result type without explicitly set the result? std::common_type<R1, R2 ...>? And if it isn't constructible, or a base class?
What will be the result of any unrecognized (unnamed) enum value? How can be handle this? This will cause error message, when the result type is not default constructible.
What if someone didn't handle all case, and lambda can't be instantiated with some value?
Many unanswered question will come up if we enable enum_switch result type deduction from only the callback.
So the current rule is: If you explicit set the type, you are the responsible to this type can be default construct. If you want to use result type that cannot be default construct, you have to pass the default result object. Else, the switch return void.
and there are no "better" way to do otherwise.
@schaumb I like the option to make it consistent with the std::visit, so that there is a fallback for all possible enums or defaults. This is also consistent with the enum warnings switch that you need to case all values or the default case.
If you don't mind, I can add the necessary traits for the checks inside the function.
If I wrote a swich, I don't need to write all case / default.
I think this is an another use-case, and probably not a switch but a visit.
I think this can be a different function which uses enum_switch with type-traits check, to handle all case + default, and guess the result type.
enum_visit ?
@Sarna555 https://github.com/Neargye/magic_enum/pull/212 I tried to improve the deduction of the return type of the enum_switch, but the function signature changed a little
enum_switch will try to deduce return the type, if this is not possible, then you still need have to specify the return type explicitly
@Sarna555 #212 I tried to improve the deduction of the return type of the enum_switch, but the function signature changed a little
enum_switch will try to deduce return the type, if this is not possible, then you still need have to specify the return type explicitly
Yes, this is what I meant, not having to specify the return type. Is it something that could be merged to the master branch and released?
@Sarna555 #212 I tried to improve the deduction of the return type of the enum_switch, but the function signature changed a little enum_switch will try to deduce return the type, if this is not possible, then you still need have to specify the return type explicitly
Yes, this is what I meant, not having to specify the return type. Is it something that could be merged to the master branch and released?
I'll take it to the master and release after some additional testing.
Fix in master Will be include in next release