ATLAS Offline Software
Loading...
Searching...
No Matches
span.icc
Go to the documentation of this file.
1/*
2 * Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration.
3 */
4/**
5 * @file CxxUtils/span.icc
6 * @author scott snyder <snyder@bnl.gov>
7 * @date Jan, 2022
8 * @brief Simplified version of the C++20 std::span.
9 */
10
11
12#include "CxxUtils/throw_out_of_range.h"
13
14
15namespace CxxUtils {
16
17
18/*
19 * @brief Default constructor.
20 * Makes an empty span.
21 */
22template <class T>
23inline
24span<T>::span()
25 : m_ptr(nullptr),
26 m_size(0)
27{
28}
29
30
31/**
32 * @brief Constructor from start and length.
33 * @param ptr Start of the span.
34 * @param sz Length of the span.
35 */
36template <class T>
37template <class U>
38requires (valid_span_type_v<T, U>)
39inline
40span<T>::span (U* ptr, size_type sz)
41 : m_ptr (ptr),
42 m_size (sz)
43{
44//cppcheck-suppress missingReturn
45}
46
47
48/**
49 * @brief Constructor from start and end.
50 * @param beg Start of the span.
51 * @param end One past the end of the span.
52 */
53template <class T>
54template <class U>
55requires (valid_span_type_v<T, U>)
56inline
57span<T>::span (U* beg, U* end)
58 : m_ptr (beg),
59 m_size (end-beg)
60{
61//cppcheck-suppress missingReturn
62}
63
64
65/**
66 * @brief Constructor from another span.
67 * @param other Span to copy from.
68 */
69template <class T>
70template <class U>
71requires (valid_span_type_v<T, U>)
72inline
73span<T>::span (const span<U>& other)
74 : m_ptr (other.begin()),
75 m_size (other.size())
76{
77}
78
79
80/**
81 * @brief Return the size of the span.
82 */
83template <class T>
84inline
85constexpr typename span<T>::size_type
86span<T>::size() const noexcept
87{
88 return m_size;
89}
90
91
92/**
93 * @brief Return the size of contents of the span, in bytes.
94 */
95template <class T>
96inline
97constexpr typename span<T>::size_type
98span<T>::size_bytes() const noexcept
99{
100 return m_size * sizeof(element_type);
101}
102
103
104/**
105 * @brief Test if the span is empty.
106 */
107template <class T>
108inline
109constexpr bool
110span<T>::empty() const noexcept
111{
112 return m_size == 0;
113}
114
115
116/**
117 * @brief Return a reference to the first element in the span.
118 */
119template <class T>
120inline
121constexpr typename span<T>::reference
122span<T>::front() noexcept
123{
124 assert (m_ptr != nullptr);
125 return *m_ptr;
126}
127
128
129/**
130 * @brief Return a reference to the first element in the span.
131 */
132template <class T>
133inline
134constexpr typename span<T>::const_reference
135span<T>::front() const noexcept
136{
137 assert (m_ptr != nullptr);
138 return *m_ptr;
139}
140
141
142/**
143 * @brief Return a reference to the last element in the span.
144 */
145template <class T>
146inline
147constexpr typename span<T>::reference
148span<T>::back() noexcept
149{
150 assert (m_ptr != nullptr);
151 return *(m_ptr + m_size-1);
152}
153
154
155/**
156 * @brief Return a reference to the last element in the span.
157 */
158template <class T>
159inline
160constexpr typename span<T>::const_reference
161span<T>::back() const noexcept
162{
163 assert (m_ptr != nullptr);
164 return *(m_ptr + m_size-1);
165}
166
167
168/**
169 * @brief Return a reference to the i-th element in the span.
170 * @param i Index of the element to return.
171 */
172template <class T>
173inline
174constexpr typename span<T>::reference
175span<T>::operator[] (size_type i) noexcept
176{
177 assert (i < m_size);
178 return m_ptr[i];
179}
180
181
182/**
183 * @brief Return a reference to the i-th element in the span.
184 * @param i Index of the element to return.
185 */
186template <class T>
187inline
188constexpr typename span<T>::const_reference
189span<T>::operator[] (size_type i) const noexcept
190{
191 assert (i < m_size);
192 return m_ptr[i];
193}
194
195
196/**
197 * @brief Return a reference to the i-th element in the span (bounds-checked).
198 * @param i Index of the element to return.
199 */
200template <class T>
201inline
202constexpr typename span<T>::reference
203span<T>::at (size_type i)
204{
205 if (i >= m_size) throw_out_of_range (__PRETTY_FUNCTION__, i, m_size, this);
206 return m_ptr[i];
207}
208
209
210/**
211 * @brief Return a reference to the i-th element in the span (bounds-checked).
212 * @param i Index of the element to return.
213 */
214template <class T>
215inline
216constexpr typename span<T>::const_reference
217span<T>::at (size_type i) const
218{
219 if (i >= m_size) throw_out_of_range (__PRETTY_FUNCTION__, i, m_size, this);
220 return m_ptr[i];
221}
222
223
224/**
225 * @brief Return a pointer to the start of the span.
226 */
227template <class T>
228inline
229constexpr typename span<T>::pointer
230span<T>::data() noexcept
231{
232 return m_ptr;
233}
234
235
236/**
237 * @brief Return a pointer to the start of the span.
238 */
239template <class T>
240inline
241constexpr typename span<T>::const_pointer
242span<T>::data() const noexcept
243{
244 return m_ptr;
245}
246
247
248/**
249 * @brief Return a begin iterator.
250 */
251template <class T>
252inline
253constexpr typename span<T>::iterator
254span<T>::begin() noexcept
255{
256 return m_ptr;
257}
258
259
260/**
261 * @brief Return a begin iterator.
262 */
263template <class T>
264inline
265constexpr typename span<T>::const_iterator
266span<T>::begin() const noexcept
267{
268 return m_ptr;
269}
270
271
272/**
273 * @brief Return an end iterator.
274 */
275template <class T>
276inline
277constexpr typename span<T>::iterator
278span<T>::end() noexcept
279{
280 return m_ptr + m_size;
281}
282
283
284/**
285 * @brief Return an end iterator.
286 */
287template <class T>
288inline
289constexpr typename span<T>::const_iterator
290span<T>::end() const noexcept
291{
292 return m_ptr + m_size;
293}
294
295
296/**
297 * @brief Return a begin reverse iterator.
298 */
299template <class T>
300inline
301constexpr typename span<T>::reverse_iterator
302span<T>::rbegin() noexcept
303{
304 return reverse_iterator (end());
305}
306
307
308/**
309 * @brief Return a begin reverse iterator.
310 */
311template <class T>
312inline
313constexpr typename span<T>::const_reverse_iterator
314span<T>::rbegin() const noexcept
315{
316 return const_reverse_iterator (end());
317}
318
319
320/**
321 * @brief Return an end reverse iterator.
322 */
323template <class T>
324inline
325constexpr typename span<T>::reverse_iterator
326span<T>::rend() noexcept
327{
328 return reverse_iterator (begin());
329}
330
331
332/**
333 * @brief Return an end reverse iterator.
334 */
335template <class T>
336inline
337constexpr typename span<T>::const_reverse_iterator
338span<T>::rend() const noexcept
339{
340 return const_reverse_iterator (begin());
341}
342
343
344/**
345 * @brief Return a subspan from the start.
346 * @param n Number of elements in the subspan.
347 */
348template <class T>
349inline
350constexpr span<T>
351span<T>::first (size_type n) noexcept
352{
353 assert (n <= size());
354 return span (m_ptr, n);
355}
356
357
358/**
359 * @brief Return a subspan from the start.
360 * @param n Number of elements in the subspan.
361 */
362template <class T>
363inline
364constexpr span<const T>
365span<T>::first (size_type n) const noexcept
366{
367 assert (n <= size());
368 const T* ptr = m_ptr;
369 return span<const T> (ptr, n);
370}
371
372
373/**
374 * @brief Return a subspan from the end.
375 * @param n Number of elements in the subspan.
376 */
377template <class T>
378inline
379constexpr span<T>
380span<T>::last (size_type n) noexcept
381{
382 assert (n <= size());
383 return span (m_ptr + (size() - n), n);
384}
385
386
387/**
388 * @brief Return a subspan from the end.
389 * @param n Number of elements in the subspan.
390 */
391template <class T>
392inline
393constexpr span<const T>
394span<T>::last (size_type n) const noexcept
395{
396 assert (n <= size());
397 const T* ptr = m_ptr;
398 return span<const T> (ptr + (size() - n), n);
399}
400
401
402/**
403 * @brief Return a subspan.
404 * @param offs Starting element of the subspan.
405 * @param n Number of elements in the subspan.
406 * If defaulted, take all remaining elements.
407 */
408template <class T>
409inline
410constexpr span<T>
411span<T>::subspan (size_type offs, size_type n /*= dynamic_extent*/) noexcept
412{
413 assert (offs <= size());
414 if (n == dynamic_extent)
415 n = size() - offs;
416 else {
417 assert (n <= size());
418 assert (offs + n <= size());
419 }
420 return span (m_ptr + offs, n);
421}
422
423
424/**
425 * @brief Return a subspan.
426 * @param offs Starting element of the subspan.
427 * @param n Number of elements in the subspan.
428 * If defaulted, take all remaining elements.
429 */
430template <class T>
431inline
432constexpr span<const T>
433span<T>::subspan (size_type offs, size_type n /*= dynamic_extent*/) const noexcept
434{
435 assert (offs <= size());
436 if (n == dynamic_extent)
437 n = size() - offs;
438 else {
439 assert (n <= size());
440 assert (offs + n <= size());
441 }
442 const T* ptr = m_ptr;
443 return span<const T> (ptr + offs, n);
444}
445
446
447} // namespace CxxUtils