blob: cd1dbd029e985c205c33088fa8e4a95a4c5bf1aa (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
#pragma once
#include <array>
#include <cassert>
#include <cstdint>
#include <vector>
constexpr int bits_ceil(int bits)
{
return bits / 8 + (bits % 8 > 0 ? 1 : 0);
}
template <unsigned int flags, auto size = bits_ceil(flags)>
struct bitset : std::array<std::uint8_t, size> {
using array_type = std::array<std::uint8_t, size>;
private:
struct bit_ref {
bitset<flags>& a;
int referenced_byte;
uint8_t referenced_bit_mask;
bool operator=(bool b)
{
if (b)
a.at(referenced_byte) |= referenced_bit_mask;
else
a.at(referenced_byte) &= ~referenced_bit_mask;
return b;
}
constexpr operator bool() const
{
return (a.at(referenced_byte) & referenced_bit_mask) > 0;
}
};
public:
template <class T>
constexpr bool operator[](T idx) const
{
unsigned int i = (unsigned int)(idx);
assert(i < flags);
return (array_type::at(i / 8) & (1 << (i % 8))) > 0;
}
template <class T>
bit_ref operator[](T idx)
{
unsigned int i = (unsigned int)(idx);
assert(i < flags);
return bit_ref(*this, i / 8, (1 << (i % 8)));
}
};
// FIXME: ??
template <>
struct bitset<0> : std::vector<std::uint8_t> {
using container_type = std::vector<std::uint8_t>;
private:
struct bit_ref {
bitset<0>& a;
int referenced_byte;
uint8_t referenced_bit_mask;
bool operator=(bool b)
{
if (b)
a.at(referenced_byte) |= referenced_bit_mask;
else
a.at(referenced_byte) &= ~referenced_bit_mask;
return b;
}
constexpr operator bool() const
{
return (a.at(referenced_byte) & referenced_bit_mask) > 0;
}
};
public:
template <class T>
constexpr bool operator[](T idx) const
{
unsigned int i = (unsigned int)(idx);
assert(i < container_type::size());
return (container_type::at(i / 8) & (1 << (i % 8))) > 0;
}
template <class T>
bit_ref operator[](T idx)
{
unsigned int i = (unsigned int)(idx);
assert(i < container_type::size());
return bit_ref(*this, i / 8, (1 << (i % 8)));
}
};
|