Arene Base
Fundamental Utilities For Safety Critical C++
Loading...
Searching...
No Matches
span.hpp
Go to the documentation of this file.
1// Copyright 2024, Toyota Motor Corporation
2//
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4
5#ifndef INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_SPAN_SPAN_HPP_
6#define INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_SPAN_SPAN_HPP_
7
8// IWYU pragma: private, include "arene/base/span.hpp"
9// IWYU pragma: friend "(arene/base(?!/tests)|stdlib/include/stdlib_detail)/.*"
10
11// parasoft-begin-suppress AUTOSAR-A7_1_5-a-2 "Trailing return syntax permitted by A7-1-5 Permit #1 v1.0.0"
12
13// AUTOSAR exceptions:
14// A11-3-1: Friend declarations shall not be used
15// The span::iterator type declares the outer span type to be a friend so that
16// the constructor can be private, preventing user code constructing iterators
17// with pointers outside the span.
18// The span::iterator non-member operator overloads are declared to be friends
19// to allow them to be defined within the class. This ensures that they are only
20// considered for overload resolution and name lookup when at least one of the
21// parameters is an iterator, and avoids the namespace-scope template overloads
22// that would otherwise be required.
23//
24// M5-0-15: Array indexing shall be the only form of pointer arithmetic.
25// span inherently refers to an array of elements. Pointer arithmetic is only
26// used to adjust the pointer within that array, as covered by M5-0-16 and
27// M5-0-17, unless iterators are incremented unchecked.
28//
29// A5-0-4: Pointer arithmetic shall not be used with pointers to non-final
30// classes.
31// The span constructors do not allow constructing a span<Base> from a
32// Derived*, so pointer arithmetic is safe unless the user does an explicit
33// cast.
34
35// parasoft-begin-suppress AUTOSAR-A16_2_2-a-2 "Arene Base aggregate headers"
36#include "arene/base/byte/byte.hpp"
37#include "arene/base/compiler_support/attributes.hpp"
38#include "arene/base/constraints/constraints.hpp"
39#include "arene/base/constraints/substitution_succeeds.hpp"
40#include "arene/base/contracts/contract.hpp"
41#include "arene/base/detail/dynamic_extent.hpp"
42#include "arene/base/detail/wrapped_iterator.hpp" // IWYU pragma: keep
43#include "arene/base/iterator/next.hpp"
44#include "arene/base/iterator/reverse_iterator.hpp"
45#include "arene/base/stdlib_choice/conditional.hpp"
46#include "arene/base/stdlib_choice/cstddef.hpp"
47#include "arene/base/stdlib_choice/declval.hpp"
48#include "arene/base/stdlib_choice/enable_if.hpp"
49#include "arene/base/stdlib_choice/integral_constant.hpp"
50#include "arene/base/stdlib_choice/is_const.hpp"
51#include "arene/base/stdlib_choice/numeric_limits.hpp"
52#include "arene/base/stdlib_choice/remove_cv.hpp"
53#include "arene/base/stdlib_choice/remove_reference.hpp"
54#include "arene/base/stdlib_choice/tuple_size.hpp"
55#include "arene/base/type_traits/is_array_convertible.hpp"
56#include "arene/base/type_traits/remove_cvref.hpp"
57// parasoft-end-suppress AUTOSAR-A16_2_2-a-2
58
59// parasoft-begin-suppress CERT_C-EXP37-a-3 "False positive: The rule does not mention naming all parameters"
60
61namespace arene {
62namespace base {
63
64// IWYU pragma: begin_keep
65template <typename T, std::size_t Extent = dynamic_extent>
66class span;
67// IWYU pragma: end_keep
68
69namespace span_detail {
70
71/// @brief Helper function for gcc8 to get @c dynamic_extent
72/// @return The value of @c dynamic_extent
73constexpr auto get_dynamic_extent() noexcept -> std::size_t { return dynamic_extent; }
74
75// parasoft-begin-suppress AUTOSAR-A11_3_1-a-2 "Passkey idiom permitted by A11-3-1 Permit #1"
76/// @brief A passkey type to restrict constructing span's iterator to span.
77class span_iter_passkey {
78 private:
79 /// @brief Default-ctor is explicit to prevent construction via {}.
80 explicit span_iter_passkey() noexcept = default;
81 template <typename T, std::size_t Extent>
82 friend class ::arene::base::span;
83};
84// parasoft-end-suppress AUTOSAR-A11_3_1-a-2
85
86/// @brief Validate the extent of a source span given a target span
87/// @param my_extent The extent of the source span
88/// @param target_extent The extent of the target span
89/// @return @c true If @c my_extent==dynamic_extent or if @c my_extent==target_extent .
90/// @c false Otherwise.
91constexpr auto is_valid_source_extent(std::size_t const my_extent, std::size_t const target_extent) noexcept -> bool {
92 return (my_extent == dynamic_extent) || (my_extent == target_extent);
93}
94
95/// @brief Validate the size of a dynamic span
96/// @param my_extent The extent of the source span
97/// @param target_size The target size to check.
98/// @param max_size The maximum size to allow.
99/// @return @c true If @c is_valid_source_extent(my_extent,target_size) and @c target_size<=max_size .
100/// @c false Otherwise.
101constexpr auto
102is_valid_runtime_size(std::size_t const my_extent, std::size_t const target_size, std::size_t const max_size) noexcept
103 -> bool {
104 return is_valid_source_extent(my_extent, target_size) && (target_size <= max_size);
105}
106
107/// @brief Check if an extent is dynamic
108/// @param my_extent The extent to check
109/// @return @c true If @c my_extent is @c dynamic_extent
110/// @c false Otherwise.
111constexpr auto is_dynamic_extent(std::size_t const my_extent) noexcept -> bool { return my_extent == dynamic_extent; }
112
113/// @brief Computes the extent for a subspan of an original span with a given extent.
114/// Specialization for @c Count!=dynamic_extent .
115/// @tparam Extent The extent of the original span.
116/// @tparam Offset The offset into the original span to slice.
117/// @tparam Count The number of elements in the subspan.
118/// @return std::size_t @c Count
119template <
120 std::size_t Extent,
121 std::size_t Offset,
122 std::size_t Count,
123 constraints<std::enable_if_t<!is_dynamic_extent(Count)>> = nullptr>
124constexpr auto extent_for_subspan() -> std::size_t {
125 return Count;
126}
127/// @brief Computes the extent for a subspan of an original span with a given extent.
128/// Specialization for @c Count==dynamic_extent and @c Extent!=dynamic_extent.
129/// @tparam Extent The extent of the original span.
130/// @tparam Offset The offset into the original span to slice.
131/// @tparam Count The number of elements in the subspan.
132/// @return std::size_t @c Extent-Offset .
133template <
134 std::size_t Extent,
135 std::size_t Offset,
136 std::size_t Count,
137 constraints<std::enable_if_t<!is_dynamic_extent(Extent)>, std::enable_if_t<is_dynamic_extent(Count)>> = nullptr>
138constexpr auto extent_for_subspan() -> std::size_t {
139 return Extent - Offset;
140}
141/// @brief Computes the extent for a subspan of an original span with a given extent.
142/// Specialization for @c Count==dynamic_extent and @c Extent==dynamic_extent.
143/// @tparam Extent The extent of the original span.
144/// @tparam Offset The offset into the original span to slice.
145/// @tparam Count The number of elements in the subspan.
146/// @return std::size_t @c dynamic_extent .
147template <
148 std::size_t Extent,
149 std::size_t Offset,
150 std::size_t Count,
151 constraints<std::enable_if_t<is_dynamic_extent(Extent)>, std::enable_if_t<is_dynamic_extent(Count)>> = nullptr>
152constexpr auto extent_for_subspan() -> std::size_t {
153 return dynamic_extent;
154}
155
156/// @brief Trait to determine if a type has a member function @c data()
157/// @tparam T The type to test against
158template <typename T>
159using use_member_data = decltype(std::declval<T>().data());
160
161/// @brief Trait to determine if a type has a member function @c data()
162/// @tparam T The type to test against
163/// @return true if @c T has a member function @c data(), false otherwise
164template <typename T>
165constexpr bool has_member_data_v = substitution_succeeds<use_member_data, T>;
166
167/// @brief Trait to determine if a type has a @c std::tuple_size specialization.
168/// @tparam T The type to test against
169template <typename T>
170using use_tuple_size = decltype(std::tuple_size<T>::value);
171
172/// @brief Trait to determine if a type has a @c std::tuple_size specialization.
173/// @tparam T The type to test against
174/// @return true if @c T has a @c std::tuple_size specialization, false otherwise
175template <typename T>
176constexpr bool has_tuple_size_v = substitution_succeeds<use_tuple_size, T>;
177
178/// @brief A constant that is true if and only if T is an instantiation of arene::base::span
179template <typename T>
180extern constexpr bool is_span = false;
181
182/// @brief A constant that is true if and only if T is an instantiation of arene::base::Span
183template <typename T, std::size_t Extent>
184extern constexpr bool is_span<span<T, Extent>> = true;
185
186/// @brief Special tag type to use for constructing Spans
187struct span_construction_tag {};
188
189/// @brief A base class for Span to prevent default construction for fixed-size non-empty Spans
190template <std::size_t Extent>
191class span_base_fixed_size_non_empty {
192 public:
193 /// @brief Construct with a given run-time size
194 constexpr explicit span_base_fixed_size_non_empty(span_construction_tag, std::size_t) noexcept {}
195
196 // parasoft-begin-suppress AUTOSAR-M11_0_1-a-2 "False positive: this is not 'member data', it is a public property"
197 /// @brief Returns the number of elements in the span
198 /// The size is fixed to the Extent
199 /// @return The number of elements in the span
200 static constexpr std::integral_constant<std::size_t, Extent> size{};
201 // parasoft-end-suppress AUTOSAR-M11_0_1-a-2
202
203 protected:
204 /// @brief protected destructor
205 ~span_base_fixed_size_non_empty() = default;
206 /// @brief protected copy constructor
207 /// @param other The source object
208 span_base_fixed_size_non_empty(span_base_fixed_size_non_empty const& other) = default;
209 /// @brief protected move constructor
210 /// @param other The source object
211 span_base_fixed_size_non_empty(span_base_fixed_size_non_empty&& other) noexcept = default;
212 /// @brief protected copy assignment
213 /// @param other The source object
214 auto operator=(span_base_fixed_size_non_empty const& other) & -> span_base_fixed_size_non_empty& = default;
215 /// @brief protected move assignment
216 /// @param other The source object
217 auto operator=(span_base_fixed_size_non_empty&& other) & noexcept -> span_base_fixed_size_non_empty& = default;
218};
219
220template <std::size_t Extent>
221constexpr std::integral_constant<std::size_t, Extent> span_base_fixed_size_non_empty<Extent>::size;
222
223/// @brief A base class for Span for a fixed-sized Span with an Extent of 0
224class span_base_fixed_size_empty {
225 public:
226 /// @brief The default constructor is trivial
227 constexpr span_base_fixed_size_empty() noexcept = default;
228
229 /// @brief Construct with a given run-time size
230 constexpr explicit span_base_fixed_size_empty(span_construction_tag, std::size_t) noexcept {}
231
232 // parasoft-begin-suppress AUTOSAR-M11_0_1-a-2 "False positive: this is not 'member data', it is a public property"
233 /// @brief Returns the number of elements in the span
234 /// The size is fixed at zero
235 /// @return 0
236 static constexpr std::integral_constant<std::size_t, 0> size{};
237 // parasoft-end-suppress AUTOSAR-M11_0_1-a-2
238
239 protected:
240 /// @brief protected destructor
241 ~span_base_fixed_size_empty() = default;
242 /// @brief protected copy constructor
243 /// @param other The source object
244 span_base_fixed_size_empty(span_base_fixed_size_empty const& other) = default;
245 /// @brief protected move constructor
246 /// @param other The source object
247 span_base_fixed_size_empty(span_base_fixed_size_empty&& other) = default;
248 /// @brief protected copy assignment
249 /// @param other The source object
250 auto operator=(span_base_fixed_size_empty const& other) & -> span_base_fixed_size_empty& = default;
251 /// @brief protected move assignment
252 /// @param other The source object
253 auto operator=(span_base_fixed_size_empty&& other) & -> span_base_fixed_size_empty& = default;
254};
255
256/// @brief A base class for Span for a dynamically-sized span
257class span_base_dynamic_size {
258 protected:
259 /// @brief The default constructor sets the size to 0
260 constexpr span_base_dynamic_size() noexcept = default;
261 /// @brief Construct with a given run-time size
262 /// @param span_size The size of the span
263 constexpr explicit span_base_dynamic_size(span_construction_tag, std::size_t const span_size) noexcept
264 : dynamic_size_(span_size) {}
265
266 /// @brief Returns the number of elements in the span
267 /// @return The number of elements in the span
268 ARENE_NODISCARD constexpr auto size() const noexcept -> std::size_t { return this->dynamic_size_; }
269
270 /// @brief protected destructor
271 ~span_base_dynamic_size() = default;
272 /// @brief protected copy constructor
273 /// @param other The source object
274 span_base_dynamic_size(span_base_dynamic_size const& other) = default;
275 /// @brief protected move constructor
276 /// @param other The source object
277 span_base_dynamic_size(span_base_dynamic_size&& other) = default;
278 /// @brief protected copy assignment
279 /// @param other The source object
280 auto operator=(span_base_dynamic_size const& other) & -> span_base_dynamic_size& = default;
281 /// @brief protected move assignment
282 /// @param other The source object
283 auto operator=(span_base_dynamic_size&& other) & -> span_base_dynamic_size& = default;
284
285 private:
286 /// @brief The size of the span
287 std::size_t dynamic_size_{0U};
288};
289
290/// @brief Select instantiation of span_base with/without default construction
291template <std::size_t Extent>
292using span_base = typename std::conditional<
293 is_dynamic_extent(Extent),
294 span_base_dynamic_size,
295 typename std::conditional<Extent == 0, span_base_fixed_size_empty, span_base_fixed_size_non_empty<Extent>>::type>::
296 type;
297
298} // namespace span_detail
299
300// parasoft-begin-suppress AUTOSAR-A13_5_1-a-2 "False positive: no non-const overload"
301/// @brief A backport of @c std::span for C++14. Provides a view over a contiguous range of elements of type T.
302///
303/// @tparam T The type of the element the span views
304/// @tparam Extent The size of the span. If set to @c arene::base::dynamic_extent , then the Size of the range is
305/// determined at runtime. Otherwise the range of elements is exactly @c Extent elements.
306template <typename T, std::size_t Extent>
307class span : span_detail::span_base<Extent> {
308 // parasoft-begin-suppress AUTOSAR-A2_10_1-e "False positive: These identifiers do not hide anything"
309 /// @brief The base class for default construction
310 using base = span_detail::span_base<Extent>;
311
312 // parasoft-begin-suppress AUTOSAR-M0_1_3-c "False positive: data_ptr_ and max_extent are both used"
313 /// @brief The start of the data
314 T* data_ptr_{nullptr};
315
316 /// @brief The max extent of the span
317 static constexpr std::size_t max_extent{
318 static_cast<std::size_t>(static_cast<std::size_t>(std::numeric_limits<std::ptrdiff_t>::max()) / sizeof(T))
319 };
320 // parasoft-end-suppress AUTOSAR-M0_1_3-c
321
322 /// @brief Check if Span is dynamic size or Extent is valid for fixed size span
323 static_assert((Extent == dynamic_extent) || Extent <= max_extent, "span extent exceeds its max value");
324
325 /// @brief Validate the extent of a source span given the target span
326 /// @tparam target_extent The extent of the source span
327 /// @return bool Equivalent to @c span_detail::is_valid_source_extent(Extent,TargetExtent) .
328 template <std::size_t TargetExtent>
329 static constexpr bool is_valid_source_extent_v{span_detail::is_valid_source_extent(Extent, TargetExtent)};
330
331 /// @brief Validate the size of a dynamic span
332 /// @param target_extent The size of the dynamic span
333 /// @return @c true The size is valid
334 /// @c false The size is invalid
335 static constexpr auto is_valid_runtime_size(std::size_t target_extent) noexcept -> bool {
336 return span_detail::is_valid_runtime_size(Extent, target_extent, max_extent);
337 }
338
339 /// @brief Tag type for a the pre-checked size constructor
340 class pre_checked_size {
341 public:
342 /// @brief Default construction requires naming the type
343 constexpr explicit pre_checked_size() noexcept = default;
344 };
345 // parasoft-end-suppress AUTOSAR-A2_10_1-e
346
347 /// @brief Construct with the specified data and size.
348 ///
349 /// @param data_pointer The data from which to construct the span.
350 /// @param data_size The size of the data span to construct.
351 /// @post @c size()==data_size .
352 /// @post @c data()=data_pointer .
353 /// @pre @c data_pointer+data_size must be in the valid range of @c data_pointer , else behavior is undefined.
354 /// @pre @c data_size must satisfy @c is_valid_runtime_size else @c ARENE_PRECONDITION violation.
355 // NOLINTNEXTLINE(readability-non-const-parameter)
356 constexpr span(pre_checked_size, T* data_pointer, std::size_t data_size) noexcept
357 : base(span_detail::span_construction_tag{}, data_size),
358 data_ptr_(data_pointer) {}
359
360 public:
361 // parasoft-begin-suppress AUTOSAR-A2_10_1-e "False positive: these type aliases do not hide anything"
362 // alias size from the base class into the public space.
363 using base::size;
364
365 /// @brief The type of the elements of the span
366 using element_type = T;
367 /// @brief The type of the elements of the span without @c const or @c volatile qualification
368 using value_type = arene::base::remove_cvref_t<T>;
369 /// @brief The type of the size of the span
370 using size_type = std::size_t;
371 /// @brief The type of pointers to elements of the span
372 using pointer = T*;
373 /// @brief The type of pointers to @c const elements of the span
374 using const_pointer = T const*;
375 /// @brief The type of references to elements of the span
376 using reference = T&;
377 /// @brief The type of references to @c const elements of the span
378 using const_reference = T const&;
379 /// @brief The type of an iterator into the data viewed by the span.
380 using iterator = detail::wrapped_iterator<pointer, span_detail::span_iter_passkey>;
381 /// @brief The type of an iterator into a const view of the data viewed by the span.
382 using const_iterator = detail::wrapped_iterator<const_pointer, span_detail::span_iter_passkey>;
383 /// @brief The type of an iterator into a reversed view of the data viewed by the span.
384 using reverse_iterator = ::arene::base::reverse_iterator<iterator>;
385 /// @brief The type of an iterator into a const and reversed view of the data viewed by the span.
386 using const_reverse_iterator = ::arene::base::reverse_iterator<const_iterator>;
387 /// @brief The type used for obtaining differences between iterators of the span.
388 using difference_type = typename iterator::difference_type;
389
390 // parasoft-begin-suppress AUTOSAR-M11_0_1-a-2 "False positive: this is not 'member data', it is a public property"
391 /// @brief The Extent of the span --- either dynamic_extent, or the fixed size
392 static constexpr std::integral_constant<std::size_t, Extent> extent{};
393 // parasoft-end-suppress AUTOSAR-M11_0_1-a-2
394 // parasoft-end-suppress AUTOSAR-A2_10_1-e
395
396 /// @brief The size of the span as a signed integer
397 /// @return The size
398 ARENE_NODISCARD constexpr auto ssize() const noexcept -> difference_type {
399 return static_cast<difference_type>(this->size());
400 }
401
402 /// @brief Default-constructs an empty span. Only exists if @c Extent==dynamic_extent or @c Extent==0
403 /// @post @c size()==0 .
404 constexpr span() noexcept = default;
405
406 // parasoft-begin-suppress AUTOSAR-A13_3_1-a-2 "False positive: Constrained via SFINAE"
407 /// @brief default copy constructor
408 /// @param other The span being copied
409 constexpr span(span const& other) = default;
410 /// @brief default move constructor
411 /// @param other The span being moved
412 constexpr span(span&& other) = default;
413 // parasoft-end-suppress AUTOSAR-A13_3_1-a-2
414
415 /// @brief default copy assignment operator
416 /// @param other The span being copied
417 constexpr auto operator=(span const& other) -> span& = default;
418 /// @brief default move assignment operator
419 /// @param other The span being moved
420 constexpr auto operator=(span&& other) -> span& = default;
421
422 /// @brief default destructor
423 ~span() = default;
424
425 // parasoft-begin-suppress AUTOSAR-A12_1_1-a-2 "False positive: This constructor delegates to another, which does
426 // initialize the base class"
427 /// @brief Construct with the specified data and size. Prevents implicit derived-to-base pointer conversions on the
428 /// supplied data argument.
429 ///
430 /// @tparam U The type of the data to convert from.
431 /// @param data_pointer The data from which to construct the span.
432 /// @param data_size The size of the data span to construct.
433 /// @post @c size()==data_size .
434 /// @post @c data()=data_pointer .
435 /// @pre @c data_pointer+data_size must be in the valid range of @c data_pointer , else behavior is undefined.
436 /// @pre @c data_size must satisfy @c is_valid_runtime_size else @c ARENE_PRECONDITION violation.
437 template <typename U, constraints<std::enable_if_t<arene::base::is_array_convertible_v<U, T>>> = nullptr>
438 // NOLINTNEXTLINE(readability-non-const-parameter)
439 constexpr span(U* data_pointer, std::size_t data_size) noexcept
440 : span(pre_checked_size{}, data_pointer, data_size) {
441 ARENE_PRECONDITION(is_valid_runtime_size(data_size));
442 }
443 // parasoft-end-suppress AUTOSAR-A12_1_1-a-2
444
445 // parasoft-begin-suppress AUTOSAR-A13_3_1-a-2 "False positive: Constrained via SFINAE"
446 // parasoft-begin-suppress AUTOSAR-A12_1_1-a-2 "False positive: This constructor delegates to another, which does
447 // initialize the base class"
448 /// @brief Constructor from a c-array.
449 ///
450 /// @tparam N The size of the c-array. Must satisfy @c is_valid_source_extent .
451 /// @param array The array to construct the span from
452 /// @post @c size()==N .
453 /// @post @c data()==&array[0] .
454 template <std::size_t N, constraints<std::enable_if_t<is_valid_source_extent_v<N>>> = nullptr>
455 // NOLINTNEXTLINE(google-explicit-constructor,hicpp-explicit-conversions,cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
456 constexpr span(T (&array)[N]) noexcept
457 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay,hicpp-no-array-decay)
458 : span(pre_checked_size{}, array, N) {}
459 // parasoft-end-suppress AUTOSAR-A12_1_1-a-2
460
461 // parasoft-begin-suppress AUTOSAR-A12_1_1-a-2 "False positive: This constructor delegates to another, which does
462 // initialize the base class"
463 /// @brief Constructor from a @c std::array.
464 ///
465 /// @tparam ArrayLikeT The template-template type of the array-like container. A container is array-like if it has a
466 /// member function @c data() and @c std::tuple_size<ArrayLikeType<U,N>> is defined.
467 /// @tparam U The @c value_type of the array. Must satisfy @c is_array_convertible_v<U,T>
468 /// @tparam N The size of the array, Must satisfy @c is_valid_source_extent
469 /// @param array The array to construct the span from
470 /// @post @c size()==N .
471 /// @post @c data()==array.data() .
472 template <
473 template <typename U, std::size_t N>
474 class ArrayLikeT,
475 typename U,
476 std::size_t N,
477 constraints<
478 std::enable_if_t<span_detail::has_member_data_v<ArrayLikeT<U, N>>>,
479 std::enable_if_t<span_detail::has_tuple_size_v<ArrayLikeT<U, N>>>,
480 std::enable_if_t<std::tuple_size<ArrayLikeT<U, N>>::value == N>,
481 std::enable_if_t<arene::base::is_array_convertible_v<U, T>>,
482 std::enable_if_t<is_valid_source_extent_v<N>>> = nullptr>
483 // NOLINTNEXTLINE(google-explicit-constructor,hicpp-explicit-conversions)
484 constexpr span(ArrayLikeT<U, N>& array) noexcept
485 : span(pre_checked_size{}, array.data(), N) {}
486 // parasoft-end-suppress AUTOSAR-A12_1_1-a-2
487
488 // parasoft-begin-suppress AUTOSAR-A12_1_1-a-2 "False positive: This constructor delegates to another, which does
489 // initialize the base class"
490 /// @brief Constructor from a const @c std::array -like type.
491 ///
492 /// @tparam ArrayLikeT The template-template type of the array-like container. A container is array-like if it has a
493 /// member function @c data() and @c std::tuple_size<ArrayLikeType<U,N>> is defined.
494 /// @tparam U The @c value_type of the array. Must satisfy <c>is_array_convertible_v<const U, T> </c>
495 /// @tparam N The size of the array, Must satisfy @c is_valid_source_extent
496 /// @param array The array to construct the span from
497 /// @post @c size()==N .
498 /// @post @c data()==array.data() .
499 template <
500 template <typename U, std::size_t N>
501 class ArrayLikeT,
502 typename U,
503 std::size_t N,
504 constraints<
505 std::enable_if_t<span_detail::has_member_data_v<ArrayLikeT<U, N>>>,
506 std::enable_if_t<span_detail::has_tuple_size_v<ArrayLikeT<U, N>>>,
507 std::enable_if_t<std::tuple_size<ArrayLikeT<U, N>>::value == N>,
508 std::enable_if_t<std::is_const<T>::value && arene::base::is_array_convertible_v<U, T>>,
509 std::enable_if_t<is_valid_source_extent_v<N>>> = nullptr>
510 // NOLINTNEXTLINE(google-explicit-constructor,hicpp-explicit-conversions)
511 constexpr span(ArrayLikeT<U, N> const& array) noexcept
512 : span(pre_checked_size{}, array.data(), N) {}
513 // parasoft-end-suppress AUTOSAR-A12_1_1-a-2
514
515 // parasoft-begin-suppress AUTOSAR-A12_1_1-a-2 "False positive: This constructor delegates to another, which does
516 // initialize the base class"
517 // parasoft-begin-suppress AUTOSAR-A8_4_6-a-2 "Span has reference semantics: forwarding not appropriate"
518 // parasoft-begin-suppress AUTOSAR-A8_4_5-a-2 "Span has reference semantics: forwarding not appropriate"
519 // parasoft-begin-suppress AUTOSAR-A12_8_4-a-2 "Span has reference semantics: forwarding not appropriate"
520 /// @brief Constructor from an rvalue @c std::array -like type.
521 ///
522 /// @tparam ArrayLikeT The template-template type of the array-like container. A container is array-like if it has a
523 /// member function @c data() and @c std::tuple_size<ArrayLikeType<U,N>> is defined.
524 /// @tparam U The @c value_type of the array. Must satisfy <c>is_array_convertible_v<const U, T> </c>
525 /// @tparam N The size of the array, Must satisfy @c is_valid_source_extent
526 /// @param array The array to construct the span from
527 /// @post @c size()==N .
528 /// @post @c data()==array.data() .
529 template <
530 template <typename U, std::size_t N>
531 class ArrayLikeT,
532 typename U,
533 std::size_t N,
534 constraints<
535 std::enable_if_t<span_detail::has_member_data_v<ArrayLikeT<U, N>>>,
536 std::enable_if_t<span_detail::has_tuple_size_v<ArrayLikeT<U, N>>>,
537 std::enable_if_t<std::tuple_size<ArrayLikeT<U, N>>::value == N>,
538 std::enable_if_t<arene::base::is_array_convertible_v<U, T>>,
539 std::enable_if_t<is_valid_source_extent_v<N>>> = nullptr>
540 // NOLINTNEXTLINE(google-explicit-constructor,hicpp-explicit-conversions)
541 constexpr span(ArrayLikeT<U, N>&& array) noexcept
542 : span(pre_checked_size{}, array.data(), N) {}
543 // parasoft-end-suppress AUTOSAR-A8_4_6-a-2
544 // parasoft-end-suppress AUTOSAR-A8_4_5-a-2
545 // parasoft-end-suppress AUTOSAR-A12_8_4-a-2
546 // parasoft-end-suppress AUTOSAR-A12_1_1-a-2
547
548 // parasoft-begin-suppress AUTOSAR-A12_1_1-a-2 "False positive: This constructor delegates to another, which does
549 // initialize the base class"
550 /// @brief Constructor from an const rvalue @c std::array -like type.
551 ///
552 /// @tparam ArrayLikeT The template-template type of the array-like container. A container is array-like if it has a
553 /// member function @c data() and @c std::tuple_size<ArrayLikeType<U,N>> is defined.
554 /// @tparam U The @c value_type of the array. Must satisfy <c>is_array_convertible_v<const U, T> </c>
555 /// @tparam N The size of the array, Must satisfy @c is_valid_source_extent
556 /// @param array The array to construct the span from
557 /// @post @c size()==N .
558 /// @post @c data()==array.data() .
559 template <
560 template <typename U, std::size_t N>
561 class ArrayLikeT,
562 typename U,
563 std::size_t N,
564 constraints<
565 std::enable_if_t<span_detail::has_member_data_v<ArrayLikeT<U, N>>>,
566 std::enable_if_t<span_detail::has_tuple_size_v<ArrayLikeT<U, N>>>,
567 std::enable_if_t<std::tuple_size<ArrayLikeT<U, N>>::value == N>,
568 std::enable_if_t<std::is_const<T>::value && arene::base::is_array_convertible_v<U, T>>,
569 std::enable_if_t<is_valid_source_extent_v<N>>> = nullptr>
570 // NOLINTNEXTLINE(google-explicit-constructor,hicpp-explicit-conversions)
571 constexpr span(ArrayLikeT<U, N> const&& array) noexcept
572 : span(pre_checked_size{}, array.data(), N) {}
573 // parasoft-end-suppress AUTOSAR-A12_1_1-a-2
574
575 /// @brief Disable construction of fixed size spans from other spans of mismatched size.
576 /// @param other The source object
577 template <
578 typename U,
579 std::size_t OtherExtent,
580 constraints<std::enable_if_t<
581 !span_detail::is_dynamic_extent(Extent) && !span_detail::is_dynamic_extent(OtherExtent) &&
582 Extent != OtherExtent>> = nullptr>
583 constexpr span(span<U, OtherExtent>&& other) noexcept = delete;
584
585 // parasoft-begin-suppress AUTOSAR-A12_1_1-a-2 "False positive: This constructor delegates to another, which does
586 // initialize the base class"
587 // parasoft-begin-suppress AUTOSAR-A8_4_6-a-2 "Span has reference semantics: forwarding not appropriate"
588 // parasoft-begin-suppress AUTOSAR-A8_4_5-a-2 "Span has reference semantics: forwarding not appropriate"
589 // parasoft-begin-suppress AUTOSAR-A12_8_4-a-2 "Span has reference semantics: forwarding not appropriate"
590 /// @brief Constructor from a container of T with contiguous elements.
591 /// @tparam Container the type of the container to construct from. A "container" is a type which has @c data() and
592 /// @c size() member functions, where @c data() returns a pointer (or equivalent) to contiguous memory
593 /// containing elements pointer-convertible to @c T .
594 /// @param source The container to construct the span from
595 /// @pre If @c Extent is not @c dynamic_extent , then @c source.size()==Extent must be true, else it is an
596 /// @c ARENE_PRECONDITION violation.
597 template <
598 typename Container,
599 constraints<
600 std::enable_if_t<
601 !span_detail::has_tuple_size_v<arene::base::remove_cvref_t<Container>> &&
602 span_detail::is_dynamic_extent(Extent)>,
603 std::enable_if_t<arene::base::is_array_convertible_v<
604 arene::base::remove_reference_t<decltype(*std::declval<Container>().data())>,
605 T>>> = nullptr>
606 // NOLINTNEXTLINE(google-explicit-constructor,hicpp-explicit-conversions,bugprone-forwarding-reference-overload)
607 constexpr span(Container&& source) noexcept
608 : span(source.data(), source.size()) {}
609 // parasoft-end-suppress AUTOSAR-A8_4_6-a-2
610 // parasoft-end-suppress AUTOSAR-A8_4_5-a-2
611 // parasoft-end-suppress AUTOSAR-A12_8_4-a-2
612 // parasoft-end-suppress AUTOSAR-A12_1_1-a-2
613
614 // parasoft-begin-suppress AUTOSAR-A12_1_1-a-2 "False positive: This constructor delegates to another, which does
615 // initialize the base class"
616 // parasoft-begin-suppress AUTOSAR-A8_4_6-a-2 "Span has reference semantics: forwarding not appropriate"
617 // parasoft-begin-suppress AUTOSAR-A8_4_5-a-2 "Span has reference semantics: forwarding not appropriate"
618 // parasoft-begin-suppress AUTOSAR-A12_8_4-a-2 "Span has reference semantics: forwarding not appropriate"
619 /// @brief Constructor from a container of T with contiguous elements.
620 /// @tparam Container the type of the container to construct from. A "container" is a type which has @c data() and
621 /// @c size() member functions, where @c data() returns a pointer (or equivalent) to contiguous memory
622 /// containing elements pointer-convertible to @c T .
623 /// @param source The container to construct the span from
624 /// @pre If @c Extent is not @c dynamic_extent , then @c source.size()==Extent must be true, else it is an
625 /// @c ARENE_PRECONDITION violation.
626 template <
627 typename Container,
628 constraints<
629 std::enable_if_t<
630 !span_detail::has_tuple_size_v<arene::base::remove_cvref_t<Container>> &&
631 !span_detail::is_dynamic_extent(Extent)>,
632 std::enable_if_t<arene::base::is_array_convertible_v<
633 arene::base::remove_reference_t<decltype(*std::declval<Container>().data())>,
634 T>>> = nullptr>
635 // NOLINTNEXTLINE(bugprone-forwarding-reference-overload)
636 explicit constexpr span(Container&& source) noexcept
637 : span(source.data(), source.size()) {
638 ARENE_PRECONDITION(source.size() == Extent);
639 }
640 // parasoft-end-suppress AUTOSAR-A8_4_6-a-2
641 // parasoft-end-suppress AUTOSAR-A8_4_5-a-2
642 // parasoft-end-suppress AUTOSAR-A12_8_4-a-2
643 // parasoft-end-suppress AUTOSAR-A12_1_1-a-2
644
645 // parasoft-begin-suppress AUTOSAR-A12_1_1-a-2 "False positive: This constructor delegates to another, which does
646 // initialize the base class"
647 /// @brief Constructor from another @c span<U,OtherExtent> when @c Extent is "no more restrictive" then @c OtherExtent
648 /// @tparam U The type of the element in the other span. Must be pointer-convertible to @c T
649 /// @tparam OtherExten If @c Extent is not @c dynamic_extent , then must be equal to @c Extent .
650 /// @param other The @c span to construct from.
651 template <
652 typename U,
653 std::size_t OtherExtent,
654 constraints<
655 std::enable_if_t<arene::base::is_array_convertible_v<U, T>>,
656 std::enable_if_t<is_valid_source_extent_v<OtherExtent>>> = nullptr>
657 // NOLINTNEXTLINE(google-explicit-constructor,hicpp-explicit-conversions)
658 constexpr span(span<U, OtherExtent> const& other) noexcept
659 // parasoft-begin-suppress AUTOSAR-A5_16_1-2 "False positive: used as a constructor argument not a subexpression"
660 : span(other.data(), (!span_detail::is_dynamic_extent(Extent)) ? Extent : other.size()) {}
661 // parasoft-end-suppress AUTOSAR-A5_16_1-2
662 // parasoft-end-suppress AUTOSAR-A12_1_1-a-2
663
664 /// @brief Constructor from @c span<U,dynamic_extent> when @c Extent is not @c dynamic_extent .
665 /// @tparam U The type of the element in the other span. Must be pointer-convertible to @c T
666 /// @param other The @c span to construct from.
667 /// @pre @c span.size()==Extent , else @c ARENE_PRECONDITION violation.
668 template <
669 typename U,
670 std::size_t OtherExtent,
671 constraints<
672 std::enable_if_t<arene::base::is_array_convertible_v<U, T>>,
673 std::enable_if_t<(!span_detail::is_dynamic_extent(Extent)) && span_detail::is_dynamic_extent(OtherExtent)>> =
674 nullptr>
675 explicit constexpr span(span<U, OtherExtent> const& other) noexcept
676 : span(other.data(), Extent) {}
677 // parasoft-end-suppress AUTOSAR-A13_3_1-a-2
678
679 /// @brief Predicate to test if the span views onto non-zero elements.
680 ///
681 /// @return true if <c>size() == 0</c>.
682 /// @return false otherwise.
683 ARENE_NODISCARD constexpr auto empty() const noexcept -> bool { return this->size() == 0U; }
684
685 /// @brief Returns the total size in bytes of the elements in the span.
686 ///
687 /// @return The total size, in bytes, of the elements in the span.
688 ARENE_NODISCARD constexpr auto size_bytes() const noexcept -> std::size_t { return this->size() * sizeof(T); }
689
690 /// @brief Accessor to the underlying data as a raw pointer.
691 ///
692 /// @return A pointer to the start of the elements covered by the span.
693 ARENE_NODISCARD constexpr auto data() const noexcept -> T* { return data_ptr_; }
694
695 /// @brief Retrieve the element at the specified index into the span. index must be less than size()
696 ///
697 /// @param index The index of the element to access
698 /// @pre <c>index < size()</c> else @c ARENE_PRECONDITION violation.
699 /// @return A reference to the element at the specified index into the span.
700
701 constexpr auto operator[](std::size_t index) const noexcept -> T& {
702 ARENE_PRECONDITION(index < this->size());
703 return begin()[static_cast<difference_type>(index)];
704 }
705
706 /// @brief Access the first element in the span.
707 ///
708 /// @pre @c empty() must be false, else @c ARENE_PRECONDITION violation.
709 /// @return A reference to the first element in the span.
710 ARENE_NODISCARD constexpr auto front() const noexcept -> T& {
711 ARENE_PRECONDITION(!empty());
712 return *data_ptr_;
713 }
714
715 /// @brief Access the last element in the span.
716 ///
717 /// @pre @c empty() must be false, else @c ARENE_PRECONDITION violation.
718 /// @return A reference to the last element in the span.
719 ARENE_NODISCARD constexpr auto back() const noexcept -> T& {
720 ARENE_PRECONDITION(!empty());
721 return this->operator[](this->size() - 1U);
722 }
723
724 /// @brief Create a new fixed-size span from the beginning of the span.
725 ///
726 /// @tparam Count The number of elements to include.
727 /// @tparam UE dummy parameter for SFINAE.
728 /// @pre @c Count<=size() . else @c ARENE_PRECONDITION violation.
729 /// @return span<T, Count> containing the first @c Count elements from the span.
730 template <
731 std::size_t Count,
732 std::size_t UE = Extent,
733 constraints<std::enable_if_t<span_detail::is_dynamic_extent(UE)>> = nullptr>
734 ARENE_NODISCARD constexpr auto first() const noexcept -> span<T, Count> {
735 ARENE_PRECONDITION(Count <= this->size());
736 return {data_ptr_, Count};
737 }
738 /// @brief Create a new fixed-size span from the beginning of the span.
739 ///
740 /// @tparam Count The number of elements to include. Must be @c <=Extent .
741 /// @return span<T, Count> containing the first @c Count elements from the span.
742 template <
743 std::size_t Count,
744 std::size_t UE = Extent,
745 constraints<std::enable_if_t<!span_detail::is_dynamic_extent(UE)>, std::enable_if_t<Count <= Extent>> = nullptr>
746 ARENE_NODISCARD constexpr auto first() const noexcept -> span<T, Count> {
747 return {data_ptr_, Count};
748 }
749
750 // parasoft-begin-suppress AUTOSAR-A2_10_1-a "False positive: 'count' does not hide anything"
751
752 /// @brief Create a new dynamic-size span from the beginning of the span.
753 ///
754 /// @param count The number of elements to include.
755 /// @pre @c count must be <= @c size() . else @c ARENE_PRECONDITION violation.
756 /// @return span<T, Count> containing the first @c count elements from the span.
757 ARENE_NODISCARD constexpr auto first(std::size_t count) const noexcept -> span<T> {
758 ARENE_PRECONDITION(count <= this->size());
759 return {data_ptr_, count};
760 }
761
762 // parasoft-end-suppress AUTOSAR-A2_10_1-a
763
764 /// @brief Create a new fixed-size span for the last @c Count elements.
765 ///
766 /// @tparam Count The number of elements to include.
767 /// @pre @c Count<=size() , else @c ARENE_PRECONDITION violation.
768 /// @return span<T, Count> containing the last @c Count elements from the span.
769 template <
770 std::size_t Count,
771 std::size_t UE = Extent,
772 constraints<std::enable_if_t<span_detail::is_dynamic_extent(UE)>> = nullptr>
773 ARENE_NODISCARD constexpr auto last() const noexcept -> span<T, Count> {
774 ARENE_PRECONDITION(Count <= this->size());
775 std::size_t const offset{this->size() - Count};
776 return span<T, Count>{arene::base::next(data_ptr_, static_cast<std::ptrdiff_t>(offset)), Count};
777 }
778 /// @brief Create a new fixed-size span for the last @c Count elements.
779 ///
780 /// @tparam Count The number of elements to include. Must be @c <=Extent .
781 /// @return span<T, Count> containing the last @c Count elements from the span.
782 template <
783 std::size_t Count,
784 std::size_t UE = Extent,
785 constraints<std::enable_if_t<!span_detail::is_dynamic_extent(UE)>, std::enable_if_t<Count <= Extent>> = nullptr>
786 ARENE_NODISCARD constexpr auto last() const noexcept -> span<T, Count> {
787 std::size_t const offset{this->size() - Count};
788 return span<T, Count>{arene::base::next(data_ptr_, static_cast<std::ptrdiff_t>(offset)), Count};
789 }
790
791 // parasoft-begin-suppress AUTOSAR-A2_10_1-a "False positive: 'count' does not hide anything"
792
793 /// @brief Create a new dynamic-size span for the last @c count elements.
794 ///
795 /// @param count The number of elements to include.
796 /// @pre @c count must be <= @c size() . else @c ARENE_PRECONDITION violation.
797 /// @return span<T, Count> containing the last @c count elements from the span.
798 ARENE_NODISCARD constexpr auto last(std::size_t count) const noexcept -> span<T> {
799 ARENE_PRECONDITION(count <= this->size());
800 std::size_t const offset{this->size() - count};
801 return span<T>{arene::base::next(data_ptr_, static_cast<std::ptrdiff_t>(offset)), count};
802 }
803
804 // parasoft-end-suppress AUTOSAR-A2_10_1-a
805
806 /// @brief Creates a new fixed-size span which is a slice of this span
807 ///
808 /// @tparam Offset The index of the first element to contain in the subspan. Must be @c <=Extent
809 /// @tparam Count The number of elements to include in the subspan. Must satisfy @c Offset+Count<=Extent , or be
810 /// @c dynamic_extent .
811 /// @return span<T,Extent-Offset> Equivalent to @c last<Extent-Offset>() .
812 template <
813 std::size_t Offset,
814 std::size_t Count = span_detail::get_dynamic_extent(),
815 constraints<
816 std::enable_if_t<Offset <= Extent>,
817 std::enable_if_t<span_detail::is_dynamic_extent(Count) && !span_detail::is_dynamic_extent(Extent)>> = nullptr>
818 ARENE_NODISCARD constexpr auto subspan() const noexcept
819 -> span<T, span_detail::extent_for_subspan<Extent, Offset, Count>()> {
820 return last<Extent - Offset>();
821 }
822 /// @brief Creates a new fixed-size span which is a slice of this span
823 ///
824 /// @tparam Offset The index of the first element to contain in the subspan. Must be @c <=Extent
825 /// @tparam Count The number of elements to include in the subspan. Must satisfy @c Offset+Count<=Extent , or be
826 /// @c dynamic_extent .
827 /// @return span<T,Count> Equivalent to @c last<Extent-Offset>().first<Count>() .
828 template <
829 std::size_t Offset,
830 std::size_t Count = span_detail::get_dynamic_extent(),
831 constraints<
832 std::enable_if_t<Offset <= Extent>,
833 std::enable_if_t<!span_detail::is_dynamic_extent(Count) && !span_detail::is_dynamic_extent(Extent)>> =
834 nullptr>
835 ARENE_NODISCARD constexpr auto subspan() const noexcept
836 -> span<T, span_detail::extent_for_subspan<Extent, Offset, Count>()> {
837 return last<Extent - Offset>().template first<Count>();
838 }
839 /// @brief Creates a new dynamic-sized span which is a slice of this span
840 ///
841 /// @tparam Offset The index of the first element to contain in the subspan. Must be <= @c size()
842 /// @tparam Count The number of elements to include in the subspan. <c> offset + count </c> must be <= @c size()
843 /// @return span<T> equivalent to @c last(size()-Offset) .
844 /// @pre <c> Count<= size() && (Count+Offset <= size()) </c>, else @c ARENE_PRECONDITION violation.
845 template <
846 std::size_t Offset,
847 std::size_t Count = span_detail::get_dynamic_extent(),
848 constraints<
849 std::enable_if_t<Offset <= Extent>,
850 std::enable_if_t<span_detail::is_dynamic_extent(Count) && span_detail::is_dynamic_extent(Extent)>> = nullptr>
851 ARENE_NODISCARD constexpr auto subspan() const noexcept
852 -> span<T, span_detail::extent_for_subspan<Extent, Offset, Count>()> {
853 ARENE_PRECONDITION(Offset <= this->size());
854 return last(this->size() - Offset);
855 }
856 /// @brief Creates a new fixed-size span which is a slice of this span
857 ///
858 /// @tparam Offset The index of the first element to contain in the subspan. Must be <= @c size()
859 /// @tparam Count The number of elements to include in the subspan. <c> offset + count </c> must be <= @c size()
860 /// @return span<T,Count> Equivalent to @c last(size()-Offset).first<Count>() .
861 /// @pre If @c Extent is @c dynamic_extent , then <c> Count<= size() && (Count+Offset <= size()) </c>, else
862 /// @c ARENE_PRECONDITION violation.
863 template <
864 std::size_t Offset,
865 std::size_t Count = span_detail::get_dynamic_extent(),
866 constraints<
867 std::enable_if_t<Offset <= Extent>,
868 std::enable_if_t<!span_detail::is_dynamic_extent(Count) && span_detail::is_dynamic_extent(Extent)>> = nullptr>
869 ARENE_NODISCARD constexpr auto subspan() const noexcept
870 -> span<T, span_detail::extent_for_subspan<Extent, Offset, Count>()> {
871 ARENE_PRECONDITION(Offset <= this->size());
872 return last(this->size() - Offset).template first<Count>();
873 }
874
875 // parasoft-begin-suppress AUTOSAR-A2_10_1-a "False positive: 'count' does not hide anything"
876
877 /// @brief Creates a new dynamic-size span which is a slice of this span
878 ///
879 /// @param offset The index of the first element to contain in the subspan. Must be <= @c size()
880 /// @param count The number of elements to include in the subspan. <c> offset + count </c> must be <= @c size()
881 /// @return span<T> If @c count==dynamic_extent , equivalent to @c last(size()-offset) , else
882 /// @c last(size()-offset).first(count) .
883 /// @pre <c> count<= size() && (count+offset <= size()) </c>, else @c ARENE_PRECONDITION violation.
884 // NOLINTNEXTLINE(bugprone-easily-swappable-parameters) this API is required by span's stdlib compatibility.
885 ARENE_NODISCARD constexpr auto subspan(std::size_t offset, std::size_t count = dynamic_extent) const noexcept
886 -> span<T> {
887 ARENE_PRECONDITION(offset <= this->size());
888 auto const last_start = this->size() - offset;
889 if (span_detail ::is_dynamic_extent(count)) {
890 return last(last_start);
891 }
892 return last(last_start).first(count);
893 }
894
895 // parasoft-end-suppress AUTOSAR-A2_10_1-a
896
897 /// @brief Obtain an iterator to the beginning of the data viewed by the span.
898 ///
899 /// @return iterator An iterator pointing to the first position in the span.
900 ARENE_NODISCARD constexpr auto begin() const noexcept -> iterator {
901 return iterator{span_detail::span_iter_passkey{}, data_ptr_};
902 }
903
904 /// @brief Obtain a const_iterator to the beginning of the data viewed by the span.
905 ///
906 /// @return const_iterator A const iterator pointing to the first position in the span.
907 ARENE_NODISCARD constexpr auto cbegin() const noexcept -> const_iterator {
908 return const_iterator{span_detail::span_iter_passkey{}, data_ptr_};
909 }
910
911 /// @brief Obtain an iterator to the one-past-the-end of the data viewed by the span
912 ///
913 /// @return iterator An iterator equivalent to @c begin()+size() .
914 ARENE_NODISCARD constexpr auto end() const noexcept -> iterator {
915 return iterator{span_detail::span_iter_passkey{}, arene::base::next(data_ptr_, ssize())};
916 }
917
918 /// @brief Obtain a const_iterator to the one-past-the-end of the data viewed by the span
919 ///
920 /// @return const_iterator A const iterator equivalent to @c cbegin()+size() .
921 ARENE_NODISCARD constexpr auto cend() const noexcept -> const_iterator {
922 return const_iterator{span_detail::span_iter_passkey{}, arene::base::next(data_ptr_, ssize())};
923 }
924
925 /// @brief Obtain an iterator to the beginning of a reversed view of the data in the span.
926 ///
927 /// @return iterator An iterator equivalent to @c reverse_iterator(end())
928 ARENE_NODISCARD constexpr auto rbegin() const noexcept -> reverse_iterator { return reverse_iterator(end()); }
929
930 /// @brief Obtain a const_iterator to the beginning of a reversed view of the data in the span.
931 ///
932 /// @return const_reverse_iterator An iterator equivalent to @c const_reverse_iterator(cend())
933 ARENE_NODISCARD constexpr auto crbegin() const noexcept -> const_reverse_iterator {
934 return const_reverse_iterator(cend());
935 }
936
937 /// @brief Obtain an iterator to one-past-the-end of a reversed view of the data in the span.
938 ///
939 /// @return iterator An iterator equivalent to @c reverse_iterator(begin())
940 ARENE_NODISCARD constexpr auto rend() const noexcept -> reverse_iterator { return reverse_iterator(begin()); }
941
942 /// @brief Obtain a const iterator to one-past-the-end of a reversed view of the data in the span.
943 ///
944 /// @return const_reverse_iterator A const iterator equivalent to @c const_reverse_iterator(cbegin())
945 ARENE_NODISCARD constexpr auto crend() const noexcept -> const_reverse_iterator {
946 return const_reverse_iterator(cbegin());
947 }
948};
949// parasoft-end-suppress AUTOSAR-A13_5_1-a-2
950
951/// @brief Obtain a const view to the object representation of the elements of the span @c spn.
952/// @param spn The span of elements to inspect.
953/// @return A <c>span<const Byte, Size></c> of the object representations of the elements of @c spn.
954template <typename T, std::size_t N>
955auto as_bytes(span<T, N> spn) noexcept
956 -> span<byte const, span_detail::is_dynamic_extent(N) ? dynamic_extent : (N * sizeof(T))> {
957 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
958 return {reinterpret_cast<byte const*>(spn.data()), spn.size_bytes()};
959}
960
961/// @brief Obtain a non-const view to the object representation of the elements of the span @c spn.
962/// @param spn The span of elements to inspect.
963/// @return A <c>span<byte, Size></c> of the object representations of the elements of @c spn.
964template <typename T, std::size_t N, constraints<std::enable_if_t<!std::is_const<T>::value>> = nullptr>
965auto as_writable_bytes(span<T, N> spn) noexcept
966 -> span<byte, span_detail::is_dynamic_extent(N) ? dynamic_extent : (N * sizeof(T))> {
967 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
968 return {reinterpret_cast<byte*>(spn.data()), spn.size_bytes()};
969}
970
971template <typename T, std::size_t Extent>
972constexpr std::integral_constant<std::size_t, Extent> span<T, Extent>::extent;
973
974} // namespace base
975} // namespace arene
976
977#endif // INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_SPAN_SPAN_HPP_
Definition array_exceptions_disabled.cpp:11
Copyright 2026, Toyota Motor Corporation.
Definition array_exceptions_disabled.cpp:10