mirror of
https://github.com/justinian/jsix.git
synced 2025-12-09 16:04:32 -08:00
[util] Make bitset more constexpr-friendly
In order to more easily express constants as bitsets, add more constexpr to util::bitset. This allows expressing uint64_t constants as bitsets in the code instead, without changing the generated assembly, to make code more readable.
This commit is contained in:
@@ -10,7 +10,6 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
namespace util {
|
namespace util {
|
||||||
|
|
||||||
/// A statically-sized templated bitset
|
/// A statically-sized templated bitset
|
||||||
@@ -62,25 +61,36 @@ private:
|
|||||||
uint64_t m_bits[num_elems] = {0};
|
uint64_t m_bits[num_elems] = {0};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
}
|
||||||
|
|
||||||
/// A statically-sized templated bitset
|
/// A statically-sized templated bitset
|
||||||
template <>
|
template <>
|
||||||
class bitset<64>
|
class bitset<64>
|
||||||
{
|
{
|
||||||
static constexpr unsigned num_elems = 1;
|
static constexpr unsigned num_elems = 1;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static constexpr uint64_t bit_or(T b) { return 1ull << uint64_t(b); }
|
||||||
|
|
||||||
|
template <typename T, typename ...Args>
|
||||||
|
static constexpr uint64_t bit_or(T b, Args... bs) { return (1ull << uint64_t(b)) | bit_or(bs...); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bitset(uint64_t v = 0) : m_bits {v} {}
|
bitset(uint64_t v = 0) : m_bits {v} {}
|
||||||
|
|
||||||
bitset(const bitset<64> &o) : m_bits {o.m_bits} {}
|
bitset(const bitset<64> &o) : m_bits {o.m_bits} {}
|
||||||
|
|
||||||
|
template <typename ...Args>
|
||||||
|
constexpr explicit bitset(Args... args) : m_bits(bit_or(args...)) {}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline bitset & operator=(T v) { m_bits = static_cast<uint64_t>(v); return *this; }
|
inline bitset & operator=(T v) { m_bits = static_cast<uint64_t>(v); return *this; }
|
||||||
|
|
||||||
inline operator uint64_t () const { return m_bits; }
|
inline constexpr operator const uint64_t () const { return m_bits; }
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline bool get(T i) const {
|
inline constexpr bool get(T i) const {
|
||||||
assert(static_cast<unsigned>(i) < 64);
|
|
||||||
return m_bits & bit(i);
|
return m_bits & bit(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,15 +109,15 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline bool operator[](T i) const { return get(i); }
|
inline constexpr bool operator[](T i) const { return get(i); }
|
||||||
|
|
||||||
inline bool empty() const { return m_bits == 0; }
|
inline constexpr bool empty() const { return m_bits == 0; }
|
||||||
|
|
||||||
inline uint64_t value() const { return m_bits; }
|
inline constexpr uint64_t value() const { return m_bits; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline uint64_t bit(T i) const { return (1ull << static_cast<uint64_t>(i)); }
|
inline constexpr uint64_t bit(T i) const { return (1ull << static_cast<uint64_t>(i)); }
|
||||||
|
|
||||||
uint64_t m_bits;
|
uint64_t m_bits;
|
||||||
};
|
};
|
||||||
@@ -118,19 +128,27 @@ class bitset<32>
|
|||||||
{
|
{
|
||||||
static constexpr unsigned num_elems = 1;
|
static constexpr unsigned num_elems = 1;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static constexpr uint32_t bit_or(T b) { return 1u << uint32_t(b); }
|
||||||
|
|
||||||
|
template <typename T, typename ...Args>
|
||||||
|
static constexpr uint32_t bit_or(T b, Args... bs) { return (1u << uint32_t(b)) | bit_or(bs...); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bitset(uint32_t v = 0) : m_bits {v} {}
|
bitset(uint32_t v = 0) : m_bits {v} {}
|
||||||
|
|
||||||
bitset(const bitset<32> &o) : m_bits {o.m_bits} {}
|
bitset(const bitset<32> &o) : m_bits {o.m_bits} {}
|
||||||
|
|
||||||
|
template <typename ...Args>
|
||||||
|
constexpr bitset(Args... args) : m_bits(bit_or(args...)) {}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline bitset & operator=(T v) { m_bits = static_cast<uint32_t>(v); return *this; }
|
inline bitset & operator=(T v) { m_bits = static_cast<uint32_t>(v); return *this; }
|
||||||
|
|
||||||
inline operator uint32_t () const { return m_bits; }
|
inline constexpr operator uint32_t () const { return m_bits; }
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline bool get(T i) const {
|
inline constexpr bool get(T i) const {
|
||||||
assert(static_cast<unsigned>(i) < 32);
|
|
||||||
return m_bits & bit(i);
|
return m_bits & bit(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,7 +171,7 @@ public:
|
|||||||
|
|
||||||
inline bool empty() const { return m_bits == 0; }
|
inline bool empty() const { return m_bits == 0; }
|
||||||
|
|
||||||
inline uint32_t value() const { return m_bits; }
|
inline constexpr uint32_t value() const { return m_bits; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|||||||
Reference in New Issue
Block a user