blob: 638a126353c73a58f3e0606dd53bba6a94dcd9ff (
plain) (
tree)
|
|
#ifndef UTILS_BITSET_H
#define UTILS_BITSET_H
#include <cassert>
#include <type_traits>
// -- BITSET -------------------------------------------------------------------
/// bitset
///
/// A simple bitset type, to experiment with with c++17 fold expressions and
/// type checked template argument packs.
///
/// Typically a bitset<> is created from an enum holding the bits of interest.
///
/// ```
/// enum mybits { x, y, z };
///
/// bitset<mybits> b;
///
/// b.set(x, y)
/// assert(b.is_set(x));
/// assert(b.any(x,z));
/// assert(!b.all(x,z));
/// ```
template <typename Bits>
struct bitset {
using bits_t = std::underlying_type_t<Bits>;
// -- CONSTRUCTOR ------------------------------------------------------------
template <typename... Bit>
constexpr explicit bitset(Bit... bit) {
(set(bit), ...);
}
// -- SET/UNSET --------------------------------------------------------------
template <typename... Bit>
void set(Bit... bit) {
(op<Bit>([&]() { set(bit); }), ...);
}
void set(Bits v) {
m_val |= shifted(v);
}
template <typename... Bit>
void unset(Bit... bit) {
(op<Bit>([&]() { unset(bit); }), ...);
}
void unset(Bits v) {
m_val &= ~shifted(v);
}
void clear() {
m_val = 0;
}
// -- QUERY ------------------------------------------------------------------
constexpr bool is_empty() const {
return m_val == 0;
}
constexpr bool is_set(Bits v) const {
return m_val & shifted(v);
}
template <typename... Bit>
constexpr bool any(Bit... bit) const {
return (is_set(bit) || ...);
}
template <typename... Bit>
constexpr bool all(Bit... bit) const {
return sizeof...(Bit) == 0 ? false : (is_set(bit) && ...);
}
// -- INTERNAL ---------------------------------------------------------------
private:
constexpr static bits_t shifted(Bits bit) {
assert(0 <= bit && bit < static_cast<bits_t>(sizeof(bits_t) * 8));
return static_cast<bits_t>(1) << bit;
}
template <typename T, typename F>
static constexpr auto op(F&& f) -> decltype(f()) {
static_assert(std::is_same_v<Bits, T>);
return f();
}
private:
bits_t m_val = 0;
};
#endif
|