1// Licensed to the .NET Foundation under one or more agreements.
2// The .NET Foundation licenses this file to you under the MIT license.
3// See the LICENSE file in the project root for more information.
4
5#ifndef TINYARRAY_H
6#define TINYARRAY_H
7
8/*****************************************************************************/
9
10// This is an array packed into some kind of integral data type
11// storagetype is the type (integral) which your array is going to be packed into
12// itemtype is the type of array elements
13// bits_per_element is size of the elements in bits
14template <class storageType, class itemType, int bits_per_element>
15class TinyArray
16{
17public:
18 // operator[] returns a 'ref' (usually a ref to the element type)
19 // This presents a problem if you wanted to implement something like a
20 // bitvector via this packed array, because you cannot make a ref to
21 // the element type.
22 // The trick is you define something that acts like a ref (TinyArrayRef in this case)
23 // which for our purposes means you can assign to and from it and our chosen
24 // element type.
25 class TinyArrayRef
26 {
27 public:
28 // this is really the getter for the array.
29 operator itemType()
30 {
31 storageType mask = ((1 << bits_per_element) - 1);
32 int shift = bits_per_element * index;
33
34 itemType result = (itemType)((*data >> shift) & mask);
35 return result;
36 }
37
38 void operator=(const itemType b)
39 {
40 storageType mask = ((1 << bits_per_element) - 1);
41 assert(itemType(b & mask) == b);
42
43 mask <<= bits_per_element * index;
44
45 *data &= ~mask;
46 *data |= b << (bits_per_element * index);
47 }
48 friend class TinyArray;
49
50 protected:
51 TinyArrayRef(storageType* d, int idx) : data(d), index(idx)
52 {
53 }
54
55 storageType* data;
56 int index;
57 };
58
59 storageType data;
60
61 void clear()
62 {
63 data = 0;
64 }
65
66 TinyArrayRef operator[](unsigned int n)
67 {
68 assert((n + 1) * bits_per_element <= sizeof(itemType) * 8);
69 return TinyArrayRef(&data, n);
70 }
71 // only use this for clearing it
72 void operator=(void* rhs)
73 {
74 assert(rhs == nullptr);
75 data = 0;
76 }
77};
78
79#endif // TINYARRAY_H
80