-
Notifications
You must be signed in to change notification settings - Fork 5
/
BitInt.h
152 lines (125 loc) · 3.14 KB
/
BitInt.h
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
/*
*
* BitInt is a helper type for use the numeric types as a binary arrays
*
* @author Valeriy V Dmitriev aka valmat <[email protected]>, http://valmat.ru/
* @licenses MIT https://opensource.org/licenses/MIT
* @repo https://github.com/valmat/LedMatrix
*
*/
#pragma once
#include "BitIntMember.h"
template<typename T, uint8_t _size = 8 * sizeof(T)>
class BitInt {
public:
// Constructors
constexpr BitInt(T value) : _value(value) {}
constexpr BitInt() : _value(0) {}
// Get size
constexpr uint8_t size () const
{
return _size;
}
// Cast to a number
constexpr operator T () const
{
return _value;
}
constexpr bool get(uint8_t index) const
{
return _value & (1 << (_size - 1 - (index % _size)));
}
BitInt& set(uint8_t index, bool state)
{
T val = (1 << (_size - 1 - index % _size));
_value = state ? (_value | val) : (_value & ~val);
return *this;
}
// Array access operator
constexpr bool operator[](uint8_t index) const
{
return get(index);
}
// Array access operator
BitIntMember<T, _size> operator[](uint8_t index)
{
return BitIntMember<T, _size>(index, *this);
}
// Cast to a number
constexpr T get () const
{
return _value;
}
// Reverse operator
// Binary order inverting transposition
BitInt operator!() const
{
T rez = 0;
uint8_t pos = 1;
T x;
uint8_t s = _size, s2 = _size / 2;
for(uint8_t i = 0; i < s2; i++) {
x = _value & (pos << i);
rez = rez | ( x << (s-2*i-1) );
}
for(uint8_t i = 0; i < s2; i++) {
x = _value & ( pos << (s - i - 1) );
rez = rez | ( x >> (s-2*i-1) );
}
return rez;
}
// Increment position (pre-increment)
BitInt &operator++()
{
++_value;
return *this;
}
// Increment position (post-increment)
BitInt operator++(int)
{
BitInt copy(*this);
++(*this);
return copy;
}
// Decrement position (pre-decrement)
BitInt &operator--()
{
--_value;
return *this;
}
// Increment position (post-decrement)
BitInt operator--(int)
{
BitInt copy(*this);
--(*this);
return copy;
}
// Make iterable
constexpr const BitIntMember<T, _size> begin() const
{
return BitIntMember<T, _size>(0, *this);
}
constexpr const BitIntMember<T, _size> end() const
{
return BitIntMember<T, _size>(_size, *this);
}
BitIntMember<T, _size> begin()
{
return BitIntMember<T, _size>(0, *this);
}
BitIntMember<T, _size> end()
{
return BitIntMember<T, _size>(_size, *this);
}
private:
T _value;
};
// Types predefinition
using buint8_t = BitInt<uint8_t>;
using buint16_t = BitInt<uint16_t>;
using buint32_t = BitInt<uint32_t>;
using buint64_t = BitInt<uint64_t>;
using bint8_t = BitInt<int8_t>;
using bint16_t = BitInt<int16_t>;
using bint32_t = BitInt<int32_t>;
using bint64_t = BitInt<int64_t>;