VapourSynth-llvmexpr
Loading...
Searching...
No Matches
DynamicBitset.hpp
Go to the documentation of this file.
1
19
20#ifndef LLVMEXPR_ANALYSIS_UTILS_DYNAMIC_BITSET_HPP
21#define LLVMEXPR_ANALYSIS_UTILS_DYNAMIC_BITSET_HPP
22
23#include <algorithm>
24#include <cstdint>
25#include <vector>
26
28
30 // NOLINTNEXTLINE(cppcoreguidelines-avoid-magic-numbers)
31 static constexpr int BITS_PER_WORD = 64;
32
33 std::vector<std::uint64_t> words;
34 int nbits = 0;
35
36 void maskUnusedBits() noexcept {
37 if (nbits <= 0 || words.empty()) {
38 return;
39 }
40 const int used_in_last = nbits % BITS_PER_WORD;
41 if (used_in_last == 0) {
42 return;
43 }
44 const std::uint64_t mask =
45 (std::uint64_t(1) << static_cast<unsigned>(used_in_last)) - 1U;
46 words.back() &= mask;
47 }
48
49 public:
50 explicit DynamicBitset(int n = 0)
51 : words((static_cast<size_t>(n) + (BITS_PER_WORD - 1)) / BITS_PER_WORD,
52 0),
53 nbits(n) {}
54
55 void setAll() noexcept {
56 std::ranges::fill(words, ~std::uint64_t(0));
57 maskUnusedBits();
58 }
59
60 void resetAll() noexcept { std::ranges::fill(words, 0); }
61
62 void set(int i) noexcept {
63 words[static_cast<size_t>(i) / BITS_PER_WORD] |=
64 (std::uint64_t(1) << static_cast<unsigned>(i % BITS_PER_WORD));
65 }
66
67 void reset(int i) noexcept {
68 words[static_cast<size_t>(i) / BITS_PER_WORD] &=
69 ~(std::uint64_t(1) << static_cast<unsigned>(i % BITS_PER_WORD));
70 }
71
72 [[nodiscard]] bool test(int i) const noexcept {
73 return (((words[static_cast<size_t>(i) / BITS_PER_WORD] >>
74 static_cast<unsigned>(i % BITS_PER_WORD)) &
75 1U) != 0);
76 }
77
78 bool intersectWith(const DynamicBitset& other) noexcept {
79 bool changed = false;
80
81 if (other.words.size() == words.size()) {
82 for (size_t i = 0; i < words.size(); ++i) {
83 const std::uint64_t nw = words[i] & other.words[i];
84 changed |= (nw != words[i]);
85 words[i] = nw;
86 }
87 maskUnusedBits();
88 return changed;
89 }
90
91 const size_t n = std::min(words.size(), other.words.size());
92 for (size_t i = 0; i < n; ++i) {
93 const std::uint64_t nw = words[i] & other.words[i];
94 changed |= (nw != words[i]);
95 words[i] = nw;
96 }
97 for (size_t i = n; i < words.size(); ++i) {
98 changed |= (words[i] != 0);
99 words[i] = 0;
100 }
101 maskUnusedBits();
102 return changed;
103 }
104
105 [[nodiscard]] bool equals(const DynamicBitset& other) const noexcept {
106 return nbits == other.nbits && words == other.words;
107 }
108};
109
110} // namespace analysis::dynamic_bitset
111
112#endif // LLVMEXPR_ANALYSIS_UTILS_DYNAMIC_BITSET_HPP
bool intersectWith(const DynamicBitset &other) noexcept
bool equals(const DynamicBitset &other) const noexcept