KleidiAI Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 94.3% 50 / 0 / 53
Functions: 82.8% 72 / 0 / 87
Branches: 30.0% 12 / 0 / 40

test/common/span.hpp
Line Branch Exec Source
1 //
2 // SPDX-FileCopyrightText: Copyright 2025 Arm Limited and/or its affiliates <open-source-office@arm.com>
3 //
4 // SPDX-License-Identifier: Apache-2.0
5 //
6
7 #pragma once
8
9 #include <array>
10 #include <cstddef>
11 #include <initializer_list>
12 #include <iterator>
13 #include <type_traits>
14 #include <vector>
15
16 #include "test/common/assert.hpp"
17
18 namespace kai::test {
19
20 /// Reference to a contiguous sequence of objects in the memory.
21 ///
22 /// This class is similar to @ref std::span from C++20.
23 template <typename T>
24 class Span {
25 template <typename U>
26 friend class Span;
27
28 public:
29 class Iterator {
30 public:
31 using iterator_category = std::random_access_iterator_tag;
32 using value_type = std::remove_cv_t<T>;
33 using difference_type = ptrdiff_t;
34 using pointer = T*;
35 using reference = T&;
36
37 175104 constexpr Iterator(T* ptr) : m_ptr(ptr) {
38 175104 }
39
40 644310 constexpr T& operator*() const noexcept {
41 644310 return *m_ptr;
42 }
43
44 constexpr T* operator->() const noexcept {
45 return m_ptr;
46 }
47
48 644310 constexpr Iterator& operator++() noexcept {
49 644310 ++m_ptr;
50 644310 return *this;
51 }
52
53 constexpr Iterator operator++(int) noexcept {
54 Iterator it = *this;
55 ++m_ptr;
56 return it;
57 }
58
59 constexpr Iterator& operator--() noexcept {
60 --m_ptr;
61 return *this;
62 }
63
64 constexpr Iterator operator--(int) noexcept {
65 Iterator it = *this;
66 --m_ptr;
67 return it;
68 }
69
70 constexpr Iterator& operator+=(size_t len) noexcept {
71 m_ptr += len;
72 return *this;
73 }
74
75 constexpr Iterator& operator-=(size_t len) noexcept {
76 m_ptr -= len;
77 return *this;
78 }
79
80 18685 [[nodiscard]] constexpr Iterator operator+(size_t len) const noexcept {
81
1/2
✓ Branch 0 taken 18685 times.
✗ Branch 1 not taken.
18685 return {m_ptr + len};
82 }
83
84 [[nodiscard]] friend constexpr Iterator operator+(size_t len, Iterator it) noexcept {
85 return {it.m_ptr + len};
86 }
87
88 6855 [[nodiscard]] constexpr Iterator operator-(size_t len) const noexcept {
89
1/2
✓ Branch 0 taken 6855 times.
✗ Branch 1 not taken.
6855 return {m_ptr - len};
90 }
91
92 5480 [[nodiscard]] constexpr ptrdiff_t operator-(Iterator other) const noexcept {
93 5480 return m_ptr - other.m_ptr;
94 }
95
96 [[nodiscard]] constexpr T& operator[](size_t idx) const noexcept {
97 return m_ptr[idx];
98 }
99
100 1200 [[nodiscard]] constexpr bool operator==(Iterator other) const noexcept {
101 1200 return m_ptr == other.m_ptr;
102 }
103
104 359377 [[nodiscard]] constexpr bool operator!=(Iterator other) const noexcept {
105 359377 return m_ptr != other.m_ptr;
106 }
107
108 [[nodiscard]] constexpr bool operator>(Iterator other) const noexcept {
109 return m_ptr > other.m_ptr;
110 }
111
112 [[nodiscard]] constexpr bool operator<(Iterator other) const noexcept {
113 return m_ptr < other.m_ptr;
114 }
115
116 [[nodiscard]] constexpr bool operator>=(Iterator other) const noexcept {
117 return m_ptr >= other.m_ptr;
118 }
119
120 [[nodiscard]] constexpr bool operator<=(Iterator other) const noexcept {
121 return m_ptr <= other.m_ptr;
122 }
123
124 private:
125 T* m_ptr;
126 };
127
128 /// Creates an empty span.
129 1130 constexpr Span() noexcept : m_ptr(nullptr), m_size(0) {
130 1130 }
131
132 /// Creates a span refering to the specified sequence.
133 ///
134 /// @param[in] first The iterator to the first element of the sequence.
135 /// @param[in] count The number of elements.
136 template <typename It>
137 467179206 constexpr Span(It first, size_t count) noexcept : m_ptr(first), m_size(count) {
138 467179206 }
139
140 /// Creates a span refering to the specified array.
141 ///
142 /// @param[in] arr The array to be refered.
143 template <typename U, size_t N>
144 32464 constexpr Span(const std::array<U, N>& arr) noexcept : m_ptr(arr.data()), m_size(arr.size()) {
145 32464 }
146
147 /// Creates a span refering to the specified array.
148 ///
149 /// @param[in] arr The array to be refered.
150 template <typename U, size_t N>
151 8004 constexpr Span(std::array<U, N>& arr) noexcept : m_ptr(arr.data()), m_size(arr.size()) {
152 8004 }
153
154 /// Creates a span refering to the specified vector.
155 ///
156 /// @param[in] vec The vector to be refered.
157 template <typename U>
158 10400 constexpr Span(const std::vector<U>& vec) noexcept : m_ptr(vec.data()), m_size(vec.size()) {
159 10400 }
160
161 /// Creates a span refering to the specified vector.
162 ///
163 /// @param[in] vec The vector to be refered.
164 template <typename U>
165 constexpr Span(std::vector<U>& vec) noexcept : m_ptr(vec.data()), m_size(vec.size()) {
166 }
167
168 /// Creates a span refering to the specified initializer list.
169 ///
170 /// @param[in] il The initializer list to be refered.
171 536156 constexpr Span(std::initializer_list<T> il) noexcept : m_ptr(std::data(il)), m_size(il.size()) {
172 536156 }
173
174 /// Creates a spen refering to the specified span.
175 ///
176 /// @param[in] other The span to be refered.
177 template <typename U>
178 2110 constexpr Span(const Span<U>& other) noexcept : m_ptr(other.m_ptr), m_size(other.m_size) {
179 2110 }
180
181 /// Destructor.
182 ~Span() = default;
183
184 /// Copy constructor.
185 constexpr Span(const Span&) noexcept = default;
186
187 /// Copy assignment.
188 constexpr Span& operator=(const Span&) noexcept = default;
189
190 /// Move constructor.
191 constexpr Span(Span&&) noexcept = default;
192
193 /// Move assignment.
194 constexpr Span& operator=(Span&&) noexcept = default;
195
196 /// Gets a forward iterator to the beginning of the span.
197 49724 [[nodiscard]] constexpr Iterator begin() const noexcept {
198
2/4
✓ Branch 0 taken 31039 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 18685 times.
✗ Branch 3 not taken.
49724 return {m_ptr};
199 }
200
201 /// Gets a forward iterator to the end of the span.
202 12354 [[nodiscard]] constexpr Iterator end() const noexcept {
203
1/4
✓ Branch 0 taken 12354 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12354 return {m_ptr + m_size};
204 }
205
206 /// Gets the first element.
207 [[nodiscard]] constexpr T& front() const {
208 return m_ptr[0];
209 }
210
211 /// Gets the last element.
212 [[nodiscard]] constexpr T& back() const {
213 return m_ptr[m_size - 1];
214 }
215
216 /// Gets the element at the specified index with bounds checking.
217 585046 [[nodiscard]] constexpr T& at(size_t idx) const {
218
3/12
✓ Branch 0 taken 564501 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 12600 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 7945 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
585046 KAI_TEST_ASSERT(idx < m_size);
219 585046 return m_ptr[idx];
220 }
221
222 /// Gets the element at the specified index.
223 [[nodiscard]] constexpr T& operator[](size_t idx) const {
224 return m_ptr[idx];
225 }
226
227 /// Gets the pointer to the data.
228 259246799 [[nodiscard]] constexpr T* data() const noexcept {
229 259246799 return m_ptr;
230 }
231
232 /// Gets the number of elements.
233 259293454 [[nodiscard]] constexpr size_t size() const noexcept {
234 259293454 return m_size;
235 }
236
237 /// Gets a value indicating whether the span is empty.
238 9455 [[nodiscard]] constexpr bool empty() const noexcept {
239 9455 return m_size == 0;
240 }
241
242 /// Gets a sub-view of the span.
243 228011 [[nodiscard]] constexpr Span subspan(size_t offset) const {
244
2/8
✓ Branch 0 taken 198364 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 29647 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
228011 KAI_TEST_ASSERT(offset <= m_size);
245 228011 return {m_ptr + offset, m_size - offset};
246 }
247
248 /// Gets a sub-view of the span.
249 225653889 [[nodiscard]] constexpr Span subspan(size_t offset, size_t count) const {
250
2/8
✓ Branch 0 taken 218024261 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 7629628 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
225653889 KAI_TEST_ASSERT(offset + count <= m_size);
251 225653889 return {m_ptr + offset, count};
252 }
253
254 private:
255 T* m_ptr;
256 size_t m_size;
257 };
258
259 } // namespace kai::test
260