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.
38requires (valid_span_type_v<T, U>)
40span<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.
55requires (valid_span_type_v<T, U>)
57span<T>::span (U* beg, U* end)
61//cppcheck-suppress missingReturn
66 * @brief Constructor from another span.
67 * @param other Span to copy from.
71requires (valid_span_type_v<T, U>)
73span<T>::span (const span<U>& other)
74 : m_ptr (other.begin()),
81 * @brief Return the size of the span.
85constexpr typename span<T>::size_type
86span<T>::size() const noexcept
93 * @brief Return the size of contents of the span, in bytes.
97constexpr typename span<T>::size_type
98span<T>::size_bytes() const noexcept
100 return m_size * sizeof(element_type);
105 * @brief Test if the span is empty.
110span<T>::empty() const noexcept
117 * @brief Return a reference to the first element in the span.
121constexpr typename span<T>::reference
122span<T>::front() noexcept
124 assert (m_ptr != nullptr);
130 * @brief Return a reference to the first element in the span.
134constexpr typename span<T>::const_reference
135span<T>::front() const noexcept
137 assert (m_ptr != nullptr);
143 * @brief Return a reference to the last element in the span.
147constexpr typename span<T>::reference
148span<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.
160constexpr typename span<T>::const_reference
161span<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.
174constexpr typename span<T>::reference
175span<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.
188constexpr typename span<T>::const_reference
189span<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.
202constexpr typename span<T>::reference
203span<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.
216constexpr typename span<T>::const_reference
217span<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.
229constexpr typename span<T>::pointer
230span<T>::data() noexcept
237 * @brief Return a pointer to the start of the span.
241constexpr typename span<T>::const_pointer
242span<T>::data() const noexcept
249 * @brief Return a begin iterator.
253constexpr typename span<T>::iterator
254span<T>::begin() noexcept
261 * @brief Return a begin iterator.
265constexpr typename span<T>::const_iterator
266span<T>::begin() const noexcept
273 * @brief Return an end iterator.
277constexpr typename span<T>::iterator
278span<T>::end() noexcept
280 return m_ptr + m_size;
285 * @brief Return an end iterator.
289constexpr typename span<T>::const_iterator
290span<T>::end() const noexcept
292 return m_ptr + m_size;
297 * @brief Return a begin reverse iterator.
301constexpr typename span<T>::reverse_iterator
302span<T>::rbegin() noexcept
304 return reverse_iterator (end());
309 * @brief Return a begin reverse iterator.
313constexpr typename span<T>::const_reverse_iterator
314span<T>::rbegin() const noexcept
316 return const_reverse_iterator (end());
321 * @brief Return an end reverse iterator.
325constexpr typename span<T>::reverse_iterator
326span<T>::rend() noexcept
328 return reverse_iterator (begin());
333 * @brief Return an end reverse iterator.
337constexpr typename span<T>::const_reverse_iterator
338span<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.
351span<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.
364constexpr span<const T>
365span<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.
380span<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.
393constexpr span<const T>
394span<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.
411span<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.
432constexpr span<const T>
433span<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