Coverage Report

Created: 2026-06-30 06:10

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/WasmEdge/include/common/dense_enum_map.h
Line
Count
Source
1
// SPDX-License-Identifier: Apache-2.0
2
// SPDX-FileCopyrightText: Copyright The WasmEdge Authors
3
4
//===-- wasmedge/common/dense_enum_map.h - mapping dense enum to data -----===//
5
//
6
// Part of the WasmEdge Project.
7
//
8
//===----------------------------------------------------------------------===//
9
///
10
/// \file
11
/// This file contains a class for mapping enum values to data.
12
///
13
//===----------------------------------------------------------------------===//
14
15
#pragma once
16
17
#include <array>
18
#include <memory>
19
#include <string_view>
20
#include <type_traits>
21
22
namespace WasmEdge {
23
24
template <std::size_t Size, class Key, class T = std::string_view>
25
class DenseEnumMap {
26
  static_assert(std::is_enum_v<Key>, "Key should be an enum type!");
27
28
public:
29
  class ConstIterator;
30
  using key_type = Key;
31
  using mapped_type = T;
32
  using value_type = const std::pair<Key, T>;
33
  using size_type = std::size_t;
34
  using difference_type = std::ptrdiff_t;
35
  using reference = value_type &;
36
  using const_reference = const value_type &;
37
  using pointer = value_type *;
38
  using const_pointer = const value_type *;
39
  using iterator = ConstIterator;
40
  using const_iterator = ConstIterator;
41
42
  constexpr DenseEnumMap() noexcept = delete;
43
  constexpr DenseEnumMap(const DenseEnumMap &) noexcept = delete;
44
  constexpr DenseEnumMap(DenseEnumMap &&) noexcept = default;
45
  constexpr DenseEnumMap &operator=(const DenseEnumMap &) noexcept = delete;
46
  constexpr DenseEnumMap &operator=(DenseEnumMap &&) noexcept = default;
47
48
  constexpr DenseEnumMap(
49
      const std::pair<Key, std::string_view> (&Array)[Size]) noexcept {
50
    for (size_type I = 0; I < Size; ++I) {
51
      Data[static_cast<size_type>(Array[I].first)] = Array[I].second;
52
    }
53
  }
54
55
0
  constexpr const mapped_type &operator[](key_type K) const noexcept {
56
0
    return Data[static_cast<size_type>(K)];
57
0
  }
Unexecuted instantiation: WasmEdge::DenseEnumMap<6ul, WasmEdge::WasmPhase, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::operator[](WasmEdge::WasmPhase) const
Unexecuted instantiation: WasmEdge::DenseEnumMap<11ul, WasmEdge::ErrInfo::MismatchCategory, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::operator[](WasmEdge::ErrInfo::MismatchCategory) const
Unexecuted instantiation: WasmEdge::DenseEnumMap<2ul, WasmEdge::ValMut, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::operator[](WasmEdge::ValMut) const
Unexecuted instantiation: WasmEdge::DenseEnumMap<5ul, WasmEdge::ExternalType, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::operator[](WasmEdge::ExternalType) const
Unexecuted instantiation: WasmEdge::DenseEnumMap<88ul, WasmEdge::ASTNodeAttr, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::operator[](WasmEdge::ASTNodeAttr) const
Unexecuted instantiation: WasmEdge::DenseEnumMap<2ul, WasmEdge::ErrInfo::PtrType, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::operator[](WasmEdge::ErrInfo::PtrType) const
Unexecuted instantiation: WasmEdge::DenseEnumMap<14ul, WasmEdge::ErrInfo::IndexCategory, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::operator[](WasmEdge::ErrInfo::IndexCategory) const
58
59
  constexpr const_iterator begin() const noexcept {
60
    return {Data, static_cast<size_type>(0)};
61
  }
62
63
0
  constexpr const_iterator end() const noexcept {
64
0
    return {Data, static_cast<size_type>(Size)};
65
0
  }
66
67
0
  constexpr const_iterator find(key_type K) const noexcept {
68
0
    return {Data, std::min(static_cast<size_type>(K), Size)};
69
0
  }
70
71
private:
72
  std::array<T, Size> Data;
73
};
74
75
template <class Key, std::size_t Size>
76
DenseEnumMap(const std::pair<Key, std::string_view> (&)[Size])
77
    -> DenseEnumMap<Size, Key>;
78
79
template <std::size_t Size, class Key, class T>
80
class DenseEnumMap<Size, Key, T>::ConstIterator {
81
public:
82
  using difference_type = DenseEnumMap<Size, Key, T>::difference_type;
83
  using value_type = DenseEnumMap<Size, Key, T>::value_type;
84
  using pointer = DenseEnumMap<Size, Key, T>::pointer;
85
  using reference = DenseEnumMap<Size, Key, T>::reference;
86
  using iterator_category = std::random_access_iterator_tag;
87
88
  constexpr ConstIterator() noexcept = default;
89
  constexpr ConstIterator(const ConstIterator &) noexcept = default;
90
  constexpr ConstIterator(ConstIterator &&) noexcept = default;
91
  constexpr ConstIterator &operator=(const ConstIterator &) noexcept = default;
92
  constexpr ConstIterator &operator=(ConstIterator &&) noexcept = default;
93
94
  constexpr ConstIterator(const std::array<T, Size> &D, size_type I) noexcept
95
0
      : Data(std::addressof(D)),
96
0
        Value(static_cast<Key>(I), I < Size ? D[I] : T{}) {}
97
98
  constexpr reference operator*() noexcept { return Value; }
99
  constexpr const_reference operator*() const noexcept { return Value; }
100
101
0
  constexpr pointer operator->() noexcept { return std::addressof(Value); }
102
  constexpr const_pointer operator->() const noexcept {
103
    return std::addressof(Value);
104
  }
105
106
  constexpr ConstIterator &operator++() noexcept {
107
    size_type I = static_cast<size_type>(Value.first);
108
    ++I;
109
    Value = {static_cast<Key>(I), I < Size ? (*Data)[I] : T{}};
110
    return *this;
111
  }
112
113
  constexpr ConstIterator &operator--() noexcept {
114
    size_type I = static_cast<size_type>(Value.first);
115
    --I;
116
    Value = {static_cast<Key>(I), I < Size ? (*Data)[I] : T{}};
117
    return *this;
118
  }
119
120
  constexpr ConstIterator operator++(int) noexcept {
121
    ConstIterator Iter(*this);
122
    ++*this;
123
    return Iter;
124
  }
125
126
  constexpr ConstIterator operator--(int) noexcept {
127
    ConstIterator Iter(*this);
128
    --*this;
129
    return Iter;
130
  }
131
132
  constexpr ConstIterator &operator+=(difference_type N) noexcept {
133
    size_type I = static_cast<size_type>(Value.first);
134
    I = static_cast<size_type>(static_cast<difference_type>(I) + N);
135
    Value = {static_cast<Key>(I), I < Size ? (*Data)[I] : T{}};
136
    return *this;
137
  }
138
139
  constexpr ConstIterator &operator-=(difference_type N) noexcept {
140
    size_type I = static_cast<size_type>(Value.first);
141
    I = static_cast<size_type>(static_cast<difference_type>(I) - N);
142
    Value = {static_cast<Key>(I), I < Size ? (*Data)[I] : T{}};
143
    return *this;
144
  }
145
146
  friend constexpr ConstIterator operator+(const ConstIterator &LHS,
147
                                           difference_type RHS) noexcept {
148
    ConstIterator Iter = LHS;
149
    return Iter += RHS;
150
  }
151
152
  friend constexpr difference_type
153
0
  operator-(const ConstIterator &LHS, const ConstIterator &RHS) noexcept {
154
    // Subtract stored indices only; end() uses index Size and must not
155
    // dereference the backing array (UB, aborts under _GLIBCXX_ASSERTIONS).
156
0
    return static_cast<difference_type>(LHS.Value.first) -
157
0
           static_cast<difference_type>(RHS.Value.first);
158
0
  }
159
160
  constexpr reference operator[](difference_type N) noexcept {
161
    return *((*this) + N);
162
  }
163
164
  friend constexpr bool operator==(const ConstIterator &LHS,
165
0
                                   const ConstIterator &RHS) noexcept {
166
0
    return (LHS - RHS) == 0;
167
0
  }
168
169
  friend constexpr bool operator!=(const ConstIterator &LHS,
170
0
                                   const ConstIterator &RHS) noexcept {
171
0
    return !(LHS == RHS);
172
0
  }
173
174
  friend constexpr bool operator<(const ConstIterator &LHS,
175
                                  const ConstIterator &RHS) noexcept {
176
    return (RHS - LHS) > 0;
177
  }
178
179
  friend constexpr bool operator>(const ConstIterator &LHS,
180
                                  const ConstIterator &RHS) noexcept {
181
    return (LHS - RHS) > 0;
182
  }
183
184
  friend constexpr bool operator<=(const ConstIterator &LHS,
185
                                   const ConstIterator &RHS) noexcept {
186
    return !(LHS > RHS);
187
  }
188
189
  friend constexpr bool operator>=(const ConstIterator &LHS,
190
                                   const ConstIterator &RHS) noexcept {
191
    return !(LHS < RHS);
192
  }
193
194
private:
195
  const std::array<T, Size> *Data = nullptr;
196
  std::pair<Key, T> Value;
197
};
198
199
} // namespace WasmEdge