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.
16 * @brief Default constructor.
17 * Makes an empty span.
29 * @brief Constructor from start and length.
30 * @param ptr Start of the span.
31 * @param sz Length of the span.
35 requires (valid_span_type_v<T, U>)
37 span<T>::span (U* ptr, size_type sz)
41 //cppcheck-suppress missingReturn
46 * @brief Constructor from start and end.
47 * @param beg Start of the span.
48 * @param end One past the end of the span.
52 requires (valid_span_type_v<T, U>)
54 span<T>::span (U* beg, U* end)
58 //cppcheck-suppress missingReturn
63 * @brief Constructor from another span.
64 * @param other Span to copy from.
68 requires (valid_span_type_v<T, U>)
70 span<T>::span (const span<U>& other)
71 : m_ptr (other.begin()),
78 * @brief Return the size of the span.
82 constexpr typename span<T>::size_type
83 span<T>::size() const noexcept
90 * @brief Return the size of contents of the span, in bytes.
94 constexpr typename span<T>::size_type
95 span<T>::size_bytes() const noexcept
97 return m_size * sizeof(element_type);
102 * @brief Test if the span is empty.
107 span<T>::empty() const noexcept
114 * @brief Return a reference to the first element in the span.
118 constexpr typename span<T>::reference
119 span<T>::front() noexcept
121 assert (m_ptr != nullptr);
127 * @brief Return a reference to the first element in the span.
131 constexpr typename span<T>::const_reference
132 span<T>::front() const noexcept
134 assert (m_ptr != nullptr);
140 * @brief Return a reference to the last element in the span.
144 constexpr typename span<T>::reference
145 span<T>::back() noexcept
147 assert (m_ptr != nullptr);
148 return *(m_ptr + m_size-1);
153 * @brief Return a reference to the last element in the span.
157 constexpr typename span<T>::const_reference
158 span<T>::back() const noexcept
160 assert (m_ptr != nullptr);
161 return *(m_ptr + m_size-1);
166 * @brief Return a reference to the i-th element in the span.
167 * @param i Index of the element to return.
171 constexpr typename span<T>::reference
172 span<T>::operator[] (size_type i) noexcept
180 * @brief Return a reference to the i-th element in the span.
181 * @param i Index of the element to return.
185 constexpr typename span<T>::const_reference
186 span<T>::operator[] (size_type i) const noexcept
194 * @brief Return a reference to the i-th element in the span (bounds-checked).
195 * @param i Index of the element to return.
199 constexpr typename span<T>::reference
200 span<T>::at (size_type i)
202 if (i >= m_size) throw std::out_of_range ("CxxUtils::span::at");
208 * @brief Return a reference to the i-th element in the span (bounds-checked).
209 * @param i Index of the element to return.
213 constexpr typename span<T>::const_reference
214 span<T>::at (size_type i) const
216 if (i >= m_size) throw std::out_of_range ("CxxUtils::span::at");
222 * @brief Return a pointer to the start of the span.
226 constexpr typename span<T>::pointer
227 span<T>::data() noexcept
234 * @brief Return a pointer to the start of the span.
238 constexpr typename span<T>::const_pointer
239 span<T>::data() const noexcept
246 * @brief Return a begin iterator.
250 constexpr typename span<T>::iterator
251 span<T>::begin() noexcept
258 * @brief Return a begin iterator.
262 constexpr typename span<T>::const_iterator
263 span<T>::begin() const noexcept
270 * @brief Return an end iterator.
274 constexpr typename span<T>::iterator
275 span<T>::end() noexcept
277 return m_ptr + m_size;
282 * @brief Return an end iterator.
286 constexpr typename span<T>::const_iterator
287 span<T>::end() const noexcept
289 return m_ptr + m_size;
294 * @brief Return a begin reverse iterator.
298 constexpr typename span<T>::reverse_iterator
299 span<T>::rbegin() noexcept
301 return reverse_iterator (end());
306 * @brief Return a begin reverse iterator.
310 constexpr typename span<T>::const_reverse_iterator
311 span<T>::rbegin() const noexcept
313 return const_reverse_iterator (end());
318 * @brief Return an end reverse iterator.
322 constexpr typename span<T>::reverse_iterator
323 span<T>::rend() noexcept
325 return reverse_iterator (begin());
330 * @brief Return an end reverse iterator.
334 constexpr typename span<T>::const_reverse_iterator
335 span<T>::rend() const noexcept
337 return const_reverse_iterator (begin());
342 * @brief Return a subspan from the start.
343 * @param n Number of elements in the subspan.
348 span<T>::first (size_type n) noexcept
350 assert (n <= size());
351 return span (m_ptr, n);
356 * @brief Return a subspan from the start.
357 * @param n Number of elements in the subspan.
361 constexpr span<const T>
362 span<T>::first (size_type n) const noexcept
364 assert (n <= size());
365 const T* ptr = m_ptr;
366 return span<const T> (ptr, n);
371 * @brief Return a subspan from the end.
372 * @param n Number of elements in the subspan.
377 span<T>::last (size_type n) noexcept
379 assert (n <= size());
380 return span (m_ptr + (size() - n), n);
385 * @brief Return a subspan from the end.
386 * @param n Number of elements in the subspan.
390 constexpr span<const T>
391 span<T>::last (size_type n) const noexcept
393 assert (n <= size());
394 const T* ptr = m_ptr;
395 return span<const T> (ptr + (size() - n), n);
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.
408 span<T>::subspan (size_type offs, size_type n /*= dynamic_extent*/) noexcept
410 assert (offs <= size());
411 if (n == dynamic_extent)
414 assert (n <= size());
415 assert (offs + n <= size());
417 return span (m_ptr + offs, n);
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.
429 constexpr span<const T>
430 span<T>::subspan (size_type offs, size_type n /*= dynamic_extent*/) const noexcept
432 assert (offs <= size());
433 if (n == dynamic_extent)
436 assert (n <= size());
437 assert (offs + n <= size());
439 const T* ptr = m_ptr;
440 return span<const T> (ptr + offs, n);
444 } // namespace CxxUtils