In the library I am currently developing, I have this little thing:
enum class BoolMode : uint8_t
{
TrueIfFalse = 0,
TrueIfTrue = 1
};
This is a tiny helper used to easily produce reversible condition checks, while only having to create a single implementation that's easy to write and to read...
For this helper to be effectively easy to use, I had to define the comparison operator for bool (obviously). I did it like that:
inline constexpr bool operator ==(const bool boolValue, const BoolMode mode) noexcept
{
return (boolValue == static_cast<const bool>(mode));
}
inline constexpr bool operator !=(const bool boolValue, const BoolMode mode) noexcept
{
return (boolValue != static_cast<const bool>(mode));
}
inline constexpr bool operator ==(const BoolMode mode, const bool boolValue) noexcept
{
return (boolValue == static_cast<const bool>(mode));
}
inline constexpr bool operator !=(const BoolMode mode, const bool boolValue) noexcept
{
return (boolValue != static_cast<const bool>(mode));
}
I was wondering if there would have any benefits to define BoolMode this way:
enum class BoolMode : bool
{
TrueIfFalse = false,
TrueIfTrue = true
};
As it does not spare the effort to have to define the comparison operators anyway, I don't see what the best option would be...
Questions:
- What is the purpose to use
boolas the underlying type ? - Is there concrete examples of the use of it ?
- Is there anything in this code to which I should be aware of ?
- Any clues and/or suggestions to improve the code ?
Thanks in advance.
If
boolis the underlying type ofX, thenstd::underlying_type_t<X>isbool.Variables of type
boolandenums withboolunderlying type only have two valid states;0and1.Variables of type
uint8_tandenums withuint8_tunderlying type has 256 valid states;0through255.Both a compiler, and metaprogramming, can be aware of this difference. A custom
notstd::optionalcould use the fact that3is not a validboolto makenotstd::optional<bool>take up a single byte (its value would be0forfalse,1fortrueand3fornullopt).This could also be used to smart-pack
bools orenums withboolunderlying type into bit-fields when serialized.In theory, the assembly generated for
==whenboolis the underlying type could do a bit comparison instead of zero or non-zero byte check. I could imagine platforms where that is faster. Meanwhile, ifuint8_twas the underlying type, a non-zero value anywhere in the enum means it maps totruewhen cast tobool.None of these issues are likely.