Coverage Report

Created: 2026-11-12 06:35

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
29.9k
  constexpr const_iterator begin() const noexcept { return {Data, 0}; }
WasmEdge::SpareEnumMap<570ul, WasmEdge::OpCode, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::begin() const
Line
Count
Source
68
2.95k
  constexpr const_iterator begin() const noexcept { return {Data, 0}; }
WasmEdge::SpareEnumMap<307ul, WasmEdge::ErrCode::Value, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::begin() const
Line
Count
Source
68
21.5k
  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
5.41k
  constexpr const_iterator begin() const noexcept { return {Data, 0}; }
WasmEdge::SpareEnumMap<49ul, WasmEdge::ComponentCanonOpCode, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::begin() const
Line
Count
Source
68
74
  constexpr const_iterator begin() const noexcept { return {Data, 0}; }
69
70
29.9k
  constexpr const_iterator end() const noexcept { return {Data, Size}; }
WasmEdge::SpareEnumMap<570ul, WasmEdge::OpCode, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::end() const
Line
Count
Source
70
2.95k
  constexpr const_iterator end() const noexcept { return {Data, Size}; }
WasmEdge::SpareEnumMap<307ul, WasmEdge::ErrCode::Value, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::end() const
Line
Count
Source
70
21.5k
  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
5.41k
  constexpr const_iterator end() const noexcept { return {Data, Size}; }
WasmEdge::SpareEnumMap<49ul, WasmEdge::ComponentCanonOpCode, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::end() const
Line
Count
Source
70
74
  constexpr const_iterator end() const noexcept { return {Data, Size}; }
71
72
29.9k
  constexpr const_iterator find(key_type K) const noexcept {
73
29.9k
    if (auto Iter = std::lower_bound(begin(), end(), value_type(K, {}));
74
29.9k
        std::equal_to<>()(Iter->first, K)) {
75
29.9k
      return Iter;
76
29.9k
    }
77
0
    return end();
78
29.9k
  }
WasmEdge::SpareEnumMap<570ul, WasmEdge::OpCode, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::find(WasmEdge::OpCode) const
Line
Count
Source
72
2.95k
  constexpr const_iterator find(key_type K) const noexcept {
73
2.95k
    if (auto Iter = std::lower_bound(begin(), end(), value_type(K, {}));
74
2.95k
        std::equal_to<>()(Iter->first, K)) {
75
2.95k
      return Iter;
76
2.95k
    }
77
0
    return end();
78
2.95k
  }
WasmEdge::SpareEnumMap<307ul, WasmEdge::ErrCode::Value, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::find(WasmEdge::ErrCode::Value) const
Line
Count
Source
72
21.5k
  constexpr const_iterator find(key_type K) const noexcept {
73
21.5k
    if (auto Iter = std::lower_bound(begin(), end(), value_type(K, {}));
74
21.5k
        std::equal_to<>()(Iter->first, K)) {
75
21.5k
      return Iter;
76
21.5k
    }
77
0
    return end();
78
21.5k
  }
WasmEdge::SpareEnumMap<29ul, WasmEdge::TypeCode, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::find(WasmEdge::TypeCode) const
Line
Count
Source
72
5.41k
  constexpr const_iterator find(key_type K) const noexcept {
73
5.41k
    if (auto Iter = std::lower_bound(begin(), end(), value_type(K, {}));
74
5.41k
        std::equal_to<>()(Iter->first, K)) {
75
5.41k
      return Iter;
76
5.41k
    }
77
0
    return end();
78
5.41k
  }
WasmEdge::SpareEnumMap<49ul, WasmEdge::ComponentCanonOpCode, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::find(WasmEdge::ComponentCanonOpCode) const
Line
Count
Source
72
74
  constexpr const_iterator find(key_type K) const noexcept {
73
74
    if (auto Iter = std::lower_bound(begin(), end(), value_type(K, {}));
74
74
        std::equal_to<>()(Iter->first, K)) {
75
74
      return Iter;
76
74
    }
77
0
    return end();
78
74
  }
79
80
29.9k
  constexpr const mapped_type &operator[](key_type K) const noexcept {
81
29.9k
    return find(K)->second;
82
29.9k
  }
WasmEdge::SpareEnumMap<570ul, WasmEdge::OpCode, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::operator[](WasmEdge::OpCode) const
Line
Count
Source
80
2.95k
  constexpr const mapped_type &operator[](key_type K) const noexcept {
81
2.95k
    return find(K)->second;
82
2.95k
  }
WasmEdge::SpareEnumMap<307ul, WasmEdge::ErrCode::Value, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::operator[](WasmEdge::ErrCode::Value) const
Line
Count
Source
80
21.5k
  constexpr const mapped_type &operator[](key_type K) const noexcept {
81
21.5k
    return find(K)->second;
82
21.5k
  }
WasmEdge::SpareEnumMap<29ul, WasmEdge::TypeCode, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::operator[](WasmEdge::TypeCode) const
Line
Count
Source
80
5.41k
  constexpr const mapped_type &operator[](key_type K) const noexcept {
81
5.41k
    return find(K)->second;
82
5.41k
  }
WasmEdge::SpareEnumMap<49ul, WasmEdge::ComponentCanonOpCode, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::operator[](WasmEdge::ComponentCanonOpCode) const
Line
Count
Source
80
74
  constexpr const mapped_type &operator[](key_type K) const noexcept {
81
74
    return find(K)->second;
82
74
  }
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
59.9k
      : Data(std::addressof(D)), Index(I) {}
WasmEdge::SpareEnumMap<307ul, 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> > >, 308ul> const&, unsigned long)
Line
Count
Source
109
43.1k
      : 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
10.8k
      : Data(std::addressof(D)), Index(I) {}
WasmEdge::SpareEnumMap<570ul, 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> > >, 571ul> const&, unsigned long)
Line
Count
Source
109
5.90k
      : Data(std::addressof(D)), Index(I) {}
WasmEdge::SpareEnumMap<49ul, WasmEdge::ComponentCanonOpCode, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::ConstIterator::ConstIterator(std::__1::array<std::__1::pair<WasmEdge::ComponentCanonOpCode, std::__1::basic_string_view<char, std::__1::char_traits<char> > >, 50ul> const&, unsigned long)
Line
Count
Source
109
148
      : Data(std::addressof(D)), Index(I) {}
110
111
231k
  constexpr reference operator*() noexcept { return (*Data)[Index]; }
WasmEdge::SpareEnumMap<570ul, WasmEdge::OpCode, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::ConstIterator::operator*()
Line
Count
Source
111
27.1k
  constexpr reference operator*() noexcept { return (*Data)[Index]; }
WasmEdge::SpareEnumMap<307ul, WasmEdge::ErrCode::Value, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::ConstIterator::operator*()
Line
Count
Source
111
176k
  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
27.0k
  constexpr reference operator*() noexcept { return (*Data)[Index]; }
WasmEdge::SpareEnumMap<49ul, WasmEdge::ComponentCanonOpCode, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::ConstIterator::operator*()
Line
Count
Source
111
415
  constexpr reference operator*() noexcept { return (*Data)[Index]; }
112
  constexpr const_reference operator*() const noexcept {
113
    return (*Data)[Index];
114
  }
115
116
59.9k
  constexpr pointer operator->() noexcept {
117
59.9k
    return std::addressof((*Data)[Index]);
118
59.9k
  }
WasmEdge::SpareEnumMap<570ul, WasmEdge::OpCode, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::ConstIterator::operator->()
Line
Count
Source
116
5.90k
  constexpr pointer operator->() noexcept {
117
5.90k
    return std::addressof((*Data)[Index]);
118
5.90k
  }
WasmEdge::SpareEnumMap<307ul, WasmEdge::ErrCode::Value, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::ConstIterator::operator->()
Line
Count
Source
116
43.1k
  constexpr pointer operator->() noexcept {
117
43.1k
    return std::addressof((*Data)[Index]);
118
43.1k
  }
WasmEdge::SpareEnumMap<29ul, WasmEdge::TypeCode, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::ConstIterator::operator->()
Line
Count
Source
116
10.8k
  constexpr pointer operator->() noexcept {
117
10.8k
    return std::addressof((*Data)[Index]);
118
10.8k
  }
WasmEdge::SpareEnumMap<49ul, WasmEdge::ComponentCanonOpCode, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::ConstIterator::operator->()
Line
Count
Source
116
148
  constexpr pointer operator->() noexcept {
117
148
    return std::addressof((*Data)[Index]);
118
148
  }
119
  constexpr const_pointer operator->() const noexcept {
120
    return std::addressof((*Data)[Index]);
121
  }
122
123
83.9k
  constexpr ConstIterator &operator++() noexcept {
124
83.9k
    ++Index;
125
83.9k
    return *this;
126
83.9k
  }
WasmEdge::SpareEnumMap<570ul, WasmEdge::OpCode, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::ConstIterator::operator++()
Line
Count
Source
123
10.4k
  constexpr ConstIterator &operator++() noexcept {
124
10.4k
    ++Index;
125
10.4k
    return *this;
126
10.4k
  }
WasmEdge::SpareEnumMap<307ul, WasmEdge::ErrCode::Value, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::ConstIterator::operator++()
Line
Count
Source
123
60.5k
  constexpr ConstIterator &operator++() noexcept {
124
60.5k
    ++Index;
125
60.5k
    return *this;
126
60.5k
  }
WasmEdge::SpareEnumMap<29ul, WasmEdge::TypeCode, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::ConstIterator::operator++()
Line
Count
Source
123
12.7k
  constexpr ConstIterator &operator++() noexcept {
124
12.7k
    ++Index;
125
12.7k
    return *this;
126
12.7k
  }
WasmEdge::SpareEnumMap<49ul, WasmEdge::ComponentCanonOpCode, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::ConstIterator::operator++()
Line
Count
Source
123
193
  constexpr ConstIterator &operator++() noexcept {
124
193
    ++Index;
125
193
    return *this;
126
193
  }
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
231k
  constexpr ConstIterator &operator+=(difference_type N) noexcept {
146
231k
    Index = static_cast<size_type>(static_cast<difference_type>(Index) + N);
147
231k
    return *this;
148
231k
  }
WasmEdge::SpareEnumMap<570ul, WasmEdge::OpCode, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::ConstIterator::operator+=(long)
Line
Count
Source
145
27.1k
  constexpr ConstIterator &operator+=(difference_type N) noexcept {
146
27.1k
    Index = static_cast<size_type>(static_cast<difference_type>(Index) + N);
147
27.1k
    return *this;
148
27.1k
  }
WasmEdge::SpareEnumMap<307ul, WasmEdge::ErrCode::Value, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::ConstIterator::operator+=(long)
Line
Count
Source
145
176k
  constexpr ConstIterator &operator+=(difference_type N) noexcept {
146
176k
    Index = static_cast<size_type>(static_cast<difference_type>(Index) + N);
147
176k
    return *this;
148
176k
  }
WasmEdge::SpareEnumMap<29ul, WasmEdge::TypeCode, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::ConstIterator::operator+=(long)
Line
Count
Source
145
27.0k
  constexpr ConstIterator &operator+=(difference_type N) noexcept {
146
27.0k
    Index = static_cast<size_type>(static_cast<difference_type>(Index) + N);
147
27.0k
    return *this;
148
27.0k
  }
WasmEdge::SpareEnumMap<49ul, WasmEdge::ComponentCanonOpCode, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::ConstIterator::operator+=(long)
Line
Count
Source
145
415
  constexpr ConstIterator &operator+=(difference_type N) noexcept {
146
415
    Index = static_cast<size_type>(static_cast<difference_type>(Index) + N);
147
415
    return *this;
148
415
  }
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
29.9k
  operator-(const ConstIterator &LHS, const ConstIterator &RHS) noexcept {
163
29.9k
    const std::pair<Key, T> *const L = std::addressof((*LHS.Data)[LHS.Index]);
164
29.9k
    const std::pair<Key, T> *const R = std::addressof((*RHS.Data)[RHS.Index]);
165
29.9k
    return L - R;
166
29.9k
  }
WasmEdge::operator-(WasmEdge::SpareEnumMap<570ul, WasmEdge::OpCode, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::ConstIterator const&, WasmEdge::SpareEnumMap<570ul, WasmEdge::OpCode, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::ConstIterator const&)
Line
Count
Source
162
2.95k
  operator-(const ConstIterator &LHS, const ConstIterator &RHS) noexcept {
163
2.95k
    const std::pair<Key, T> *const L = std::addressof((*LHS.Data)[LHS.Index]);
164
2.95k
    const std::pair<Key, T> *const R = std::addressof((*RHS.Data)[RHS.Index]);
165
2.95k
    return L - R;
166
2.95k
  }
WasmEdge::operator-(WasmEdge::SpareEnumMap<307ul, WasmEdge::ErrCode::Value, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::ConstIterator const&, WasmEdge::SpareEnumMap<307ul, WasmEdge::ErrCode::Value, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::ConstIterator const&)
Line
Count
Source
162
21.5k
  operator-(const ConstIterator &LHS, const ConstIterator &RHS) noexcept {
163
21.5k
    const std::pair<Key, T> *const L = std::addressof((*LHS.Data)[LHS.Index]);
164
21.5k
    const std::pair<Key, T> *const R = std::addressof((*RHS.Data)[RHS.Index]);
165
21.5k
    return L - R;
166
21.5k
  }
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
5.41k
  operator-(const ConstIterator &LHS, const ConstIterator &RHS) noexcept {
163
5.41k
    const std::pair<Key, T> *const L = std::addressof((*LHS.Data)[LHS.Index]);
164
5.41k
    const std::pair<Key, T> *const R = std::addressof((*RHS.Data)[RHS.Index]);
165
5.41k
    return L - R;
166
5.41k
  }
WasmEdge::operator-(WasmEdge::SpareEnumMap<49ul, WasmEdge::ComponentCanonOpCode, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::ConstIterator const&, WasmEdge::SpareEnumMap<49ul, WasmEdge::ComponentCanonOpCode, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::ConstIterator const&)
Line
Count
Source
162
74
  operator-(const ConstIterator &LHS, const ConstIterator &RHS) noexcept {
163
74
    const std::pair<Key, T> *const L = std::addressof((*LHS.Data)[LHS.Index]);
164
74
    const std::pair<Key, T> *const R = std::addressof((*RHS.Data)[RHS.Index]);
165
74
    return L - R;
166
74
  }
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