11
11
#include < type_traits>
12
12
#include < utility>
13
13
14
- /* * A Span is an object that can refer to a contiguous sequence of objects.
14
+ /* * A span is an object that can refer to a contiguous sequence of objects.
15
15
*
16
- * Things to be aware of when writing code that deals with Spans :
16
+ * Things to be aware of when writing code that deals with spans :
17
17
*
18
- * - Similar to references themselves, Spans are subject to reference lifetime
18
+ * - Similar to references themselves, spans are subject to reference lifetime
19
19
* issues. The user is responsible for making sure the objects pointed to by
20
- * a Span live as long as the Span is used. For example:
20
+ * a span live as long as the span is used. For example:
21
21
*
22
22
* std::vector<int> vec{1,2,3,4};
23
- * Span <int> sp(vec);
23
+ * std::span <int> sp(vec);
24
24
* vec.push_back(5);
25
25
* printf("%i\n", sp.front()); // UB!
26
26
*
27
27
* may exhibit undefined behavior, as increasing the size of a vector may
28
28
* invalidate references.
29
29
*
30
- * - One particular pitfall is that Spans can be constructed from temporaries,
31
- * but this is unsafe when the Span is stored in a variable, outliving the
30
+ * - One particular pitfall is that spans can be constructed from temporaries,
31
+ * but this is unsafe when the span is stored in a variable, outliving the
32
32
* temporary. For example, this will compile, but exhibits undefined behavior:
33
33
*
34
- * Span <const int> sp(std::vector<int>{1, 2, 3});
34
+ * std::span <const int> sp(std::vector<int>{1, 2, 3});
35
35
* printf("%i\n", sp.front()); // UB!
36
36
*
37
37
* The lifetime of the vector ends when the statement it is created in ends.
38
- * Thus the Span is left with a dangling reference, and using it is undefined.
38
+ * Thus the span is left with a dangling reference, and using it is undefined.
39
39
*
40
- * - Due to Span's automatic creation from range-like objects (arrays, and data
40
+ * - Due to spans automatic creation from range-like objects (arrays, and data
41
41
* types that expose a data() and size() member function), functions that
42
- * accept a Span as input parameter can be called with any compatible
42
+ * accept a span as input parameter can be called with any compatible
43
43
* range-like object. For example, this works:
44
44
*
45
- * void Foo(Span <const int> arg);
45
+ * void Foo(std::span <const int> arg);
46
46
*
47
47
* Foo(std::vector<int>{1, 2, 3}); // Works
48
48
*
49
49
* This is very useful in cases where a function truly does not care about the
50
50
* container, and only about having exactly a range of elements. However it
51
51
* may also be surprising to see automatic conversions in this case.
52
52
*
53
- * When a function accepts a Span with a mutable element type, it will not
53
+ * When a function accepts a span with a mutable element type, it will not
54
54
* accept temporaries; only variables or other references. For example:
55
55
*
56
- * void FooMut(Span <int> arg);
56
+ * void FooMut(std::span <int> arg);
57
57
*
58
58
* FooMut(std::vector<int>{1, 2, 3}); // Does not compile
59
59
* std::vector<int> baz{1, 2, 3};
69
69
* result will be present in that variable after the call. Passing a temporary
70
70
* is useless in that context.
71
71
*/
72
- #define Span std::span
73
72
74
73
/* * Pop the last element off a span, and return a reference to that element. */
75
74
template <typename T>
@@ -81,18 +80,6 @@ T& SpanPopBack(std::span<T>& span)
81
80
return back;
82
81
}
83
82
84
- // From C++20 as_bytes and as_writeable_bytes
85
- template <typename T>
86
- Span<const std::byte> AsBytes (Span<T> s) noexcept
87
- {
88
- return {reinterpret_cast <const std::byte*>(s.data ()), s.size_bytes ()};
89
- }
90
- template <typename T>
91
- Span<std::byte> AsWritableBytes (Span<T> s) noexcept
92
- {
93
- return {reinterpret_cast <std::byte*>(s.data ()), s.size_bytes ()};
94
- }
95
-
96
83
template <typename V>
97
84
auto MakeByteSpan (const V& v) noexcept
98
85
{
@@ -117,10 +104,10 @@ inline const unsigned char* UCharCast(const std::byte* c) { return reinterpret_c
117
104
template <typename B>
118
105
concept BasicByte = requires { UCharCast (std::span<B>{}.data ()); };
119
106
120
- // Helper function to safely convert a Span to a Span <[const] unsigned char>.
107
+ // Helper function to safely convert a span to a span <[const] unsigned char>.
121
108
template <typename T, size_t N> constexpr auto UCharSpanCast (std::span<T, N> s) { return std::span<std::remove_pointer_t <decltype (UCharCast (s.data ()))>, N>{UCharCast (s.data ()), s.size ()}; }
122
109
123
- /* * Like the Span constructor, but for (const) unsigned char member types only. Only works for (un)signed char containers. */
110
+ /* * Like the std::span constructor, but for (const) unsigned char member types only. Only works for (un)signed char containers. */
124
111
template <typename V> constexpr auto MakeUCharSpan (const V& v) -> decltype(UCharSpanCast(std::span{v})) { return UCharSpanCast (std::span{v}); }
125
112
template <typename V> constexpr auto MakeWritableUCharSpan (V&& v) -> decltype(UCharSpanCast(std::span{std::forward<V>(v)})) { return UCharSpanCast (std::span{std::forward<V>(v)}); }
126
113
0 commit comments