/src/WasmEdge/include/common/spare_enum_map.h
Line | Count | Source |
1 | | // SPDX-License-Identifier: Apache-2.0 |
2 | | // SPDX-FileCopyrightText: Copyright The WasmEdge Authors |
3 | | |
4 | | //===-- wasmedge/common/spare_enum_map.h - mapping spare enum to data -----===// |
5 | | // |
6 | | // Part of the WasmEdge Project. |
7 | | // |
8 | | //===----------------------------------------------------------------------===// |
9 | | /// |
10 | | /// \file |
11 | | /// This file contains a class for mapping spare enum values to data. |
12 | | /// |
13 | | //===----------------------------------------------------------------------===// |
14 | | |
15 | | #pragma once |
16 | | |
17 | | #include <algorithm> |
18 | | #include <array> |
19 | | #include <functional> |
20 | | #include <iterator> |
21 | | #include <memory> |
22 | | #include <string_view> |
23 | | #include <tuple> |
24 | | #include <type_traits> |
25 | | #include <utility> |
26 | | |
27 | | namespace WasmEdge { |
28 | | |
29 | | template <std::size_t Size, class Key, class T = std::string_view> |
30 | | class SpareEnumMap { |
31 | | static_assert(std::is_enum_v<Key>, "Key should be an enum type!"); |
32 | | |
33 | | public: |
34 | | class ConstIterator; |
35 | | using key_type = Key; |
36 | | using mapped_type = T; |
37 | | using value_type = const std::pair<Key, T>; |
38 | | using size_type = std::size_t; |
39 | | using difference_type = std::ptrdiff_t; |
40 | | using reference = value_type &; |
41 | | using const_reference = const value_type &; |
42 | | using pointer = value_type *; |
43 | | using const_pointer = const value_type *; |
44 | | using iterator = ConstIterator; |
45 | | using const_iterator = ConstIterator; |
46 | | |
47 | | constexpr SpareEnumMap() noexcept = delete; |
48 | | constexpr SpareEnumMap(const SpareEnumMap &) noexcept = delete; |
49 | | constexpr SpareEnumMap(SpareEnumMap &&) noexcept = default; |
50 | | constexpr SpareEnumMap &operator=(const SpareEnumMap &) noexcept = delete; |
51 | | constexpr SpareEnumMap &operator=(SpareEnumMap &&) noexcept = default; |
52 | | |
53 | | constexpr SpareEnumMap(value_type (&Array)[Size]) noexcept { |
54 | | for (size_t I = 0; I < Size; ++I) { |
55 | | size_t J = I; |
56 | | for (; J > 0; --J) { |
57 | | if (std::less<>()(Data[J - 1], Array[I])) { |
58 | | break; |
59 | | } |
60 | | Data[J].first = std::move(Data[J - 1].first); |
61 | | Data[J].second = std::move(Data[J - 1].second); |
62 | | } |
63 | | Data[J].first = std::move(Array[I].first); |
64 | | Data[J].second = std::move(Array[I].second); |
65 | | } |
66 | | } |
67 | | |
68 | 15.7k | constexpr const_iterator begin() const noexcept { return {Data, 0}; }WasmEdge::SpareEnumMap<566ul, WasmEdge::OpCode, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::begin() const Line | Count | Source | 68 | 281 | constexpr const_iterator begin() const noexcept { return {Data, 0}; } |
WasmEdge::SpareEnumMap<165ul, WasmEdge::ErrCode::Value, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::begin() const Line | Count | Source | 68 | 15.1k | constexpr const_iterator begin() const noexcept { return {Data, 0}; } |
WasmEdge::SpareEnumMap<29ul, WasmEdge::TypeCode, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::begin() const Line | Count | Source | 68 | 331 | constexpr const_iterator begin() const noexcept { return {Data, 0}; } |
|
69 | | |
70 | 15.7k | constexpr const_iterator end() const noexcept { return {Data, Size}; }WasmEdge::SpareEnumMap<566ul, WasmEdge::OpCode, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::end() const Line | Count | Source | 70 | 281 | constexpr const_iterator end() const noexcept { return {Data, Size}; } |
WasmEdge::SpareEnumMap<165ul, WasmEdge::ErrCode::Value, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::end() const Line | Count | Source | 70 | 15.1k | constexpr const_iterator end() const noexcept { return {Data, Size}; } |
WasmEdge::SpareEnumMap<29ul, WasmEdge::TypeCode, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::end() const Line | Count | Source | 70 | 331 | constexpr const_iterator end() const noexcept { return {Data, Size}; } |
|
71 | | |
72 | 15.7k | constexpr const_iterator find(key_type K) const noexcept { |
73 | 15.7k | if (auto Iter = std::lower_bound(begin(), end(), value_type(K, {})); |
74 | 15.7k | std::equal_to<>()(Iter->first, K)) { |
75 | 15.7k | return Iter; |
76 | 15.7k | } |
77 | 0 | return end(); |
78 | 15.7k | } WasmEdge::SpareEnumMap<566ul, WasmEdge::OpCode, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::find(WasmEdge::OpCode) const Line | Count | Source | 72 | 281 | constexpr const_iterator find(key_type K) const noexcept { | 73 | 281 | if (auto Iter = std::lower_bound(begin(), end(), value_type(K, {})); | 74 | 281 | std::equal_to<>()(Iter->first, K)) { | 75 | 281 | return Iter; | 76 | 281 | } | 77 | 0 | return end(); | 78 | 281 | } |
WasmEdge::SpareEnumMap<165ul, WasmEdge::ErrCode::Value, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::find(WasmEdge::ErrCode::Value) const Line | Count | Source | 72 | 15.1k | constexpr const_iterator find(key_type K) const noexcept { | 73 | 15.1k | if (auto Iter = std::lower_bound(begin(), end(), value_type(K, {})); | 74 | 15.1k | std::equal_to<>()(Iter->first, K)) { | 75 | 15.1k | return Iter; | 76 | 15.1k | } | 77 | 0 | return end(); | 78 | 15.1k | } |
WasmEdge::SpareEnumMap<29ul, WasmEdge::TypeCode, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::find(WasmEdge::TypeCode) const Line | Count | Source | 72 | 331 | constexpr const_iterator find(key_type K) const noexcept { | 73 | 331 | if (auto Iter = std::lower_bound(begin(), end(), value_type(K, {})); | 74 | 331 | std::equal_to<>()(Iter->first, K)) { | 75 | 331 | return Iter; | 76 | 331 | } | 77 | 0 | return end(); | 78 | 331 | } |
|
79 | | |
80 | 15.7k | constexpr const mapped_type &operator[](key_type K) const noexcept { |
81 | 15.7k | return find(K)->second; |
82 | 15.7k | } WasmEdge::SpareEnumMap<566ul, WasmEdge::OpCode, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::operator[](WasmEdge::OpCode) const Line | Count | Source | 80 | 281 | constexpr const mapped_type &operator[](key_type K) const noexcept { | 81 | 281 | return find(K)->second; | 82 | 281 | } |
WasmEdge::SpareEnumMap<165ul, WasmEdge::ErrCode::Value, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::operator[](WasmEdge::ErrCode::Value) const Line | Count | Source | 80 | 15.1k | constexpr const mapped_type &operator[](key_type K) const noexcept { | 81 | 15.1k | return find(K)->second; | 82 | 15.1k | } |
WasmEdge::SpareEnumMap<29ul, WasmEdge::TypeCode, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::operator[](WasmEdge::TypeCode) const Line | Count | Source | 80 | 331 | constexpr const mapped_type &operator[](key_type K) const noexcept { | 81 | 331 | return find(K)->second; | 82 | 331 | } |
|
83 | | |
84 | | private: |
85 | | std::array<std::pair<Key, T>, Size + 1> Data; |
86 | | }; |
87 | | |
88 | | template <class Key, std::size_t Size> |
89 | | SpareEnumMap(const std::pair<Key, std::string_view> (&)[Size]) |
90 | | -> SpareEnumMap<Size, Key>; |
91 | | |
92 | | template <std::size_t Size, class Key, class T> |
93 | | class SpareEnumMap<Size, Key, T>::ConstIterator { |
94 | | public: |
95 | | using difference_type = SpareEnumMap<Size, Key, T>::difference_type; |
96 | | using value_type = SpareEnumMap<Size, Key, T>::value_type; |
97 | | using pointer = SpareEnumMap<Size, Key, T>::pointer; |
98 | | using reference = SpareEnumMap<Size, Key, T>::reference; |
99 | | using iterator_category = std::random_access_iterator_tag; |
100 | | |
101 | | constexpr ConstIterator() noexcept = default; |
102 | | constexpr ConstIterator(const ConstIterator &) noexcept = default; |
103 | | constexpr ConstIterator(ConstIterator &&) noexcept = default; |
104 | | constexpr ConstIterator &operator=(const ConstIterator &) noexcept = default; |
105 | | constexpr ConstIterator &operator=(ConstIterator &&) noexcept = default; |
106 | | |
107 | | constexpr ConstIterator(const std::array<std::pair<Key, T>, Size + 1> &D, |
108 | | size_type I) noexcept |
109 | 31.5k | : Data(std::addressof(D)), Index(I) {}WasmEdge::SpareEnumMap<165ul, WasmEdge::ErrCode::Value, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::ConstIterator::ConstIterator(std::__1::array<std::__1::pair<WasmEdge::ErrCode::Value, std::__1::basic_string_view<char, std::__1::char_traits<char> > >, 166ul> const&, unsigned long) Line | Count | Source | 109 | 30.3k | : Data(std::addressof(D)), Index(I) {} |
WasmEdge::SpareEnumMap<29ul, WasmEdge::TypeCode, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::ConstIterator::ConstIterator(std::__1::array<std::__1::pair<WasmEdge::TypeCode, std::__1::basic_string_view<char, std::__1::char_traits<char> > >, 30ul> const&, unsigned long) Line | Count | Source | 109 | 662 | : Data(std::addressof(D)), Index(I) {} |
WasmEdge::SpareEnumMap<566ul, WasmEdge::OpCode, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::ConstIterator::ConstIterator(std::__1::array<std::__1::pair<WasmEdge::OpCode, std::__1::basic_string_view<char, std::__1::char_traits<char> > >, 567ul> const&, unsigned long) Line | Count | Source | 109 | 562 | : Data(std::addressof(D)), Index(I) {} |
|
110 | | |
111 | 114k | constexpr reference operator*() noexcept { return (*Data)[Index]; }WasmEdge::SpareEnumMap<566ul, WasmEdge::OpCode, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::ConstIterator::operator*() Line | Count | Source | 111 | 2.57k | constexpr reference operator*() noexcept { return (*Data)[Index]; } |
WasmEdge::SpareEnumMap<165ul, WasmEdge::ErrCode::Value, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::ConstIterator::operator*() Line | Count | Source | 111 | 110k | constexpr reference operator*() noexcept { return (*Data)[Index]; } |
WasmEdge::SpareEnumMap<29ul, WasmEdge::TypeCode, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::ConstIterator::operator*() Line | Count | Source | 111 | 1.64k | constexpr reference operator*() noexcept { return (*Data)[Index]; } |
|
112 | | constexpr const_reference operator*() const noexcept { |
113 | | return (*Data)[Index]; |
114 | | } |
115 | | |
116 | 31.5k | constexpr pointer operator->() noexcept { |
117 | 31.5k | return std::addressof((*Data)[Index]); |
118 | 31.5k | } WasmEdge::SpareEnumMap<566ul, WasmEdge::OpCode, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::ConstIterator::operator->() Line | Count | Source | 116 | 562 | constexpr pointer operator->() noexcept { | 117 | 562 | return std::addressof((*Data)[Index]); | 118 | 562 | } |
WasmEdge::SpareEnumMap<165ul, WasmEdge::ErrCode::Value, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::ConstIterator::operator->() Line | Count | Source | 116 | 30.3k | constexpr pointer operator->() noexcept { | 117 | 30.3k | return std::addressof((*Data)[Index]); | 118 | 30.3k | } |
WasmEdge::SpareEnumMap<29ul, WasmEdge::TypeCode, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::ConstIterator::operator->() Line | Count | Source | 116 | 662 | constexpr pointer operator->() noexcept { | 117 | 662 | return std::addressof((*Data)[Index]); | 118 | 662 | } |
|
119 | | constexpr const_pointer operator->() const noexcept { |
120 | | return std::addressof((*Data)[Index]); |
121 | | } |
122 | | |
123 | 51.0k | constexpr ConstIterator &operator++() noexcept { |
124 | 51.0k | ++Index; |
125 | 51.0k | return *this; |
126 | 51.0k | } WasmEdge::SpareEnumMap<566ul, WasmEdge::OpCode, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::ConstIterator::operator++() Line | Count | Source | 123 | 1.02k | constexpr ConstIterator &operator++() noexcept { | 124 | 1.02k | ++Index; | 125 | 1.02k | return *this; | 126 | 1.02k | } |
WasmEdge::SpareEnumMap<165ul, WasmEdge::ErrCode::Value, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::ConstIterator::operator++() Line | Count | Source | 123 | 49.4k | constexpr ConstIterator &operator++() noexcept { | 124 | 49.4k | ++Index; | 125 | 49.4k | return *this; | 126 | 49.4k | } |
WasmEdge::SpareEnumMap<29ul, WasmEdge::TypeCode, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::ConstIterator::operator++() Line | Count | Source | 123 | 591 | constexpr ConstIterator &operator++() noexcept { | 124 | 591 | ++Index; | 125 | 591 | return *this; | 126 | 591 | } |
|
127 | | |
128 | | constexpr ConstIterator &operator--() noexcept { |
129 | | --Index; |
130 | | return *this; |
131 | | } |
132 | | |
133 | | constexpr ConstIterator operator++(int) noexcept { |
134 | | ConstIterator Iter(*this); |
135 | | ++*this; |
136 | | return Iter; |
137 | | } |
138 | | |
139 | | constexpr ConstIterator operator--(int) noexcept { |
140 | | ConstIterator Iter(*this); |
141 | | --*this; |
142 | | return Iter; |
143 | | } |
144 | | |
145 | 114k | constexpr ConstIterator &operator+=(difference_type N) noexcept { |
146 | 114k | Index = static_cast<size_type>(static_cast<difference_type>(Index) + N); |
147 | 114k | return *this; |
148 | 114k | } WasmEdge::SpareEnumMap<566ul, WasmEdge::OpCode, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::ConstIterator::operator+=(long) Line | Count | Source | 145 | 2.57k | constexpr ConstIterator &operator+=(difference_type N) noexcept { | 146 | 2.57k | Index = static_cast<size_type>(static_cast<difference_type>(Index) + N); | 147 | 2.57k | return *this; | 148 | 2.57k | } |
WasmEdge::SpareEnumMap<165ul, WasmEdge::ErrCode::Value, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::ConstIterator::operator+=(long) Line | Count | Source | 145 | 110k | constexpr ConstIterator &operator+=(difference_type N) noexcept { | 146 | 110k | Index = static_cast<size_type>(static_cast<difference_type>(Index) + N); | 147 | 110k | return *this; | 148 | 110k | } |
WasmEdge::SpareEnumMap<29ul, WasmEdge::TypeCode, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::ConstIterator::operator+=(long) Line | Count | Source | 145 | 1.64k | constexpr ConstIterator &operator+=(difference_type N) noexcept { | 146 | 1.64k | Index = static_cast<size_type>(static_cast<difference_type>(Index) + N); | 147 | 1.64k | return *this; | 148 | 1.64k | } |
|
149 | | |
150 | | constexpr ConstIterator &operator-=(difference_type N) noexcept { |
151 | | Index = static_cast<size_type>(static_cast<difference_type>(Index) - N); |
152 | | return *this; |
153 | | } |
154 | | |
155 | | friend constexpr ConstIterator operator+(const ConstIterator &LHS, |
156 | | difference_type RHS) noexcept { |
157 | | ConstIterator Iter = LHS; |
158 | | return Iter += RHS; |
159 | | } |
160 | | |
161 | | friend constexpr difference_type |
162 | 15.7k | operator-(const ConstIterator &LHS, const ConstIterator &RHS) noexcept { |
163 | 15.7k | const std::pair<Key, T> *const L = std::addressof((*LHS.Data)[LHS.Index]); |
164 | 15.7k | const std::pair<Key, T> *const R = std::addressof((*RHS.Data)[RHS.Index]); |
165 | 15.7k | return L - R; |
166 | 15.7k | } WasmEdge::operator-(WasmEdge::SpareEnumMap<566ul, WasmEdge::OpCode, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::ConstIterator const&, WasmEdge::SpareEnumMap<566ul, WasmEdge::OpCode, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::ConstIterator const&) Line | Count | Source | 162 | 281 | operator-(const ConstIterator &LHS, const ConstIterator &RHS) noexcept { | 163 | 281 | const std::pair<Key, T> *const L = std::addressof((*LHS.Data)[LHS.Index]); | 164 | 281 | const std::pair<Key, T> *const R = std::addressof((*RHS.Data)[RHS.Index]); | 165 | 281 | return L - R; | 166 | 281 | } |
WasmEdge::operator-(WasmEdge::SpareEnumMap<165ul, WasmEdge::ErrCode::Value, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::ConstIterator const&, WasmEdge::SpareEnumMap<165ul, WasmEdge::ErrCode::Value, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::ConstIterator const&) Line | Count | Source | 162 | 15.1k | operator-(const ConstIterator &LHS, const ConstIterator &RHS) noexcept { | 163 | 15.1k | const std::pair<Key, T> *const L = std::addressof((*LHS.Data)[LHS.Index]); | 164 | 15.1k | const std::pair<Key, T> *const R = std::addressof((*RHS.Data)[RHS.Index]); | 165 | 15.1k | return L - R; | 166 | 15.1k | } |
WasmEdge::operator-(WasmEdge::SpareEnumMap<29ul, WasmEdge::TypeCode, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::ConstIterator const&, WasmEdge::SpareEnumMap<29ul, WasmEdge::TypeCode, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::ConstIterator const&) Line | Count | Source | 162 | 331 | operator-(const ConstIterator &LHS, const ConstIterator &RHS) noexcept { | 163 | 331 | const std::pair<Key, T> *const L = std::addressof((*LHS.Data)[LHS.Index]); | 164 | 331 | const std::pair<Key, T> *const R = std::addressof((*RHS.Data)[RHS.Index]); | 165 | 331 | return L - R; | 166 | 331 | } |
|
167 | | |
168 | | constexpr reference operator[](difference_type N) noexcept { |
169 | | return *((*this) + N); |
170 | | } |
171 | | |
172 | | friend constexpr bool operator==(const ConstIterator &LHS, |
173 | | const ConstIterator &RHS) noexcept { |
174 | | return (LHS - RHS) == 0; |
175 | | } |
176 | | |
177 | | friend constexpr bool operator!=(const ConstIterator &LHS, |
178 | | const ConstIterator &RHS) noexcept { |
179 | | return !(LHS == RHS); |
180 | | } |
181 | | |
182 | | friend constexpr bool operator<(const ConstIterator &LHS, |
183 | | const ConstIterator &RHS) noexcept { |
184 | | return (RHS - LHS) > 0; |
185 | | } |
186 | | |
187 | | friend constexpr bool operator>(const ConstIterator &LHS, |
188 | | const ConstIterator &RHS) noexcept { |
189 | | return (LHS - RHS) > 0; |
190 | | } |
191 | | |
192 | | friend constexpr bool operator<=(const ConstIterator &LHS, |
193 | | const ConstIterator &RHS) noexcept { |
194 | | return !(LHS > RHS); |
195 | | } |
196 | | |
197 | | friend constexpr bool operator>=(const ConstIterator &LHS, |
198 | | const ConstIterator &RHS) noexcept { |
199 | | return !(LHS < RHS); |
200 | | } |
201 | | |
202 | | private: |
203 | | const std::array<std::pair<Key, T>, Size + 1> *Data = nullptr; |
204 | | size_type Index = 0; |
205 | | }; |
206 | | |
207 | | } // namespace WasmEdge |