1#pragma once
2
3#include <nn/types.h>
4
5namespace nn::util {
6
7template <class StorageT, class Tag = void>
8struct BitPack {
9 StorageT storage;
10
11 void SetBit(int p, bool on) {
12 int mask = MakeMask(p);
13 if (on) {
14 storage |= mask;
15 } else {
16 storage &= ~mask;
17 }
18 }
19
20 bool GetBit(int p) const { return IsAnyBitOn(mask: MakeMask(p)); }
21
22 void Clear() { storage = 0; }
23
24 void SetMaskedBits(int, int);
25 int GetMaskedBits(int) const;
26 void SetAllBitOn(int);
27 void SetAllBitOff(int);
28 bool IsAllBitOn(int) const;
29 bool IsAllBitOff(int) const;
30
31 bool IsAnyBitOn(int mask) const { return static_cast<int>(storage & mask) == mask; }
32 bool IsAnyBitOff(int mask) const { return static_cast<int>(storage & mask) != mask; }
33
34 template <int BitPos, int BitWidth, class T>
35 struct Field {
36 static const int Pos = BitPos;
37 static const int Next = BitPos + 1;
38 static const int Mask = 1 << BitPos;
39 static const int Width = BitWidth;
40
41 typedef T Type;
42 };
43
44private:
45 static int MakeMask(int p) { return 1 << p; }
46
47 Tag ReadValue(bool*, int, int) const;
48};
49
50typedef BitPack<u8> BitPack8;
51typedef BitPack<u16> BitPack16;
52typedef BitPack<u32> BitPack32;
53
54} // namespace nn::util