/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2022 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see .
*/
#pragma once
#include
namespace detail
{
/// Marks an enum as supporting boolean operators
template
struct enum_is_flags : public std::false_type {};
/// For return types that should be convertible to bool
template
struct enum_bool_helper
{
Enum value;
constexpr enum_bool_helper(Enum value): value(value) {}
constexpr operator Enum() const { return value; }
constexpr operator bool() const { return static_cast(static_cast::type>(value)); }
};
};
#define MARK_ENUM_AS_FLAGS(T) template<> struct detail::enum_is_flags : public std::true_type {}
template
constexpr typename std::enable_if::value, Enum>::type
operator|(Enum lhs, Enum rhs) noexcept
{
using underlying = typename std::underlying_type::type;
return static_cast(static_cast(lhs) | static_cast(rhs));
}
template
constexpr typename std::enable_if::value, detail::enum_bool_helper>::type
operator&(Enum lhs, Enum rhs) noexcept
{
using underlying = typename std::underlying_type::type;
return static_cast(static_cast(lhs) & static_cast(rhs));
}
template
constexpr typename std::enable_if::value, Enum>::type
operator^(Enum lhs, Enum rhs) noexcept
{
using underlying = typename std::underlying_type::type;
return static_cast(static_cast(lhs) ^ static_cast(rhs));
}
template
constexpr typename std::enable_if::value, Enum&>::type
operator|=(Enum& lhs, Enum rhs) noexcept
{
return lhs = lhs | rhs;
}
template
constexpr typename std::enable_if::value, Enum&>::type
operator&=(Enum& lhs, Enum rhs) noexcept
{
return lhs = lhs & rhs;
}
template
constexpr typename std::enable_if::value, Enum&>::type
operator^=(Enum& lhs, Enum rhs) noexcept
{
return lhs = lhs ^ rhs;
}
template
constexpr typename std::enable_if::value, bool>::type
operator!(Enum e) noexcept
{
return !static_cast::type>(e);
}
template
constexpr typename std::enable_if::value, Enum>::type
operator~(Enum e) noexcept
{
return static_cast(~static_cast::type>(e));
}