You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

119 lines
3.8 KiB

#ifndef Magnum_Set_h
#define Magnum_Set_h
/*
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz>
This file is part of Magnum.
Magnum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 3
only, as published by the Free Software Foundation.
Magnum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License version 3 for more details.
*/
/** @file
* @brief Class Magnum::Set
*/
namespace Magnum {
/** @ingroup utility
@brief %Set
@tparam T Enum type
@tparam U Underlying type of the enum
Provides strongly-typed set-like functionality for strongly typed enums, such
as binary OR and AND operations. The only requirement for enum type is that
all the values must be binary exclusive.
Desired usage is via typedef'ing and then calling SET_OPERATORS() macro with
the resulting type as parameter to have all the operators implemented.
@code
enum class State: unsigned char {
Ready = 0x01,
Waiting = 0x02,
Done = 0x04
};
typedef Set<State, unsigned char> States;
SET_OPERATORS(States)
@endcode
*/
template<class T, class U> class Set {
public:
typedef T Type; /**< @brief Enum type */
typedef U UnderlyingType; /**< @brief Underlying type of the enum */
/** @brief Create empty set */
constexpr inline Set(): value() {}
/** @brief Create set from one value */
constexpr inline Set(T value): value(static_cast<UnderlyingType>(value)) {}
/** @brief Add value to the set */
constexpr inline Set<T, U> operator|(T other) const {
return Set<T, U>(value | static_cast<UnderlyingType>(other));
}
/** @brief Union of two sets */
constexpr inline Set<T, U> operator|(Set<T, U> other) const {
return Set<T, U>(value | other.value);
}
/** @brief Add value to the set and assign */
inline Set<T, U>& operator|=(T other) {
value |= static_cast<UnderlyingType>(other);
return *this;
}
/** @brief Union two sets and assign */
inline Set<T, U>& operator|=(Set<T, U> other) {
value |= other.value;
return *this;
}
/** @brief Check if given value is in the set */
constexpr inline T operator&(T other) const {
return static_cast<T>(value & static_cast<UnderlyingType>(other));
}
/** @brief Intersection of two sets */
constexpr inline Set<T, U> operator&(Set<T, U> other) const {
return Set<T, U>(value & other.value);
}
/** @brief Intersect two sets and assign */
inline Set<T, U>& operator&=(Set<T, U> other) const {
value &= other.value;
return *this;
}
/** @brief Value in underlying type */
constexpr inline UnderlyingType toUnderlyingType() const {
return value;
}
private:
constexpr inline explicit Set(UnderlyingType type): value(type) {}
UnderlyingType value;
};
/** @hideinitializer
@brief Define out-of-class operators for given Set implementation
*/
#define SET_OPERATORS(class) \
inline constexpr class operator|(class::Type a, class b) { \
return b | a; \
} \
inline constexpr class operator&(class::Type a, class b) { \
return b & a; \
}
}
#endif