template<class T, typename std::underlying_type<T>::type fullValue = typename std::underlying_type<T>::type(~0)>
Corrade::Containers::EnumSet class

Set of enum values.

Template parameters
T Enum type
fullValue All enum values together. Defaults to all bits set to 1.

Provides strongly-typed set-like functionality for strongly typed enums, such as binary OR and AND operations. The only requirement for the enum type is that all the values must be binary exclusive.

Desired usage is via typedef'ing. You should also call the CORRADE_ENUMSET_OPERATORS() macro with the resulting type as a parameter to have out-of-class operators defined:

enum class Feature: unsigned int {
    Fast = 1 << 0,
    Cheap = 1 << 1,
    Tested = 1 << 2,
    Popular = 1 << 3
};

typedef Containers::EnumSet<Feature> Features;
CORRADE_ENUMSET_OPERATORS(Features)

You can have the EnumSet as a private or protected member of any class. The only difference is that you need to call CORRADE_ENUMSET_FRIEND_OPERATORS() inside the class. Do not combine it with the CORRADE_ENUMSET_OPERATORS() in this case, you'd get duplicate definitions. This macro works with templated classes as well.

class Application {
    private:
        enum class Flag: unsigned int {
            Redraw = 1 << 0,
            Exit = 1 << 1
        };

        typedef Containers::EnumSet<Flag> Flags;
        CORRADE_ENUMSET_FRIEND_OPERATORS(Flags)
};

Public types

enum (anonymous): UnderlyingType { FullValue = fullValue }
using Type = T
Enum type.
using UnderlyingType = std::underlying_type<T>::type
Underlying type of the enum.

Constructors, destructors, conversion operators

EnumSet() constexpr noexcept
Create an empty set.
EnumSet(T value) constexpr noexcept
Create a set from one value.
EnumSet(Corrade::NoInitT) explicit
Create an uninitialized set.
operator bool() const explicit constexpr
Boolean conversion.
operator UnderlyingType() const explicit constexpr
Convert to the underlying enum type.

Public functions

auto operator==(EnumSet<T, fullValue> other) const -> bool constexpr
Equality comparison.
auto operator!=(EnumSet<T, fullValue> other) const -> bool constexpr
Non-equality comparison.
auto operator>=(EnumSet<T, fullValue> other) const -> bool constexpr
Whether other is a subset of this ( $ a \supseteq o $ )
auto operator<=(EnumSet<T, fullValue> other) const -> bool constexpr
Whether other is a superset of this ( $ a \subseteq o $ )
auto operator|(EnumSet<T, fullValue> other) const -> EnumSet<T, fullValue> constexpr
Union of two sets.
auto operator|=(EnumSet<T, fullValue> other) -> EnumSet<T, fullValue>&
Union two sets and assign.
auto operator&(EnumSet<T, fullValue> other) const -> EnumSet<T, fullValue> constexpr
Intersection of two sets.
auto operator&=(EnumSet<T, fullValue> other) -> EnumSet<T, fullValue>&
Intersect two sets and assign.
auto operator^(EnumSet<T, fullValue> other) const -> EnumSet<T, fullValue> constexpr
XOR of two sets.
auto operator^=(EnumSet<T, fullValue> other) -> EnumSet<T, fullValue>&
XOR two sets and assign.
auto operator~() const -> EnumSet<T, fullValue> constexpr
Set complement.

Enum documentation

template<class T, typename std::underlying_type<T>::type fullValue>
enum Corrade::Containers::EnumSet<T, fullValue>::(anonymous): UnderlyingType

Enumerators
FullValue

All enum values together

Function documentation

template<class T, typename std::underlying_type<T>::type fullValue>
Corrade::Containers::EnumSet<T, fullValue>::EnumSet(Corrade::NoInitT) explicit

Create an uninitialized set.

The contents are left in an undefined state.

template<class T, typename std::underlying_type<T>::type fullValue>
Corrade::Containers::EnumSet<T, fullValue>::operator bool() const explicit constexpr

Boolean conversion.

Returns true if at least one bit is set, false otherwise.

template<class T, typename std::underlying_type<T>::type fullValue>
bool Corrade::Containers::EnumSet<T, fullValue>::operator>=(EnumSet<T, fullValue> other) const constexpr

Whether other is a subset of this ( $ a \supseteq o $ )

Equivalent to (a & other) == other.

template<class T, typename std::underlying_type<T>::type fullValue>
bool Corrade::Containers::EnumSet<T, fullValue>::operator<=(EnumSet<T, fullValue> other) const constexpr

Whether other is a superset of this ( $ a \subseteq o $ )

Equivalent to (a & other) == a.

template<class T, typename std::underlying_type<T>::type fullValue> template<class T, class = typename std::enable_if<std::is_enum<T>::value>::type>
std::underlying_type<T>::type enumCastUnderlyingType(T value) constexpr new in 2020.06

Cast an enum to its underlying type.

Works only with EnumSet, not with BigEnumSet.

template<class T, typename std::underlying_type<T>::type fullValue> template<class T, typename std::underlying_type<T>::type fullValue>
std::underlying_type<T>::type enumCastUnderlyingType(EnumSet<T, fullValue> value) constexpr new in 2020.06

Cast an enum set to its underlying type.

Works only with EnumSet, not with BigEnumSet.

template<class T, typename std::underlying_type<T>::type fullValue> template<class T, typename std::underlying_type<T>::type fullValue>
Utility::Debug& enumSetDebugOutput(Utility::Debug& debug, EnumSet<T, fullValue> value, const char* empty, std::initializer_list<T> enums)

Print an enum set to debug output.

Parameters
debug Debug output
value Value to be printed
empty What to print in case of an empty enum set
enums Recognized enum values

Assuming the underlying enum type has already implemented operator<< for Utility::Debug, this function is able to print the values in given enum set. Example definition:

enum class Feature: unsigned int {
    Fast = 1 << 0,
    Cheap = 1 << 1,
    Tested = 1 << 2,
    Popular = 1 << 3
};

// already defined to print values as e.g. Feature::Fast and Features(0xabcd)
// for unknown values
Utility::Debug& operator<<(Utility::Debug&, Feature);

typedef Containers::EnumSet<Feature> Features;
CORRADE_ENUMSET_OPERATORS(Features)

Utility::Debug& operator<<(Utility::Debug& debug, Features value) {
    return Containers::enumSetDebugOutput(debug, value, "Features{}", {
        Feature::Fast,
        Feature::Cheap,
        Feature::Tested,
        Feature::Popular});
}

The usage would then be straightforward:

// prints Feature::Fast|Feature::Cheap
Utility::Debug{} << (Feature::Fast|Feature::Cheap);

// prints Feature::Popular|Feature(0xdead)
Utility::Debug{} << (Feature::Popular|Feature(0xdead));

// prints Features{}
Utility::Debug{} << Features{};