2 * Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration.
5 * @file CxxUtils/span.icc
6 * @author scott snyder <snyder@bnl.gov>
8 * @brief Simplified version of the C++20 std::span.
12 #include "CxxUtils/throw_out_of_range.h"
19 * @brief Default constructor.
20 * Makes an empty span.
32 * @brief Constructor from start and length.
33 * @param ptr Start of the span.
34 * @param sz Length of the span.
38 requires (valid_span_type_v<T, U>)
40 span<T>::span (U* ptr, size_type sz)
44 //cppcheck-suppress missingReturn
49 * @brief Constructor from start and end.
50 * @param beg Start of the span.
51 * @param end One past the end of the span.
55 requires (valid_span_type_v<T, U>)
57 span<T>::span (U* beg, U* end)
61 //cppcheck-suppress missingReturn
66 * @brief Constructor from another span.
67 * @param other Span to copy from.
71 requires (valid_span_type_v<T, U>)
73 span<T>::span (const span<U>& other)
74 : m_ptr (other.begin()),
81 * @brief Return the size of the span.
85 constexpr typename span<T>::size_type
86 span<T>::size() const noexcept
93 * @brief Return the size of contents of the span, in bytes.
97 constexpr typename span<T>::size_type
98 span<T>::size_bytes() const noexcept
100 return m_size * sizeof(element_type);
105 * @brief Test if the span is empty.
110 span<T>::empty() const noexcept
117 * @brief Return a reference to the first element in the span.
121 constexpr typename span<T>::reference
122 span<T>::front() noexcept
124 assert (m_ptr != nullptr);
130 * @brief Return a reference to the first element in the span.
134 constexpr typename span<T>::const_reference
135 span<T>::front() const noexcept
137 assert (m_ptr != nullptr);
143 * @brief Return a reference to the last element in the span.
147 constexpr typename span<T>::reference
148 span<T>::back() noexcept
150 assert (m_ptr != nullptr);
151 return *(m_ptr + m_size-1);
156 * @brief Return a reference to the last element in the span.
160 constexpr typename span<T>::const_reference
161 span<T>::back() const noexcept
163 assert (m_ptr != nullptr);
164 return *(m_ptr + m_size-1);
169 * @brief Return a reference to the i-th element in the span.
170 * @param i Index of the element to return.
174 constexpr typename span<T>::reference
175 span<T>::operator[] (size_type i) noexcept
183 * @brief Return a reference to the i-th element in the span.
184 * @param i Index of the element to return.
188 constexpr typename span<T>::const_reference
189 span<T>::operator[] (size_type i) const noexcept
197 * @brief Return a reference to the i-th element in the span (bounds-checked).
198 * @param i Index of the element to return.
202 constexpr typename span<T>::reference
203 span<T>::at (size_type i)
205 if (i >= m_size) throw_out_of_range (__PRETTY_FUNCTION__, i, m_size, this);
211 * @brief Return a reference to the i-th element in the span (bounds-checked).
212 * @param i Index of the element to return.
216 constexpr typename span<T>::const_reference
217 span<T>::at (size_type i) const
219 if (i >= m_size) throw_out_of_range (__PRETTY_FUNCTION__, i, m_size, this);
225 * @brief Return a pointer to the start of the span.
229 constexpr typename span<T>::pointer
230 span<T>::data() noexcept
237 * @brief Return a pointer to the start of the span.
241 constexpr typename span<T>::const_pointer
242 span<T>::data() const noexcept
249 * @brief Return a begin iterator.
253 constexpr typename span<T>::iterator
254 span<T>::begin() noexcept
261 * @brief Return a begin iterator.
265 constexpr typename span<T>::const_iterator
266 span<T>::begin() const noexcept
273 * @brief Return an end iterator.
277 constexpr typename span<T>::iterator
278 span<T>::end() noexcept
280 return m_ptr + m_size;
285 * @brief Return an end iterator.
289 constexpr typename span<T>::const_iterator
290 span<T>::end() const noexcept
292 return m_ptr + m_size;
297 * @brief Return a begin reverse iterator.
301 constexpr typename span<T>::reverse_iterator
302 span<T>::rbegin() noexcept
304 return reverse_iterator (end());
309 * @brief Return a begin reverse iterator.
313 constexpr typename span<T>::const_reverse_iterator
314 span<T>::rbegin() const noexcept
316 return const_reverse_iterator (end());
321 * @brief Return an end reverse iterator.
325 constexpr typename span<T>::reverse_iterator
326 span<T>::rend() noexcept
328 return reverse_iterator (begin());
333 * @brief Return an end reverse iterator.
337 constexpr typename span<T>::const_reverse_iterator
338 span<T>::rend() const noexcept
340 return const_reverse_iterator (begin());
345 * @brief Return a subspan from the start.
346 * @param n Number of elements in the subspan.
351 span<T>::first (size_type n) noexcept
353 assert (n <= size());
354 return span (m_ptr, n);
359 * @brief Return a subspan from the start.
360 * @param n Number of elements in the subspan.
364 constexpr span<const T>
365 span<T>::first (size_type n) const noexcept
367 assert (n <= size());
368 const T* ptr = m_ptr;
369 return span<const T> (ptr, n);
374 * @brief Return a subspan from the end.
375 * @param n Number of elements in the subspan.
380 span<T>::last (size_type n) noexcept
382 assert (n <= size());
383 return span (m_ptr + (size() - n), n);
388 * @brief Return a subspan from the end.
389 * @param n Number of elements in the subspan.
393 constexpr span<const T>
394 span<T>::last (size_type n) const noexcept
396 assert (n <= size());
397 const T* ptr = m_ptr;
398 return span<const T> (ptr + (size() - n), n);
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.
411 span<T>::subspan (size_type offs, size_type n /*= dynamic_extent*/) noexcept
413 assert (offs <= size());
414 if (n == dynamic_extent)
417 assert (n <= size());
418 assert (offs + n <= size());
420 return span (m_ptr + offs, n);
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.
432 constexpr span<const T>
433 span<T>::subspan (size_type offs, size_type n /*= dynamic_extent*/) const noexcept
435 assert (offs <= size());
436 if (n == dynamic_extent)
439 assert (n <= size());
440 assert (offs + n <= size());
442 const T* ptr = m_ptr;
443 return span<const T> (ptr + offs, n);
447 } // namespace CxxUtils