#ifndef Magnum_Set_h #define Magnum_Set_h /* Copyright © 2010, 2011, 2012 Vladimír Vondruš 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 States; SET_OPERATORS(States) @endcode */ template class Set { public: typedef T Type; /**< @brief Enum type */ typedef U UnderlyingType; /**< @brief Underlying type of the enum */ /** @brief Create empty set */ inline constexpr Set(): value() {} /** @brief Create set from one value */ inline constexpr Set(T value): value(static_cast(value)) {} /** @brief Add value to the set */ inline constexpr Set operator|(T other) const { return Set(value | static_cast(other)); } /** @brief Union of two sets */ inline constexpr Set operator|(Set other) const { return Set(value | other.value); } /** @brief Add value to the set and assign */ inline Set& operator|=(T other) { value |= static_cast(other); return *this; } /** @brief Union two sets and assign */ inline Set& operator|=(Set other) { value |= other.value; return *this; } /** @brief Check if given value is in the set */ inline constexpr T operator&(T other) const { return static_cast(value & static_cast(other)); } /** @brief Intersection of two sets */ inline constexpr Set operator&(Set other) const { return Set(value & other.value); } /** @brief Intersect two sets and assign */ inline Set& operator&=(Set other) const { value &= other.value; return *this; } /** @brief Value in underlying type */ inline constexpr UnderlyingType toUnderlyingType() const { return value; } private: inline constexpr 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