summaryrefslogtreecommitdiff
path: root/src/jit/tinyarray.h
blob: afef7e15ae9638dda2858e94c0c76c79fc3fd0a8 (plain)
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
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//

#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(itemType) * 8);
        return TinyArrayRef(&data, n);
    }
    // only use this for clearing it 
    void operator=(void *rhs)
    {
        assert(rhs==NULL);
        data = 0;
    }
};

#endif // TINYARRAY_H