Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qspan.qdoc
Go to the documentation of this file.
1// Copyright (C) 2023 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
3
4/*!
5 \class QSpan
6 \inmodule QtCore
7 \since 6.7
8 \brief A non-owning container over contiguous data.
9 \ingroup tools
10 \reentrant
11
12 A QSpan references a contiguous portion of another contiguous container.
13 It acts as an interface type for all kinds of contiguous containers,
14 without the need to construct an owning container such as QList or
15 std::vector first.
16
17 The data referenced by a QSpan may be represented as an array (or
18 array-compatible data-structure such as QList, std::vector,
19 QVarLengthArray, etc.). QSpan itself merely stores a pointer to the data,
20 so users must ensure that QSpan objects do not outlive the data they
21 reference.
22
23 Unlike views such as QStringView, QLatin1StringView and QUtf8StringView,
24 referenced data can be modified through a QSpan object. To prevent this,
25 construct a QSpan over a \c{const T}:
26
27 \code
28 int numbers[] = {0, 1, 2};
29 QSpan<int> span = numbers;
30 span[0] = 42;
31 // numbers == {42, 1, 2};
32 QSpan<const int> cspan = numbers;
33 cspan[0] = 0; // ERROR: cspan[0] is read-only
34 \endcode
35
36 A QSpan can be \e{fixed-size} or \e{variable-sized}.
37
38 A variable-sized span is formed by omitting the second template argument
39 (or setting it to \c{std::dynamic_extent}, which is, however, only
40 available in C++20 builds), as seen in the example above.
41
42 A fixed-size span is formed by passing a number as the second template
43 argument:
44
45 \code
46 int numbers[] = {0, 1, 2};
47 QSpan<int, 3> span = numbers;
48 QSpan<const int, 3> = numbers; // also OK
49 \endcode
50
51 As the name suggests, a fixed-size span's size() is fixed at compile-time
52 whereas the size() of a variable-sized span is determined only at run-time.
53
54 A fixed-size span is not default-constructible (unless its \l extent is zero
55 (0)). A variable-sized span \e{is} default-constructible and will have
56 \c{data() == nullptr} and \c{size() == 0}.
57
58 A fixed-size span can be implicitly converted into a variable-sized one.
59 The opposite direction (variable-length into fixed-length) has the
60 precondition that both span's sizes must match.
61
62 Unlike with owning containers, \c{const} is \e{shallow} in QSpan: you can
63 still modify the data through a const QSpan (but not through a
64 \c{QSpan<const T>}), and begin() and end() are not overloaded on
65 \c{const}/non-\c{const}. There are cbegin() and cend(), though, that return
66 const_iterators which prevent modification of the data even though \c{T} is
67 not const:
68 \code
69 int numbers[] = {0, 1, 2};
70 const QSpan<int> span = numbers;
71 span.front() = 42; // OK, numbers[0] == 42 now
72 *span.begin() = 31; // OK, numbers[0] == 31 now
73 *span.cbegin() = -1; // ERROR: cannot assign through a const_iterator
74 \endcode
75
76 QSpan should be passed by value, not by reference-to-const:
77
78 \code
79 void consume(QSpan<const int> data); // OK
80 void consume(const QSpan<const int> &data); // works, but is non-idiomatic and less efficient
81 \endcode
82
83 \c{QSpan<T,N>} is a \e{Literal Type}, regardless of whether \c{T} is a
84 Literal Type or not.
85
86 \section2 QSpan vs. std::span
87 \target span-STL
88
89 QSpan is closely modelled after
90 \l{https://en.cppreference.com/w/cpp/container/span}{std::span}, but has a
91 few differences which we'll discuss here. Since they both implicitly
92 convert into each other, you're free to choose whichever one you like best
93 in your own code.
94
95 \list
96 \li QSpan is using the signed qsizetype as \c{size_type}
97 whereas \c{std::span} uses \c{size_t}.
98 \li All QSpan constructors are implicit;
99 many \c{std::span} ones are \c{explicit}.
100 \li QSpan can be constructed from rvalue owning containers, \c{std::span} can not.
101 \endlist
102
103 The last two are required for source-compatibility when functions that took
104 owning containers are converted to take QSpan instead, which is a
105 vitally-important use-case in Qt. The use of qsizetype is for consistency
106 with the rest of Qt containers. QSpan template arguments still use size_t
107 to avoid introducing unnecessary error conditions (negative sizes).
108
109 \section2 Compatible Iterators
110 \target span-compatible-iterators
111
112 QSpan can be constructed from an iterator and size or from an
113 iterator pair, provided the iterators are \e{compatible} ones.
114 Eventually, this should mean C++20 \c{std::contiguous_iterator} and
115 \c{std::sentinel_for}, but while Qt still supports C++17, only raw pointers
116 are considered contiguous iterators.
117
118 \section2 Compatible Ranges
119 \target span-compatible-ranges
120
121 QSpan can also be constructed from a \e{compatible} range. A range is
122 compatible if it has \l{span-compatible-iterators}{compatible iterators}.
123
124 \sa QList, QStringView, QLatin1StringView, QUtf8StringView
125*/
126
127//
128// Nested types and constants
129//
130
131/*!
132 \typedef QSpan::element_type
133
134 An alias for \c{T}. Includes the \c{const}, if any.
135
136 This alias is provided for compatbility with the STL.
137
138 \sa value_type, pointer
139*/
140
141/*!
142 \typedef QSpan::value_type
143
144 An alias for \c{T}. Excludes the \c{const}, if any.
145
146 This alias is provided for compatbility with the STL.
147
148 \sa element_type
149*/
150
151/*!
152 \typedef QSpan::size_type
153
154 An alias for qsizetype. This \l{span-STL}{differs from \c{std::span}}.
155
156 This alias is provided for compatbility with the STL.
157*/
158
159/*!
160 \typedef QSpan::difference_type
161
162 An alias for qptrdiff. This \l{span-STL}{differs from \c{std::span}}.
163
164 This alias is provided for compatbility with the STL.
165*/
166
167/*!
168 \typedef QSpan::pointer
169
170 An alias for \c{T*} and \c{element_type*}, respectively. Includes the \c{const}, if any.
171
172 This alias is provided for compatbility with the STL.
173
174 \sa element_type, const_pointer, reference, iterator
175*/
176
177/*!
178 \typedef QSpan::const_pointer
179
180 An alias for \c{const T*} and \c{const element_type*}, respectively.
181
182 This alias is provided for compatbility with the STL.
183
184 \sa element_type, pointer, const_reference, const_iterator
185*/
186
187/*!
188 \typedef QSpan::reference
189
190 An alias for \c{T&} and \c{element_type&}, respectively. Includes the \c{const}, if any.
191
192 This alias is provided for compatbility with the STL.
193
194 \sa element_type, const_reference, pointer
195*/
196
197/*!
198 \typedef QSpan::const_reference
199
200 An alias for \c{const T&} and \c{const element_type&}, respectively.
201
202 This alias is provided for compatbility with the STL.
203
204 \sa element_type, reference, const_pointer
205*/
206
207/*!
208 \typedef QSpan::iterator
209
210 An alias for \c{T*} and \c{pointer}, respectively. Includes the \c{const}, if any.
211
212 \sa pointer, const_iterator, reverse_iterator
213*/
214
215/*!
216 \typedef QSpan::const_iterator
217
218 An alias for \c{const T*} and \c{const_pointer}, respectively.
219
220 \sa const_pointer, iterator, const_reverse_iterator
221*/
222
223/*!
224 \typedef QSpan::reverse_iterator
225
226 An alias for \c{std::reverse_iterator<iterator>}. Includes the \c{const}, if any.
227
228 \sa iterator, const_reverse_iterator
229*/
230
231/*!
232 \typedef QSpan::const_reverse_iterator
233
234 An alias for \c{std::reverse_iterator<const_iterator>}.
235
236 \sa const_iterator, reverse_iterator
237*/
238
239/*!
240 \variable QSpan::extent
241
242 The second template argument of \c{QSpan<T, E>}, that is, \c{E}. This is
243 \c{std::dynamic_extent} for variable-sized spans.
244
245 \note While all other sizes and indexes in QSpan use qsizetype, this
246 variable, like \c{E}, is actually of type \c{size_t}, for compatibility with
247 \c{std::span} and \c{std::dynamic_extent}.
248
249 \sa size()
250*/
251
252//
253// Constructors and SMFs
254//
255
256/*!
257 \fn template <typename T, size_t E> QSpan<T,E>::QSpan()
258
259 Default constructor.
260
261 This constructor is only present if \c{E} is either zero (0) or
262 \c{std::dynamic_extent}. In other words: only fixed-zero-sized or variable-sized spans
263 are default-constructible.
264
265 \sa extent
266*/
267
268/*!
269 \fn template <typename T, size_t E> QSpan<T,E>::QSpan(const QSpan &other)
270 \fn template <typename T, size_t E> QSpan<T,E>::QSpan(QSpan &&other)
271 \fn template <typename T, size_t E> QSpan<T,E> &QSpan<T,E>::operator=(const QSpan &other)
272 \fn template <typename T, size_t E> QSpan<T,E> &QSpan<T,E>::operator=(QSpan &&other)
273 \fn template <typename T, size_t E> QSpan<T,E>::~QSpan()
274
275 These Special Member Functions are implicitly-defined.
276
277 \note Moves are equivalent to copies. Only data() and size() are copied
278 from span to span, not the referenced data.
279*/
280
281/*!
282 \fn template <typename T, size_t E> template <typename It, QSpan<T, E>::if_compatible_iterator<It>> QSpan<T,E>::QSpan(It first, qsizetype count)
283
284 Constructs a QSpan referencing the data starting at \a first and having length
285 \a count.
286
287 \c{[first, count)} must be a valid range.
288
289 \note This constructor participates in overload resolution only if \c{It}
290 is \l{span-compatible-iterators}{a compatible iterator}.
291*/
292
293/*!
294 \fn template <typename T, size_t E> template <typename It, QSpan<T, E>::if_compatible_iterator<It>> QSpan<T,E>::QSpan(It first, It last)
295
296 Constructs a QSpan referencing the data starting at \a first and having length
297 (\a last - \a first).
298
299 \c{[first, last)} must be a valid range.
300
301 \note This constructor participates in overload resolution only if \c{It}
302 is \l{span-compatible-iterators}{a compatible iterator}.
303*/
304
305/*!
306 \fn template <typename T, size_t E> template <size_t N> QSpan<T,E>::QSpan(q20::type_identity_t<T> (&arr)[N]);
307 \fn template <typename T, size_t E> template <typename S, size_t N, QSpan<T, E>::if_qualification_conversion<S> = true> QSpan<T,E>::QSpan(std::array<S, N> &arr);
308 \fn template <typename T, size_t E> template <typename S, size_t N, QSpan<T, E>::if_qualification_conversion<S> = true> QSpan<T,E>::QSpan(const std::array<S, N> &arr);
309
310 Constructs a QSpan referencing the data in the supplied array \a arr.
311
312 \note This constructor participates in overload resolution only if
313 \list
314 \li either \c{N} or \l{extent} are \c{std::dynamic_extent} or otherwise \l{extent} \c{==} \c{N}
315 \li and either \c{S} or \c{const S} are the same as \c{T}.
316 \endlist
317
318 \note \c{q20::type_identity_t} is a C++17 backport of C++20's
319 \l{https://en.cppreference.com/w/cpp/types/type_identity}{\c{std::type_identity_t}}.
320*/
321
322/*!
323 \fn template <typename T, size_t E> template <typename Range, QSpan<T, E>::if_compatible_range<Range> = true> QSpan<T,E>::QSpan(Range &&r)
324
325 Constructs a QSpan referencing the data in the supplied range \a r.
326
327 \note This constructor participates in overload resolution only if \c{Range}
328 is \l{span-compatible-ranges}{a compatible range}.
329*/
330
331/*!
332 \fn template <typename T, size_t E> template <typename S, size_t N, QSpan<T, E>::if_qualification_conversion<S> = true> QSpan<T,E>::QSpan(QSpan<S, N> other);
333 \fn template <typename T, size_t E> template <typename S, size_t N, QSpan<T, E>::if_qualification_conversion<S> = true> QSpan<T,E>::QSpan(std::span<S, N> other);
334
335 Constructs a QSpan referencing the data in the supplied span \a other.
336
337 \note This constructor participates in overload resolution only if
338 \list
339 \li either \c{N} or \l{extent} are \c{std::dynamic_extent} or \l{extent} \c{==} \c{N}
340 \li and either \c{S} or \c{const S} are the same as \c{T}.
341 \endlist
342*/
343
344/*!
345 \fn template <typename T, size_t E> QSpan<T, E>::QSpan(std::initializer_list<value_type> il);
346
347 Constructs a QSpan referencing the data in the supplied initializer list \a il.
348
349 \note This constructor participates in overload resolution only if \c{T} is \c{const}-qualified.
350
351 \note This constructor is \c{noexcept} only if \c{E} is \c{std::dynamic_extent}.
352
353 \note If \c{E} is not \c{std::dynamic_extent} and the size of \a il is not \c{E}, the behavior is undefined.
354*/
355
356//
357// Member functions: sizes
358//
359
360/*!
361 \fn template <typename T, size_t E> auto QSpan<T, E>::size() const
362
363 Returns the size of the span, that is, the number of elements it references.
364
365 \sa size_bytes(), empty(), isEmpty()
366*/
367
368/*!
369 \fn template <typename T, size_t E> auto QSpan<T, E>::size_bytes() const
370
371 Returns the size of the span in bytes, that is, the number of elements
372 multiplied by \c{sizeof(T)}.
373
374 \sa size(), empty(), isEmpty()
375*/
376
377/*!
378 \fn template <typename T, size_t E> auto QSpan<T, E>::empty() const
379 \fn template <typename T, size_t E> auto QSpan<T, E>::isEmpty() const
380
381 Returns whether the span is empty, that is, whether \c{size() == 0}.
382
383 These functions do the same thing: empty() is provided for STL
384 compatibility and isEmpty() is provided for Qt compatibility.
385
386 \sa size(), size_bytes()
387*/
388
389//
390// element access
391//
392
393/*!
394 \fn template <typename T, size_t E> QSpan<T, E>::operator[](size_type idx) const
395
396 Returns a reference to the element at index \a idx in the span.
397
398 The index must be in range, that is, \a idx >= 0 and \a idx < size(),
399 otherwise the behavior is undefined.
400
401 \sa front(), back(), size(), empty()
402*/
403
404/*!
405 \fn template <typename T, size_t E> auto QSpan<T, E>::front() const
406
407 Returns a reference to the first element in the span.
408
409 The span must not be empty, otherwise the behavior is undefined.
410
411 \sa operator[](), back(), size(), empty()
412*/
413
414/*!
415 \fn template <typename T, size_t E> auto QSpan<T, E>::back() const
416
417 Returns a reference to the last element in the span.
418
419 The span must not be empty, otherwise the behavior is undefined.
420
421 \sa operator[](), front(), size(), empty()
422*/
423
424/*!
425 \fn template <typename T, size_t E> auto QSpan<T, E>::data() const
426
427 Returns a pointer to the beginning of the span.
428
429 The same as calling begin().
430
431 \sa begin(), front()
432*/
433
434//
435// iterators
436//
437
438/*!
439 \fn template <typename T, size_t E> auto QSpan<T, E>::begin() const
440
441 Returns an interator pointing at the beginning of the span.
442
443 Because QSpan iterators are just pointers, this is the same as calling
444 data().
445
446 \sa end(), cbegin(), rbegin(), crbegin(), data()
447*/
448
449/*!
450 \fn template <typename T, size_t E> auto QSpan<T, E>::end() const
451
452 Returns an iterator pointing to one past the end of the span.
453
454 Because QSpan iterators are just pointers, this it the same as calling
455 \c{data() + size()}.
456
457 \sa begin(), cend(), rend(), crend(), data(), size()
458*/
459
460/*!
461 \fn template <typename T, size_t E> auto QSpan<T, E>::cbegin() const
462
463 Returns a const_iterator pointing to the beginning of the span.
464
465 This will return a read-only iterator even if \c{T} is not \c{const}:
466 \code
467 QSpan<int> span = ~~~;
468 *span.begin() = 42; // OK
469 *span.cbegin() = 42; // ERROR: cannot assign through a const_iterator
470 \endcode
471
472 \sa cend(), begin(), crbegin(), rbegin(), data()
473*/
474
475/*!
476 \fn template <typename T, size_t E> auto QSpan<T, E>::cend() const
477
478 Returns a const_iterator pointing to one past the end of the span.
479
480 \sa cbegin(), end(), crend(), rend(), data(), size()
481*/
482
483/*!
484 \fn template <typename T, size_t E> auto QSpan<T, E>::rbegin() const
485
486 Returns a reverse_iterator pointing to the beginning of the reversed span.
487
488 \sa rend(), crbegin(), begin(), cbegin()
489*/
490
491/*!
492 \fn template <typename T, size_t E> auto QSpan<T, E>::rend() const
493
494 Returns a reverse_iterator pointing to one past the end of the reversed span.
495
496 \sa rbegin(), crend(), end(), cend()
497*/
498
499/*!
500 \fn template <typename T, size_t E> auto QSpan<T, E>::crbegin() const
501
502 Returns a const_reverse_iterator pointing to the beginning of the reversed span.
503
504 \sa crend(), rbegin(), cbegin(), begin()
505*/
506
507/*!
508 \fn template <typename T, size_t E> auto QSpan<T, E>::crend() const
509
510 Returns a const_reverse_iterator pointing to one past the end of the reversed span.
511
512 \sa crbegin(), rend(), cend(), end()
513*/
514
515//
516// compile-time subspans:
517//
518
519/*!
520 \fn template <typename T, size_t E> template <std::size_t Count> auto QSpan<T, E>::first() const
521 \keyword first-t
522
523 Returns a fixed-sized span of size \c{Count} referencing the first \c{Count} elements of \c{*this}.
524
525 The span must hold at least \c{Count} elements (\c{E} >= \c{Count} \e{and}
526 size() >= \c{Count}), otherwise the behavior is undefined.
527
528 \sa first(QSpan<T,E>::size_type), last(), subspan()
529*/
530
531/*!
532 \fn template <typename T, size_t E> template <std::size_t Count> auto QSpan<T, E>::last() const
533 \keyword last-t
534
535 Returns a fixed-sized span of size \c{Count} referencing the last \c{Count} elements of \c{*this}.
536
537 The span must hold at least \c{Count} elements (\c{E} >= \c{Count} \e{and}
538 size() >= \c{Count}), otherwise the behavior is undefined.
539
540 \sa last(QSpan<T,E>::size_type), first(), subspan()
541*/
542
543/*!
544 \fn template <typename T, size_t E> template <std::size_t Offset> auto QSpan<T, E>::subspan() const
545 \keyword subspan-t1
546
547 Returns a span of size \c{E - Offset} referencing the remainder of this span
548 after dropping the first \c{Offset} elements.
549
550 If \c{*this} is a variable-sized span, the return type is a variable-sized
551 span, otherwise it is a fixed-sized span.
552
553 This span must hold at least \c{Offset} elements (\c{E} >= \c{Offset} \e{and}
554 size() >= \c{Offset}), otherwise the behavior is undefined.
555
556 \sa subspan(QSpan<T,E>::size_type), subspan(), first(), last()
557*/
558
559#if 0 // needs fix for QTBUG-118080 integrated into qt5.git
560/*!
561 \fn template <typename T, size_t E> template <std::size_t Offset, std::size_t Count> auto QSpan<T, E>::subspan() const
562 \keyword subspan-t2
563
564 Returns a span of size \c{Count} referencing the \c{Count} elements of this
565 span starting at \c{Offset}.
566
567 If \c{*this} is a variable-sized span, the return type is a variable-sized
568 span, otherwise it is a fixed-sized span.
569
570 This span must hold at least \c{Offset + Count} elements (\c{E} >=
571 \c{Offset + Count} \e{and} size() >= \c{Offset + Count}), otherwise the
572 behavior is undefined.
573
574 \sa subspan(QSpan<T,E>::size_type, QSpan<T,E>::size_type), subspan(), first(), last()
575*/
576#endif
577
578//
579// runtime subspans:
580//
581
582/*!
583 \fn template <typename T, size_t E> auto QSpan<T, E>::first(qsizetype n) const
584 \keyword first-n
585
586 Returns a variable-sized span of size \a n referencing the first \a n elements of \c{*this}.
587
588 \a n must be non-negative.
589
590 The span must hold at least \a n elements (\c{E} >= \a n \e{and} size() >=
591 \a n), otherwise the behavior is undefined.
592
593 \sa {first-t}{first<N>()}, last(QSpan<T,E>::size_type), subspan(QSpan<T,E>::size_type),
594 subspan(QSpan<T,E>::size_type, QSpan<T,E>::size_type)
595 \sa sliced()
596*/
597
598/*!
599 \fn template <typename T, size_t E> auto QSpan<T, E>::last(qsizetype n) const
600 \keyword last-n
601
602 Returns a variable-sized span of size \a n referencing the last \a n elements of \c{*this}.
603
604 \a n must be non-negative.
605
606 The span must hold at least \a n elements (\c{E} >= \a n \e{and}
607 size() >= \a n), otherwise the behavior is undefined.
608
609 \sa last(), first(QSpan<T,E>::size_type), subspan(QSpan<T,E>::size_type),
610 subspan(QSpan<T,E>::size_type, QSpan<T,E>::size_type), sliced()
611*/
612
613/*!
614 \fn template <typename T, size_t E> auto QSpan<T, E>::subspan(qsizetype pos) const
615 \fn template <typename T, size_t E> auto QSpan<T, E>::sliced(qsizetype pos) const
616 \keyword subspan-n1
617
618 Returns a variable-sized span of size \c{size() - pos} referencing the
619 remainder of this span after dropping the first \a pos elements.
620
621 \a pos must be non-negative.
622
623 This span must hold at least \a pos elements (\c{E} >= \a pos \e{and}
624 size() >= \a pos), otherwise the behavior is undefined.
625
626 These functions do the same thing: subspan() is provided for STL
627 compatibility and sliced() is provided for Qt compatibility.
628
629 \sa subspan(), first(QSpan<T,E>::size_type), last(QSpan<T,E>::size_type)
630*/
631
632/*!
633 \fn template <typename T, size_t E> auto QSpan<T, E>::subspan(qsizetype pos, qsizetype n) const
634 \fn template <typename T, size_t E> auto QSpan<T, E>::sliced(qsizetype pos, qsizetype n) const
635 \keyword subspan-n2
636
637 Returns a variable-sized span of size \a n referencing the \a n elements of
638 this span starting at \a pos.
639
640 Both \a pos and \a n must be non-negative.
641
642 This span must hold at least \c{pos + n} elements (\c{E} >=
643 \c{pos + n} \e{and} size() >= \c{pos + n}), otherwise the
644 behavior is undefined.
645
646 These functions do the same thing: subspan() is provided for STL
647 compatibility and sliced() is provided for Qt compatibility.
648
649 \sa subspan(), first(QSpan<T,E>::size_type), last(QSpan<T,E>::size_type)
650*/
651