1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
diff --git a/include/span b/include/span
index 46df783..0101dcb 100644
--- a/include/span
+++ b/include/span
@@ -181,6 +181,29 @@ concept __span_compatible_range =
!__is_std_array<remove_cvref_t<_Range>>::value &&
!is_array_v<remove_cvref_t<_Range>> &&
is_convertible_v<remove_reference_t<ranges::range_reference_t<_Range>>(*)[], _ElementType(*)[]>;
+#else
+template <class _Tp, class _ElementType, class = void>
+struct __is_span_compatible_container : public false_type {};
+
+template <class _Tp, class _ElementType>
+struct __is_span_compatible_container<_Tp, _ElementType,
+ void_t<
+ // is not a specialization of span
+ enable_if_t<!__is_std_span<_Tp>::value, nullptr_t>,
+ // is not a specialization of array
+ enable_if_t<!__is_std_array<_Tp>::value, nullptr_t>,
+ // is_array_v<Container> is false,
+ enable_if_t<!is_array_v<_Tp>, nullptr_t>,
+ // data(cont) and size(cont) are well formed
+ decltype(data(declval<_Tp>())),
+ decltype(size(declval<_Tp>())),
+ // remove_pointer_t<decltype(data(cont))>(*)[] is convertible to ElementType(*)[]
+ enable_if_t<
+ is_convertible_v<remove_pointer_t<decltype(data(declval<_Tp &>()))>(*)[],
+ _ElementType(*)[]>,
+ nullptr_t>
+ >>
+ : public true_type {};
#endif
template <typename _Tp, size_t _Extent>
@@ -235,6 +258,11 @@ public:
_LIBCPP_ASSERT(__last - __first == _Extent,
"invalid range in span's constructor (iterator, sentinel): last - first != extent");
}
+#else
+ _LIBCPP_INLINE_VISIBILITY constexpr explicit span(pointer __ptr, size_type __count) : __data{__ptr}
+ { (void)__count; _LIBCPP_ASSERT(_Extent == __count, "size mismatch in span's constructor (ptr, len)"); }
+ _LIBCPP_INLINE_VISIBILITY constexpr explicit span(pointer __f, pointer __l) : __data{__f}
+ { (void)__l; _LIBCPP_ASSERT(_Extent == distance(__f, __l), "size mismatch in span's constructor (ptr, ptr)"); }
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
_LIBCPP_INLINE_VISIBILITY constexpr span(type_identity_t<element_type> (&__arr)[_Extent]) noexcept : __data{__arr} {}
@@ -255,6 +283,22 @@ public:
constexpr explicit span(_Range&& __r) : __data{ranges::data(__r)} {
_LIBCPP_ASSERT(ranges::size(__r) == _Extent, "size mismatch in span's constructor (range)");
}
+#else
+ template <class _Container>
+ _LIBCPP_INLINE_VISIBILITY
+ constexpr explicit span( _Container& __c,
+ enable_if_t<__is_span_compatible_container<_Container, _Tp>::value, nullptr_t> = nullptr)
+ : __data{_VSTD::data(__c)} {
+ _LIBCPP_ASSERT(_Extent == _VSTD::size(__c), "size mismatch in span's constructor (range)");
+ }
+
+ template <class _Container>
+ _LIBCPP_INLINE_VISIBILITY
+ constexpr explicit span(const _Container& __c,
+ enable_if_t<__is_span_compatible_container<const _Container, _Tp>::value, nullptr_t> = nullptr)
+ : __data{_VSTD::data(__c)} {
+ _LIBCPP_ASSERT(_Extent == _VSTD::size(__c), "size mismatch in span's constructor (range)");
+ }
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
template <class _OtherElementType>
@@ -419,6 +463,9 @@ public:
_LIBCPP_INLINE_VISIBILITY
constexpr span(_It __first, _End __last)
: __data(_VSTD::to_address(__first)), __size(__last - __first) {}
+#else
+ _LIBCPP_INLINE_VISIBILITY constexpr span(pointer __ptr, size_type __count) : __data{__ptr}, __size{__count} {}
+ _LIBCPP_INLINE_VISIBILITY constexpr span(pointer __f, pointer __l) : __data{__f}, __size{static_cast<size_t>(distance(__f, __l))} {}
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
template <size_t _Sz>
@@ -439,6 +486,18 @@ public:
template <__span_compatible_range<element_type> _Range>
_LIBCPP_INLINE_VISIBILITY
constexpr span(_Range&& __r) : __data(ranges::data(__r)), __size{ranges::size(__r)} {}
+#else
+ template <class _Container>
+ _LIBCPP_INLINE_VISIBILITY
+ constexpr span( _Container& __c,
+ enable_if_t<__is_span_compatible_container<_Container, _Tp>::value, nullptr_t> = nullptr)
+ : __data{_VSTD::data(__c)}, __size{(size_type) _VSTD::size(__c)} {}
+
+ template <class _Container>
+ _LIBCPP_INLINE_VISIBILITY
+ constexpr span(const _Container& __c,
+ enable_if_t<__is_span_compatible_container<const _Container, _Tp>::value, nullptr_t> = nullptr)
+ : __data{_VSTD::data(__c)}, __size{(size_type) _VSTD::size(__c)} {}
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
template <class _OtherElementType, size_t _OtherExtent>
@@ -533,17 +592,23 @@ public:
_LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); }
_LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator rend() const noexcept { return reverse_iterator(begin()); }
- _LIBCPP_INLINE_VISIBILITY span<const byte, dynamic_extent> __as_bytes() const noexcept
- { return {reinterpret_cast<const byte *>(data()), size_bytes()}; }
+ inline _LIBCPP_INLINE_VISIBILITY span<const byte, dynamic_extent> __as_bytes() const noexcept;
- _LIBCPP_INLINE_VISIBILITY span<byte, dynamic_extent> __as_writable_bytes() const noexcept
- { return {reinterpret_cast<byte *>(data()), size_bytes()}; }
+ inline _LIBCPP_INLINE_VISIBILITY span<byte, dynamic_extent> __as_writable_bytes() const noexcept;
private:
pointer __data;
size_type __size;
};
+template<typename _Tp>
+inline _LIBCPP_INLINE_VISIBILITY span<const byte, dynamic_extent> span<_Tp, dynamic_extent>::__as_bytes() const noexcept
+{ return {reinterpret_cast<const byte *>(data()), size_bytes()}; }
+
+template<typename _Tp>
+inline _LIBCPP_INLINE_VISIBILITY span<byte, dynamic_extent> span<_Tp, dynamic_extent>::__as_writable_bytes() const noexcept
+{ return {reinterpret_cast<byte *>(data()), size_bytes()}; }
+
#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
template <class _Tp, size_t _Extent>
inline constexpr bool ranges::enable_borrowed_range<span<_Tp, _Extent> > = true;
|