Skip to content

Commit

Permalink
Merge pull request #209 from ValeevGroup/207-compilation-error-with-g…
Browse files Browse the repository at this point in the history
…cc-12

`constexpr` reserved bitset and null bitset.
  • Loading branch information
evaleev authored Jun 18, 2024
2 parents add0253 + 79773b5 commit 237e141
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 20 deletions.
20 changes: 12 additions & 8 deletions SeQuant/core/space.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@

namespace sequant {

namespace bitset {
using type = int32_t;
constexpr type reserved = 0x80000000;
constexpr type null = 0x00000000;
} // namespace bitset

using bitset_t = bitset::type;

class QuantumNumbersAttr; // used to constrain TypeAttr ctor

class Index; // friend of TypeAttr
Expand All @@ -29,8 +37,6 @@ class Index; // friend of TypeAttr
/// (intersection, union, etc.) it is encoded as a fixed-width (32) bitset.
class TypeAttr {
public:
using bitset_t = int32_t;

/// default ctor creates a null TypeAttr
constexpr TypeAttr() noexcept = default;

Expand All @@ -43,7 +49,7 @@ class TypeAttr {
/// @param bitset bitset representation of this Type
/// @pre `(bitset & make_reserved().bitset) == null.bitset`
explicit constexpr TypeAttr(bitset_t bitset) noexcept : bitset(bitset) {
assert((this->bitset & reserved.bitset) == null.bitset);
assert((this->bitset & bitset::reserved) == bitset::null);
}

/// construct TypeAddr from things that can be cast to bitset_t, but exclude
Expand Down Expand Up @@ -144,8 +150,6 @@ inline const TypeAttr TypeAttr::reserved = TypeAttr::make_reserved();
/// denotes other quantum numbers (particle type, spin, etc.)
class QuantumNumbersAttr {
public:
using bitset_t = int32_t;

/// default ctor creates a null QuantumNumbersAttr
/// @post `static_cast<bool>(*this) == false`
constexpr QuantumNumbersAttr() noexcept = default;
Expand All @@ -160,7 +164,7 @@ class QuantumNumbersAttr {
/// @pre `(bitset & make_reserved().bitset()) == null.bitset()`
explicit constexpr QuantumNumbersAttr(bitset_t bitset) noexcept
: bitset(bitset) {
assert((this->bitset & reserved.bitset) == null.bitset);
assert((this->bitset & bitset::reserved) == bitset::null);
}

template <typename QN,
Expand Down Expand Up @@ -241,7 +245,7 @@ class QuantumNumbersAttr {
}

private:
bitset_t bitset = 0;
bitset_t bitset = bitset::null;

friend class Index;

Expand All @@ -252,7 +256,7 @@ class QuantumNumbersAttr {
/// makes reserved object
static QuantumNumbersAttr make_reserved() {
QuantumNumbersAttr result;
result.bitset = 0x80000000;
result.bitset = bitset::reserved;
return result;
}
}; // struct QuantumNumbersAttr
Expand Down
21 changes: 9 additions & 12 deletions SeQuant/domain/mbpt/spin.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ namespace mbpt {

/// quantum numbers tags related to spin
/// \note spin quantum number takes 2 rightmost bits
enum class Spin : QuantumNumbersAttr::bitset_t {
enum class Spin : bitset_t {
alpha = 0b000001,
beta = 0b000010,
any = 0b000011, // both bits set so that overlap and union work as expected
Expand All @@ -34,28 +34,25 @@ enum class Spin : QuantumNumbersAttr::bitset_t {

// Spin is a scoped enum, hence not implicitly convertible to
// QuantumNumbersAttr::bitset_t
static_assert(
!std::is_convertible_v<sequant::mbpt::Spin, QuantumNumbersAttr::bitset_t>);
static_assert(!std::is_convertible_v<sequant::mbpt::Spin, bitset_t>);
// QuantumNumbersAttr::bitset_t cannot be constructed from Spin
static_assert(!std::is_constructible_v<QuantumNumbersAttr::bitset_t,
sequant::mbpt::Spin>);
static_assert(!std::is_constructible_v<bitset_t, sequant::mbpt::Spin>);
// but Spin can be cast to QuantumNumbersAttr::bitset_t
static_assert(meta::is_statically_castable_v<sequant::mbpt::Spin,
QuantumNumbersAttr::bitset_t>);
static_assert(meta::is_statically_castable_v<sequant::mbpt::Spin, bitset_t>);
// Spin cannot be cast to nonsense ...
static_assert(
!meta::is_statically_castable_v<sequant::mbpt::Spin, std::string>);

inline Spin operator~(Spin s) {
return static_cast<Spin>(~(static_cast<QuantumNumbersAttr::bitset_t>(s)));
return static_cast<Spin>(~(static_cast<bitset_t>(s)));
}
inline Spin operator|(Spin s1, Spin s2) {
return static_cast<Spin>(static_cast<QuantumNumbersAttr::bitset_t>(s1) |
static_cast<QuantumNumbersAttr::bitset_t>(s2));
return static_cast<Spin>(static_cast<bitset_t>(s1) |
static_cast<bitset_t>(s2));
}
inline Spin operator&(Spin s1, Spin s2) {
return static_cast<Spin>(static_cast<QuantumNumbersAttr::bitset_t>(s1) &
static_cast<QuantumNumbersAttr::bitset_t>(s2));
return static_cast<Spin>(static_cast<bitset_t>(s1) &
static_cast<bitset_t>(s2));
}

/// converts QuantumNumbersAttr to Spin
Expand Down

0 comments on commit 237e141

Please sign in to comment.