ezEngine  Milestone 7
ezBitflags< T > Struct Template Reference

The ezBitflags class allows you to work with type-safe bitflags. More...

#include <Bitflags.h>

Public Member Functions

EZ_FORCE_INLINE ezBitflags ()
 Constructor. Initializes the flags to all empty.
 
EZ_FORCE_INLINE ezBitflags (Enum flag1)
 Converts the incoming type to ezBitflags<T>
 
EZ_FORCE_INLINE bool operator== (const StorageType rhs) const
 Comparison operator.
 
EZ_FORCE_INLINE bool operator!= (const StorageType rhs) const
 Comparison operator.
 
EZ_FORCE_INLINE bool operator== (const ezBitflags< T > &rhs) const
 Comparison operator.
 
EZ_FORCE_INLINE bool operator!= (const ezBitflags< T > &rhs) const
 Comparison operator.
 
EZ_FORCE_INLINE void Clear ()
 Clears all flags.
 
EZ_FORCE_INLINE bool IsSet (Enum flag) const
 Checks if certain flags are set within the bitfield.
 
EZ_FORCE_INLINE bool AreAllSet (const ezBitflags< T > &rhs) const
 Returns whether all the given flags are set.
 
EZ_FORCE_INLINE bool IsAnySet (const ezBitflags< T > &rhs) const
 Returns whether any of the given flags is set.
 
EZ_FORCE_INLINE void Add (const ezBitflags< T > &rhs)
 Sets the given flag.
 
EZ_FORCE_INLINE void Remove (const ezBitflags< T > &rhs)
 Removes the given flag.
 
EZ_FORCE_INLINE void Toggle (const ezBitflags< T > &rhs)
 Toggles the state of the given flag.
 
EZ_FORCE_INLINE void AddOrRemove (const ezBitflags< T > &rhs, bool state)
 Sets or clears the given flag.
 
ezBitflags< T > operator| (const ezBitflags< T > &rhs) const
 Returns an object that has the flags of this and rhs combined.
 
ezBitflags< T > operator& (const ezBitflags< T > &rhs) const
 Returns an object that has the flags that were set both in this and rhs.
 
void operator|= (const ezBitflags< T > &rhs)
 Modifies this to also contain the bits from rhs.
 
void operator&= (const ezBitflags< T > &rhs)
 Modifies this to only contain the bits that were set in this and rhs.
 
EZ_FORCE_INLINE StorageType GetValue () const
 Returns the stored value as the underlying integer type.
 

Private Types

typedef T::Enum Enum
 
typedef T::Bits Bits
 
typedef T::StorageType StorageType
 

Private Member Functions

EZ_FORCE_INLINE ezBitflags (StorageType flags)
 

Private Attributes

union {
StorageType m_Value
 
Bits m_bits
 
}; 
 

Detailed Description

template<typename T>
struct ezBitflags< T >

The ezBitflags class allows you to work with type-safe bitflags.

ezBitflags takes a struct as its template parameter, which contains an enum for the available flag values. ezBitflags wraps this type in a way which enables the compiler to do type-checks. This makes it very easy to document and enforce what flags are to be used in an interface. For example, in traditional C++ code, you usually need to have an integer as a function parameter type, when that parameter is supposed to take flags. However, WHICH flags (e.g. from which enum) cannot be enforced through compile time checks. Thus it is difficult for the user to see whether he used the correct type, and it is impossible for the compiler to help find such bugs. ezBitflags solves this problem. However the flag type used to instantiate ezBitflags must fulfill some requirements.

There are two ways to define your bitflags type, that can be used with ezBitflags.

The easier, less powerful way: Use the EZ_DECLARE_FLAGS() macro.
Example:

EZ_DECLARE_FLAGS(ezUInt8, SimpleRenderFlags, EnableEffects, EnableLighting, EnableShadows);

This will declare a type 'SimpleRenderFlags' which contains three different flags. You can then create a function which takes flags like this:

void RenderScene(ezBitflags<SimpleRenderFlags> Flags);

And this function can be called like this:

RenderScene(EnableEffects | EnableLighting | EnableShadows);

However it will refuse to compile with anything else, for example this will not work:

RenderScene(1);

The second way to declare your bitflags type allows even more flexibility. Here you need to declare your bitflag type manually:

struct SimpleRenderFlags
{
typedef ezUInt32 StorageType;
enum Enum
{
EnableEffects = EZ_BIT(0),
EnableLighting = EZ_BIT(1),
EnableShadows = EZ_BIT(2),
FullLighting = EnableLighting | EnableShadows,
AllFeatures = FullLighting | EnableEffects,
Default = AllFeatures
};
struct Bits
{
StorageType EnableEffects : 1;
StorageType EnableLighting : 1;
StorageType EnableShadows : 1;
};
};
EZ_DECLARE_FLAGS_OPERATORS(SimpleRenderFlags);

Here we declare a struct which contains our enum that contains all the flags that we want to have. This enum can contain flags that are combinations of other flags. Note also the 'Default' flag, which is mandatory.
The 'Bits' struct enables debuggers to show exactly which flags are enabled (with nice names) when you inspect an ezBitflags instance. You could leave this struct empty, but then your debugger can not show helpful information about the flags anymore. The Bits struct should contain one named entry for each individual bit. E.g. here only the flags 'EnableEffects', 'EnableLighting' and 'EnableShadows' actually map to single bits, the other flags are combinations of those. Therefore the Bits struct only specifies names for those first three Bits.
The typedef 'StorageType' is also mandatory, such that ezBitflags can access it.
Finally the macro EZ_DECLARE_FLAGS_OPERATORS will define the required operator to be able to combine bitflags of your type. I.e. it enables to write ezBitflags<SimpleRenderFlags> f = EnableEffects | EnableLighting;

For a real world usage example, see ezCVarFlags.


The documentation for this struct was generated from the following file: