Mercurial > code
view C++/modules/Flags/Flags.h @ 334:0b576ee64d45
* Create brand new hierarchy
* Rename DynLib to Dynlib
* Remove some warnings
author | David Demelier <markand@malikania.fr> |
---|---|
date | Sun, 08 Mar 2015 14:26:33 +0100 |
parents | C++/Flags.h@a9946b5ca0cb |
children | d5ec1174b707 |
line wrap: on
line source
/* * Flags.h -- safe wrapper for enum flags * * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr> * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifndef _FLAGS_H_ #define _FLAGS_H_ /** * @file Flags.h * @brief Provide template class Flags and operators for enum classes */ #include <type_traits> /** * @class Flags * @brief Wrapper that store enum flags * * This class is used to store an enum and make bitwise operations on it. User do not need * to supply these operators because they are implemented in the class. * * This class is very cheap and store the real underlying type from the enum and all functions * are inlined. */ template <typename Enum, typename Type = std::underlying_type_t<Enum>> class Flags final { private: Type m_value { 0 }; public: /** * Construct flags to 0. */ constexpr Flags() noexcept = default; /** * Construct flags with the enum value. * * @param m the mask */ constexpr Flags(Enum m) noexcept : m_value(static_cast<Type>(m)) { } /** * Construct flags with the enum value. * * @param m the mask */ constexpr Flags(Type m) noexcept : m_value(m) { } /** * Move constructor. * * @param other the other */ inline Flags(Flags &&other) noexcept = default; /** * Copy constructor. * * @param other the other */ inline Flags(const Flags &other) noexcept = default; /** * Move operator. * * @param other the other */ inline Flags &operator=(Flags &&other) noexcept = default; /** * Copy operator. * * @param other the other */ inline Flags &operator=(const Flags &other) noexcept = default; /** * &= operator. * * @param m the mask * @return *this */ inline Flags &operator&=(Enum m) noexcept { m_value &= static_cast<Type>(m); return *this; } /** * &= operator. * * @param m the mask * @return *this */ inline Flags &operator&=(Type m) noexcept { m_value &= m; return *this; } /** * |= operator. * * @param m the mask * @return *this */ inline Flags &operator|=(Enum m) noexcept { m_value |= static_cast<Type>(m); return *this; } /** * |= operator. * * @param m the mask * @return *this */ inline Flags &operator|=(Type m) noexcept { m_value |= m; return *this; } /** * ^= operator. * * @param m the mask * @return *this */ inline Flags &operator^=(Enum m) noexcept { m_value ^= static_cast<Type>(m); return *this; } /** * ^= operator. * * @param m the mask * @return *this */ inline Flags &operator^=(Type m) noexcept { m_value ^= m; return *this; } /** * & operator. * * @param m the mask * @return & combination */ constexpr Flags operator&(Enum m) const noexcept { return m_value & static_cast<Type>(m); } /** * & operator. * * @param m the mask * @return & combination */ constexpr Flags operator&(Type m) const noexcept { return m_value & m; } /** * | operator. * * @param m the mask * @return | combination */ constexpr Flags operator|(Enum m) const noexcept { return m_value | static_cast<Type>(m); } /** * | operator. * * @param m the mask * @return | combination */ constexpr Flags operator|(Type m) const noexcept { return m_value | m; } /** * ^ operator. * * @param m the mask * @return ^ combination */ constexpr Flags operator^(Enum m) const noexcept { return m_value & static_cast<Type>(m); } /** * ^ operator. * * @param m the mask * @return ^ combination */ constexpr Flags operator^(Type m) const noexcept { return m_value & m; } /** * ~ unary operator. * * @return ~ */ constexpr Flags operator~() const noexcept { return ~m_value; } /** * Convert to bool. Simply check if value is not 0. * * @return true if value != 0 */ constexpr operator bool() const noexcept { return m_value != 0; } /** * Operator !. Simply check if value is 0. * * @return true if value == 0 */ constexpr bool operator!() const noexcept { return m_value == 0; } /** * Test comparison with other mask. * * @return true if this value == m */ constexpr bool operator==(Enum m) const noexcept { return m_value == static_cast<Type>(m); } /** * Test comparison with other mask. * * @return true if this value == m */ constexpr bool operator==(Type m) const noexcept { return m_value == m; } }; /** * Apply & operator on the enum. * * @param x1 the first value * @param x2 the second value */ template <typename Value, typename Type = std::enable_if_t<std::is_enum<Value>::value, std::underlying_type_t<Value>>> constexpr Value operator&(Value x1, Value x2) noexcept { return static_cast<Value>(static_cast<Type>(x1) & static_cast<Type>(x2)); } /** * Apply | operator on the enum. * * @param x1 the first value * @param x2 the second value */ template <typename Value, typename Type = std::enable_if_t<std::is_enum<Value>::value, std::underlying_type_t<Value>>> constexpr Value operator|(Value x1, Value x2) noexcept { return static_cast<Value>(static_cast<Type>(x1) | static_cast<Type>(x2)); } /** * Apply ^ operator on the enum. * * @param x1 the first value * @param x2 the second value */ template <typename Value, typename Type = std::enable_if_t<std::is_enum<Value>::value, std::underlying_type_t<Value>>> constexpr Value operator^(Value x1, Value x2) noexcept { return static_cast<Value>(static_cast<Type>(x1) ^ static_cast<Type>(x2)); } /** * Apply ~ operator on the enum. * * @param x1 the first value * @param x2 the second value */ template <typename Value, typename Type = std::enable_if_t<std::is_enum<Value>::value, std::underlying_type_t<Value>>> constexpr Value operator~(Value x) noexcept { return static_cast<Value>(~static_cast<Type>(x)); } #endif // !_FLAGS_H_