Warning: This file is not a C or C++ file. It does not have highlighting.
1 | //===-- include/flang/Common/constexpr-bitset.h -----------------*- C++ -*-===// |
---|---|
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #ifndef FORTRAN_COMMON_CONSTEXPR_BITSET_H_ |
10 | #define FORTRAN_COMMON_CONSTEXPR_BITSET_H_ |
11 | |
12 | // Implements a replacement for std::bitset<> that is suitable for use |
13 | // in constexpr expressions. Limited to elements in [0..127]. |
14 | |
15 | #include "bit-population-count.h" |
16 | #include "uint128.h" |
17 | #include <cstddef> |
18 | #include <cstdint> |
19 | #include <initializer_list> |
20 | #include <optional> |
21 | #include <type_traits> |
22 | |
23 | namespace Fortran::common { |
24 | |
25 | template <int BITS> class BitSet { |
26 | static_assert(BITS > 0 && BITS <= 128); |
27 | using Word = HostUnsignedIntType<(BITS <= 32 ? 32 : BITS)>; |
28 | static constexpr Word allBits{ |
29 | ~static_cast<Word>(0) >> (8 * sizeof(Word) - BITS)}; |
30 | |
31 | constexpr BitSet(Word b) : bits_{b} {} |
32 | |
33 | public: |
34 | constexpr BitSet() {} |
35 | constexpr BitSet(const std::initializer_list<int> &xs) { |
36 | for (auto x : xs) { |
37 | set(x); |
38 | } |
39 | } |
40 | constexpr BitSet(const BitSet &) = default; |
41 | constexpr BitSet(BitSet &&) = default; |
42 | constexpr BitSet &operator=(const BitSet &) = default; |
43 | constexpr BitSet &operator=(BitSet &&) = default; |
44 | |
45 | constexpr BitSet &operator&=(const BitSet &that) { |
46 | bits_ &= that.bits_; |
47 | return *this; |
48 | } |
49 | constexpr BitSet &operator&=(BitSet &&that) { |
50 | bits_ &= that.bits_; |
51 | return *this; |
52 | } |
53 | constexpr BitSet &operator^=(const BitSet &that) { |
54 | bits_ ^= that.bits_; |
55 | return *this; |
56 | } |
57 | constexpr BitSet &operator^=(BitSet &&that) { |
58 | bits_ ^= that.bits_; |
59 | return *this; |
60 | } |
61 | constexpr BitSet &operator|=(const BitSet &that) { |
62 | bits_ |= that.bits_; |
63 | return *this; |
64 | } |
65 | constexpr BitSet &operator|=(BitSet &&that) { |
66 | bits_ |= that.bits_; |
67 | return *this; |
68 | } |
69 | |
70 | constexpr BitSet operator~() const { return ~bits_; } |
71 | constexpr BitSet operator&(const BitSet &that) const { |
72 | return bits_ & that.bits_; |
73 | } |
74 | constexpr BitSet operator&(BitSet &&that) const { return bits_ & that.bits_; } |
75 | constexpr BitSet operator^(const BitSet &that) const { |
76 | return bits_ ^ that.bits_; |
77 | } |
78 | constexpr BitSet operator^(BitSet &&that) const { return bits_ & that.bits_; } |
79 | constexpr BitSet operator|(const BitSet &that) const { |
80 | return bits_ | that.bits_; |
81 | } |
82 | constexpr BitSet operator|(BitSet &&that) const { return bits_ | that.bits_; } |
83 | |
84 | constexpr bool operator==(const BitSet &that) const { |
85 | return bits_ == that.bits_; |
86 | } |
87 | constexpr bool operator==(BitSet &&that) const { return bits_ == that.bits_; } |
88 | constexpr bool operator!=(const BitSet &that) const { |
89 | return bits_ != that.bits_; |
90 | } |
91 | constexpr bool operator!=(BitSet &&that) const { return bits_ != that.bits_; } |
92 | |
93 | static constexpr std::size_t size() { return BITS; } |
94 | constexpr bool test(std::size_t x) const { |
95 | return x < BITS && ((bits_ >> x) & 1) != 0; |
96 | } |
97 | |
98 | constexpr bool all() const { return bits_ == allBits; } |
99 | constexpr bool any() const { return bits_ != 0; } |
100 | constexpr bool none() const { return bits_ == 0; } |
101 | |
102 | constexpr std::size_t count() const { return BitPopulationCount(bits_); } |
103 | |
104 | constexpr BitSet &set() { |
105 | bits_ = allBits; |
106 | return *this; |
107 | } |
108 | constexpr BitSet set(std::size_t x, bool value = true) { |
109 | if (!value) { |
110 | return reset(x); |
111 | } else { |
112 | bits_ |= static_cast<Word>(1) << x; |
113 | return *this; |
114 | } |
115 | } |
116 | constexpr BitSet &reset() { |
117 | bits_ = 0; |
118 | return *this; |
119 | } |
120 | constexpr BitSet &reset(std::size_t x) { |
121 | bits_ &= ~(static_cast<Word>(1) << x); |
122 | return *this; |
123 | } |
124 | constexpr BitSet &flip() { |
125 | bits_ ^= allBits; |
126 | return *this; |
127 | } |
128 | constexpr BitSet &flip(std::size_t x) { |
129 | bits_ ^= static_cast<Word>(1) << x; |
130 | return *this; |
131 | } |
132 | |
133 | constexpr std::optional<std::size_t> LeastElement() const { |
134 | if (bits_ == 0) { |
135 | return std::nullopt; |
136 | } else { |
137 | return {TrailingZeroBitCount(bits_)}; |
138 | } |
139 | } |
140 | |
141 | Word bits() const { return bits_; } |
142 | |
143 | private: |
144 | Word bits_{0}; |
145 | }; |
146 | } // namespace Fortran::common |
147 | #endif // FORTRAN_COMMON_CONSTEXPR_BITSET_H_ |
148 |
Warning: This file is not a C or C++ file. It does not have highlighting.