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