• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
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 
16 #ifndef PANDA_VERIFIER_UTIL_TAG_FOR_ENUM__
17 #define PANDA_VERIFIER_UTIL_TAG_FOR_ENUM__
18 
19 #include <cstddef>
20 
21 #include "utils/bit_utils.h"
22 
23 #include "macros.h"
24 
25 namespace panda::verifier {
26 
27 template <size_t I_num, typename Enum, Enum... Items>
28 class TagForEnumNumerated {
29 protected:
30     static constexpr size_t Size = 0ULL;
31 
GetIndexFor(Enum)32     static size_t GetIndexFor([[maybe_unused]] Enum)
33     {
34         UNREACHABLE();
35     }
36 
GetValueFor(size_t)37     static Enum GetValueFor([[maybe_unused]] size_t)
38     {
39         UNREACHABLE();
40     }
41 };
42 
43 // TagForEnumNumerated needs because recursive numeration with Size - 1 gives wrong ordering
44 template <size_t I_num, typename Enum, Enum I, Enum... Items>
45 class TagForEnumNumerated<I_num, Enum, I, Items...> : public TagForEnumNumerated<I_num + 1ULL, Enum, Items...> {
46     using Base = TagForEnumNumerated<I_num + 1ULL, Enum, Items...>;
47 
48 protected:
49     static constexpr size_t Size = Base::Size + 1ULL;
50 
GetIndexFor(Enum e)51     static size_t GetIndexFor(Enum e)
52     {
53         if (e == I) {
54             return I_num;
55         }
56         return Base::GetIndexFor(e);
57     }
58 
GetValueFor(size_t tag)59     static Enum GetValueFor(size_t tag)
60     {
61         if (tag == I_num) {
62             return I;
63         }
64         return Base::GetValueFor(tag);
65     }
66 };
67 
68 template <typename Enum, Enum... Items>
69 class TagForEnum : public TagForEnumNumerated<0ULL, Enum, Items...> {
70     using Base = TagForEnumNumerated<0ULL, Enum, Items...>;
71 
72 public:
73     using type = Enum;
74 
75     static constexpr size_t Size = Base::Size;
76     static constexpr size_t Bits = sizeof(size_t) * 8ULL - panda::Clz(Size);
77 
GetIndexFor(Enum e)78     static size_t GetIndexFor(Enum e)
79     {
80         return Base::GetIndexFor(e);
81     }
82 
GetValueFor(size_t tag)83     static Enum GetValueFor(size_t tag)
84     {
85         return Base::GetValueFor(tag);
86     }
87 };
88 
89 }  // namespace panda::verifier
90 
91 #endif  // !PANDA_VERIFIER_UTIL_TAG_FOR_ENUM__