2 * Copyright (C) 2002-2024 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.
36 requires (valid_span_type_v<T, U>)
38 template <class U, typename>
41 span<T>::span (U* ptr, size_type sz)
45 // cppcheck-suppress missingReturn; false positive
50 * @brief Constructor from start and end.
51 * @param beg Start of the span.
52 * @param end One past the end of the span.
57 requires (valid_span_type_v<T, U>)
59 template <class U, typename>
62 span<T>::span (U* beg, U* end)
66 // cppcheck-suppress missingReturn; false positive
71 * @brief Constructor from another span.
72 * @param other Span to copy from.
77 requires (valid_span_type_v<T, U>)
79 template <class U, typename>
82 span<T>::span (const span<U>& other)
83 : m_ptr (other.begin()),
90 * @brief Return the size of the span.
94 constexpr typename span<T>::size_type
95 span<T>::size() const noexcept
102 * @brief Return the size of contents of the span, in bytes.
106 constexpr typename span<T>::size_type
107 span<T>::size_bytes() const noexcept
109 return m_size * sizeof(element_type);
114 * @brief Test if the span is empty.
119 span<T>::empty() const noexcept
126 * @brief Return a reference to the first element in the span.
130 constexpr typename span<T>::reference
131 span<T>::front() noexcept
133 assert (m_ptr != nullptr);
139 * @brief Return a reference to the first element in the span.
143 constexpr typename span<T>::const_reference
144 span<T>::front() const noexcept
146 assert (m_ptr != nullptr);
152 * @brief Return a reference to the last element in the span.
156 constexpr typename span<T>::reference
157 span<T>::back() noexcept
159 assert (m_ptr != nullptr);
160 return *(m_ptr + m_size-1);
165 * @brief Return a reference to the last element in the span.
169 constexpr typename span<T>::const_reference
170 span<T>::back() const noexcept
172 assert (m_ptr != nullptr);
173 return *(m_ptr + m_size-1);
178 * @brief Return a reference to the i-th element in the span.
179 * @param i Index of the element to return.
183 constexpr typename span<T>::reference
184 span<T>::operator[] (size_type i) noexcept
192 * @brief Return a reference to the i-th element in the span.
193 * @param i Index of the element to return.
197 constexpr typename span<T>::const_reference
198 span<T>::operator[] (size_type i) const noexcept
206 * @brief Return a reference to the i-th element in the span (bounds-checked).
207 * @param i Index of the element to return.
211 constexpr typename span<T>::reference
212 span<T>::at (size_type i)
214 if (i >= m_size) throw std::out_of_range ("CxxUtils::span::at");
220 * @brief Return a reference to the i-th element in the span (bounds-checked).
221 * @param i Index of the element to return.
225 constexpr typename span<T>::const_reference
226 span<T>::at (size_type i) const
228 if (i >= m_size) throw std::out_of_range ("CxxUtils::span::at");
234 * @brief Return a pointer to the start of the span.
238 constexpr typename span<T>::pointer
239 span<T>::data() noexcept
246 * @brief Return a pointer to the start of the span.
250 constexpr typename span<T>::const_pointer
251 span<T>::data() const noexcept
258 * @brief Return a begin iterator.
262 constexpr typename span<T>::iterator
263 span<T>::begin() noexcept
270 * @brief Return a begin iterator.
274 constexpr typename span<T>::const_iterator
275 span<T>::begin() const noexcept
282 * @brief Return an end iterator.
286 constexpr typename span<T>::iterator
287 span<T>::end() noexcept
289 return m_ptr + m_size;
294 * @brief Return an end iterator.
298 constexpr typename span<T>::const_iterator
299 span<T>::end() const noexcept
301 return m_ptr + m_size;
306 * @brief Return a begin reverse iterator.
310 constexpr typename span<T>::reverse_iterator
311 span<T>::rbegin() noexcept
313 return reverse_iterator (end());
318 * @brief Return a begin reverse iterator.
322 constexpr typename span<T>::const_reverse_iterator
323 span<T>::rbegin() const noexcept
325 return const_reverse_iterator (end());
330 * @brief Return an end reverse iterator.
334 constexpr typename span<T>::reverse_iterator
335 span<T>::rend() noexcept
337 return reverse_iterator (begin());
342 * @brief Return an end reverse iterator.
346 constexpr typename span<T>::const_reverse_iterator
347 span<T>::rend() const noexcept
349 return const_reverse_iterator (begin());
354 * @brief Return a subspan from the start.
355 * @param n Number of elements in the subspan.
360 span<T>::first (size_type n) noexcept
362 assert (n <= size());
363 return span (m_ptr, n);
368 * @brief Return a subspan from the start.
369 * @param n Number of elements in the subspan.
373 constexpr span<const T>
374 span<T>::first (size_type n) const noexcept
376 assert (n <= size());
377 const T* ptr = m_ptr;
378 return span<const T> (ptr, n);
383 * @brief Return a subspan from the end.
384 * @param n Number of elements in the subspan.
389 span<T>::last (size_type n) noexcept
391 assert (n <= size());
392 return span (m_ptr + (size() - n), n);
397 * @brief Return a subspan from the end.
398 * @param n Number of elements in the subspan.
402 constexpr span<const T>
403 span<T>::last (size_type n) const noexcept
405 assert (n <= size());
406 const T* ptr = m_ptr;
407 return span<const T> (ptr + (size() - n), n);
412 * @brief Return a subspan.
413 * @param offs Starting element of the subspan.
414 * @param n Number of elements in the subspan.
415 * If defaulted, take all remaining elements.
420 span<T>::subspan (size_type offs, size_type n /*= dynamic_extent*/) noexcept
422 assert (offs <= size());
423 if (n == dynamic_extent)
426 assert (n <= size());
427 assert (offs + n <= size());
429 return span (m_ptr + offs, n);
434 * @brief Return a subspan.
435 * @param offs Starting element of the subspan.
436 * @param n Number of elements in the subspan.
437 * If defaulted, take all remaining elements.
441 constexpr span<const T>
442 span<T>::subspan (size_type offs, size_type n /*= dynamic_extent*/) const noexcept
444 assert (offs <= size());
445 if (n == dynamic_extent)
448 assert (n <= size());
449 assert (offs + n <= size());
451 const T* ptr = m_ptr;
452 return span<const T> (ptr + offs, n);
456 } // namespace CxxUtils