Encoding agnostic parsing with c++2b - c++

Sometimes I have to parse text files with various encodings,
I wonder if the upcoming standard will bring some tools for this
because I'm not very happy with my current solution.
I'm not even sure if this is the right approach, however
I define a functor template to extract a character from stream:
#include <string>
#include <istream> // 'std::istream'
/////////////////////////////////////////////////////////////////////////////
// Generic implementation (couldn't resist to put one)
template<bool LE,typename T> class ReadChar
{
public:
std::istream& operator()(T& c, std::istream& in)
{
in.read(buf,bufsiz);
//const std::streamsize n_read = in ? bufsiz : in.gcount();
if(!in)
{// Could not real all bytes
c = std::char_traits<T>::eof();
}
else if constexpr (LE)
{// Little endian
c = buf[0];
for(int i=1; i<bufsiz; ++i) c |= buf[i] << (8*i);
}
else
{// Big endian
const std::size_t imax = bufsiz-1;
for(std::size_t i=0; i<imax; ++i) c |= buf[i] << (8*(imax-i));
c |= buf[imax];
}
return in;
}
private:
static constexpr std::size_t bufsiz = sizeof(T);
unsigned char buf[bufsiz];
};
/////////////////////////////////////////////////////////////////////////////
// Partial specialization for 32bit chars
template<bool LE> class ReadChar<LE,char32_t>
{
public:
std::istream& operator()(char32_t& c, std::istream& in)
{
in.read(buf,4);
if constexpr (LE) c = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24); // Little endian
else c = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; // Big endian
return in;
}
private:
char buf[4];
};
/////////////////////////////////////////////////////////////////////////////
// Partial specialization for 16bit chars
template<bool LE> class ReadChar<LE,char16_t>
{
public:
std::istream& operator()(char16_t& c, std::istream& in)
{
in.read(buf,2);
if constexpr (LE) c = buf[0] | (buf[1] << 8); // Little endian
else c = (buf[0] << 8) | buf[1]; // Big endian
return in;
}
private:
char buf[2];
};
/////////////////////////////////////////////////////////////////////////////
// Specialization for 8bit chars
template<> class ReadChar<false,char>
{
public:
std::istream& operator()(char& c, std::istream& in)
{
return in.get(c);
}
};
I use ReadChar to implement the parsing function:
template<typename T,bool LE> void parse(std::istream& fin)
{
ReadChar<LE,T> get;
T c;
while( get(c,fin) )
{
if(c==static_cast<T>('a')) {/* ... */} // Ugly comparison of T with a char literal
}
}
The ugly part are the static_cast when I need to compare to a char literal.
Then I use parse with this ugly boilerplate code:
#include <fstream> // 'std::ifstream'
std::ifstream fin("/path/to/file", std::ios::binary);
auto bom = check_bom(fin); // 'check_bom' function is quite trivial
if( bom.is_empty() ) parse<char>(fin);
else if( bom.is_utf8() ) parse<char>(fin); // In my case there's no need to handle multi-byte chars
else if( bom.is_utf16le() ) parse<char16_t,true>(fin);
else if( bom.is_utf16be() ) parse<char16_t,false>(fin);
else if( bom.is_utf32le() ) parse<char32_t,true>(fin);
else if( bom.is_utf32be() ) parse<char32_t,false>(fin);
else throw std::runtime_error("Unrecognized BOM");
Now, this solution has some quirks (can't use directly string literals in parse)
my question is if there are alternative approaches to this problem,
maybe using existing or upcoming standard facilities that I'm ignoring.

In c++17 we gained type-safe unions. These can be used to map between runtime and compile time state together with std::visit.
template<auto x>
using constant_t = std::integral_constant<std::decay_t<decltype(x)>, x>;
template<auto x>
constexpr constant_t<x> constant = {};
template<auto...Xs>
using variant_enum_t = std::variant< constant_t<Xs>... >;
enum class EBom {
None,
utf8,
utf16le,
utf16be,
utf32le,
utf32be,
count,
};
// you could use the existence of EBom::count and the
// assumption of contiguous indexes to automate this as well:
using VEBom = variant_enum< EBom::None, EBom::utf8, EBom::utf16le, EBom::utf16be, EBom::utf32le, EBom::utf32be >;
template<std::size_t...Is>
constexpr VEBom make_ve_bom( EBom bom, std::index_sequence<Is...> ) {
static constexpr VEBom retvals[] = {
constant<static_cast<EBom>(Is)>...
};
return retvals[ static_cast<std::size_t>(bom) ];
}
constexpr VEBom make_ve_bom( EBom bom ) {
return make_ve_bom( bom, std::make_index_sequence< static_cast<std::size_t>(EBom::count) >{} );
}
And now, with a runtime EBom value, we can produce a VEBom.
With that VEBom we can get at the type at compile time. Suppose you have traits, like:
template<EBom>
constexpr boom bom_is_bigendian_v = ???;
template<EBom>
using bom_chartype_t = ???;
you can now write code like:
std::visit( vebom, [&](auto bom) {
bom_chartype_t<bom> next = ???;
if constexpr (bom_is_bigendian_v<bom>) {
// swizzle
}
} );
etc.
Your non-DRY code
template<bool LE, class char_t> class ReadChar {
public:
std::istream& operator()(char_t& c, std::istream& in)
{
in.read(buf,sizeof(char_t));
c = buf[0] | (buf[1] << 8);
if constexpr(!LE)
reverse_bytes(&c);
return in;
}
private:
char buf[sizeof(char_t)];
};
becomes DRY with a simple rewrite.
Your boilerplate becomes:
std::ifstream fin("/path/to/file", std::ios::binary);
auto bom = check_bom(fin); // 'check_bom' function is quite trivial
if (bom.invalid())
throw std::runtime_error("Unrecognized BOM");
auto vebom = make_ve_bom( bom.getEnum() );
std:visit( vebom, [&]( auto ebom ) {
parse<bom_chartype_t<ebom>, !bom_is_bigendian_v<ebom>>( fin );
});
and the magic is done elsewhere.
That magic here is that the std::variant holds a bunch of integral_constants, each of which is both stateless and knows (in its type) what its value is.
So the only state in the std::variant is which of the stateless enum values it contains.
std::visit proceeds to call the passed in lambda with whichever stateless std::integral_constant that is in the std::variant. Within that lambda, we can use its value as a compile time constant, like we would with any other std::integral_constant.
The runtime state of the std::variant is actually the value of the EBom because of how we set it up, so converting an EBom to a VEBom is literally copying the number over (so, free). The magic is in std::visit, which automates writing the switch statement and injecting the compile time (integral constant) value for each of the possibilities into your code.
None of this is c++23. Most of it is c++17, I may have used a c++20 feature in there as well.
The above code is not compiled, it is just written. It probably contains typos, but the technique is sound.
--
We can automate the making of the variant type:
template<class Enum, std::size_t...Is, class VEnum=variant_enum<
constant_t<static_cast<Enum>(Is)>...
>>
constexpr VEnum make_venum( Enum e, std::index_sequence<Is...> ) {
static constexpr VEnum retvals[] = {
constant<static_cast<Enum>(Is)>...
};
return retvals[ static_cast<std::size_t>(e) ];
}
template<class Enum>
constexpr auto make_venum( Enum e ) {
return make_venum( e, std::make_index_sequence< static_cast<std::size_t>(Enum::count) >{} );
}
template<class Enum>
using venum_t = decltype(make_venum( static_cast<Enum>(0) ));
now our VEBom is just:
using VEBom = venum_t<EBom>;
Anyhow, a live example with typos fixed.

Related

Append structs to a vector<uint8_t>

I'm writing a message comuniction lib, and need to read some data to a struct, and append this struct to a vector, and read again, append again.
If in C language, memcpy works perfect, but I want is to make all code in C++11 code style.
I tried to use std::copy, but it needs a begin and end interator, so how exactly I can use std::copy like std::copy(&a, &a + sizeof(A), back_inserter(buffer));?
You can do this:
struct MyStruct {
int a;
double b;
int c;
};
std::vector<uint8_t> buffer;
MyStruct data { 42, 3.14159, 123 };
uint8_t* ptr = reinterpret_cast<uint8_t*>(&data);
std::copy(ptr, ptr + sizeof(data), back_inserter(buffer));
Note that std::copy in this case just reverts to std::memcpy underneath, and reinterpret_cast throws away all type safety of the language. Alexander's suggestion of using a static_assert is a good one.
EDIT:
Mário is right, back_inserter would cause std::copy to not be equivalent to std::memcpy. An alternative could be to reallocate your buffer first, then copy:
size_t len = buffer.size();
buffer.resize(len+sizeof(data));
std::copy(ptr, ptr + sizeof(data), buffer.data() + len);
(or something to that extent).
Here is a clean C++ way to do it:
First a simple range type:
template<class It>
struct range_t {
It b, e;
It begin() const { return b; }
It end() const { return e; }
std::size_t size() const { return end()-begin(); }
};
template<class It>
range_t<It> range(It s, It f) { return {s,f}; }
it represents a range of some iterators.
Next, some functions to treat pod data as bytes:
template<class T>
range_t< unsigned char* > as_bytes( T* t ) {
static_assert( std::is_trivially_copyable<T>::value, "bad idea if not trivially copyable" );
auto* ptr = reinterpret_cast<unsigned char*>(t);
return range(ptr, ptr+sizeof(T));
}
template<class T>
range_t< unsigned char const* > as_bytes( T const* t ) {
static_assert( std::is_trivially_copyable<T>::value, "bad idea if not trivially copyable" );
auto* ptr = reinterpret_cast<unsigned char const*>(t);
return range(ptr, ptr+sizeof(T));
}
both read and write versions.
Next, functions that take a structure and stuff them into a vector, or pop them out:
template<class T>
void push_bytes_in( std::vector<std::uint8_t>& target, T const* data ) {
auto bytes = as_bytes(data);
target.insert( target.end(), bytes.begin(), bytes.end() );
}
template<class T>
bool pop_bytes_out( std::vector<std::uint8_t>& src, T* data ) {
auto bytes = as_bytes(data);
if (bytes.size() > src.size()) return false;
std::copy( src.end()-bytes.size(), src.end(), bytes.begin() );
src.resize( src.size()-bytes.size() );
return true;
}
Finally, test code:
struct some_data {
int x, y;
char buff[1024];
};
std::vector<std::uint8_t> bytes;
some_data data{1,2, "hello"};
push_bytes_in( bytes, &data );
some_data d2;
if (!pop_bytes_out( bytes, &d2)) {
std::cout << "failed\n";
return -1;
}
std::cout << d2.buff << "\n";
Live example.
We could optimize push bytes if they turn out to be too slow to pre-size the buffer, then shove the bytes in using std copy or memcpy. However, you should be careful to ensure exponential data reservation in that case.
template<class T>
void push_bytes_in( std::vector<std::uint8_t>& target, T const* data ) {
if (target.capacity() < target.size()+sizeof(T)) {
target.reserve( target.capacity()*3/2 +1 );
}
auto bytes = as_bytes(data);
target.resize( target.size() + sizeof(T) );
std::copy( bytes.begin(), bytes.end(), target.end()-sizeof(T) );
}
that may turn out to be a bit faster.
You can use vector insert member function.
This is better than copy since vector insert knows how to allocate memory(you do not need to use ugly back_inserter).
void append(std::vector<unsigned char>& v, const MyStruct& s){
v.insert(v.end(), (unsigned char*) &s, ((unsigned char*)&s)+sizeof s);
}
full code here
note that this is very simple code compared to Yakk answer but I think it may be easier for some people to read code without templates. Also I use C style cast that some people think should not be done in C++ but I find reinterpret cast too verbose for this use case.

Combining enum values in C++ [duplicate]

Treating enums as flags works nicely in C# via the [Flags] attribute, but what's the best way to do this in C++?
For example, I'd like to write:
enum AnimalFlags
{
HasClaws = 1,
CanFly =2,
EatsFish = 4,
Endangered = 8
};
seahawk.flags = CanFly | EatsFish | Endangered;
However, I get compiler errors regarding int/enum conversions. Is there a nicer way to express this than just blunt casting? Preferably, I don't want to rely on constructs from 3rd party libraries such as boost or Qt.
EDIT: As indicated in the answers, I can avoid the compiler error by declaring seahawk.flags as int. However, I'd like to have some mechanism to enforce type safety, so someone can't write seahawk.flags = HasMaximizeButton.
The "correct" way is to define bit operators for the enum, as:
enum AnimalFlags
{
HasClaws = 1,
CanFly = 2,
EatsFish = 4,
Endangered = 8
};
inline AnimalFlags operator|(AnimalFlags a, AnimalFlags b)
{
return static_cast<AnimalFlags>(static_cast<int>(a) | static_cast<int>(b));
}
Etc. rest of the bit operators. Modify as needed if the enum range exceeds int range.
Note (also a bit off topic): Another way to make unique flags can be done using a bit shift. I, myself, find this easier to read.
enum Flags
{
A = 1 << 0, // binary 0001
B = 1 << 1, // binary 0010
C = 1 << 2, // binary 0100
D = 1 << 3 // binary 1000
};
It can hold values up to an int so that is, most of the time, 32 flags which is clearly reflected in the shift amount.
Note if you are working in Windows environment, there is a DEFINE_ENUM_FLAG_OPERATORS macro defined in winnt.h that does the job for you. So in this case, you can do this:
enum AnimalFlags
{
HasClaws = 1,
CanFly =2,
EatsFish = 4,
Endangered = 8
};
DEFINE_ENUM_FLAG_OPERATORS(AnimalFlags)
seahawk.flags = CanFly | EatsFish | Endangered;
For lazy people like me, here is templated solution to copy&paste:
template<class T> inline T operator~ (T a) { return (T)~(int)a; }
template<class T> inline T operator| (T a, T b) { return (T)((int)a | (int)b); }
template<class T> inline T operator& (T a, T b) { return (T)((int)a & (int)b); }
template<class T> inline T operator^ (T a, T b) { return (T)((int)a ^ (int)b); }
template<class T> inline T& operator|= (T& a, T b) { return (T&)((int&)a |= (int)b); }
template<class T> inline T& operator&= (T& a, T b) { return (T&)((int&)a &= (int)b); }
template<class T> inline T& operator^= (T& a, T b) { return (T&)((int&)a ^= (int)b); }
What type is the seahawk.flags variable?
In standard C++, enumerations are not type-safe. They are effectively integers.
AnimalFlags should NOT be the type of your variable. Your variable should be int and the error will go away.
Putting hexadecimal values like some other people suggested is not needed. It makes no difference.
The enum values ARE of type int by default. So you can surely bitwise OR combine them and put them together and store the result in an int.
The enum type is a restricted subset of int whose value is one of its enumerated values. Hence, when you make some new value outside of that range, you can't assign it without casting to a variable of your enum type.
You can also change the enum value types if you'd like, but there is no point for this question.
EDIT: The poster said they were concerned with type safety and they don't want a value that should not exist inside the int type.
But it would be type unsafe to put a value outside of AnimalFlags's range inside a variable of type AnimalFlags.
There is a safe way to check for out of range values though inside the int type...
int iFlags = HasClaws | CanFly;
//InvalidAnimalFlagMaxValue-1 gives you a value of all the bits
// smaller than itself set to 1
//This check makes sure that no other bits are set.
assert(iFlags & ~(InvalidAnimalFlagMaxValue-1) == 0);
enum AnimalFlags {
HasClaws = 1,
CanFly =2,
EatsFish = 4,
Endangered = 8,
// put new enum values above here
InvalidAnimalFlagMaxValue = 16
};
The above doesn't stop you from putting an invalid flag from a different enum that has the value 1,2,4, or 8 though.
If you want absolute type safety then you could simply create a std::set and store each flag inside there. It is not space efficient, but it is type safe and gives you the same ability as a bitflag int does.
C++0x note: Strongly typed enums
In C++0x you can finally have type safe enum values....
enum class AnimalFlags {
CanFly = 2,
HasClaws = 4
};
if(CanFly == 2) { }//Compiling error
I find the currently accepted answer by eidolon too dangerous. The compiler's optimizer might make assumptions about possible values in the enum and you might get garbage back with invalid values. And usually nobody wants to define all possible permutations in flags enums.
As Brian R. Bondy states below, if you're using C++11 (which everyone should, it's that good) you can now do this more easily with enum class:
enum class ObjectType : uint32_t
{
ANIMAL = (1 << 0),
VEGETABLE = (1 << 1),
MINERAL = (1 << 2)
};
constexpr enum ObjectType operator |( const enum ObjectType selfValue, const enum ObjectType inValue )
{
return (enum ObjectType)(uint32_t(selfValue) | uint32_t(inValue));
}
// ... add more operators here.
This ensures a stable size and value range by specifying a type for the enum, inhibits automatic downcasting of enums to ints etc. by using enum class, and uses constexpr to ensure the code for the operators gets inlined and thus just as fast as regular numbers.
For people stuck with pre-11 C++ dialects
If I was stuck with a compiler that doesn't support C++11, I'd go with wrapping an int-type in a class that then permits only use of bitwise operators and the types from that enum to set its values:
template<class ENUM,class UNDERLYING=typename std::underlying_type<ENUM>::type>
class SafeEnum
{
public:
SafeEnum() : mFlags(0) {}
SafeEnum( ENUM singleFlag ) : mFlags(singleFlag) {}
SafeEnum( const SafeEnum& original ) : mFlags(original.mFlags) {}
SafeEnum& operator |=( ENUM addValue ) { mFlags |= addValue; return *this; }
SafeEnum operator |( ENUM addValue ) { SafeEnum result(*this); result |= addValue; return result; }
SafeEnum& operator &=( ENUM maskValue ) { mFlags &= maskValue; return *this; }
SafeEnum operator &( ENUM maskValue ) { SafeEnum result(*this); result &= maskValue; return result; }
SafeEnum operator ~() { SafeEnum result(*this); result.mFlags = ~result.mFlags; return result; }
explicit operator bool() { return mFlags != 0; }
protected:
UNDERLYING mFlags;
};
You can define this pretty much like a regular enum + typedef:
enum TFlags_
{
EFlagsNone = 0,
EFlagOne = (1 << 0),
EFlagTwo = (1 << 1),
EFlagThree = (1 << 2),
EFlagFour = (1 << 3)
};
typedef SafeEnum<enum TFlags_> TFlags;
And usage is similar as well:
TFlags myFlags;
myFlags |= EFlagTwo;
myFlags |= EFlagThree;
if( myFlags & EFlagTwo )
std::cout << "flag 2 is set" << std::endl;
if( (myFlags & EFlagFour) == EFlagsNone )
std::cout << "flag 4 is not set" << std::endl;
And you can also override the underlying type for binary-stable enums (like C++11's enum foo : type) using the second template parameter, i.e. typedef SafeEnum<enum TFlags_,uint8_t> TFlags;.
I marked the operator bool override with C++11's explicit keyword to prevent it from resulting in int conversions, as those could cause sets of flags to end up collapsed into 0 or 1 when writing them out. If you can't use C++11, leave that overload out and rewrite the first conditional in the example usage as (myFlags & EFlagTwo) == EFlagTwo.
Easiest way to do this as shown here, using the standard library class bitset.
To emulate the C# feature in a type-safe way, you'd have to write a template wrapper around the bitset, replacing the int arguments with an enum given as a type parameter to the template. Something like:
template <class T, int N>
class FlagSet
{
bitset<N> bits;
FlagSet(T enumVal)
{
bits.set(enumVal);
}
// etc.
};
enum MyFlags
{
FLAG_ONE,
FLAG_TWO
};
FlagSet<MyFlags, 2> myFlag;
In my opinion none of the answers so far are ideal. To be ideal I would expect the solution:
Support the ==,!=,=,&,&=,|,|= and ~ operators in the conventional
sense (i.e. a & b)
Be type safe i.e. not permit non-enumerated values such as literals or integer types to be assigned (except for bitwise combinations of enumerated values) or allow an enum variable to be assigned to an integer type
Permit expressions such as if (a & b)...
Not require evil macros, implementation specific features or other hacks
Most of the solutions thus far fall over on points 2 or 3. WebDancer's is the closes in my opinion but fails at point 3 and needs to be repeated for every enum.
My proposed solution is a generalized version of WebDancer's that also addresses point 3:
#include <cstdint>
#include <type_traits>
template<typename T, typename = typename std::enable_if<std::is_enum<T>::value, T>::type>
class auto_bool
{
T val_;
public:
constexpr auto_bool(T val) : val_(val) {}
constexpr operator T() const { return val_; }
constexpr explicit operator bool() const
{
return static_cast<std::underlying_type_t<T>>(val_) != 0;
}
};
template <typename T, typename = typename std::enable_if<std::is_enum<T>::value, T>::type>
constexpr auto_bool<T> operator&(T lhs, T rhs)
{
return static_cast<T>(
static_cast<typename std::underlying_type<T>::type>(lhs) &
static_cast<typename std::underlying_type<T>::type>(rhs));
}
template <typename T, typename = typename std::enable_if<std::is_enum<T>::value, T>::type>
constexpr T operator|(T lhs, T rhs)
{
return static_cast<T>(
static_cast<typename std::underlying_type<T>::type>(lhs) |
static_cast<typename std::underlying_type<T>::type>(rhs));
}
enum class AnimalFlags : uint8_t
{
HasClaws = 1,
CanFly = 2,
EatsFish = 4,
Endangered = 8
};
enum class PlantFlags : uint8_t
{
HasLeaves = 1,
HasFlowers = 2,
HasFruit = 4,
HasThorns = 8
};
int main()
{
AnimalFlags seahawk = AnimalFlags::CanFly; // Compiles, as expected
AnimalFlags lion = AnimalFlags::HasClaws; // Compiles, as expected
PlantFlags rose = PlantFlags::HasFlowers; // Compiles, as expected
// rose = 1; // Won't compile, as expected
if (seahawk != lion) {} // Compiles, as expected
// if (seahawk == rose) {} // Won't compile, as expected
// seahawk = PlantFlags::HasThorns; // Won't compile, as expected
seahawk = seahawk | AnimalFlags::EatsFish; // Compiles, as expected
lion = AnimalFlags::HasClaws | // Compiles, as expected
AnimalFlags::Endangered;
// int eagle = AnimalFlags::CanFly | // Won't compile, as expected
// AnimalFlags::HasClaws;
// int has_claws = seahawk & AnimalFlags::CanFly; // Won't compile, as expected
if (seahawk & AnimalFlags::CanFly) {} // Compiles, as expected
seahawk = seahawk & AnimalFlags::CanFly; // Compiles, as expected
return 0;
}
This creates overloads of the necessary operators but uses SFINAE to limit them to enumerated types. Note that in the interests of brevity I haven't defined all of the operators but the only one that is any different is the &. The operators are currently global (i.e. apply to all enumerated types) but this could be reduced either by placing the overloads in a namespace (what I do), or by adding additional SFINAE conditions (perhaps using particular underlying types, or specially created type aliases). The underlying_type_t is a C++14 feature but it seems to be well supported and is easy to emulate for C++11 with a simple template<typename T> using underlying_type_t = underlying_type<T>::type;
Edit: I incorporated the change suggested by Vladimir Afinello. Tested with GCC 10, CLANG 13 and Visual Studio 2022.
Only syntactic sugar. No additional metadata.
namespace UserRole // grupy
{
constexpr uint8_t dea = 1;
constexpr uint8_t red = 2;
constexpr uint8_t stu = 4;
constexpr uint8_t kie = 8;
constexpr uint8_t adm = 16;
constexpr uint8_t mas = 32;
}
Flag operators on integral type just works.
The C++ standard explicitly talks about this, see section "17.5.2.1.3 Bitmask types":
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3485.pdf
Given this "template" you get:
enum AnimalFlags : unsigned int
{
HasClaws = 1,
CanFly = 2,
EatsFish = 4,
Endangered = 8
};
constexpr AnimalFlags operator|(AnimalFlags X, AnimalFlags Y) {
return static_cast<AnimalFlags>(
static_cast<unsigned int>(X) | static_cast<unsigned int>(Y));
}
AnimalFlags& operator|=(AnimalFlags& X, AnimalFlags Y) {
X = X | Y; return X;
}
And similar for the other operators.
Also note the "constexpr", it is needed if you want the compiler to be able to execute the operators compile time.
If you are using C++/CLI and want to able assign to enum members of ref classes you need to use tracking references instead:
AnimalFlags% operator|=(AnimalFlags% X, AnimalFlags Y) {
X = X | Y; return X;
}
NOTE: This sample is not complete, see section "17.5.2.1.3 Bitmask types" for a complete set of operators.
I use the following macro:
#define ENUM_FLAG_OPERATORS(T) \
inline T operator~ (T a) { return static_cast<T>( ~static_cast<std::underlying_type<T>::type>(a) ); } \
inline T operator| (T a, T b) { return static_cast<T>( static_cast<std::underlying_type<T>::type>(a) | static_cast<std::underlying_type<T>::type>(b) ); } \
inline T operator& (T a, T b) { return static_cast<T>( static_cast<std::underlying_type<T>::type>(a) & static_cast<std::underlying_type<T>::type>(b) ); } \
inline T operator^ (T a, T b) { return static_cast<T>( static_cast<std::underlying_type<T>::type>(a) ^ static_cast<std::underlying_type<T>::type>(b) ); } \
inline T& operator|= (T& a, T b) { return reinterpret_cast<T&>( reinterpret_cast<std::underlying_type<T>::type&>(a) |= static_cast<std::underlying_type<T>::type>(b) ); } \
inline T& operator&= (T& a, T b) { return reinterpret_cast<T&>( reinterpret_cast<std::underlying_type<T>::type&>(a) &= static_cast<std::underlying_type<T>::type>(b) ); } \
inline T& operator^= (T& a, T b) { return reinterpret_cast<T&>( reinterpret_cast<std::underlying_type<T>::type&>(a) ^= static_cast<std::underlying_type<T>::type>(b) ); }
It is similar to the ones mentioned above but has several improvements:
It is type safe (it does not suppose that the underlying type is an int)
It does not require to specify manually the underlying type (as opposed to #LunarEclipse 's answer)
It does need to include type_traits:
#include <type_traits>
I found myself asking the same question and came up with a generic C++11 based solution, similar to soru's:
template <typename TENUM>
class FlagSet {
private:
using TUNDER = typename std::underlying_type<TENUM>::type;
std::bitset<std::numeric_limits<TUNDER>::max()> m_flags;
public:
FlagSet() = default;
template <typename... ARGS>
FlagSet(TENUM f, ARGS... args) : FlagSet(args...)
{
set(f);
}
FlagSet& set(TENUM f)
{
m_flags.set(static_cast<TUNDER>(f));
return *this;
}
bool test(TENUM f)
{
return m_flags.test(static_cast<TUNDER>(f));
}
FlagSet& operator|=(TENUM f)
{
return set(f);
}
};
The interface can be improved to taste. Then it can be used like so:
FlagSet<Flags> flags{Flags::FLAG_A, Flags::FLAG_C};
flags |= Flags::FLAG_D;
If your compiler doesn't support strongly typed enums yet, you can give a look to the following article from the c++ source:
From the abstract:
This article presents a solution to the problem of constraining bit operations to
allow only safe and legitimate ones, and turn all invalid bit manipulations into
compile-time errors. Best of all, the syntax of bit operations remains unchanged,
and the code working with bits does not need to be modified, except possibly to
fix errors that had as yet remained undetected.
Here's an option for bitmasks if you don't actually have a use for the individual enum values (ex. you don't need to switch off of them)... and if you aren't worried about maintaining binary compatibility ie: you don't care where your bits live... which you probably are. Also you'd better not be too concerned with scoping and access control. Hmmm, enums have some nice properties for bit-fields... wonder if anyone has ever tried that :)
struct AnimalProperties
{
bool HasClaws : 1;
bool CanFly : 1;
bool EatsFish : 1;
bool Endangered : 1;
};
union AnimalDescription
{
AnimalProperties Properties;
int Flags;
};
void TestUnionFlags()
{
AnimalDescription propertiesA;
propertiesA.Properties.CanFly = true;
AnimalDescription propertiesB = propertiesA;
propertiesB.Properties.EatsFish = true;
if( propertiesA.Flags == propertiesB.Flags )
{
cout << "Life is terrible :(";
}
else
{
cout << "Life is great!";
}
AnimalDescription propertiesC = propertiesA;
if( propertiesA.Flags == propertiesC.Flags )
{
cout << "Life is great!";
}
else
{
cout << "Life is terrible :(";
}
}
We can see that life is great, we have our discrete values, and we have a nice int to & and | to our hearts content, which still has context of what its bits mean. Everything is consistent and predictable... for me... as long as I keep using Microsoft's VC++ compiler w/ Update 3 on Win10 x64 and don't touch my compiler flags :)
Even though everything is great... we have some context as to the meaning of flags now, since its in a union w/ the bitfield in the terrible real world where your program may be be responsible for more than a single discrete task you could still accidentally (quite easily) smash two flags fields of different unions together (say, AnimalProperties and ObjectProperties, since they're both ints), mixing up all yours bits, which is a horrible bug to trace down... and how I know many people on this post don't work with bitmasks very often, since building them is easy and maintaining them is hard.
class AnimalDefinition {
public:
static AnimalDefinition *GetAnimalDefinition( AnimalFlags flags ); //A little too obvious for my taste... NEXT!
static AnimalDefinition *GetAnimalDefinition( AnimalProperties properties ); //Oh I see how to use this! BORING, NEXT!
static AnimalDefinition *GetAnimalDefinition( int flags ); //hmm, wish I could see how to construct a valid "flags" int without CrossFingers+Ctrl+Shift+F("Animal*"). Maybe just hard-code 16 or something?
AnimalFlags animalFlags; //Well this is *way* too hard to break unintentionally, screw this!
int flags; //PERFECT! Nothing will ever go wrong here...
//wait, what values are used for this particular flags field? Is this AnimalFlags or ObjectFlags? Or is it RuntimePlatformFlags? Does it matter? Where's the documentation?
//Well luckily anyone in the code base and get confused and destroy the whole program! At least I don't need to static_cast anymore, phew!
private:
AnimalDescription m_description; //Oh I know what this is. All of the mystery and excitement of life has been stolen away :(
}
So then you make your union declaration private to prevent direct access to "Flags", and have to add getters/setters and operator overloads, then make a macro for all that, and you're basically right back where you started when you tried to do this with an Enum.
Unfortunately if you want your code to be portable, I don't think there is any way to either A) guarantee the bit layout or B) determine the bit layout at compile time (so you can track it and at least correct for changes across versions/platforms etc)
Offset in a struct with bit fields
At runtime you can play tricks w/ setting the the fields and XORing the flags to see which bits did change, sounds pretty crappy to me though verses having a 100% consistent, platform independent, and completely deterministic solution ie: an ENUM.
TL;DR:
Don't listen to the haters. C++ is not English. Just because the literal definition of an abbreviated keyword inherited from C might not fit your usage doesn't mean you shouldn't use it when the C and C++ definition of the keyword absolutely includes your use case. You can also use structs to model things other than structures, and classes for things other than school and social caste. You may use float for values which are grounded. You may use char for variables which are neither un-burnt nor a person in a novel, play, or movie. Any programmer who goes to the dictionary to determine the meaning of a keyword before the language spec is a... well I'll hold my tongue there.
If you do want your code modeled after spoken language you'd be best off writing in Objective-C, which incidentally also uses enums heavily for bitfields.
I'd like to elaborate on Uliwitness answer, fixing his code for C++98 and using the Safe Bool idiom, for lack of the std::underlying_type<> template and the explicit keyword in C++ versions below C++11.
I also modified it so that the enum values can be sequential without any explicit assignment, so you can have
enum AnimalFlags_
{
HasClaws,
CanFly,
EatsFish,
Endangered
};
typedef FlagsEnum<AnimalFlags_> AnimalFlags;
seahawk.flags = AnimalFlags() | CanFly | EatsFish | Endangered;
You can then get the raw flags value with
seahawk.flags.value();
Here's the code.
template <typename EnumType, typename Underlying = int>
class FlagsEnum
{
typedef Underlying FlagsEnum::* RestrictedBool;
public:
FlagsEnum() : m_flags(Underlying()) {}
FlagsEnum(EnumType singleFlag):
m_flags(1 << singleFlag)
{}
FlagsEnum(const FlagsEnum& original):
m_flags(original.m_flags)
{}
FlagsEnum& operator |=(const FlagsEnum& f) {
m_flags |= f.m_flags;
return *this;
}
FlagsEnum& operator &=(const FlagsEnum& f) {
m_flags &= f.m_flags;
return *this;
}
friend FlagsEnum operator |(const FlagsEnum& f1, const FlagsEnum& f2) {
return FlagsEnum(f1) |= f2;
}
friend FlagsEnum operator &(const FlagsEnum& f1, const FlagsEnum& f2) {
return FlagsEnum(f1) &= f2;
}
FlagsEnum operator ~() const {
FlagsEnum result(*this);
result.m_flags = ~result.m_flags;
return result;
}
operator RestrictedBool() const {
return m_flags ? &FlagsEnum::m_flags : 0;
}
Underlying value() const {
return m_flags;
}
protected:
Underlying m_flags;
};
Currently there is no language support for enum flags, Meta classes might inherently add this feature if it would ever be part of the c++ standard.
My solution would be to create enum-only instantiated template functions adding support for type-safe bitwise operations for enum class using its underlying type:
File: EnumClassBitwise.h
#pragma once
#ifndef _ENUM_CLASS_BITWISE_H_
#define _ENUM_CLASS_BITWISE_H_
#include <type_traits>
//unary ~operator
template <typename Enum, typename std::enable_if_t<std::is_enum<Enum>::value, int> = 0>
constexpr inline Enum& operator~ (Enum& val)
{
val = static_cast<Enum>(~static_cast<std::underlying_type_t<Enum>>(val));
return val;
}
// & operator
template <typename Enum, typename std::enable_if_t<std::is_enum<Enum>::value, int> = 0>
constexpr inline Enum operator& (Enum lhs, Enum rhs)
{
return static_cast<Enum>(static_cast<std::underlying_type_t<Enum>>(lhs) & static_cast<std::underlying_type_t<Enum>>(rhs));
}
// &= operator
template <typename Enum, typename std::enable_if_t<std::is_enum<Enum>::value, int> = 0>
constexpr inline Enum operator&= (Enum& lhs, Enum rhs)
{
lhs = static_cast<Enum>(static_cast<std::underlying_type_t<Enum>>(lhs) & static_cast<std::underlying_type_t<Enum>>(rhs));
return lhs;
}
//| operator
template <typename Enum, typename std::enable_if_t<std::is_enum<Enum>::value, int> = 0>
constexpr inline Enum operator| (Enum lhs, Enum rhs)
{
return static_cast<Enum>(static_cast<std::underlying_type_t<Enum>>(lhs) | static_cast<std::underlying_type_t<Enum>>(rhs));
}
//|= operator
template <typename Enum, typename std::enable_if_t<std::is_enum<Enum>::value, int> = 0>
constexpr inline Enum& operator|= (Enum& lhs, Enum rhs)
{
lhs = static_cast<Enum>(static_cast<std::underlying_type_t<Enum>>(lhs) | static_cast<std::underlying_type_t<Enum>>(rhs));
return lhs;
}
#endif // _ENUM_CLASS_BITWISE_H_
For convenience and for reducing mistakes, you might want to wrap your bit flags operations for enums and for integers as well:
File: BitFlags.h
#pragma once
#ifndef _BIT_FLAGS_H_
#define _BIT_FLAGS_H_
#include "EnumClassBitwise.h"
template<typename T>
class BitFlags
{
public:
constexpr inline BitFlags() = default;
constexpr inline BitFlags(T value) { mValue = value; }
constexpr inline BitFlags operator| (T rhs) const { return mValue | rhs; }
constexpr inline BitFlags operator& (T rhs) const { return mValue & rhs; }
constexpr inline BitFlags operator~ () const { return ~mValue; }
constexpr inline operator T() const { return mValue; }
constexpr inline BitFlags& operator|=(T rhs) { mValue |= rhs; return *this; }
constexpr inline BitFlags& operator&=(T rhs) { mValue &= rhs; return *this; }
constexpr inline bool test(T rhs) const { return (mValue & rhs) == rhs; }
constexpr inline void set(T rhs) { mValue |= rhs; }
constexpr inline void clear(T rhs) { mValue &= ~rhs; }
private:
T mValue;
};
#endif //#define _BIT_FLAGS_H_
Possible usage:
#include <cstdint>
#include <BitFlags.h>
void main()
{
enum class Options : uint32_t
{
NoOption = 0 << 0
, Option1 = 1 << 0
, Option2 = 1 << 1
, Option3 = 1 << 2
, Option4 = 1 << 3
};
const uint32_t Option1 = 1 << 0;
const uint32_t Option2 = 1 << 1;
const uint32_t Option3 = 1 << 2;
const uint32_t Option4 = 1 << 3;
//Enum BitFlags
BitFlags<Options> optionsEnum(Options::NoOption);
optionsEnum.set(Options::Option1 | Options::Option3);
//Standard integer BitFlags
BitFlags<uint32_t> optionsUint32(0);
optionsUint32.set(Option1 | Option3);
return 0;
}
#Xaqq has provided a really nice type-safe way to use enum flags here by a flag_set class.
I published the code in GitHub, usage is as follows:
#include "flag_set.hpp"
enum class AnimalFlags : uint8_t {
HAS_CLAWS,
CAN_FLY,
EATS_FISH,
ENDANGERED,
_
};
int main()
{
flag_set<AnimalFlags> seahawkFlags(AnimalFlags::HAS_CLAWS
| AnimalFlags::EATS_FISH
| AnimalFlags::ENDANGERED);
if (seahawkFlags & AnimalFlags::ENDANGERED)
cout << "Seahawk is endangered";
}
Another macro solution, but unlike the existing answers this does not use reinterpret_cast (or a C-cast) to cast between Enum& and Int&, which is forbidden in standard C++ (see this post).
#define MAKE_FLAGS_ENUM(TEnum, TUnder) \
TEnum operator~ ( TEnum a ) { return static_cast<TEnum> (~static_cast<TUnder> (a) ); } \
TEnum operator| ( TEnum a, TEnum b ) { return static_cast<TEnum> ( static_cast<TUnder> (a) | static_cast<TUnder>(b) ); } \
TEnum operator& ( TEnum a, TEnum b ) { return static_cast<TEnum> ( static_cast<TUnder> (a) & static_cast<TUnder>(b) ); } \
TEnum operator^ ( TEnum a, TEnum b ) { return static_cast<TEnum> ( static_cast<TUnder> (a) ^ static_cast<TUnder>(b) ); } \
TEnum& operator|= ( TEnum& a, TEnum b ) { a = static_cast<TEnum>(static_cast<TUnder>(a) | static_cast<TUnder>(b) ); return a; } \
TEnum& operator&= ( TEnum& a, TEnum b ) { a = static_cast<TEnum>(static_cast<TUnder>(a) & static_cast<TUnder>(b) ); return a; } \
TEnum& operator^= ( TEnum& a, TEnum b ) { a = static_cast<TEnum>(static_cast<TUnder>(a) ^ static_cast<TUnder>(b) ); return a; }
Losing the reinterpret_cast means we can't rely on the x |= y syntax any more, but by expanding these into their x = x | y forms we no longer need it.
Note: You can use std::underlying_type to obtain TUnder, I've not included it for brevity.
You are confusing objects and collections of objects. Specifically, you are confusing binary flags with sets of binary flags. A proper solution would look like this:
// These are individual flags
enum AnimalFlag // Flag, not Flags
{
HasClaws = 0,
CanFly,
EatsFish,
Endangered
};
class AnimalFlagSet
{
int m_Flags;
public:
AnimalFlagSet() : m_Flags(0) { }
void Set( AnimalFlag flag ) { m_Flags |= (1 << flag); }
void Clear( AnimalFlag flag ) { m_Flags &= ~ (1 << flag); }
bool Get( AnimalFlag flag ) const { return (m_Flags >> flag) & 1; }
};
Here is my solution without needing any bunch of overloading or casting:
namespace EFoobar
{
enum
{
FB_A = 0x1,
FB_B = 0x2,
FB_C = 0x4,
};
typedef long Flags;
}
void Foobar(EFoobar::Flags flags)
{
if (flags & EFoobar::FB_A)
// do sth
;
if (flags & EFoobar::FB_B)
// do sth
;
}
void ExampleUsage()
{
Foobar(EFoobar::FB_A | EFoobar::FB_B);
EFoobar::Flags otherflags = 0;
otherflags|= EFoobar::FB_B;
otherflags&= ~EFoobar::FB_B;
Foobar(otherflags);
}
I think it's ok, because we identify (non strongly typed) enums and ints anyway.
Just as a (longer) side note, if you
want to use strongly typed enums and
don't need heavy bit fiddling with your flags
performance is not an issue
I would come up with this:
#include <set>
enum class EFoobarFlags
{
FB_A = 1,
FB_B,
FB_C,
};
void Foobar(const std::set<EFoobarFlags>& flags)
{
if (flags.find(EFoobarFlags::FB_A) != flags.end())
// do sth
;
if (flags.find(EFoobarFlags::FB_B) != flags.end())
// do sth
;
}
void ExampleUsage()
{
Foobar({EFoobarFlags::FB_A, EFoobarFlags::FB_B});
std::set<EFoobarFlags> otherflags{};
otherflags.insert(EFoobarFlags::FB_B);
otherflags.erase(EFoobarFlags::FB_B);
Foobar(otherflags);
}
using C++11 initializer lists and enum class.
Copy-pasteable "evil" macro based on some of the other answers in this thread:
#include <type_traits>
/*
* Macro to allow enum values to be combined and evaluated as flags.
* * Based on:
* - DEFINE_ENUM_FLAG_OPERATORS from <winnt.h>
* - https://stackoverflow.com/a/63031334/1624459
*/
#define MAKE_ENUM_FLAGS(TEnum) \
inline TEnum operator~(TEnum a) { \
using TUnder = typename std::underlying_type_t<TEnum>; \
return static_cast<TEnum>(~static_cast<TUnder>(a)); \
} \
inline TEnum operator|(TEnum a, TEnum b) { \
using TUnder = typename std::underlying_type_t<TEnum>; \
return static_cast<TEnum>(static_cast<TUnder>(a) | static_cast<TUnder>(b)); \
} \
inline TEnum operator&(TEnum a, TEnum b) { \
using TUnder = typename std::underlying_type_t<TEnum>; \
return static_cast<TEnum>(static_cast<TUnder>(a) & static_cast<TUnder>(b)); \
} \
inline TEnum operator^(TEnum a, TEnum b) { \
using TUnder = typename std::underlying_type_t<TEnum>; \
return static_cast<TEnum>(static_cast<TUnder>(a) ^ static_cast<TUnder>(b)); \
} \
inline TEnum& operator|=(TEnum& a, TEnum b) { \
using TUnder = typename std::underlying_type_t<TEnum>; \
a = static_cast<TEnum>(static_cast<TUnder>(a) | static_cast<TUnder>(b)); \
return a; \
} \
inline TEnum& operator&=(TEnum& a, TEnum b) { \
using TUnder = typename std::underlying_type_t<TEnum>; \
a = static_cast<TEnum>(static_cast<TUnder>(a) & static_cast<TUnder>(b)); \
return a; \
} \
inline TEnum& operator^=(TEnum& a, TEnum b) { \
using TUnder = typename std::underlying_type_t<TEnum>; \
a = static_cast<TEnum>(static_cast<TUnder>(a) ^ static_cast<TUnder>(b)); \
return a; \
}
Usage
enum class Passability : std::uint8_t {
Clear = 0,
GroundUnit = 1 << 1,
FlyingUnit = 1 << 2,
Building = 1 << 3,
Tree = 1 << 4,
Mountain = 1 << 5,
Blocked = 1 << 6,
Water = 1 << 7,
Coastline = 1 << 8
};
MAKE_ENUM_FLAGS(Passability)
Advantages
Only applies to chosen enums when used explicitly.
No use of illegal reinterpret_cast.
No need to specify the underlying type.
Notes
Replace std::underlying_type_t<TEnum> with std::underlying_type<TEnum>::type if using C++ <14.
Here's a lazy C++11 solution that doesn't change the default behavior of enums. It also works for enum struct and enum class, and is constexpr.
#include <type_traits>
template<class T = void> struct enum_traits {};
template<> struct enum_traits<void> {
struct _allow_bitops {
static constexpr bool allow_bitops = true;
};
using allow_bitops = _allow_bitops;
template<class T, class R = T>
using t = typename std::enable_if<std::is_enum<T>::value and
enum_traits<T>::allow_bitops, R>::type;
template<class T>
using u = typename std::underlying_type<T>::type;
};
template<class T>
constexpr enum_traits<>::t<T> operator~(T a) {
return static_cast<T>(~static_cast<enum_traits<>::u<T>>(a));
}
template<class T>
constexpr enum_traits<>::t<T> operator|(T a, T b) {
return static_cast<T>(
static_cast<enum_traits<>::u<T>>(a) |
static_cast<enum_traits<>::u<T>>(b));
}
template<class T>
constexpr enum_traits<>::t<T> operator&(T a, T b) {
return static_cast<T>(
static_cast<enum_traits<>::u<T>>(a) &
static_cast<enum_traits<>::u<T>>(b));
}
template<class T>
constexpr enum_traits<>::t<T> operator^(T a, T b) {
return static_cast<T>(
static_cast<enum_traits<>::u<T>>(a) ^
static_cast<enum_traits<>::u<T>>(b));
}
template<class T>
constexpr enum_traits<>::t<T, T&> operator|=(T& a, T b) {
a = a | b;
return a;
}
template<class T>
constexpr enum_traits<>::t<T, T&> operator&=(T& a, T b) {
a = a & b;
return a;
}
template<class T>
constexpr enum_traits<>::t<T, T&> operator^=(T& a, T b) {
a = a ^ b;
return a;
}
To enable bitwise operators for an enum:
enum class my_enum {
Flag1 = 1 << 0,
Flag2 = 1 << 1,
Flag3 = 1 << 2,
// ...
};
// The magic happens here
template<> struct enum_traits<my_enum> :
enum_traits<>::allow_bitops {};
constexpr my_enum foo = my_enum::Flag1 | my_enum::Flag2 | my_enum::Flag3;
As above(Kai) or do the following. Really enums are "Enumerations", what you want to do is have a set, therefore you should really use stl::set
enum AnimalFlags
{
HasClaws = 1,
CanFly =2,
EatsFish = 4,
Endangered = 8
};
int main(void)
{
AnimalFlags seahawk;
//seahawk= CanFly | EatsFish | Endangered;
seahawk= static_cast<AnimalFlags>(CanFly | EatsFish | Endangered);
}
Maybe like NS_OPTIONS of Objective-C.
#define ENUM(T1, T2) \
enum class T1 : T2; \
inline T1 operator~ (T1 a) { return (T1)~(int)a; } \
inline T1 operator| (T1 a, T1 b) { return static_cast<T1>((static_cast<T2>(a) | static_cast<T2>(b))); } \
inline T1 operator& (T1 a, T1 b) { return static_cast<T1>((static_cast<T2>(a) & static_cast<T2>(b))); } \
inline T1 operator^ (T1 a, T1 b) { return static_cast<T1>((static_cast<T2>(a) ^ static_cast<T2>(b))); } \
inline T1& operator|= (T1& a, T1 b) { return reinterpret_cast<T1&>((reinterpret_cast<T2&>(a) |= static_cast<T2>(b))); } \
inline T1& operator&= (T1& a, T1 b) { return reinterpret_cast<T1&>((reinterpret_cast<T2&>(a) &= static_cast<T2>(b))); } \
inline T1& operator^= (T1& a, T1 b) { return reinterpret_cast<T1&>((reinterpret_cast<T2&>(a) ^= static_cast<T2>(b))); } \
enum class T1 : T2
ENUM(Options, short) {
FIRST = 1 << 0,
SECOND = 1 << 1,
THIRD = 1 << 2,
FOURTH = 1 << 3
};
auto options = Options::FIRST | Options::SECOND;
options |= Options::THIRD;
if ((options & Options::SECOND) == Options::SECOND)
cout << "Contains second option." << endl;
if ((options & Options::THIRD) == Options::THIRD)
cout << "Contains third option." << endl;
return 0;
// Output:
// Contains second option.
// Contains third option.
C++20 Type-Safe Enum Operators
TL;DR
template<typename T>
requires std::is_enum_v<T> and
requires (std::underlying_type_t<T> x) {
{ x | x } -> std::same_as<std::underlying_type_t<T>>;
T(x);
}
T operator|(T left, T right)
{
using U = std::underlying_type_t<T>;
return T( U(left) | U(right) );
}
template<typename T>
requires std::is_enum_v<T> and
requires (std::underlying_type_t<T> x) {
{ x | x } -> std::same_as<std::underlying_type_t<T>>;
T(x);
}
T operator&(T left, T right)
{
using U = std::underlying_type_t<T>;
return T( U(left) & U(right) );
}
template<typename T>
requires std::is_enum_v<T> and requires (T x) { { x | x } -> std::same_as<T>; }
T & operator|=(T &left, T right)
{
return left = left | right;
}
template<typename T>
requires std::is_enum_v<T> and requires (T x) { { x & x } -> std::same_as<T>; }
T & operator&=(T &left, T right)
{
return left = left & right;
}
Rationale
With type trait std::is_enum we can test some type T for whether it is an enumeration type.
This includes both unscoped and scoped enums (i.e. enum and enum class).
With type trait std::underlying_type we can get the underlying type of an enum.
With C++20 concepts and constraints it is quite easy to then provide overloads for bitwise operations.
Scoped vs. Unscoped
If the operations should only be overloaded for either scoped or unscoped enums, std::is_scoped_enum can be used to extend the template constraints accordingly.
C++23
With C++23 we get std::to_underlying to convert an enum value to its underlying type more easily.
Move Semantics & Perfect Forwarding
Should you get in the bizarre situation that your underlying type has different semantics for copy vs. move or it does not provide a copy c'tor, then you should do perfect forwarding of the operands with std::forward.
You can use struct as follow:
struct UiFlags2 {
static const int
FULLSCREEN = 0x00000004, //api 16
HIDE_NAVIGATION = 0x00000002, //api 14
LAYOUT_HIDE_NAVIGATION = 0x00000200, //api 16
LAYOUT_FULLSCREEN = 0x00000400, //api 16
LAYOUT_STABLE = 0x00000100, //api 16
IMMERSIVE_STICKY = 0x00001000; //api 19
};
and use as this:
int flags = UiFlags2::FULLSCREEN | UiFlags2::HIDE_NAVIGATION;
So you don't need to int casting and it is directly usable.
Also it is scope separated like enum class
I prefer using magic_enum as it helps automate converting strings to enums and vice versa.
It is a header-only library which is written in C++17 standard.
magic_enum already has template functions for enum bitwise operators.
See documentation.
Usage:
#include <magic_enum.hpp>
enum Flag { ... };
Flag flag{};
Flag value{};
using namespace magic_enum::bitwise_operators;
flag |= value;

How does one use an enum class as a set of flags?

Let's say I have a set of flags and a class like this:
/// <summary>Options controlling a search for files.</summary>
enum class FindFilesOptions : unsigned char
{
LocalSearch = 0,
RecursiveSearch = 1,
IncludeDotDirectories = 2
};
class FindFiles : boost::noncopyable
{
/* omitted */
public:
FindFiles(std::wstring const& pattern, FindFilesOptions options);
/* omitted */
}
and I want a caller to be able to select more than one option:
FindFiles handle(Append(basicRootPath, L"*"),
FindFilesOptions::RecursiveSearch | FindFilesOptions::IncludeDotDirectories);
Is it possible to support this in a strongly-typed way with C++11 enum class, or do I have to revert to untyped enumerations?
(I know the caller could static_cast to the underlying type and static_cast back, but I don't want the caller to have to do that)
It is certainly possible to use enum classes for bitmaps. It is, unfortunately, a bit painful to do so: You need to define the necessary bit operations on your type. Below is an example how this could look like. It would be nice if the enum classes could derive from some other type which could live in a suitable namespace defining the necessary operator boilerplate code.
#include <iostream>
#include <type_traits>
enum class bitmap: unsigned char
{
a = 0x01,
b = 0x02,
c = 0x04
};
bitmap operator& (bitmap x, bitmap y)
{
typedef std::underlying_type<bitmap>::type uchar;
return bitmap(uchar(x) & uchar(y));
}
bitmap operator| (bitmap x, bitmap y)
{
typedef std::underlying_type<bitmap>::type uchar;
return bitmap(uchar(x) | uchar(y));
}
bitmap operator^ (bitmap x, bitmap y)
{
typedef std::underlying_type<bitmap>::type uchar;
return bitmap(uchar(x) ^ uchar(y));
}
bool test(bitmap x)
{
return std::underlying_type<bitmap>::type(x);
}
int main()
{
bitmap v = bitmap::a | bitmap::b;
if (test(v & bitmap::a)) {
std::cout << "a ";
}
if (test(v & bitmap::b)) {
std::cout << "b ";
}
if (test(v & bitmap::c)) {
std::cout << "c ";
}
std::cout << '\n';
}
Templates play well with enum class so you can define sets of operators that work on sets of similar enumeration types. The key is to use a traits template to specify what interface(s) each enumeration conforms/subscribes to.
As a start:
enum class mood_flag {
jumpy,
happy,
upset,
count // size of enumeration
};
template<>
struct enum_traits< mood_flag > {
static constexpr bool bit_index = true;
};
template< typename t >
struct flag_bits : std::bitset< static_cast< int >( t::count ) > {
flag_bits( t bit ) // implicit
{ this->set( static_cast< int >( bit ) ); }
// Should be explicit but I'm lazy to type:
flag_bits( typename flag_bits::bitset set )
: flag_bits::bitset( set ) {}
};
template< typename e >
typename std::enable_if< enum_traits< e >::bit_index,
flag_bits< e > >::type
operator | ( flag_bits< e > set, e next )
{ return set | flag_bits< e >( next ); }
template< typename e >
typename std::enable_if< enum_traits< e >::bit_index,
flag_bits< e > >::type
operator | ( e first, e next )
{ return flag_bits< e >( first ) | next; }
http://ideone.com/kJ271Z
GCC 4.9 reported that some implicit member functions were constexpr while I was getting this to compile, so the templates should probably be so as well.
This should probably also have a free function to_scalar or something which returns an unsigned integer type given either an individual flag or a flag_bits set.
How about defining FindFiles so that it takes std::initializer_list of FindFilesOptions.
void FindFiles(std::wstring const& pattern, std::initializer_list<FindFilesOptions> options)
{
auto has_option = [&](FindFilesOptions const option)
{
return std::find(std::begin(options), std::end(options), option) != std::end(options);
};
if (has_option(FindFilesOptions::LocalSearch))
{
// ...
}
if (has_option(FindFilesOptions::RecursiveSearch))
{
// ...
}
if (has_option(FindFilesOptions::IncludeDotDirectories))
{
// ...
}
}
Then you could call it like so:
FindFiles({}, {FindFilesOptions::RecursiveSearch, FindFilesOptions::IncludeDotDirectories});
The problem is not the explicit enum type but the class scope.
With C++11, enum as compile time constant loose a lot of interest compared to a bunch of constexpr when you need operate on the value ( bitwise operation, incrementation, etc)
If you don't care about performance, change your options to set<FindFilesOptions>!

hash template metafunction and function

Any computation is possible at compile-time with C++ template metafunctions. Therefore, I was considering, if the following were possible:
void my_function(char const* string_ptr)
{
switch (hash_function(string_ptr))
{
case hash_metafunction<"yoohooo">::value:
...
break;
case hash_metafunction<"woooooo">::value:
...
break;
...
}
}
Can you give leads as to where to find code (library) for both the hash function and template metafunction. If none such library exists, can you give hints on how I might roll the template metafunction myself? I am particularly worried about the char const* parameter to the template metafunction. Maybe some preprocessor magic is possible?
How about a constexpr function? Of course implementing that hash could be a pain. You'll have something like this:
// maybe another return type
constexpr uint64_t hash_metafunction(const char* input) {
// replace some_value with the hash implementation
return some_value;
}
void my_function(char const* string_ptr)
{
switch (hash_function(string_ptr))
{
case hash_metafunction("yoohooo"):
...
break;
case hash_metafunction("woooooo"):
...
break;
...
}
}
The hash_metafunction function would be executed on compile-time.
Edit: This is a naive implementation, which basically converts the input string to a uint64_t:
constexpr uint64_t do_the_hash(const char* input, uint64_t value_so_far) {
return *input ? do_the_hash(input + 1, (value_so_far << 8) | *input) : value_so_far;
}
constexpr uint64_t hash_metafunction(const char* input) {
return do_the_hash(input, 0);
}
Live demo here.
Edit: I've implemented a compile time MD5, you can find the source code here. In order to use it, do the following:
#include <iostream>
#include "md5.h"
int main() {
constexpr auto value = ConstexprHashes::md5("constexpr rulz");
std::cout << std::hex;
for(auto v : value) {
if(((size_t)v & 0xff) < 0x10)
std::cout << '0';
std::cout << ((size_t)v & 0xff);
}
std::cout << std::endl;
}
This prints out the hash: "b8b4e2be16d2b11a5902b80f9c0fe6d6".
I have created a constexpr version of MurmurHash3 as a gist on GitHub.
int main() {
constexpr uint32_t hash = Murmur3_32("some_string_to_hash", 0xAED123FD);
assert(hash == 4291478129);
}

Generic way to cast int to enum in C++

Is there a generic way to cast int to enum in C++?
If int falls in range of an enum it should return an enum value, otherwise throw an exception. Is there a way to write it generically? More than one enum type should be supported.
Background: I have an external enum type and no control over the source code. I'd like to store this value in a database and retrieve it.
The obvious thing is to annotate your enum:
// generic code
#include <algorithm>
template <typename T>
struct enum_traits {};
template<typename T, size_t N>
T *endof(T (&ra)[N]) {
return ra + N;
}
template<typename T, typename ValType>
T check(ValType v) {
typedef enum_traits<T> traits;
const T *first = traits::enumerators;
const T *last = endof(traits::enumerators);
if (traits::sorted) { // probably premature optimization
if (std::binary_search(first, last, v)) return T(v);
} else if (std::find(first, last, v) != last) {
return T(v);
}
throw "exception";
}
// "enhanced" definition of enum
enum e {
x = 1,
y = 4,
z = 10,
};
template<>
struct enum_traits<e> {
static const e enumerators[];
static const bool sorted = true;
};
// must appear in only one TU,
// so if the above is in a header then it will need the array size
const e enum_traits<e>::enumerators[] = {x, y, z};
// usage
int main() {
e good = check<e>(1);
e bad = check<e>(2);
}
You need the array to be kept up to date with e, which is a nuisance if you're not the author of e. As Sjoerd says, it can probably be automated with any decent build system.
In any case, you're up against 7.2/6:
For an enumeration where emin is the
smallest enumerator and emax is the
largest, the values of the enumeration
are the values of the underlying type
in the range bmin to bmax, where bmin
and bmax are, respectively, the
smallest and largest values of the
smallest bit-field that can store emin
and emax. It is possible to define an
enumeration that has values not
defined by any of its enumerators.
So if you aren't the author of e, you may or may not have a guarantee that valid values of e actually appear in its definition.
Ugly.
enum MyEnum { one = 1, two = 2 };
MyEnum to_enum(int n)
{
switch( n )
{
case 1 : return one;
case 2 : return two;
}
throw something();
}
Now for the real question. Why do you need this? The code is ugly, not easy to write (*?) and not easy to maintain, and not easy to incorporate in to your code. The code it telling you that it's wrong. Why fight it?
EDIT:
Alternatively, given that enums are integral types in C++:
enum my_enum_val = static_cast<MyEnum>(my_int_val);
but this is even uglier that above, much more prone to errors, and it won't throw as you desire.
If, as you describe, the values are in a database, why not write a code generator that reads this table and creates a .h and .cpp file with both the enum and a to_enum(int) function?
Advantages:
Easy to add a to_string(my_enum) function.
Little maintenance required
Database and code are in synch
No- there's no introspection in C++, nor is there any built in "domain check" facility.
What do you think about this one?
#include <iostream>
#include <stdexcept>
#include <set>
#include <string>
using namespace std;
template<typename T>
class Enum
{
public:
static void insert(int value)
{
_set.insert(value);
}
static T buildFrom(int value)
{
if (_set.find(value) != _set.end()) {
T retval;
retval.assign(value);
return retval;
}
throw std::runtime_error("unexpected value");
}
operator int() const { return _value; }
private:
void assign(int value)
{
_value = value;
}
int _value;
static std::set<int> _set;
};
template<typename T> std::set<int> Enum<T>::_set;
class Apples: public Enum<Apples> {};
class Oranges: public Enum<Oranges> {};
class Proxy
{
public:
Proxy(int value): _value(value) {}
template<typename T>
operator T()
{
T theEnum;
return theEnum.buildFrom(_value);
}
int _value;
};
Proxy convert(int value)
{
return Proxy(value);
}
int main()
{
Apples::insert(4);
Apples::insert(8);
Apples a = convert(4); // works
std::cout << a << std::endl; // prints 4
try {
Apples b = convert(9); // throws
}
catch (std::exception const& e) {
std::cout << e.what() << std::endl; // prints "unexpected value"
}
try {
Oranges b = convert(4); // also throws
}
catch (std::exception const& e) {
std::cout << e.what() << std::endl; // prints "unexpected value"
}
}
You could then use code I posted here to switch on values.
You should not want something like what you describe to exist, I fear there are problems in your code design.
Also, you assume that enums come in a range, but that's not always the case:
enum Flags { one = 1, two = 2, four = 4, eigh = 8, big = 2000000000 };
This is not in a range: even if it was possible, are you supposed to check every integer from 0 to 2^n to see if they match some enum's value?
If you are prepared to list your enum values as template parameters you can do this in C++ 11 with varadic templates. You can look at this as a good thing, allowing you to accept subsets of the valid enum values in different contexts; often useful when parsing codes from external sources.
Perhaps not quite as generic as you'd like, but the checking code itself is generalised, you just need to specify the set of values. This approach handles gaps, arbitrary values, etc.
template<typename EnumType, EnumType... Values> class EnumCheck;
template<typename EnumType> class EnumCheck<EnumType>
{
public:
template<typename IntType>
static bool constexpr is_value(IntType) { return false; }
};
template<typename EnumType, EnumType V, EnumType... Next>
class EnumCheck<EnumType, V, Next...> : private EnumCheck<EnumType, Next...>
{
using super = EnumCheck<EnumType, Next...>;
public:
template<typename IntType>
static bool constexpr is_value(IntType v)
{
return v == static_cast<typename std::underlying_type<EnumType>::type>(V) || super::is_value(v);
}
EnumType convert(IntType v)
{
if (!is_value(v)) throw std::runtime_error("Enum value out of range");
return static_cast<EnumType>(v);
};
enum class Test {
A = 1,
C = 3,
E = 5
};
using TestCheck = EnumCheck<Test, Test::A, Test::C, Test::E>;
void check_value(int v)
{
if (TestCheck::is_value(v))
printf("%d is OK\n", v);
else
printf("%d is not OK\n", v);
}
int main()
{
for (int i = 0; i < 10; ++i)
check_value(i);
}
C++0x alternative to the "ugly" version, allows for multiple enums. Uses initializer lists rather than switches, a bit cleaner IMO. Unfortunately, this doesn't work around the need to hard-code the enum values.
#include <cassert> // assert
namespace // unnamed namespace
{
enum class e1 { value_1 = 1, value_2 = 2 };
enum class e2 { value_3 = 3, value_4 = 4 };
template <typename T>
int valid_enum( const int val, const T& vec )
{
for ( const auto item : vec )
if ( static_cast<int>( item ) == val ) return val;
throw std::exception( "invalid enum value!" ); // throw something useful here
} // valid_enum
} // ns
int main()
{
// generate list of valid values
const auto e1_valid_values = { e1::value_1, e1::value_2 };
const auto e2_valid_values = { e2::value_3, e2::value_4 };
auto result1 = static_cast<e1>( valid_enum( 1, e1_valid_values ) );
assert( result1 == e1::value_1 );
auto result2 = static_cast<e2>( valid_enum( 3, e2_valid_values ) );
assert( result2 == e2::value_3 );
// test throw on invalid value
try
{
auto result3 = static_cast<e1>( valid_enum( 9999999, e1_valid_values ) );
assert( false );
}
catch ( ... )
{
assert( true );
}
}