9 #ifndef hog2_glut_NBitArray_h
10 #define hog2_glut_NBitArray_h
22 template <u
int64_t numBits>
34 void Resize(uint64_t newMaxEntries);
35 uint64_t
Size()
const;
36 uint64_t
Get(uint64_t index)
const;
37 void Set(uint64_t index, uint64_t val);
38 uint64_t
GetMaxValue()
const { uint64_t v = 1;
return (v<<numBits)-1;}
42 bool Write(
const char *);
43 bool Read(
const char *);
51 template <u
int64_t numBits>
57 template <u
int64_t numBits>
59 :entries(numEntries), memorySize(((entries*numBits+63)/64))
61 static_assert(numBits >= 1 && numBits <= 64,
"numBits out of bounds!");
66 template <u
int64_t numBits>
70 static_assert(numBits >= 1 && numBits <= 64,
"numBits out of bounds!");
74 template <u
int64_t numBits>
79 mem =
new uint64_t[memorySize];
80 memcpy(mem, copyMe.
mem, memorySize*
sizeof(mem[0]));
84 template <u
int64_t numBits>
90 template <u
int64_t numBits>
98 mem =
new uint64_t[memorySize];
99 memcpy(mem, copyMe.
mem, memorySize*
sizeof(mem[0]));
103 template <u
int64_t numBits>
106 if (
this == &compare)
108 if (entries != compare.
entries)
110 for (
size_t x = 0; x < memorySize; x++)
112 if (mem[x] != compare.
mem[x])
115 #pragma message("Last bits are not being tested properly")
122 template <u
int64_t numBits>
125 memset(mem, 0xFF, memorySize*8);
128 template <u
int64_t numBits>
131 memset(mem, 0, memorySize*8);
134 template <u
int64_t numBits>
137 entries = newMaxEntries;
138 memorySize = ((entries*numBits+63)/64);
140 mem =
new uint64_t[memorySize];
143 template <u
int64_t numBits>
149 template <u
int64_t numBits>
152 if (fwrite(&entries,
sizeof(uint64_t), 1, f) != 1)
154 if (fwrite(&memorySize,
sizeof(uint64_t), 1, f) != 1)
156 if (fwrite(mem,
sizeof(uint64_t), memorySize, f) != memorySize)
158 printf(
"Wrote %" PRId64
" bytes to disk\n", memorySize*
sizeof(uint64_t));
162 template <u
int64_t numBits>
167 success = success&&(fread(&e1,
sizeof(uint64_t), 1, f) == 1);
168 success = success&&(fread(&m1,
sizeof(uint64_t), 1, f) == 1);
174 mem =
new uint64_t[memorySize];
175 success = success&&(fread(mem,
sizeof(uint64_t), memorySize, f) == memorySize);
180 template <u
int64_t numBits>
183 FILE *f = fopen(file,
"w+b");
186 perror(
"Could not open file for writing in NBitArray");
189 bool result = Write(f);
194 template <u
int64_t numBits>
197 FILE *f = fopen(file,
"rb");
200 perror(
"Could not open file for reading in NBitArray");
203 bool result = Read(f);
208 template <u
int64_t numBits>
211 uint64_t startingBit = index*numBits;
212 uint64_t offset1 = startingBit/64;
213 uint64_t bitOffset1 = startingBit&0x3F;
214 uint64_t bitCount1 =
std::min(64-bitOffset1, numBits);
215 uint64_t bitCount2 = numBits - bitCount1;
216 uint64_t bitMask1 = (1ull<<bitCount1)-1;
217 uint64_t bitMask2 = (1ull<<bitCount2)-1;
218 uint64_t result = (mem[offset1]>>bitOffset1)&bitMask1;
219 result = ((mem[offset1+1]&bitMask2)<<bitCount1) | result;
223 template <u
int64_t numBits>
226 uint64_t startingBit = index*numBits;
227 uint64_t offset1 = startingBit/64;
228 uint64_t bitOffset1 = startingBit&0x3F;
229 uint64_t bitCount1 =
std::min(64-bitOffset1, (uint64_t)numBits);
230 uint64_t bitCount2 = numBits - bitCount1;
231 uint64_t bitMask1 = (1ull<<bitCount1)-1;
232 uint64_t bitMask2 = (1ull<<bitCount2)-1;
233 mem[offset1] = (mem[offset1]&(~(bitMask1<<bitOffset1))) | ((val&bitMask1)<<bitOffset1);
234 mem[offset1+1] = (mem[offset1+1]&(~(bitMask2))) | ((val>>bitCount1)&bitMask2);