forked from dotnet/runtime
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtinyarray.h
78 lines (65 loc) · 2.23 KB
/
tinyarray.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
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
#ifndef TINYARRAY_H
#define TINYARRAY_H
/*****************************************************************************/
// This is an array packed into some kind of integral data type
// storagetype is the type (integral) which your array is going to be packed into
// itemtype is the type of array elements
// bits_per_element is size of the elements in bits
template <class storageType, class itemType, int bits_per_element>
class TinyArray
{
public:
// operator[] returns a 'ref' (usually a ref to the element type)
// This presents a problem if you wanted to implement something like a
// bitvector via this packed array, because you cannot make a ref to
// the element type.
// The trick is you define something that acts like a ref (TinyArrayRef in this case)
// which for our purposes means you can assign to and from it and our chosen
// element type.
class TinyArrayRef
{
public:
// this is really the getter for the array.
operator itemType()
{
storageType mask = ((1 << bits_per_element) - 1);
int shift = bits_per_element * index;
itemType result = (itemType)((*data >> shift) & mask);
return result;
}
void operator=(const itemType b)
{
storageType mask = ((1 << bits_per_element) - 1);
assert(itemType(b & mask) == b);
mask <<= bits_per_element * index;
*data &= ~mask;
*data |= b << (bits_per_element * index);
}
friend class TinyArray;
protected:
TinyArrayRef(storageType* d, int idx) : data(d), index(idx)
{
}
storageType* data;
int index;
};
storageType data;
void clear()
{
data = 0;
}
TinyArrayRef operator[](unsigned int n)
{
assert((n + 1) * bits_per_element <= sizeof(storageType) * 8);
return TinyArrayRef(&data, n);
}
// only use this for clearing it
void operator=(void* rhs)
{
assert(rhs == nullptr);
data = 0;
}
};
#endif // TINYARRAY_H