chore: make FlagsEnum constexpr (#5510)
This commit is contained in:
+75
-44
@@ -1,59 +1,74 @@
|
||||
#pragma once
|
||||
|
||||
#include <initializer_list>
|
||||
#include <concepts>
|
||||
#include <type_traits>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
template <typename T, typename Q = typename std::underlying_type<T>::type>
|
||||
template <typename T>
|
||||
requires std::is_enum_v<T>
|
||||
class FlagsEnum
|
||||
{
|
||||
public:
|
||||
FlagsEnum()
|
||||
: value_(static_cast<T>(0))
|
||||
using Int = std::underlying_type_t<T>;
|
||||
|
||||
constexpr FlagsEnum() noexcept = default;
|
||||
|
||||
constexpr FlagsEnum(std::convertible_to<T> auto... flags) noexcept
|
||||
: value_(
|
||||
static_cast<T>((static_cast<Int>(static_cast<T>(flags)) | ...)))
|
||||
{
|
||||
}
|
||||
|
||||
FlagsEnum(T value)
|
||||
: value_(value)
|
||||
friend constexpr bool operator==(FlagsEnum lhs, FlagsEnum rhs) noexcept
|
||||
{
|
||||
return lhs.value_ == rhs.value_;
|
||||
}
|
||||
friend constexpr bool operator!=(FlagsEnum lhs, FlagsEnum rhs) noexcept
|
||||
{
|
||||
return lhs.value_ != rhs.value_;
|
||||
}
|
||||
|
||||
FlagsEnum(std::initializer_list<T> flags)
|
||||
friend constexpr bool operator==(FlagsEnum lhs, T rhs) noexcept
|
||||
{
|
||||
for (auto flag : flags)
|
||||
{
|
||||
this->set(flag);
|
||||
}
|
||||
return lhs.value_ == rhs;
|
||||
}
|
||||
friend constexpr bool operator!=(FlagsEnum lhs, T rhs) noexcept
|
||||
{
|
||||
return lhs.value_ != rhs;
|
||||
}
|
||||
|
||||
bool operator==(const FlagsEnum<T> &other) const
|
||||
friend constexpr bool operator==(T lhs, FlagsEnum rhs) noexcept
|
||||
{
|
||||
return this->value_ == other.value_;
|
||||
return lhs == rhs.value_;
|
||||
}
|
||||
friend constexpr bool operator!=(T lhs, FlagsEnum rhs) noexcept
|
||||
{
|
||||
return lhs != rhs.value_;
|
||||
}
|
||||
|
||||
bool operator!=(const FlagsEnum<T> &other) const
|
||||
constexpr void set(std::convertible_to<T> auto... flags) noexcept
|
||||
{
|
||||
return this->value_ != other.value_;
|
||||
}
|
||||
|
||||
void set(T flag)
|
||||
{
|
||||
reinterpret_cast<Q &>(this->value_) |= static_cast<Q>(flag);
|
||||
this->value_ =
|
||||
static_cast<T>(static_cast<Int>(this->value_) |
|
||||
(static_cast<Int>(static_cast<T>(flags)) | ...));
|
||||
}
|
||||
|
||||
/** Adds the flags from `flags` in this enum. */
|
||||
void set(FlagsEnum flags)
|
||||
constexpr void set(FlagsEnum flags) noexcept
|
||||
{
|
||||
reinterpret_cast<Q &>(this->value_) |= static_cast<Q>(flags.value_);
|
||||
this->value_ = static_cast<T>(static_cast<Int>(this->value_) |
|
||||
static_cast<Int>(flags.value_));
|
||||
}
|
||||
|
||||
void unset(T flag)
|
||||
constexpr void unset(std::convertible_to<T> auto... flags) noexcept
|
||||
{
|
||||
reinterpret_cast<Q &>(this->value_) &= ~static_cast<Q>(flag);
|
||||
this->value_ =
|
||||
static_cast<T>(static_cast<Int>(this->value_) &
|
||||
~(static_cast<Int>(static_cast<T>(flags)) | ...));
|
||||
}
|
||||
|
||||
void set(T flag, bool value)
|
||||
constexpr void set(T flag, bool value) noexcept
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
@@ -65,43 +80,59 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
bool has(T flag) const
|
||||
constexpr FlagsEnum operator|(T flag) const noexcept
|
||||
{
|
||||
return static_cast<Q>(this->value_) & static_cast<Q>(flag);
|
||||
return static_cast<T>(static_cast<Int>(this->value_) |
|
||||
static_cast<Int>(flag));
|
||||
}
|
||||
|
||||
FlagsEnum operator|(T flag)
|
||||
constexpr FlagsEnum operator|(FlagsEnum rhs) const noexcept
|
||||
{
|
||||
FlagsEnum xd;
|
||||
xd.value_ = this->value_;
|
||||
xd.set(flag, true);
|
||||
|
||||
return xd;
|
||||
return static_cast<T>(static_cast<Int>(this->value_) |
|
||||
static_cast<Int>(rhs.value_));
|
||||
}
|
||||
|
||||
FlagsEnum operator|(FlagsEnum rhs)
|
||||
constexpr bool has(T flag) const noexcept
|
||||
{
|
||||
return static_cast<T>(static_cast<Q>(this->value_) |
|
||||
static_cast<Q>(rhs.value_));
|
||||
return static_cast<Int>(this->value_) & static_cast<Int>(flag);
|
||||
}
|
||||
|
||||
bool hasAny(FlagsEnum flags) const
|
||||
constexpr bool hasAny(FlagsEnum flags) const noexcept
|
||||
{
|
||||
return static_cast<Q>(this->value_) & static_cast<Q>(flags.value_);
|
||||
return (static_cast<Int>(this->value_) &
|
||||
static_cast<Int>(flags.value_)) != 0;
|
||||
}
|
||||
|
||||
bool hasAll(FlagsEnum<T> flags) const
|
||||
constexpr bool hasAny(std::convertible_to<T> auto... flags) const noexcept
|
||||
{
|
||||
return (static_cast<Q>(this->value_) & static_cast<Q>(flags.value_)) &&
|
||||
static_cast<Q>(flags->value);
|
||||
return this->hasAny(FlagsEnum{flags...});
|
||||
}
|
||||
|
||||
bool hasNone(std::initializer_list<T> flags) const
|
||||
constexpr bool hasAll(FlagsEnum flags) const noexcept
|
||||
{
|
||||
return !this->hasAny(flags);
|
||||
return (static_cast<Int>(this->value_) &
|
||||
static_cast<Int>(flags.value_)) ==
|
||||
static_cast<Int>(flags.value_);
|
||||
}
|
||||
|
||||
T value() const
|
||||
constexpr bool hasAll(std::convertible_to<T> auto... flags) const noexcept
|
||||
{
|
||||
return this->hasAll(FlagsEnum{flags...});
|
||||
}
|
||||
|
||||
constexpr bool hasNone(FlagsEnum flags) const noexcept
|
||||
{
|
||||
return (static_cast<Int>(this->value_) &
|
||||
static_cast<Int>(flags.value_)) == 0;
|
||||
}
|
||||
|
||||
constexpr bool hasNone() const noexcept = delete;
|
||||
constexpr bool hasNone(std::convertible_to<T> auto... flags) const noexcept
|
||||
{
|
||||
return this->hasNone(FlagsEnum{flags...});
|
||||
}
|
||||
|
||||
constexpr T value() const noexcept
|
||||
{
|
||||
return this->value_;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user