// Copyright (C) 2020 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 used to combine enumeration values into flags bitfield */ /*! * \brief Constructs a Flags object using a bitfield * * \param value Bitfield to be used * * Uses a bitfield to builds the flag value. (e.g. if bit 0 is active, then Enum value 0 will be set as active). */ template constexpr Flags::Flags(BitField value) : m_value(value) { } /*! * \brief Constructs a Flags object using an Enum value * * \param enumVal enumVal * * Setup a Flags object with only one flag active (corresponding to the enum value passed as argument). */ template constexpr Flags::Flags(E enumVal) : Flags(GetFlagValue(enumVal)) { } /*! * \brief Clear all flags * * \see Test */ template void Flags::Clear() { m_value = 0; } /*! * \brief Clear some flags * * \param flags Flags to be cleared * * \see Test */ template void Flags::Clear(const Flags& flags) { m_value &= ~flags.m_value; } /*! * \brief Enable some flags * * \param flags Flags to be enabled * * \see Clear * \see Test */ template void Flags::Set(const Flags& flags) { m_value |= flags.m_value; } /*! * \brief Tests if all flags from a Flags object are enabled * \return True if all tested flags are enabled. * * \see Clear */ template constexpr bool Flags::Test(const Flags& flags) const { return (m_value & flags.m_value) == flags.m_value; } /*! * \brief Tests any flag * \return True if any flag is enabled. * * This will convert to a boolean value allowing to check if any flag is set. */ template constexpr Flags::operator bool() const { return m_value != 0; } /*! * \brief Converts to an integer * \return Enabled flags as a integer * * This will only works if the integer type is large enough to store all flags states */ template template constexpr Flags::operator T() const { return m_value; } /*! * \brief Reverse flag states * \return Opposite enabled flags * * This will returns a copy of the Flags object with reversed flags states. */ template constexpr Flags Flags::operator~() const { return Flags((~m_value) & ValueMask); } /*! * \brief Compare flag states * \return Shared flags * * \param rhs Flags to compare with. * * This will returns a copy of the Flags object with only enabled flags in common with the parameter */ template constexpr Flags Flags::operator&(const Flags& rhs) const { return Flags(m_value & rhs.m_value); } /*! * \brief Combine flag states * \return Combined flags * * This will returns a copy of the Flags object with combined flags from the parameter. * * \param rhs Flags to combine with. */ template constexpr Flags Flags::operator|(const Flags& rhs) const { return Flags(m_value | rhs.m_value); } /*! * \brief XOR flag states * \return XORed flags. * * \param rhs Flags to XOR with. * * This performs a XOR (Exclusive OR) on a copy of the flag object. * This will returns a copy of the object with disabled common flags and enabled unique ones. */ template constexpr Flags Flags::operator^(const Flags& rhs) const { return Flags((m_value ^ rhs.m_value) & ValueMask); } /*! * \brief Check equality with flag object * \return True if both flags objects have the same states. * * \param rhs Flags to compare with. * * Compare two Flags object and returns true if the flag states are identical. */ template constexpr bool Flags::operator==(const Flags& rhs) const { return m_value == rhs.m_value; } /*! * \brief Check inequality with flag object * \return True if both flags objects have different states. * * \param rhs Flags to compare with. * * Compare two Flags object and returns true if the flag states are identical. */ template constexpr bool Flags::operator!=(const Flags& rhs) const { return !operator==(rhs); } /*! * \brief Combine flag states * \return A reference to the object. * * \param rhs Flags to combine with. * * This will enable flags which are enabled in parameter object and not in Flag object. */ template /*constexpr*/ Flags& Flags::operator|=(const Flags& rhs) { m_value |= rhs.m_value; return *this; } /*! * \brief Compare flag states * \return A reference to the object. * * \param rhs Flags to compare with. * * This will disable flags which are disabled in parameter object and enabled in Flag object (and vice-versa). */ template /*constexpr*/ Flags& Flags::operator&=(const Flags& rhs) { m_value &= rhs.m_value; return *this; } /*! * \brief XOR flag states * \return A reference to the object. * * \param rhs Flags to XOR with. * * This performs a XOR (Exclusive OR) on the flag object. * This will disable flags enabled in both Flags objects and enable those enabled in only one of the Flags objects. */ template /*constexpr*/ Flags& Flags::operator^=(const Flags& rhs) { m_value ^= rhs.m_value; m_value &= ValueMask; return *this; } /*! * \brief Returns a bitfield corresponding to an enum value. * \return Bitfield representation of the enum value * * \param enumValue Enumeration value to get as a bitfield. * * Internally, every enum option is turned into a bit, this function allows to get a bitfield with only the bit of the enumeration value enabled. */ template constexpr typename Flags::BitField Flags::GetFlagValue(E enumValue) { return 1U << static_cast(enumValue); } /*! * \brief Compare flag states * \return Compared flags * * This will returns a copy of the Flags object compared with the enum state. * * \param lhs Enum to compare with flags. * \param rhs Flags object. */ template constexpr Flags operator&(E lhs, Flags rhs) { return rhs & lhs; } /*! * \brief Combine flag states * \return Combined flags * * This will returns a copy of the Flags object combined with the enum state. * * \param lhs Enum to combine with flags. * \param rhs Flags object. */ template constexpr Flags operator|(E lhs, Flags rhs) { return rhs | lhs; } /*! * \brief XOR flag states * \return XORed flags * * This will returns a copy of the Flags object XORed with the enum state. * * \param lhs Enum to XOR with flags. * \param rhs Flags object. */ template constexpr Flags operator^(E lhs, Flags rhs) { return rhs ^ lhs; } namespace FlagsOperators { /*! * \brief Override binary NOT operator on enum to turns into a Flags object. * \return A Flags object with reversed bits. * * \param lhs Enumeration value to reverse. * * Returns a Flags object with all state enabled except for the enum one. */ template constexpr std::enable_if_t::value, Flags> operator~(E lhs) { return ~Flags(lhs); } /*! * \brief Override binary AND operator on enum to turns into a Flags object. * \return A Flags object with compare enum states. * * \param lhs First enumeration value to compare. * \param rhs Second enumeration value to compare. * * Returns a Flags object with compared states from the two enumeration values. * In this case, only one flag will be enabled if both enumeration values are the same. */ template constexpr std::enable_if_t::value, Flags> operator&(E lhs, E rhs) { return Flags(lhs) & rhs; } /*! * \brief Override binary OR operator on enum to turns into a Flags object. * \return A Flags object with combined enum states. * * \param lhs First enumeration value to combine. * \param rhs Second enumeration value to combine. * * Returns a Flags object with combined states from the two enumeration values. */ template constexpr std::enable_if_t::value, Flags> operator|(E lhs, E rhs) { return Flags(lhs) | rhs; } /*! * \brief Override binary XOR operator on enum to turns into a Flags object. * \return A Flags object with XORed enum states. * * \param lhs First enumeration value to compare. * \param rhs Second enumeration value to compare. * * Returns a Flags object with XORed states from the two enumeration values. * In this case, two flags will be enabled if both the enumeration values are different. */ template constexpr std::enable_if_t::value, Flags> operator^(E lhs, E rhs) { return Flags(lhs) ^ rhs; } } } #include