1 // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef compressed_enum_table_h
16 #define compressed_enum_table_h
17 
18 #include <cstdint>
19 #include <cassert>
20 #include <type_traits>
21 
22 template<typename Tenum, size_t Nbits, size_t Nitems>
23 class CompressedEnumTable
24 {
25 public:
data()26     uint32_t* data()
27     {
28         return mData;
29     }
30 
data() const31     const uint32_t* data() const
32     {
33         return mData;
34     }
35 
get(size_t index) const36     Tenum get(size_t index) const
37     {
38         assert(index < Nitems);
39         size_t wordIndex = index / ITEMS_PER_WORD;
40         size_t offset = (index % ITEMS_PER_WORD) * Nbits;
41 
42         return static_cast<Tenum>((mData[wordIndex] >> offset) & VALUE_MASK);
43     }
44 
set(size_t index,Tenum val)45     void set(size_t index, Tenum val)
46     {
47         assert(index < Nitems);
48         size_t wordIndex = index / ITEMS_PER_WORD;
49         size_t offset = (index % ITEMS_PER_WORD) * Nbits;
50 
51         uint32_t v = static_cast<uint32_t>(val) << offset;
52         mData[wordIndex] = (mData[wordIndex] & ~(VALUE_MASK << offset)) | v;
53     }
54 
getWordIndex(size_t index)55     static constexpr size_t getWordIndex(size_t index)
56     {
57         return index / ITEMS_PER_WORD;
58     }
59 
byteSize()60     static constexpr size_t byteSize()
61     {
62         return WORD_COUNT * 4;
63     }
64 
count()65     static constexpr size_t count()
66     {
67         return Nitems;
68     }
69 
70 
71 protected:
72     static_assert(32 % Nbits == 0, "Nbits must divide 32");
73     static const size_t ITEMS_PER_WORD = 32 / Nbits;
74     static const size_t WORD_COUNT = ( Nbits * Nitems + 31 ) / 32;
75     static const uint32_t VALUE_MASK = (1 << Nbits) - 1;
76     uint32_t mData[WORD_COUNT];
77 };
78 
79 #endif /* compressed_enum_table_h */
80