FLANG
constexpr-bitset.h
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
22namespace Fortran::common {
23RT_OFFLOAD_VAR_GROUP_BEGIN
24template <int BITS> class BitSet {
25 static_assert(BITS > 0 && BITS <= 128);
26 using Word = HostUnsignedIntType<(BITS <= 32 ? 32 : BITS)>;
27 static constexpr Word allBits{
28 ~static_cast<Word>(0) >> (8 * sizeof(Word) - BITS)};
29
30 constexpr BitSet(Word b) : bits_{b} {}
31
32public:
33 constexpr BitSet() {}
34 constexpr BitSet(const std::initializer_list<int> &xs) {
35 for (auto x : xs) {
36 set(x);
37 }
38 }
39 constexpr BitSet(const BitSet &) = default;
40 constexpr BitSet(BitSet &&) = default;
41 constexpr BitSet &operator=(const BitSet &) = default;
42 constexpr BitSet &operator=(BitSet &&) = default;
43
44 constexpr BitSet &operator&=(const BitSet &that) {
45 bits_ &= that.bits_;
46 return *this;
47 }
48 constexpr BitSet &operator&=(BitSet &&that) {
49 bits_ &= that.bits_;
50 return *this;
51 }
52 constexpr BitSet &operator^=(const BitSet &that) {
53 bits_ ^= that.bits_;
54 return *this;
55 }
56 constexpr BitSet &operator^=(BitSet &&that) {
57 bits_ ^= that.bits_;
58 return *this;
59 }
60 constexpr BitSet &operator|=(const BitSet &that) {
61 bits_ |= that.bits_;
62 return *this;
63 }
64 constexpr BitSet &operator|=(BitSet &&that) {
65 bits_ |= that.bits_;
66 return *this;
67 }
68
69 constexpr BitSet operator~() const { return ~bits_; }
70 constexpr BitSet operator&(const BitSet &that) const {
71 return bits_ & that.bits_;
72 }
73 constexpr BitSet operator&(BitSet &&that) const { return bits_ & that.bits_; }
74 constexpr BitSet operator^(const BitSet &that) const {
75 return bits_ ^ that.bits_;
76 }
77 constexpr BitSet operator^(BitSet &&that) const { return bits_ & that.bits_; }
78 constexpr BitSet operator|(const BitSet &that) const {
79 return bits_ | that.bits_;
80 }
81 constexpr BitSet operator|(BitSet &&that) const { return bits_ | that.bits_; }
82
83 constexpr bool operator==(const BitSet &that) const {
84 return bits_ == that.bits_;
85 }
86 constexpr bool operator==(BitSet &&that) const { return bits_ == that.bits_; }
87 constexpr bool operator!=(const BitSet &that) const {
88 return bits_ != that.bits_;
89 }
90 constexpr bool operator!=(BitSet &&that) const { return bits_ != that.bits_; }
91
92 static constexpr std::size_t size() { return BITS; }
93 constexpr bool test(std::size_t x) const {
94 return x < BITS && ((bits_ >> x) & 1) != 0;
95 }
96
97 constexpr bool all() const { return bits_ == allBits; }
98 constexpr bool any() const { return bits_ != 0; }
99 constexpr bool none() const { return bits_ == 0; }
100
101 constexpr std::size_t count() const { return BitPopulationCount(bits_); }
102
103 constexpr BitSet &set() {
104 bits_ = allBits;
105 return *this;
106 }
107 constexpr BitSet set(std::size_t x, bool value = true) {
108 if (!value) {
109 return reset(x);
110 } else {
111 bits_ |= static_cast<Word>(1) << x;
112 return *this;
113 }
114 }
115 constexpr BitSet &reset() {
116 bits_ = 0;
117 return *this;
118 }
119 constexpr BitSet &reset(std::size_t x) {
120 bits_ &= ~(static_cast<Word>(1) << x);
121 return *this;
122 }
123 constexpr BitSet &flip() {
124 bits_ ^= allBits;
125 return *this;
126 }
127 constexpr BitSet &flip(std::size_t x) {
128 bits_ ^= static_cast<Word>(1) << x;
129 return *this;
130 }
131
132 constexpr std::optional<std::size_t> LeastElement() const {
133 if (bits_ == 0) {
134 return std::nullopt;
135 } else {
136 return {TrailingZeroBitCount(bits_)};
137 }
138 }
139
140 Word bits() const { return bits_; }
141
142private:
143 Word bits_{0};
144};
145RT_OFFLOAD_VAR_GROUP_END
146} // namespace Fortran::common
147#endif // FORTRAN_COMMON_CONSTEXPR_BITSET_H_
Definition bit-population-count.h:20