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