diff --git a/include/Nazara/Core/Flags.hpp b/include/Nazara/Core/Flags.hpp new file mode 100644 index 000000000..ad96212fe --- /dev/null +++ b/include/Nazara/Core/Flags.hpp @@ -0,0 +1,59 @@ +// Copyright (C) 2016 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_FLAGS_HPP +#define NAZARA_FLAGS_HPP + +#include +#include + +namespace Nz +{ + template + class Flags + { + static_assert(std::is_enum::value, "Type must be an enumeration"); + + public: + constexpr Flags(UInt32 value); + constexpr Flags(E enumVal); + + explicit constexpr operator bool() const; + + constexpr Flags operator~() const; + constexpr Flags operator&(Flags rhs) const; + constexpr Flags operator|(Flags rhs) const; + constexpr Flags operator^(Flags rhs) const; + + constexpr bool operator==(Flags rhs) const; + constexpr bool operator!=(Flags rhs) const; + + /*constexpr*/ Flags& operator|=(Flags rhs); + /*constexpr*/ Flags& operator&=(Flags rhs); + /*constexpr*/ Flags& operator^=(Flags rhs); + + static constexpr UInt32 GetFlagValue(E enumValue); + + private: + UInt32 m_value; + }; + + // From: https://www.justsoftwaresolutions.co.uk/cplusplus/using-enum-classes-as-bitfields.html + template + struct EnableFlagsOperators + { + static constexpr bool value = false; + }; + + template constexpr std::enable_if_t::value, Flags> operator~(E lhs); + template constexpr std::enable_if_t::value, Flags> operator|(E lhs, E rhs); + template constexpr std::enable_if_t::value, Flags> operator&(E lhs, E rhs); + template constexpr std::enable_if_t::value, Flags> operator^(E lhs, E rhs); +} + +#include + +#endif // NAZARA_FLAGS_HPP diff --git a/include/Nazara/Core/Flags.inl b/include/Nazara/Core/Flags.inl new file mode 100644 index 000000000..fa8dd4950 --- /dev/null +++ b/include/Nazara/Core/Flags.inl @@ -0,0 +1,128 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include + +namespace Nz +{ + /*! + * \ingroup core + * \class Nz::Flags + * \brief Core class that represents a set of bits + * + * This class meets the requirements of Container, AllocatorAwareContainer, SequenceContainer + */ + + template + constexpr Flags::Flags(UInt32 value) : + m_value(value) + { + } + + template + constexpr Flags::Flags(E enumVal) : + Flags(GetFlagValue(enumVal)) + { + } + + template + constexpr Flags::operator bool() const + { + return m_value != 0; + } + + template + constexpr Flags Flags::operator~() const + { + return Flags(~m_value); + } + + template + constexpr Flags Flags::operator&(Flags rhs) const + { + return Flags(m_value & rhs.m_value); + } + + template + constexpr Flags Flags::operator|(Flags rhs) const + { + return Flags(m_value | rhs.m_value); + } + + template + constexpr Flags Flags::operator^(Flags rhs) const + { + return Flags(m_value ^ rhs.m_value); + } + + template + constexpr bool Flags::operator==(Flags rhs) const + { + return m_value == rhs.m_value; + } + + template + constexpr bool Flags::operator!=(Flags rhs) const + { + return !operator==(rhs); + } + + template + /*constexpr*/ Flags& Flags::operator|=(Flags rhs) + { + m_value |= rhs.m_value; + + return *this; + } + + template + /*constexpr*/ Flags& Flags::operator&=(Flags rhs) + { + m_value &= rhs.m_value; + + return *this; + } + + template + /*constexpr*/ Flags& Flags::operator^=(Flags rhs) + { + m_value ^= rhs.m_value; + + return *this; + } + + template + constexpr UInt32 Flags::GetFlagValue(E enumValue) + { + return 1U << static_cast(enumValue); + } + + + template + constexpr std::enable_if_t::value, Flags> operator~(E lhs) + { + return ~Flags(lhs); + } + + template + constexpr std::enable_if_t::value, Flags> operator|(E lhs, E rhs) + { + return Flags(lhs) | rhs; + } + + template + constexpr std::enable_if_t::value, Flags> operator&(E lhs, E rhs) + { + return Flags(lhs) & rhs; + } + + template + constexpr std::enable_if_t::value, Flags> operator^(E lhs, E rhs) + { + return Flags(lhs) ^ rhs; + } +} + +#include