mikejsavage.co.uk • About • Archive • RSS • Thanks for blocking ads! Blocking ads owns: AdGuard for Safari / uBlock Origin for everything else
It's annoying having to write stuff like
for( MyEnum i = MyEnum( 0 ); i < MyEnum_Count; i = MyEnum( i + 1 ) ) {
Doubly so with enums that are really bitfields where you can actually do arithmetic, they just return non-enum types and C++ doesn't allow the implicit casts back to the enum in all situations.
At some point you might get sick of this and start implementing arithmetic operators on your enums, but why not just do it for all of them?
template< typename E > concept IsEnum = __is_enum( E );
template< typename E > using UnderlyingType = __underlying_type( E );
template< IsEnum E > void operator++( E & x, int ) { x = E( UnderlyingType< E >( x ) + 1 ); }
template< IsEnum E > void operator&=( E & lhs, E rhs ) { lhs = E( UnderlyingType< E >( lhs ) & UnderlyingType< E >( rhs ) ); }
template< IsEnum E > void operator|=( E & lhs, E rhs ) { lhs = E( UnderlyingType< E >( lhs ) | UnderlyingType< E >( rhs ) ); }
// you can do these in base C++ but they return ints and MyEnum x = int; doesn't compile
template< IsEnum E > constexpr E operator&( E lhs, E rhs ) { return E( UnderlyingType< E >( lhs ) & UnderlyingType< E >( rhs ) ); }
template< IsEnum E > constexpr E operator|( E lhs, E rhs ) { return E( UnderlyingType< E >( lhs ) | UnderlyingType< E >( rhs ) ); }
template< IsEnum E > constexpr E operator~( E x ) { return E( ~UnderlyingType< E >( x ) ); }
Every compiler supports the same intrinsics, so no need for compiler specific code or the STL.