BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bslstl_span.h
Go to the documentation of this file.
1/// @file bslstl_span.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslstl_span.h -*-C++-*-
8#ifndef INCLUDED_BSLSTL_SPAN
9#define INCLUDED_BSLSTL_SPAN
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslstl_span bslstl_span
15/// @brief Provide a (mostly) standard-compliant `span` class template.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslstl
19/// @{
20/// @addtogroup bslstl_span
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslstl_span-purpose"> Purpose</a>
25/// * <a href="#bslstl_span-classes"> Classes </a>
26/// * <a href="#bslstl_span-canonical-header"> Canonical Header </a>
27/// * <a href="#bslstl_span-description"> Description </a>
28/// * <a href="#bslstl_span-usage"> Usage </a>
29/// * <a href="#bslstl_span-example-1-using-span-to-pass-a-portion-of-an-array-as-a-container"> Example 1: Using Span To Pass A Portion Of An Array As A Container </a>
30/// * <a href="#bslstl_span-example-2-returning-a-subset-of-a-container-from-a-function"> Example 2: Returning A Subset Of A Container From A Function </a>
31///
32/// # Purpose {#bslstl_span-purpose}
33/// Provide a (mostly) standard-compliant `span` class template.
34///
35/// # Classes {#bslstl_span-classes}
36///
37/// - bsl::span: C++03-compliant implementation of `std::span`.
38///
39/// # Canonical Header {#bslstl_span-canonical-header}
40/// bsl_span.h
41///
42/// @see ISO C++ Standard
43///
44/// # Description {#bslstl_span-description}
45/// This component provides the C+20 standard view type `span`,
46/// that is a view over a contiguous sequence of objects. Note that if compiler
47/// supports the C++20 standard, then the `std` implementation of `span` is
48/// used.
49///
50/// There are two implementations of `span`; one for `statically sized` (i. e.,
51/// size fixed at compile time) spans, and `dynamically sized` (size can be
52/// altered at run-time).
53///
54/// `bsl::span` differs from `std::span` in the following ways:
55/// * The `constexpr` inline symbol `std::dynamic_extent` has been replaced by
56/// an enumeration for C++03 compatibility.
57/// * A `bsl::span` can be implicitly constructed from a `bsl::array`.
58/// * The implicit construction from an arbitrary container that supports
59/// `data()` and `size()` is enabled only for C++11 and later.
60/// * bsl::span is implicitly constructible from a bsl::vector in C++03.
61///
62/// ## Usage {#bslstl_span-usage}
63///
64///
65/// This section illustrates intended usage of this component.
66///
67/// ### Example 1: Using Span To Pass A Portion Of An Array As A Container {#bslstl_span-example-1-using-span-to-pass-a-portion-of-an-array-as-a-container}
68///
69///
70/// Suppose we already have an array of values of type `TYPE`, and we want to
71/// pass a subset of the array to a function, which is expecting some kind of a
72/// container. We can create a `span` from the array, and then pass that.
73/// Since the span is a `view` into the array, i.e, the span owns no storage,
74/// the elements in the span are the same as the ones in the array.
75///
76/// First, we create a template function that takes a generic container. This
77/// function inspects each of the (numeric) values in the container, and if the
78/// low bit is set, flips it. This has the effect of turning odd values into
79/// even values.
80/// @code
81/// template <class CONTAINER>
82/// void MakeEven(CONTAINER &c)
83/// // Make every value in the specified container 'c' even.
84/// {
85/// for (typename CONTAINER::iterator it = c.begin();
86/// it != c.end();
87/// ++it) {
88/// if (*it & 1) {
89/// *it ^= 1;
90/// }
91/// }
92/// }
93/// @endcode
94/// We then create a span, and verify that it contains the values that we
95/// expect, and pass it to `MakeEven` to modify it. Afterwards, we check that
96/// none of the elements in the array that were not included in the span are
97/// unchanged, and the ones in the span were.
98/// @code
99/// int arr[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
100/// bsl::span<int> sp(arr + 3, 4); // 4 elements, starting at 3.
101/// for (int i = 0; i < 10; ++i)
102/// {
103/// assert(arr[i] == i);
104/// }
105///
106/// assert(sp[0] == 3);
107/// assert(sp[1] == 4);
108/// assert(sp[2] == 5);
109/// assert(sp[3] == 6);
110///
111/// MakeEven(sp);
112///
113/// assert(sp[0] == 2); // Has been changed
114/// assert(sp[1] == 4);
115/// assert(sp[2] == 4); // Has been changed
116/// assert(sp[3] == 6);
117///
118/// assert(arr[0] == 0); // Not part of the span
119/// assert(arr[1] == 1); // Not part of the span
120/// assert(arr[2] == 2); // Not part of the span
121/// assert(arr[3] == 2); // Has been changed
122/// assert(arr[4] == 4);
123/// assert(arr[5] == 4); // Has been changed
124/// assert(arr[6] == 6);
125/// assert(arr[7] == 7); // Not part of the span
126/// assert(arr[8] == 8); // Not part of the span
127/// assert(arr[9] == 9); // Not part of the span
128/// @endcode
129///
130/// ### Example 2: Returning A Subset Of A Container From A Function {#bslstl_span-example-2-returning-a-subset-of-a-container-from-a-function}
131///
132///
133/// Suppose we already have a vector of values of type `TYPE`, and we want to
134/// return a (contiguous) subset of the vector from a function, which can then
135/// be processed processed using a range-based for loop. To achieve that, we
136/// can use `span` as the return type. The calling code can then interate over
137/// the span as if it was a container. Note that since the span doesn't own the
138/// elements of the vector, the span might become invalid when the vector is
139/// changed (or resized, or destroyed).
140///
141/// First, we create the vector and define our function that returns a slice as
142/// a `span`.
143/// @code
144/// bsl::vector<int> v = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
145///
146/// /// Return a span into the specified `vec`, starting at the specified
147/// /// `first` index, and continuing up to (but not including) the
148/// /// specified `last` index.
149/// bsl::span<const int> slice(const bsl::vector<int>& vec,
150/// size_t first,
151/// size_t last)
152/// {
153/// return bsl::span<const int>(vec.data() + first, last-first);
154/// }
155/// @endcode
156/// We can now iterate over the elements in the slice using the span:
157/// @code
158/// bsl::span<const int> sp = slice(v, 4, 7);
159/// int val = 4;
160/// for (int x: sp) {
161/// assert(x == val++);
162/// }
163/// @endcode
164/// Note that we can use the return value directly and avoid declaring the
165/// variable `sp`:
166/// @code
167/// val = 2;
168/// for (int x: slice(v, 2, 8)) {
169/// assert(x == val++);
170/// }
171/// @endcode
172/// @}
173/** @} */
174/** @} */
175
176/** @addtogroup bsl
177 * @{
178 */
179/** @addtogroup bslstl
180 * @{
181 */
182/** @addtogroup bslstl_span
183 * @{
184 */
185
186#include <bslscm_version.h>
187
189#include <bsls_libraryfeatures.h>
190
191#if defined (BSLS_LIBRARYFEATURES_HAS_CPP20_BASELINE_LIBRARY) && \
192 !(defined(BSLS_LIBRARYFEATURES_FORCE_ABI_ENABLED) && \
193 (BSLS_LIBRARYFEATURES_FORCE_ABI_ENABLED < 20))
194#include <span>
195namespace bsl {
196 using std::dynamic_extent;
197 using std::span;
198 using std::as_bytes;
199 using std::as_writable_bytes;
200}
201#define BSLSTL_SPAN_IS_ALIASED
202#endif // BSLS_LIBRARYFEATURES_HAS_CPP20_BASELINE_LIBRARY & not disabled
203
204#ifndef BSLSTL_SPAN_IS_ALIASED
205#include <bslmf_assert.h>
206#include <bslmf_enableif.h>
208#include <bslmf_isconvertible.h>
209#include <bslmf_removepointer.h>
210#include <bslmf_removecv.h>
211
212#include <bsls_assert.h>
213#include <bsls_keyword.h>
214#include <bsls_nullptr.h>
215
216#include <bslstl_array.h>
217#include <bslstl_iterator.h>
218#include <bslstl_string.h>
219#include <bslstl_vector.h>
220
221#ifdef BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
222#include <array> // 'std::array'
223#endif
224#include <iterator> // 'reverse_iterator', '!='
225#include <stddef.h> // 'size_t', 'NULL', 'std::byte'
226
227namespace bsl {
228
229enum { dynamic_extent = ~size_t(0) }; // -1 generates a warning
230
231template <class TYPE, size_t EXTENT = dynamic_extent> class span;
232
233
234 // ===================
235 // struct Span_Utility
236 // ===================
237
238/// This component-private struct provides a namespace for meta-programming
239/// utilities used by the `span` implementation.
240struct Span_Utility
241{
242 // PUBLIC TYPES
243
244 /// A metaclass that derives from `true_type` if an array of type `FROM`
245 /// objects (or functions) can be implicitly converted to an array of
246 /// type `TO` objects (or functions). Typically, this is a test that
247 /// `TO` is the same type as `FROM`, but potentially having a stricter cv-qualification.
248 ///
249 /// \note Note that the preferred implementation would use
250 /// arrays of unknown bound to be clear that there is nothing specific
251 /// about the length of the arrays; however, to avoid warnings on the
252 /// Solaris compiler that complains about the use of pointers to arrays
253 /// of unknown bound, we arbitrarily pick the array length of 5, as the
254 /// behavior is the same regardless of the length of the arrays.
255 template <class FROM, class TO>
256 struct IsArrayConvertible : bsl::is_convertible<FROM(*)[5], TO(*)[5]>::type
257 {
258 };
259
260 template <class TYPE, size_t EXTENT, size_t COUNT, size_t OFFSET>
261 struct SubspanReturnType
262 {
263 // PUBLIC TYPES
264 typedef bsl::span<TYPE, COUNT != dynamic_extent
265 ? COUNT
266 : EXTENT - OFFSET> type;
267
268 };
269
270 template <class TYPE>
271 struct TypeIdentity
272 {
273 // PUBLIC TYPES
274 typedef TYPE type;
275 };
276
277#ifdef BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
278 template <class TP>
279 struct IsSpanImpl : public bsl::false_type {};
280
281 template <class TP, size_t SZ>
282 struct IsSpanImpl<span<TP, SZ> > : public bsl::true_type {};
283
284 template <class TP>
285 struct IsSpan : public IsSpanImpl<typename bsl::remove_cv<TP>::type> {};
286
287 template <class TP>
288 struct IsBSLArrayImpl : public bsl::false_type {};
289
290 template <class TP, size_t SZ>
291 struct IsBSLArrayImpl<bsl::array<TP, SZ> > : public bsl::true_type {};
292
293 template <class TP>
294 struct IsBSLArray
295 : public IsBSLArrayImpl<typename bsl::remove_cv<TP>::type> {};
296
297 template <class TP>
298 struct IsSTDArrayImpl : public bsl::false_type {};
299
300 template <class TP, size_t SZ>
301 struct IsSTDArrayImpl<std::array<TP, SZ> > : public bsl::true_type {};
302
303 template <class TP>
304 struct IsSTDArray
305 : public IsSTDArrayImpl<typename bsl::remove_cv<TP>::type> {};
306
307 template <class TP, class ELEMENT_TYPE, class = void>
308 struct IsSpanCompatibleContainer : public bsl::false_type {};
309
310 template <class TP, class ELEMENT_TYPE>
311 struct IsSpanCompatibleContainer<TP, ELEMENT_TYPE,
312 bsl::void_t<
313 // is not a specialization of span
314 typename bsl::enable_if<!IsSpan<TP>::value, bsl::nullptr_t>::type,
315 // is not a specialization of bsl::array
316 typename bsl::enable_if<
317 !IsBSLArray<TP>::value, bsl::nullptr_t>::type,
318 // is not a specialization of std::array
319 typename bsl::enable_if<
320 !IsSTDArray<TP>::value, bsl::nullptr_t>::type,
321 // is not a C-style array
322 typename bsl::enable_if<
323 !bsl::is_array<TP>::value, bsl::nullptr_t>::type,
324 // data(cont) and size(cont) are well formed
325 decltype(bsl::data(std::declval<TP>())),
326 decltype(bsl::size(std::declval<TP>())),
327 // The underlying types are compatible
328 typename bsl::enable_if<
329 Span_Utility::IsArrayConvertible<
330 typename bsl::remove_pointer<
331 decltype(bsl::data(std::declval<TP &>()))>::type,
332 ELEMENT_TYPE>::value,
333 bsl::nullptr_t>::type
334 > >
335 : public bsl::true_type {};
336#endif // BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
337
338};
339
340template <class TYPE, size_t EXTENT>
341class span {
342
343 public:
344 // PUBLIC TYPES
345 typedef TYPE element_type;
346 typedef typename bsl::remove_cv<TYPE>::type value_type;
347 typedef size_t size_type;
348 typedef ptrdiff_t difference_type;
349 typedef TYPE *pointer;
350 typedef const TYPE *const_pointer;
351 typedef TYPE& reference;
352 typedef const TYPE& const_reference;
353 typedef pointer iterator;
354 typedef bsl::reverse_iterator<iterator> reverse_iterator;
355
356// BDE_VERIFY pragma: push
357// BDE_VERIFY pragma: -MN03 // Constant ... names must begin with 's_' or 'k_'
358 // PUBLIC CLASS DATA
359 static const size_type extent = EXTENT;
360// BDE_VERIFY pragma: pop
361
362 // TRAITS
364
365 // CREATORS
366
367 /// Construct an empty `span` object.
368 /// \pre The behavior is undefined unless
369 /// `0 == EXTENT`
371
372 /// Create a span that refers to the same data as the specified
373 /// `original` object.
374 BSLS_KEYWORD_CONSTEXPR_CPP14 span(const span&) noexcept = default;
375
376 /// Construct a span that refers to the specified `count` consecutive
377 /// objects starting from the specified `ptr`.
378 ///
379 /// \pre The behavior is undefined unless `EXTENT == count`.
380 BSLS_KEYWORD_CONSTEXPR_CPP14 explicit span(pointer ptr, size_type count);
381
382 /// Construct a span from the specified `first` and specified `last`.
383 ///
384 /// \pre The behavior is undefined unless
385 /// `EXTENT == bsl::distance(first, last)`.
386 BSLS_KEYWORD_CONSTEXPR_CPP14 explicit span(pointer first, pointer last);
387
388 /// Construct a span from the specified C-style array `arr`.
389 ///
390 /// \pre The behavior is undefined unless `SIZE == EXTENT`.
391 template <size_t SIZE>
393 typename Span_Utility::TypeIdentity<element_type>::type (&arr)[SIZE])
395
396#ifndef BSLSTL_ARRAY_IS_ALIASED
397 /// Construct a span from the specified bsl::array `arr`. This
398 /// constructor participates in overload resolution only if
399 /// `t_OTHER_TYPE(*)[]` is convertible to `element_type(*)[]`.
400 template <class t_OTHER_TYPE>
403 typename bsl::enable_if<
404 Span_Utility::IsArrayConvertible<t_OTHER_TYPE, element_type>::value,
405 void *>::type = NULL) BSLS_KEYWORD_NOEXCEPT;
406
407 /// Construct a span from the specified bsl::array `arr`. This
408 /// constructor participates in overload resolution only if
409 /// `t_OTHER_TYPE(*)[]` is convertible to `element_type(*)[]`.
410 template <class t_OTHER_TYPE>
413 typename bsl::enable_if<
414 Span_Utility::IsArrayConvertible<
415 const t_OTHER_TYPE, element_type>::value,
416 void *>::type = NULL) BSLS_KEYWORD_NOEXCEPT;
417#endif // BSLSTL_ARRAY_IS_ALIASED
418
419#ifdef BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
420 /// Construct a span from the specified std::array `arr`. This
421 /// constructor participates in overload resolution only if
422 /// `t_OTHER_TYPE(*)[]` is convertible to `element_type(*)[]`.
423 template <class t_OTHER_TYPE>
425 std::array<t_OTHER_TYPE, EXTENT>& arr,
426 typename bsl::enable_if<
427 Span_Utility::IsArrayConvertible<
428 t_OTHER_TYPE, element_type>::value,
429 void *>::type = NULL) BSLS_KEYWORD_NOEXCEPT;
430
431 /// Construct a span from the specified std::array `arr`. This
432 /// constructor participates in overload resolution only if
433 /// `t_OTHER_TYPE(*)[]` is convertible to `element_type(*)[]`.
434 template <class t_OTHER_TYPE>
436 const std::array<t_OTHER_TYPE, EXTENT>& arr,
437 typename bsl::enable_if<
438 Span_Utility::IsArrayConvertible<
439 const t_OTHER_TYPE, element_type>::value,
440 void *>::type = NULL) BSLS_KEYWORD_NOEXCEPT;
441#endif // BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
442
443 /// Construct a span from the specified span `other`. This constructor
444 /// participates in overload resolution only if `t_OTHER_TYPE(*)[]` is
445 /// convertible to `element_type(*)[]`.
446 template <class t_OTHER_TYPE>
448 const span<t_OTHER_TYPE, EXTENT>& other,
449 typename bsl::enable_if<
450 Span_Utility::IsArrayConvertible<
451 t_OTHER_TYPE, element_type>::value,
452 void *>::type = NULL) BSLS_KEYWORD_NOEXCEPT;
453
454 /// Construct a span from the specified span `other`. This constructor
455 /// participates in overload resolution only if `t_OTHER_TYPE(*)[]` is
456 /// convertible to `element_type(*)[]`.
457 ///
458 /// \pre The behavior is undefined unless `other.size() == EXTENT`.
459 template <class t_OTHER_TYPE>
461 const span<t_OTHER_TYPE, dynamic_extent>& other,
462 typename bsl::enable_if<
463 Span_Utility::IsArrayConvertible<
464 t_OTHER_TYPE, element_type>::value,
465 void *>::type = NULL) BSLS_KEYWORD_NOEXCEPT;
466
467 /// Destroy this object.
468 ~span() noexcept = default;
469
470 // ACCESSORS
471
472 /// Return a reference to the last element of this span.
473 ///
474 /// \pre The behavior is undefined if this span is empty.
475 BSLS_KEYWORD_CONSTEXPR_CPP14 reference back() const
476 {
477 // Implemented inline because of Sun/AIX compiler limitations.
478 BSLMF_ASSERT(EXTENT > 0);
479 return d_data_p[size() - 1];
480 }
481
482 /// Return a pointer to the data referenced by this span.
484
485 /// Return `true` if this span contains no elements and `false`
486 /// otherwise.
488
489 /// Return a statically-sized span consisting of the first `COUNT` elements of this span.
490 ///
491 /// \pre The behavior is undefined unless
492 /// `COUNT <= size()`.
493 template <size_t COUNT>
495 span<element_type, COUNT> first() const;
496
497 /// Return a dynamically-sized span consisting of the first (specified) `count` elements of this span.
498 ///
499 /// \pre The behavior is undefined unless
500 /// `count <= size()`.
502 span<element_type, dynamic_extent>
503 first(size_type count) const;
504
505 /// Return a reference to the first element of this span.
506 ///
507 /// \pre The behavior is undefined if this span is empty.
508 BSLS_KEYWORD_CONSTEXPR_CPP14 reference front() const
509 {
510 // Implemented inline because of Sun/AIX compiler limitations.
511 BSLMF_ASSERT(EXTENT > 0);
512 return d_data_p[0];
513 }
514
515 /// Return a statically-sized span consisting of the last `COUNT` elements of this span.
516 ///
517 /// \pre The behavior is undefined unless
518 /// `COUNT <= size()`.
519 template <size_t COUNT>
521 span<element_type, COUNT> last() const;
522
523 /// Return a dynamically-sized span consisting of the last (specified) `count` elements of this span.
524 ///
525 /// \pre The behavior is undefined unless
526 /// `count <= size()`.
528 span<element_type, dynamic_extent>
529 last(size_type count) const;
530
531 /// Return the size of this span.
532 BSLS_KEYWORD_CONSTEXPR size_type size() const BSLS_KEYWORD_NOEXCEPT
533 {
534 // Implemented inline because of Sun/AIX compiler limitations.
535 return EXTENT;
536 }
537
538 /// Return the size of this span in bytes.
539 BSLS_KEYWORD_CONSTEXPR size_type size_bytes() const BSLS_KEYWORD_NOEXCEPT;
540
541 /// If the template parameter `COUNT` is @ref dynamic_extent , return a
542 /// dynamically-sized span consisting consisting of the elements of this
543 /// span in the half-open range `[OFFSET, EXTENT)`. Otherwise, return a
544 /// statically-sized span consisting of the elements of this span in the
545 /// half-open range `[OFFSET, OFFSET+COUNT)`.
546 ///
547 /// \pre The behavior is undefined unless `OFFSET <= EXTENT`. If `COUNT != dynamic_extent`, the
548 /// behavior is undefined unless `OFFSET + COUNT <= EXTENT`.
549 template <size_t OFFSET,
550#ifdef BSLS_COMPILERFEATURES_SUPPORT_DEFAULT_TEMPLATE_ARGS
551 size_t COUNT = dynamic_extent>
552#else
553 size_t COUNT>
554#endif
556 typename Span_Utility::SubspanReturnType<TYPE, EXTENT, COUNT, OFFSET>::type
557 subspan() const
558 {
559 // Implemented inline because of Sun/AIX compiler limitations.
560 typedef typename
561 Span_Utility::SubspanReturnType<TYPE, EXTENT, COUNT, OFFSET>::type
562 ReturnType;
563 BSLMF_ASSERT(OFFSET <= EXTENT);
564 BSLMF_ASSERT(COUNT == dynamic_extent || OFFSET + COUNT <= EXTENT);
565 return ReturnType(data() + OFFSET,
566 COUNT == dynamic_extent ? size() - OFFSET : COUNT);
567 }
568
569 /// Return a dynamically-sized span starting at the specified `offset`.
570 /// If the optionally specified `count` is @ref dynamic_extent , the span
571 /// will consist of the half-open range `[offset, size () - offset)` and
572 /// the behavior is undefined if `offset > size()`. Otherwise, the span
573 /// will consist of the half-open range `[offset, count)` and the
574 /// behavior is undefined if `offset + count > size()`.
576 span<element_type, dynamic_extent>
577 subspan(size_type offset, size_type count = dynamic_extent) const;
578
579 /// Return a reference to the element at the specified `index`.
580 ///
581 /// \pre The behavior is undefined unless `index < size()`.
583 reference operator[](size_type index) const
584 {
585 // Implemented inline because of Sun/AIX compiler limitations.
586 BSLS_ASSERT(index < size());
587 return d_data_p[index];
588 }
589
590 /// Return a reference to the element at the specified `index`. Throws
591 /// an @ref out_of_range exception if `index >= size()`.
593 reference at(size_type index) const;
594
595 // ITERATOR OPERATIONS
596
597
598 /// Return an iterator providing modifiable access to the first element
599 /// of this span, and the past-the-end iterator if this span is empty.
601
602 /// Return the past-the-end iterator providing modifiable access to this
603 /// span.
605 iterator end() const BSLS_KEYWORD_NOEXCEPT;
606
607 /// Return a reverse iterator providing modifiable access to the last
608 /// element of this span, and the past-the-end reverse iterator if this
609 /// span is empty.
611 reverse_iterator rbegin() const BSLS_KEYWORD_NOEXCEPT;
612
613 /// Return the past-the-end reverse iterator providing modifiable access
614 /// to this span.
616 reverse_iterator rend() const BSLS_KEYWORD_NOEXCEPT;
617
618 // MANIPULATORS
619
620 /// Assign to this span the value of the specified `rhs` object, and
621 /// return a reference providing modifiable access to this span.
622 constexpr span& operator=(const span&) noexcept = default;
623
624 /// Exchange the value of this span with the value of the specified
625 /// `other` object.
627
628 private:
629 // DATA
630 pointer d_data_p;
631};
632
633
634template <class TYPE>
635class span<TYPE, dynamic_extent> {
636 public:
637 // PUBLIC TYPES
638 typedef TYPE element_type;
639 typedef typename bsl::remove_cv<TYPE>::type value_type;
640 typedef size_t size_type;
641 typedef ptrdiff_t difference_type;
642 typedef TYPE *pointer;
643 typedef const TYPE *const_pointer;
644 typedef TYPE& reference;
645 typedef const TYPE& const_reference;
646 typedef pointer iterator;
647 typedef bsl::reverse_iterator<iterator> reverse_iterator;
648
649// BDE_VERIFY pragma: push
650// BDE_VERIFY pragma: -MN03 // Constant ... names must begin with 's_' or 'k_'
651 // PUBLIC CLASS DATA
652 static const size_type extent = dynamic_extent;
653// BDE_VERIFY pragma: pop
654
655 // TRAITS
657
658 // CREATORS
659
660 /// Construct an empty `span` object.
662
663 /// Create a span that refers to the same data as the specified
664 /// `original` object.
665 BSLS_KEYWORD_CONSTEXPR_CPP14 span(const span&) noexcept = default;
666
667 /// Construct a span that refers to the specified `count` consecutive
668 /// objects starting from the specified `ptr`.
669 BSLS_KEYWORD_CONSTEXPR_CPP14 span(pointer ptr, size_type count);
670
671 /// Construct a span from the specified `first` and specified `last`.
672 BSLS_KEYWORD_CONSTEXPR_CPP14 span(pointer first, pointer last);
673
674 /// Construct a span from the specified C-style array `arr`.
675 template <size_t SIZE>
677 typename Span_Utility::TypeIdentity<element_type>::type (&arr)[SIZE])
679
680#ifndef BSLSTL_ARRAY_IS_ALIASED
681 /// Construct a span from the specified bsl::array `arr`. This
682 /// constructor participates in overload resolution only if
683 /// `t_OTHER_TYPE(*)[]` is convertible to `element_type(*)[]`.
684 template <class t_OTHER_TYPE, size_t SIZE>
686 typename bsl::enable_if<
687 Span_Utility::IsArrayConvertible<
688 t_OTHER_TYPE, element_type>::value,
689 void *>::type = NULL) BSLS_KEYWORD_NOEXCEPT;
690
691 /// Construct a span from the specified bsl::array `arr`. This
692 /// constructor participates in overload resolution only if
693 /// `t_OTHER_TYPE(*)[]` is convertible to `element_type(*)[]`.
694 template <class t_OTHER_TYPE, size_t SIZE>
697 typename bsl::enable_if<
698 Span_Utility::IsArrayConvertible<
699 const t_OTHER_TYPE, element_type>::value,
700 void *>::type = NULL) BSLS_KEYWORD_NOEXCEPT;
701#endif // BSLSTL_ARRAY_IS_ALIASED
702
703#ifdef BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
704 /// Construct a span from the specified std::array `arr`. This
705 /// constructor participates in overload resolution only if
706 /// `t_OTHER_TYPE(*)[]` is convertible to `element_type(*)[]`.
707 template <class t_OTHER_TYPE, size_t SIZE>
708 BSLS_KEYWORD_CONSTEXPR_CPP14 span(std::array<t_OTHER_TYPE, SIZE>& arr,
709 typename bsl::enable_if<
710 Span_Utility::IsArrayConvertible<
711 t_OTHER_TYPE, element_type>::value,
712 void *>::type = NULL) BSLS_KEYWORD_NOEXCEPT;
713
714 /// Construct a span from the specified std::array `arr`. This
715 /// constructor participates in overload resolution only if
716 /// `t_OTHER_TYPE(*)[]` is convertible to `element_type(*)[]`.
717 template <class t_OTHER_TYPE, size_t SIZE>
719 const std::array<t_OTHER_TYPE, SIZE>& arr,
720 typename bsl::enable_if<
721 Span_Utility::IsArrayConvertible<
722 const t_OTHER_TYPE, element_type>::value,
723 void *>::type = NULL) BSLS_KEYWORD_NOEXCEPT;
724#endif // BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
725
726#ifndef BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
727 /// Construct a span from the specified bsl::vector `v`. This
728 /// constructor participates in overload resolution only if
729 /// `t_OTHER_TYPE(*)[]` is convertible to `element_type(*)[]`.
730 template <class t_OTHER_TYPE, class ALLOCATOR>
732 typename bsl::enable_if<
733 Span_Utility::IsArrayConvertible<
734 t_OTHER_TYPE, element_type>::value,
735 void *>::type = NULL) BSLS_KEYWORD_NOEXCEPT;
736
737 /// Construct a span from the specified bsl::vector `v`. This
738 /// constructor participates in overload resolution only if
739 /// `const t_OTHER_TYPE(*)[]` is convertible to `element_type(*)[]`.
740 template <class t_OTHER_TYPE, class ALLOCATOR>
742 typename bsl::enable_if<
743 Span_Utility::IsArrayConvertible<
744 const t_OTHER_TYPE, element_type>::value,
745 void *>::type = NULL) BSLS_KEYWORD_NOEXCEPT;
746
747 /// Construct a span from the specified bsl::string `s`. This
748 /// constructor participates in overload resolution only if
749 /// `CHAR_TYPE(*)[]` is convertible to `element_type(*)[]`.
750 template<class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR>
752 typename bsl::enable_if<
753 Span_Utility::IsArrayConvertible<
754 CHAR_TYPE, element_type>::value,
755 void *>::type = NULL) BSLS_KEYWORD_NOEXCEPT;
756
757 /// Construct a span from the specified bsl::string `s`. This
758 /// constructor participates in overload resolution only if
759 /// `const CHAR_TYPE(*)[]` is convertible to `element_type(*)[]`.
760 template<class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR>
762 typename bsl::enable_if<
763 Span_Utility::IsArrayConvertible<
764 const CHAR_TYPE, element_type>::value,
765 void *>::type = NULL) BSLS_KEYWORD_NOEXCEPT;
766
767 /// Construct a span from the specified bsl::string_view `sv`. This
768 /// constructor participates in overload resolution only if
769 /// `const CHAR_TYPE(*)[]` is convertible to `element_type(*)[]`.
770 template<class CHAR_TYPE, class CHAR_TRAITS>
772 typename bsl::enable_if<
773 Span_Utility::IsArrayConvertible<
774 const CHAR_TYPE, element_type>::value,
775 void *>::type = NULL) BSLS_KEYWORD_NOEXCEPT;
776#endif // no BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
777
778#ifdef BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
779 template <class CONTAINER>
781 CONTAINER& c,
782 typename bsl::enable_if<
783 Span_Utility::IsSpanCompatibleContainer<CONTAINER, TYPE>::value,
784 void *>::type = NULL)
785 : d_data_p(bsl::data(c))
786 , d_size(bsl::size(c))
787 {
788 }
789
790 template <class CONTAINER>
792 const CONTAINER& c,
793 typename bsl::enable_if<
794 Span_Utility::IsSpanCompatibleContainer<const CONTAINER, TYPE>::value,
795 void *>::type = NULL)
796 : d_data_p(bsl::data(c))
797 , d_size(bsl::size(c))
798 {
799 }
800#endif // BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
801
802 /// Construct a span from the specified span `other`. This constructor
803 /// participates in overload resolution only if `t_OTHER_TYPE(*)[]` is
804 /// convertible to `element_type(*)[]`.
805 template <class t_OTHER_TYPE, size_t OTHER_EXTENT>
807 span(const span<t_OTHER_TYPE, OTHER_EXTENT>& other,
808 typename bsl::enable_if<
809 Span_Utility::IsArrayConvertible<t_OTHER_TYPE, element_type>::value,
810 void *>::type = NULL) BSLS_KEYWORD_NOEXCEPT;
811
812 /// Destroy this object.
813 ~span() noexcept = default;
814
815 // ACCESSORS
816
817 /// Return a reference to the last element of this span.
818 ///
819 /// \pre The behavior is undefined if this span is empty.
820 BSLS_KEYWORD_CONSTEXPR_CPP14 reference back() const;
821
822 /// Return a pointer to the data referenced by this span.
824
825 // Return `true` if `size() == 0` and `false` otherwise.
827
828 /// Return a statically-sized span consisting of the first `COUNT` elements of this span.
829 ///
830 /// \pre The behavior is undefined unless
831 /// `COUNT <= size()`.
832 template <size_t COUNT>
834 span<element_type, COUNT> first() const;
835
836 /// Return a dynamically-sized span consisting of the first (specified) `count` elements of this span.
837 ///
838 /// \pre The behavior is undefined unless
839 /// `count <= size()`.
841 span<element_type, dynamic_extent>
842 first(size_type count) const;
843
844 /// Return a reference to the first element of this span.
845 ///
846 /// \pre The behavior is undefined if this span is empty.
847 BSLS_KEYWORD_CONSTEXPR_CPP14 reference front() const;
848
849 /// Return a statically-sized span consisting of the last `COUNT` elements of this span.
850 ///
851 /// \pre The behavior is undefined unless
852 /// `COUNT <= size()`.
853 template <size_t COUNT>
855 span<element_type, COUNT> last() const;
856
857 /// Return a dynamically-sized span consisting of the last (specified) `count` elements of this span.
858 ///
859 /// \pre The behavior is undefined unless
860 /// `count <= size()`.
862 span<element_type, dynamic_extent>
863 last(size_type count) const;
864
865 /// Return the size of this span.
866 BSLS_KEYWORD_CONSTEXPR size_type size() const BSLS_KEYWORD_NOEXCEPT;
867
868 /// Return the size of this span in bytes.
869 BSLS_KEYWORD_CONSTEXPR size_type size_bytes() const BSLS_KEYWORD_NOEXCEPT;
870
871 /// Return a dynamically-sized span consisting of the `COUNT` elements of this span starting at `OFFSET`.
872 ///
873 /// \pre The behavior is undefined unless
874 /// `COUNT + OFFSET <= size()`.
875 template <size_t OFFSET,
876#ifdef BSLS_COMPILERFEATURES_SUPPORT_DEFAULT_TEMPLATE_ARGS
877 size_t COUNT = dynamic_extent>
878#else
879 size_t COUNT>
880#endif
882 span<element_type, COUNT> subspan() const;
883
884 /// Return a dynamically-sized span starting at the specified `offset`.
885 /// If the optionally specified `count` is @ref dynamic_extent , the span
886 /// will consist of the half-open range `[offset, size () - offset)` and
887 /// the behavior is undefined unless `offset <= size()`. Otherwise, the
888 /// span will consist of the half-open range `[offset, count)` and the
889 /// behavior is undefined unless `offset + count <= size()`.
890 BSLS_KEYWORD_CONSTEXPR_CPP14 span<element_type, dynamic_extent>
891 subspan(size_type offset, size_type count = dynamic_extent) const;
892
893 /// Return a reference to the element at the specified `index`.
894 ///
895 /// \pre The behavior is undefined unless `index < size()`.
897 reference operator[](size_type index) const;
898
899 /// Return a reference to the element at the specified `index`. Throws
900 /// an @ref out_of_range exception if `index >= size()`.
902 reference at(size_type index) const;
903
904 // ITERATOR OPERATIONS
905
906 /// Return an iterator providing modifiable access to the first element
907 /// of this span, and the past-the-end iterator if this span is empty.
909
910 /// Return the past-the-end iterator providing modifiable access to this
911 /// span.
913 iterator end() const BSLS_KEYWORD_NOEXCEPT;
914
915 /// Return a reverse iterator providing modifiable access to the last
916 /// element of this span, and the past-the-end reverse iterator if this
917 /// span is empty.
919 reverse_iterator rbegin() const BSLS_KEYWORD_NOEXCEPT;
920
921 /// Return the past-the-end reverse iterator providing modifiable access
922 /// to this span.
924 reverse_iterator rend() const BSLS_KEYWORD_NOEXCEPT;
925
926 // MANIPULATORS
927
928 /// Assign to this span the value of the specified `rhs` object, and
929 /// return a reference providing modifiable access to this span.
930 constexpr span& operator=(const span&) noexcept = default;
931
932 /// Exchange the value of this span with the value of the specified
933 /// `other` object.
935
936 private:
937 // DATA
938 pointer d_data_p;
939 size_type d_size;
940};
941
942#ifdef BSLS_COMPILERFEATURES_SUPPORT_CTAD
943// CLASS TEMPLATE DEDUCTION GUIDES
944
945/// Deduce the template parameters `TYPE` and `SIZE` from the type and size
946/// of the array supplied to the constructor of `span`.
947template <class TYPE, size_t SIZE>
948span(TYPE (&)[SIZE]) -> span<TYPE, SIZE>;
949
950#ifndef BSLSTL_ARRAY_IS_ALIASED
951/// Deduce the template parameters `TYPE` and `SIZE` from the corresponding
952/// template parameters of the `bsl::array` supplied to the constructor of
953/// `span`.
954template <class TYPE, size_t SIZE>
955span(bsl::array<TYPE, SIZE> &) -> span<TYPE, SIZE>;
956
957/// Deduce the template parameters `TYPE` and `SIZE` from the corresponding
958/// template parameters of the `bsl::array` supplied to the constructor of
959/// `span`.
960template <class TYPE, size_t SIZE>
961span(const bsl::array<TYPE, SIZE> &) -> span<const TYPE, SIZE>;
962#endif // not BSLSTL_ARRAY_IS_ALIASED
963
964/// Deduce the template parameters `TYPE` and `SIZE` from the corresponding
965/// template parameters of the `std::array` supplied to the constructor of
966/// `span`.
967template <class TYPE, size_t SIZE>
968span(std::array<TYPE, SIZE> &) -> span<TYPE, SIZE>;
969
970/// Deduce the template parameters `TYPE` and `SIZE` from the corresponding
971/// template parameters of the `std::array` supplied to the constructor of
972/// `span`.
973template <class TYPE, size_t SIZE>
974span(const std::array<TYPE, SIZE> &) -> span<const TYPE, SIZE>;
975
976/// Deduce the template parameters `TYPE` from the corresponding template
977/// parameter of the `bsl::vector` supplied to the constructor of `span`.
978template <class TYPE, class ALLOCATOR>
979span(bsl::vector<TYPE, ALLOCATOR> &) -> span<TYPE>;
980
981/// Deduce the template parameters `TYPE` from the corresponding template
982/// parameter of the `bsl::vector` supplied to the constructor of `span`.
983template <class TYPE, class ALLOCATOR>
984span(const bsl::vector<TYPE, ALLOCATOR> &) -> span<const TYPE>;
985#endif // BSLS_COMPILERFEATURES_SUPPORT_CTAD
986
987// FREE FUNCTIONS
988#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
989
990/// Return a span referring to same data as the specified `s`, but
991/// referring to the data as a span of non-modifiable bytes.
992template <class TYPE, size_t EXTENT>
993BSLS_KEYWORD_CONSTEXPR_CPP14 span<const std::byte, EXTENT * sizeof(TYPE)>
994as_bytes(span<TYPE, EXTENT> s) BSLS_KEYWORD_NOEXCEPT;
995
996/// Return a span referring to same data as the specified `s`, but
997/// referring to the data as a span of non-modifiable bytes.
998template <class TYPE>
999BSLS_KEYWORD_CONSTEXPR_CPP14 span<const std::byte, dynamic_extent>
1000as_bytes(span<TYPE, dynamic_extent> s) BSLS_KEYWORD_NOEXCEPT;
1001
1002/// Return a span referring to same data as the specified `s`, but
1003/// referring to the data as a span of modifiable bytes.
1004template <class TYPE, size_t EXTENT>
1005BSLS_KEYWORD_CONSTEXPR_CPP14 span<std::byte, EXTENT * sizeof(TYPE)>
1006as_writable_bytes(span<TYPE, EXTENT> s) BSLS_KEYWORD_NOEXCEPT;
1007
1008/// Return a span referring to same data as the specified `s`, but
1009/// referring to the data as a span of modifiable bytes.
1010template <class TYPE>
1011BSLS_KEYWORD_CONSTEXPR_CPP14 span<std::byte, dynamic_extent>
1012as_writable_bytes(span<TYPE, dynamic_extent> s) BSLS_KEYWORD_NOEXCEPT;
1013
1014#endif // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
1015
1016/// Exchange the value of the specified `a` object with the value of the
1017/// specified `b` object.
1018template <class TYPE, size_t EXTENT>
1019BSLS_KEYWORD_CONSTEXPR_CPP14 void swap(span<TYPE, EXTENT>& a,
1020 span<TYPE, EXTENT>& b)
1022
1023} // close namespace bsl
1024
1025// ============================================================================
1026// INLINE DEFINITIONS
1027// ============================================================================
1028
1029 // ----------------
1030 // class span<T, N>
1031 // ----------------
1032
1033// CREATORS
1034template <class TYPE, size_t EXTENT>
1036bsl::span<TYPE, EXTENT>::span() BSLS_KEYWORD_NOEXCEPT
1037: d_data_p(NULL)
1038{
1039 BSLMF_ASSERT(EXTENT == 0);
1040}
1041
1042template <class TYPE, size_t EXTENT>
1044bsl::span<TYPE, EXTENT>::span(pointer ptr, size_type count)
1045: d_data_p(ptr)
1046{
1047 (void)count;
1048 BSLS_ASSERT(EXTENT == count);
1049}
1050
1051template <class TYPE, size_t EXTENT>
1053bsl::span<TYPE, EXTENT>::span(pointer first, pointer last)
1054: d_data_p(first)
1055{
1056 (void)last;
1057 BSLS_ASSERT(EXTENT == bsl::distance(first, last));
1058}
1059
1060
1061template <class TYPE, size_t EXTENT>
1062template <size_t SIZE>
1064bsl::span<TYPE, EXTENT>::span(
1065 typename bsl::Span_Utility::TypeIdentity<element_type>::type (&arr)[SIZE])
1067: d_data_p(arr)
1068{
1069 BSLMF_ASSERT(SIZE == EXTENT);
1070}
1071
1072#ifndef BSLSTL_ARRAY_IS_ALIASED
1073template <class TYPE, size_t EXTENT>
1074template <class t_OTHER_TYPE>
1076bsl::span<TYPE, EXTENT>::span(bsl::array<t_OTHER_TYPE, EXTENT>& arr,
1077 typename bsl::enable_if<
1078 Span_Utility::IsArrayConvertible<t_OTHER_TYPE, element_type>::value,
1079 void *>::type) BSLS_KEYWORD_NOEXCEPT
1080: d_data_p(arr.data())
1081{
1082}
1083
1084template <class TYPE, size_t EXTENT>
1085template <class t_OTHER_TYPE>
1087bsl::span<TYPE, EXTENT>::span(const bsl::array<t_OTHER_TYPE, EXTENT>& arr,
1088 typename bsl::enable_if<
1089 Span_Utility::IsArrayConvertible<
1090 const t_OTHER_TYPE, element_type>::value,
1091 void *>::type) BSLS_KEYWORD_NOEXCEPT
1092: d_data_p(arr.data())
1093{
1094}
1095#endif // not BSLSTL_ARRAY_IS_ALIASED
1096
1097#ifdef BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
1098template <class TYPE, size_t EXTENT>
1099template <class t_OTHER_TYPE>
1101bsl::span<TYPE, EXTENT>::span(std::array<t_OTHER_TYPE, EXTENT>& arr,
1102 typename bsl::enable_if<
1103 Span_Utility::IsArrayConvertible<t_OTHER_TYPE, element_type>::value,
1104 void *>::type) BSLS_KEYWORD_NOEXCEPT
1105: d_data_p(arr.data())
1106{
1107}
1108
1109template <class TYPE, size_t EXTENT>
1110template <class t_OTHER_TYPE>
1112bsl::span<TYPE, EXTENT>::span(const std::array<t_OTHER_TYPE, EXTENT>& arr,
1113 typename bsl::enable_if<
1114 Span_Utility::IsArrayConvertible<const t_OTHER_TYPE, element_type>::value,
1115 void *>::type) BSLS_KEYWORD_NOEXCEPT
1116: d_data_p(arr.data())
1117{
1118}
1119#endif // BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
1120
1121template <class TYPE, size_t EXTENT>
1122template <class t_OTHER_TYPE>
1124bsl::span<TYPE, EXTENT>::span(const bsl::span<t_OTHER_TYPE, EXTENT>& other,
1125 typename bsl::enable_if<
1126 Span_Utility::IsArrayConvertible<t_OTHER_TYPE, element_type>::value,
1127 void *>::type) BSLS_KEYWORD_NOEXCEPT
1128: d_data_p(other.data())
1129{
1130}
1131
1132
1133template <class TYPE, size_t EXTENT>
1134template <class t_OTHER_TYPE>
1136bsl::span<TYPE, EXTENT>::span(
1137 const bsl::span<t_OTHER_TYPE, bsl::dynamic_extent>& other,
1138 typename bsl::enable_if<
1139 Span_Utility::IsArrayConvertible<t_OTHER_TYPE, element_type>::value,
1140 void *>::type) BSLS_KEYWORD_NOEXCEPT
1141: d_data_p(other.data())
1142{
1143 BSLS_ASSERT(EXTENT == other.size());
1144}
1145
1146// ACCESSORS
1147template <class TYPE, size_t EXTENT>
1149typename bsl::span<TYPE, EXTENT>::pointer
1150bsl::span<TYPE, EXTENT>::data() const BSLS_KEYWORD_NOEXCEPT
1151{
1152 return d_data_p;
1153}
1154
1155template <class TYPE, size_t EXTENT>
1157bool bsl::span<TYPE, EXTENT>::empty() const BSLS_KEYWORD_NOEXCEPT
1158{
1159 return 0 == EXTENT;
1160}
1161
1162template <class TYPE, size_t EXTENT>
1163template <size_t COUNT>
1165bsl::span<TYPE, COUNT>
1166bsl::span<TYPE, EXTENT>::first() const
1167{
1168 typedef bsl::span<TYPE, COUNT> ReturnType;
1169 BSLMF_ASSERT(COUNT <= EXTENT);
1170 return ReturnType(data(), COUNT);
1171}
1172
1173template <class TYPE, size_t EXTENT>
1175bsl::span<TYPE, bsl::dynamic_extent>
1176bsl::span<TYPE, EXTENT>::first(size_type count) const
1177{
1178 typedef bsl::span<TYPE, bsl::dynamic_extent> ReturnType;
1179 BSLS_ASSERT(count <= size());
1180 return ReturnType(data(), count);
1181}
1182
1183template <class TYPE, size_t EXTENT>
1184template <size_t COUNT>
1186bsl::span<TYPE, COUNT>
1187bsl::span<TYPE, EXTENT>::last() const
1188{
1189 typedef bsl::span<TYPE, COUNT> ReturnType;
1190 BSLMF_ASSERT(COUNT <= EXTENT);
1191 return ReturnType(data() + size() - COUNT, COUNT);
1192}
1193
1194template <class TYPE, size_t EXTENT>
1196bsl::span<TYPE, bsl::dynamic_extent>
1197bsl::span<TYPE, EXTENT>::last(size_type count) const
1198{
1199 typedef bsl::span<TYPE, bsl::dynamic_extent> ReturnType;
1200 BSLS_ASSERT(count <= size());
1201 return ReturnType(data() + size() - count, count);
1202}
1203
1204template <class TYPE, size_t EXTENT>
1206typename bsl::span<TYPE, EXTENT>::size_type
1207bsl::span<TYPE, EXTENT>::size_bytes() const BSLS_KEYWORD_NOEXCEPT
1208{
1209 return EXTENT * sizeof(element_type);
1210}
1211
1212template <class TYPE, size_t EXTENT>
1214bsl::span<TYPE, bsl::dynamic_extent>
1215bsl::span<TYPE, EXTENT>::subspan(size_type offset, size_type count) const
1216{
1217 typedef bsl::span<TYPE, bsl::dynamic_extent> ReturnType;
1218 BSLS_ASSERT(offset <= size());
1219 BSLS_ASSERT(count <= size() || count == bsl::dynamic_extent);
1220 if (count == bsl::dynamic_extent)
1221 return ReturnType(data() + offset, size() - offset); // RETURN
1222
1223 BSLS_ASSERT(offset <= size() - count);
1224 return ReturnType(data() + offset, count);
1225}
1226
1227template <class TYPE, size_t EXTENT>
1229typename bsl::span<TYPE, EXTENT>::reference
1230bsl::span<TYPE, EXTENT>::at(size_type index) const
1231{
1234 BloombergLP::bslstl::StdExceptUtil::throwOutOfRange(
1235 "span<T, static_extent>::at(index): invalid index");
1236 }
1237 return d_data_p[index];
1238}
1239
1240// ITERATOR OPERATIONS
1241template <class TYPE, size_t EXTENT>
1243typename bsl::span<TYPE, EXTENT>::iterator
1244bsl::span<TYPE, EXTENT>::begin() const BSLS_KEYWORD_NOEXCEPT
1245{
1246 return iterator(data());
1247}
1248
1249template <class TYPE, size_t EXTENT>
1251typename bsl::span<TYPE, EXTENT>::iterator
1252bsl::span<TYPE, EXTENT>::end() const BSLS_KEYWORD_NOEXCEPT
1253{
1254 return iterator(data() + size());
1255}
1256
1257template <class TYPE, size_t EXTENT>
1259typename bsl::span<TYPE, EXTENT>::reverse_iterator
1260bsl::span<TYPE, EXTENT>::rbegin() const BSLS_KEYWORD_NOEXCEPT
1261{
1262 return reverse_iterator(end());
1263}
1264
1265template <class TYPE, size_t EXTENT>
1267typename bsl::span<TYPE, EXTENT>::reverse_iterator
1268bsl::span<TYPE, EXTENT>::rend() const BSLS_KEYWORD_NOEXCEPT
1269{
1270 return reverse_iterator(begin());
1271}
1272
1273// MANIPULATORS
1274template <class TYPE, size_t EXTENT>
1276void bsl::span<TYPE, EXTENT>::swap(span &other) BSLS_KEYWORD_NOEXCEPT
1277{
1278 pointer p = d_data_p;
1279 d_data_p = other.d_data_p;
1280 other.d_data_p = p;
1281}
1282
1283 // -----------------------------------------
1284 // class span<T, bsl::dynamic_extent>
1285 // -----------------------------------------
1286
1287// CREATORS
1288template <class TYPE>
1290bsl::span<TYPE, bsl::dynamic_extent>::span() BSLS_KEYWORD_NOEXCEPT
1291: d_data_p(NULL)
1292, d_size(0)
1293{
1294}
1295
1296template <class TYPE>
1298bsl::span<TYPE, bsl::dynamic_extent>::span(pointer ptr, size_type count)
1299: d_data_p(ptr)
1300, d_size(count)
1301{
1302}
1303
1304template <class TYPE>
1306bsl::span<TYPE, bsl::dynamic_extent>::span(pointer first, pointer last)
1307: d_data_p(first)
1308, d_size(bsl::distance(first, last))
1309{
1310}
1311
1312
1313template <class TYPE>
1314template <size_t SIZE>
1316bsl::span<TYPE, bsl::dynamic_extent>::span(
1317 typename bsl::Span_Utility::TypeIdentity<element_type>::type (&arr)[SIZE])
1319: d_data_p(arr)
1320, d_size(SIZE)
1321{
1322}
1323
1324#ifndef BSLSTL_ARRAY_IS_ALIASED
1325template <class TYPE>
1326template <class t_OTHER_TYPE, size_t SIZE>
1328bsl::span<TYPE, bsl::dynamic_extent>::span(
1330 typename bsl::enable_if<
1331 Span_Utility::IsArrayConvertible<t_OTHER_TYPE, element_type>::value,
1332 void *>::type) BSLS_KEYWORD_NOEXCEPT
1333: d_data_p(arr.data())
1334, d_size(SIZE)
1335{
1336}
1337
1338template <class TYPE>
1339template <class t_OTHER_TYPE, size_t SIZE>
1341bsl::span<TYPE, bsl::dynamic_extent>::span(
1343 typename bsl::enable_if<
1344 Span_Utility::IsArrayConvertible<const t_OTHER_TYPE, element_type>::value,
1345 void *>::type) BSLS_KEYWORD_NOEXCEPT
1346: d_data_p(arr.data())
1347, d_size(SIZE)
1348{
1349}
1350#endif // not BSLSTL_ARRAY_IS_ALIASED
1351
1352#ifdef BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
1353template <class TYPE>
1354template <class t_OTHER_TYPE, size_t SIZE>
1356bsl::span<TYPE, bsl::dynamic_extent>::span(
1357 std::array<t_OTHER_TYPE, SIZE>& arr,
1358 typename bsl::enable_if<
1359 Span_Utility::IsArrayConvertible<t_OTHER_TYPE, element_type>::value,
1360 void *>::type) BSLS_KEYWORD_NOEXCEPT
1361: d_data_p(arr.data())
1362, d_size(SIZE)
1363{
1364}
1365
1366template <class TYPE>
1367template <class t_OTHER_TYPE, size_t SIZE>
1369bsl::span<TYPE, bsl::dynamic_extent>::span(
1370 const std::array<t_OTHER_TYPE, SIZE>& arr,
1371 typename bsl::enable_if<
1372 Span_Utility::IsArrayConvertible<
1373 const t_OTHER_TYPE, element_type>::value,
1374 void *>::type) BSLS_KEYWORD_NOEXCEPT
1375: d_data_p(arr.data())
1376, d_size(SIZE)
1377{
1378}
1379#endif // BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
1380
1381#ifndef BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
1382template <class TYPE>
1383template <class t_OTHER_TYPE, class ALLOCATOR>
1384inline bsl::span<TYPE, bsl::dynamic_extent>::span(
1386 typename bsl::enable_if<Span_Utility::IsArrayConvertible<
1387 t_OTHER_TYPE, element_type>::value,
1388 void *>::type) BSLS_KEYWORD_NOEXCEPT
1389: d_data_p(v.data())
1390, d_size(v.size())
1391{
1392}
1393
1394template <class TYPE>
1395template <class t_OTHER_TYPE, class ALLOCATOR>
1396inline bsl::span<TYPE, bsl::dynamic_extent>::span(
1398 typename bsl::enable_if<Span_Utility::IsArrayConvertible<
1399 const t_OTHER_TYPE, element_type>::value,
1400 void *>::type) BSLS_KEYWORD_NOEXCEPT
1401: d_data_p(v.data())
1402, d_size(v.size())
1403{
1404}
1405
1406template <class TYPE>
1407template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR>
1408inline bsl::span<TYPE, bsl::dynamic_extent>::span(
1410 typename bsl::enable_if<Span_Utility::IsArrayConvertible<
1411 CHAR_TYPE, element_type>::value,
1412 void *>::type) BSLS_KEYWORD_NOEXCEPT
1413: d_data_p(s.data())
1414, d_size(s.size())
1415{
1416}
1417
1418template <class TYPE>
1419template <class CHAR_TYPE, class CHAR_TRAITS, class ALLOCATOR>
1420inline bsl::span<TYPE, bsl::dynamic_extent>::span(
1422 typename bsl::enable_if<Span_Utility::IsArrayConvertible<
1423 const CHAR_TYPE, element_type>::value,
1424 void *>::type) BSLS_KEYWORD_NOEXCEPT
1425: d_data_p(s.data())
1426, d_size(s.size())
1427{
1428}
1429
1430template <class TYPE>
1431template <class CHAR_TYPE, class CHAR_TRAITS>
1432inline bsl::span<TYPE, bsl::dynamic_extent>::span(
1434 typename bsl::enable_if<Span_Utility::IsArrayConvertible<
1435 const CHAR_TYPE, element_type>::value,
1436 void *>::type) BSLS_KEYWORD_NOEXCEPT
1437: d_data_p(sv.data())
1438, d_size(sv.size())
1439{
1440}
1441#endif // no BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY
1442
1443template <class TYPE>
1444template <class t_OTHER_TYPE, size_t OTHER_EXTENT>
1446bsl::span<TYPE, bsl::dynamic_extent>::span(
1447 const bsl::span<t_OTHER_TYPE, OTHER_EXTENT>& other,
1448 typename bsl::enable_if<
1449 Span_Utility::IsArrayConvertible<t_OTHER_TYPE, element_type>::value,
1450 void *>::type) BSLS_KEYWORD_NOEXCEPT
1451: d_data_p(other.data())
1452, d_size(other.size())
1453{
1454}
1455
1456// ACCESSORS
1457template <class TYPE>
1459typename bsl::span<TYPE, bsl::dynamic_extent>::reference
1460bsl::span<TYPE, bsl::dynamic_extent>::back() const
1461{
1462 BSLS_ASSERT(size() > 0);
1463 return d_data_p[size() - 1];
1464}
1465
1466template <class TYPE>
1468typename bsl::span<TYPE, bsl::dynamic_extent>::pointer
1469bsl::span<TYPE, bsl::dynamic_extent>::data() const BSLS_KEYWORD_NOEXCEPT
1470{
1471 return d_data_p;
1472}
1473
1474template <class TYPE>
1476bool
1477bsl::span<TYPE, bsl::dynamic_extent>::empty() const BSLS_KEYWORD_NOEXCEPT
1478{
1479 return 0 == size();
1480}
1481
1482template <class TYPE>
1483template <size_t COUNT>
1485bsl::span<TYPE, COUNT>
1486bsl::span<TYPE, bsl::dynamic_extent>::first() const
1487{
1488 typedef bsl::span<TYPE, COUNT> ReturnType;
1489 BSLS_ASSERT(COUNT <= size());
1490 return ReturnType(data(), COUNT);
1491}
1492
1493template <class TYPE>
1495bsl::span<TYPE, bsl::dynamic_extent>
1496bsl::span<TYPE, bsl::dynamic_extent>::first(size_type count) const
1497{
1498 typedef bsl::span<TYPE, bsl::dynamic_extent> ReturnType;
1499 BSLS_ASSERT(count <= size());
1500 return ReturnType(data(), count);
1501}
1502
1503template <class TYPE>
1505typename bsl::span<TYPE, bsl::dynamic_extent>::reference
1506bsl::span<TYPE, bsl::dynamic_extent>::front() const
1507{
1508 BSLS_ASSERT(size() > 0);
1509 return d_data_p[0];
1510}
1511
1512template <class TYPE>
1513template <size_t COUNT>
1515bsl::span<TYPE, COUNT>
1516bsl::span<TYPE, bsl::dynamic_extent>::last() const
1517{
1518 typedef bsl::span<TYPE, COUNT> ReturnType;
1519 BSLS_ASSERT(COUNT <= size());
1520 return ReturnType(data() + size() - COUNT, COUNT);
1521}
1522
1523template <class TYPE>
1525bsl::span<TYPE, bsl::dynamic_extent>
1526bsl::span<TYPE, bsl::dynamic_extent>::last(size_type count) const
1527{
1528 typedef bsl::span<TYPE, bsl::dynamic_extent> ReturnType;
1529 BSLS_ASSERT(count <= size());
1530 return ReturnType(data() + size() - count, count);
1531}
1532
1533template <class TYPE>
1535typename bsl::span<TYPE, bsl::dynamic_extent>::size_type
1536bsl::span<TYPE, bsl::dynamic_extent>::size() const BSLS_KEYWORD_NOEXCEPT
1537{
1538 return d_size;
1539}
1540
1541template <class TYPE>
1543typename bsl::span<TYPE, bsl::dynamic_extent>::size_type
1544bsl::span<TYPE, bsl::dynamic_extent>::size_bytes() const
1546{
1547 return size() * sizeof(element_type);
1548}
1549
1550template <class TYPE>
1551template <size_t OFFSET, size_t COUNT>
1553bsl::span<TYPE, COUNT>
1554bsl::span<TYPE, bsl::dynamic_extent>::subspan() const
1555{
1556 typedef bsl::span<TYPE, COUNT> ReturnType;
1557 BSLS_ASSERT(OFFSET <= size());
1558 BSLS_ASSERT(COUNT == bsl::dynamic_extent || OFFSET + COUNT <= size());
1559 return ReturnType(data() + OFFSET,
1560 COUNT == bsl::dynamic_extent ? size() - OFFSET : COUNT);
1561}
1562
1563template <class TYPE>
1565bsl::span<TYPE, bsl::dynamic_extent>
1566bsl::span<TYPE, bsl::dynamic_extent>::subspan(size_type offset,
1567 size_type count) const
1568{
1569 typedef bsl::span<TYPE, bsl::dynamic_extent> ReturnType;
1570 BSLS_ASSERT(offset <= size());
1571 BSLS_ASSERT(count <= size() || count == bsl::dynamic_extent);
1572 if (count == bsl::dynamic_extent)
1573 return ReturnType(data() + offset, size() - offset); // RETURN
1574
1575 BSLS_ASSERT(offset <= size() - count);
1576 return ReturnType(data() + offset, count);
1577}
1578
1579template <class TYPE>
1581typename bsl::span<TYPE, bsl::dynamic_extent>::reference
1582bsl::span<TYPE, bsl::dynamic_extent>::operator[](size_type index) const
1583{
1584 BSLS_ASSERT(index < size());
1585 return d_data_p[index];
1586}
1587
1588template <class TYPE>
1590typename bsl::span<TYPE, bsl::dynamic_extent>::reference
1591bsl::span<TYPE, bsl::dynamic_extent>::at(size_type index) const
1592{
1595 BloombergLP::bslstl::StdExceptUtil::throwOutOfRange(
1596 "span<T, dynamic_extent>::at(index): invalid index");
1597 }
1598 return d_data_p[index];
1599}
1600
1601// MANIPULATORS
1602template <class TYPE>
1604void bsl::span<TYPE, bsl::dynamic_extent>::swap(span &other)
1606{
1607 pointer p = d_data_p;
1608 d_data_p = other.d_data_p;
1609 other.d_data_p = p;
1610
1611 size_t sz = d_size;
1612 d_size = other.d_size;
1613 other.d_size = sz;
1614}
1615
1616// ITERATOR OPERATIONS
1617template <class TYPE>
1619typename bsl::span<TYPE, bsl::dynamic_extent>::iterator
1620bsl::span<TYPE, bsl::dynamic_extent>::begin() const BSLS_KEYWORD_NOEXCEPT
1621{
1622 return iterator(data());
1623}
1624
1625template <class TYPE>
1627typename bsl::span<TYPE, bsl::dynamic_extent>::iterator
1628bsl::span<TYPE, bsl::dynamic_extent>::end() const BSLS_KEYWORD_NOEXCEPT
1629{
1630 return iterator(data() + size());
1631}
1632
1633template <class TYPE>
1635typename bsl::span<TYPE, bsl::dynamic_extent>::reverse_iterator
1636bsl::span<TYPE, bsl::dynamic_extent>::rbegin() const BSLS_KEYWORD_NOEXCEPT
1637{
1638 return reverse_iterator(end());
1639}
1640
1641template <class TYPE>
1643typename bsl::span<TYPE, bsl::dynamic_extent>::reverse_iterator
1644bsl::span<TYPE, bsl::dynamic_extent>::rend() const BSLS_KEYWORD_NOEXCEPT
1645{
1646 return reverse_iterator(begin());
1647}
1648
1649// FREE FUNCTIONS
1650#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
1651// BDE_VERIFY pragma: push
1652// BDE_VERIFY pragma: -SAL01: // Possible strict-aliasing violation
1653
1654template <class TYPE, size_t EXTENT>
1656bsl::span<const std::byte, EXTENT * sizeof(TYPE)>
1657bsl::as_bytes(bsl::span<TYPE, EXTENT> s) BSLS_KEYWORD_NOEXCEPT
1658{
1659 return bsl::span<const std::byte, EXTENT * sizeof(TYPE)> (
1660 reinterpret_cast<const std::byte *>(s.data()),
1661 s.size_bytes());
1662}
1663
1664template <class TYPE>
1666bsl::span<const std::byte, bsl::dynamic_extent>
1667bsl::as_bytes(bsl::span<TYPE, bsl::dynamic_extent> s) BSLS_KEYWORD_NOEXCEPT
1668{
1669 return bsl::span<const std::byte, bsl::dynamic_extent>(
1670 reinterpret_cast<const std::byte *>(s.data()),
1671 s.size_bytes());
1672}
1673
1674template <class TYPE, size_t EXTENT>
1676bsl::span<std::byte, EXTENT * sizeof(TYPE)>
1677bsl::as_writable_bytes(bsl::span<TYPE, EXTENT> s) BSLS_KEYWORD_NOEXCEPT
1678{
1679 return bsl::span<std::byte, EXTENT * sizeof(TYPE)>(
1680 reinterpret_cast<std::byte *>(s.data()),
1681 s.size_bytes());
1682}
1683
1684template <class TYPE>
1686bsl::span<std::byte, bsl::dynamic_extent>
1687bsl::as_writable_bytes(bsl::span<TYPE, bsl::dynamic_extent> s)
1689{
1690 return bsl::span<std::byte, bsl::dynamic_extent>(
1691 reinterpret_cast<std::byte *>(s.data()),
1692 s.size_bytes());
1693}
1694
1695// BDE_VERIFY pragma: pop
1696#endif // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
1697
1698template <class TYPE, size_t EXTENT>
1700void
1701bsl::swap(bsl::span<TYPE, EXTENT>& a, bsl::span<TYPE, EXTENT>& b)
1703{
1704 a.swap(b);
1705}
1706
1707#endif // BSLSTL_SPAN_IS_ALIASED
1708
1709#endif
1710
1711// ----------------------------------------------------------------------------
1712// Copyright 2022 Bloomberg Finance L.P.
1713//
1714// Licensed under the Apache License, Version 2.0 (the "License");
1715// you may not use this file except in compliance with the License.
1716// You may obtain a copy of the License at
1717//
1718// http://www.apache.org/licenses/LICENSE-2.0
1719//
1720// Unless required by applicable law or agreed to in writing, software
1721// distributed under the License is distributed on an "AS IS" BASIS,
1722// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1723// See the License for the specific language governing permissions and
1724// limitations under the License.
1725// ----------------------------- END-OF-FILE ----------------------------------
1726
1727/** @} */
1728/** @} */
1729/** @} */
#define BSLMF_NESTED_TRAIT_DECLARATION(t_TYPE, t_TRAIT)
Definition bslmf_nestedtraitdeclaration.h:231
Definition bslstl_stringview.h:471
Definition bslstl_string.h:1252
Definition bslstl_vector.h:1120
#define BSLMF_ASSERT(expr)
Definition bslmf_assert.h:231
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1976
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
#define BSLS_KEYWORD_CONSTEXPR_CPP14
Definition bsls_keyword.h:631
#define BSLS_KEYWORD_CONSTEXPR
Definition bsls_keyword.h:624
#define BSLS_KEYWORD_NOEXCEPT
Definition bsls_keyword.h:674
#define BSLS_PERFORMANCEHINT_UNLIKELY_HINT
Definition bsls_performancehint.h:484
#define BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(expr)
Definition bsls_performancehint.h:452
bsl::size_t size(const TYPE &array)
Return the number of elements in the specified array.
iterator_traits< typenamet_RANGE::const_iterator >::difference_type distance(const t_RANGE &range)
Definition bslstl_iterator.h:1779
Definition bdlat_valuetypefunctions.h:939
void swap(array< VALUE_TYPE, SIZE > &lhs, array< VALUE_TYPE, SIZE > &rhs)
T::iterator begin(T &container)
Definition bslstl_iterator.h:1593
BSLS_KEYWORD_CONSTEXPR size_t size(const TYPE(&)[DIMENSION]) BSLS_KEYWORD_NOEXCEPT
Return the dimension of the specified array argument.
Definition bslstl_iterator.h:1429
T::iterator end(T &container)
Definition bslstl_iterator.h:1621
BSLS_KEYWORD_CONSTEXPR CONTAINER::value_type * data(CONTAINER &container)
Definition bslstl_iterator.h:1325
Definition bdldfp_decimal.h:5549
Definition bslstl_array.h:293
Definition bslmf_enableif.h:530
Definition bslmf_integralconstant.h:261
Definition bslmf_isconvertible.h:875
Definition bslmf_istriviallycopyable.h:324
remove_const< typenameremove_volatile< t_TYPE >::type >::type type
Definition bslmf_removecv.h:128