Skip to content

Instantly share code, notes, and snippets.

@martinus
Created October 13, 2020 08:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save martinus/2149aa2d80a0d45ca4a40dfdce1a9bf1 to your computer and use it in GitHub Desktop.
Save martinus/2149aa2d80a0d45ca4a40dfdce1a9bf1 to your computer and use it in GitHub Desktop.
#pragma once
#include <bitset>
#include <type_traits>
namespace util {
// Provides a type-safe bitset for enums
template <typename E>
class EnumFlags {
static_assert(std::is_enum_v<E>, "EnumFlags can only be specialized for enum types");
public:
auto set(E pos, bool value) -> EnumFlags& {
mBits.set(under(pos), value);
return *this;
}
auto set(E pos) -> EnumFlags& {
return set(pos, true);
}
auto reset(E pos) -> EnumFlags& {
return set(pos, false);
}
auto reset() -> EnumFlags& {
mBits.reset();
return *this;
}
[[nodiscard]] auto all() const noexcept -> bool {
return mBits.all();
}
[[nodiscard]] auto any() const noexcept -> bool {
return mBits.any();
}
[[nodiscard]] auto none() const noexcept -> bool {
return mBits.none();
}
// Size of the bitset (same as flags_size)
[[nodiscard]] constexpr auto size() const noexcept -> size_t {
return mBits.size();
}
[[nodiscard]] auto count() const noexcept -> size_t {
return mBits.count();
}
constexpr auto operator[](E pos) const -> bool {
return mBits[under(pos)];
}
auto operator[](E pos) {
return mBits[under(pos)];
}
private:
using UnderlyingUnsigned = typename std::make_unsigned_t<typename std::underlying_type_t<E>>;
static constexpr auto under(E e) noexcept -> UnderlyingUnsigned {
return static_cast<UnderlyingUnsigned>(e);
}
std::bitset<under(E::flags_size)> mBits{};
};
} // namespace util
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment