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