From 1d4c66a9a04ee8a206787fa7125913490cf39da0 Mon Sep 17 00:00:00 2001 From: "Justin C. Miller" Date: Sun, 11 Sep 2022 14:07:21 -0700 Subject: [PATCH] [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. --- src/libraries/util/util/bitset.h | 42 +++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/src/libraries/util/util/bitset.h b/src/libraries/util/util/bitset.h index 756310f..667b644 100644 --- a/src/libraries/util/util/bitset.h +++ b/src/libraries/util/util/bitset.h @@ -10,7 +10,6 @@ #include - namespace util { /// A statically-sized templated bitset @@ -62,25 +61,36 @@ private: uint64_t m_bits[num_elems] = {0}; }; +namespace { +} + /// A statically-sized templated bitset template <> class bitset<64> { static constexpr unsigned num_elems = 1; + template + static constexpr uint64_t bit_or(T b) { return 1ull << uint64_t(b); } + + template + static constexpr uint64_t bit_or(T b, Args... bs) { return (1ull << uint64_t(b)) | bit_or(bs...); } + public: bitset(uint64_t v = 0) : m_bits {v} {} bitset(const bitset<64> &o) : m_bits {o.m_bits} {} + template + constexpr explicit bitset(Args... args) : m_bits(bit_or(args...)) {} + template inline bitset & operator=(T v) { m_bits = static_cast(v); return *this; } - inline operator uint64_t () const { return m_bits; } + inline constexpr operator const uint64_t () const { return m_bits; } template - inline bool get(T i) const { - assert(static_cast(i) < 64); + inline constexpr bool get(T i) const { return m_bits & bit(i); } @@ -99,15 +109,15 @@ public: } template - 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: template - inline uint64_t bit(T i) const { return (1ull << static_cast(i)); } + inline constexpr uint64_t bit(T i) const { return (1ull << static_cast(i)); } uint64_t m_bits; }; @@ -118,19 +128,27 @@ class bitset<32> { static constexpr unsigned num_elems = 1; + template + static constexpr uint32_t bit_or(T b) { return 1u << uint32_t(b); } + + template + static constexpr uint32_t bit_or(T b, Args... bs) { return (1u << uint32_t(b)) | bit_or(bs...); } + public: bitset(uint32_t v = 0) : m_bits {v} {} bitset(const bitset<32> &o) : m_bits {o.m_bits} {} + template + constexpr bitset(Args... args) : m_bits(bit_or(args...)) {} + template inline bitset & operator=(T v) { m_bits = static_cast(v); return *this; } - inline operator uint32_t () const { return m_bits; } + inline constexpr operator uint32_t () const { return m_bits; } template - inline bool get(T i) const { - assert(static_cast(i) < 32); + inline constexpr bool get(T i) const { return m_bits & bit(i); } @@ -153,7 +171,7 @@ public: 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: template