summaryrefslogtreecommitdiff
path: root/libcxx/include/span
diff options
context:
space:
mode:
Diffstat (limited to 'libcxx/include/span')
-rw-r--r--libcxx/include/span170
1 files changed, 64 insertions, 106 deletions
diff --git a/libcxx/include/span b/libcxx/include/span
index 3421ca0f5a8ee..b307c98aee204 100644
--- a/libcxx/include/span
+++ b/libcxx/include/span
@@ -46,15 +46,13 @@ public:
using reference = element_type&;
using const_reference = const element_type&;
using iterator = implementation-defined;
- using const_iterator = implementation-defined;
using reverse_iterator = std::reverse_iterator<iterator>;
- using const_reverse_iterator = std::reverse_iterator<const_iterator>;
static constexpr size_type extent = Extent;
// [span.cons], span constructors, copy, assignment, and destructor
constexpr span() noexcept;
- constexpr span(pointer ptr, size_type count);
- constexpr span(pointer firstElem, pointer lastElem);
+ constexpr explicit(Extent != dynamic_extent) span(pointer ptr, size_type count);
+ constexpr explicit(Extent != dynamic_extent) span(pointer firstElem, pointer lastElem);
template <size_t N>
constexpr span(element_type (&arr)[N]) noexcept;
template <size_t N>
@@ -62,12 +60,12 @@ public:
template <size_t N>
constexpr span(const array<value_type, N>& arr) noexcept;
template <class Container>
- constexpr span(Container& cont);
+ constexpr explicit(Extent != dynamic_extent) span(Container& cont);
template <class Container>
- constexpr span(const Container& cont);
+ constexpr explicit(Extent != dynamic_extent) span(const Container& cont);
constexpr span(const span& other) noexcept = default;
template <class OtherElementType, size_t OtherExtent>
- constexpr span(const span<OtherElementType, OtherExtent>& s) noexcept;
+ constexpr explicit(Extent != dynamic_extent) span(const span<OtherElementType, OtherExtent>& s) noexcept;
~span() noexcept = default;
constexpr span& operator=(const span& other) noexcept = default;
@@ -97,12 +95,8 @@ public:
// [span.iterators], span iterator support
constexpr iterator begin() const noexcept;
constexpr iterator end() const noexcept;
- constexpr const_iterator cbegin() const noexcept;
- constexpr const_iterator cend() const noexcept;
constexpr reverse_iterator rbegin() const noexcept;
constexpr reverse_iterator rend() const noexcept;
- constexpr const_reverse_iterator crbegin() const noexcept;
- constexpr const_reverse_iterator crend() const noexcept;
private:
pointer data_; // exposition only
@@ -129,11 +123,10 @@ template<class Container>
*/
#include <__config>
-#include <cstddef> // for ptrdiff_t
-#include <iterator> // for iterators
#include <array> // for array
-#include <type_traits> // for remove_cv, etc
#include <cstddef> // for byte
+#include <iterator> // for iterators
+#include <type_traits> // for remove_cv, etc
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
@@ -143,7 +136,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER > 17
-inline constexpr size_t dynamic_extent = numeric_limits<size_t>::max();
+inline constexpr size_t dynamic_extent = (numeric_limits<size_t>::max)();
template <typename _Tp, size_t _Extent = dynamic_extent> class span;
@@ -202,27 +195,49 @@ public:
using reference = _Tp &;
using const_reference = const _Tp &;
using iterator = __wrap_iter<pointer>;
- using const_iterator = __wrap_iter<const_pointer>;
using reverse_iterator = _VSTD::reverse_iterator<iterator>;
- using const_reverse_iterator = _VSTD::reverse_iterator<const_iterator>;
static constexpr size_type extent = _Extent;
// [span.cons], span constructors, copy, assignment, and destructor
- _LIBCPP_INLINE_VISIBILITY constexpr span() noexcept : __data{nullptr}
- { static_assert(_Extent == 0, "Can't default construct a statically sized span with size > 0"); }
+ template <size_t _Sz = _Extent, enable_if_t<_Sz == 0, nullptr_t> = nullptr>
+ _LIBCPP_INLINE_VISIBILITY constexpr span() noexcept : __data{nullptr} {}
constexpr span (const span&) noexcept = default;
constexpr span& operator=(const span&) noexcept = default;
- _LIBCPP_INLINE_VISIBILITY constexpr span(pointer __ptr, size_type __count) : __data{__ptr}
+ _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 span(pointer __f, pointer __l) : __data{__f}
+ _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)"); }
_LIBCPP_INLINE_VISIBILITY constexpr span(element_type (&__arr)[_Extent]) noexcept : __data{__arr} {}
- _LIBCPP_INLINE_VISIBILITY constexpr span( array<value_type, _Extent>& __arr) noexcept : __data{__arr.data()} {}
- _LIBCPP_INLINE_VISIBILITY constexpr span(const array<value_type, _Extent>& __arr) noexcept : __data{__arr.data()} {}
+
+ template <class _OtherElementType,
+ enable_if_t<is_convertible_v<_OtherElementType(*)[], element_type (*)[]>, nullptr_t> = nullptr>
+ _LIBCPP_INLINE_VISIBILITY
+ constexpr span(array<_OtherElementType, _Extent>& __arr) noexcept : __data{__arr.data()} {}
+
+ template <class _OtherElementType,
+ enable_if_t<is_convertible_v<const _OtherElementType(*)[], element_type (*)[]>, nullptr_t> = nullptr>
+ _LIBCPP_INLINE_VISIBILITY
+ constexpr span(const array<_OtherElementType, _Extent>& __arr) noexcept : __data{__arr.data()} {}
+
+ 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)");
+ }
template <class _OtherElementType>
_LIBCPP_INLINE_VISIBILITY
@@ -234,7 +249,7 @@ public:
template <class _OtherElementType>
_LIBCPP_INLINE_VISIBILITY
- constexpr span(const span<_OtherElementType, dynamic_extent>& __other,
+ constexpr explicit span(const span<_OtherElementType, dynamic_extent>& __other,
enable_if_t<
is_convertible_v<_OtherElementType(*)[], element_type (*)[]>,
nullptr_t> = nullptr) noexcept
@@ -248,7 +263,7 @@ public:
constexpr span<element_type, _Count> first() const noexcept
{
static_assert(_Count <= _Extent, "Count out of range in span::first()");
- return {data(), _Count};
+ return span<element_type, _Count>{data(), _Count};
}
template <size_t _Count>
@@ -256,7 +271,7 @@ public:
constexpr span<element_type, _Count> last() const noexcept
{
static_assert(_Count <= _Extent, "Count out of range in span::last()");
- return {data() + size() - _Count, _Count};
+ return span<element_type, _Count>{data() + size() - _Count, _Count};
}
_LIBCPP_INLINE_VISIBILITY
@@ -279,7 +294,10 @@ public:
-> span<element_type, _Count != dynamic_extent ? _Count : _Extent - _Offset>
{
static_assert(_Offset <= _Extent, "Offset out of range in span::subspan()");
- return {data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count};
+ static_assert(_Count == dynamic_extent || _Count <= _Extent - _Offset, "Offset + count out of range in span::subspan()");
+
+ using _ReturnType = span<element_type, _Count != dynamic_extent ? _Count : _Extent - _Offset>;
+ return _ReturnType{data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count};
}
@@ -291,7 +309,7 @@ public:
_LIBCPP_ASSERT(__count <= size() || __count == dynamic_extent, "Count out of range in span::subspan(offset, count)");
if (__count == dynamic_extent)
return {data() + __offset, size() - __offset};
- _LIBCPP_ASSERT(__offset <= size() - __count, "count + offset out of range in span::subspan(offset, count)");
+ _LIBCPP_ASSERT(__count <= size() - __offset, "Offset + count out of range in span::subspan(offset, count)");
return {data() + __offset, __count};
}
@@ -301,19 +319,19 @@ public:
_LIBCPP_INLINE_VISIBILITY constexpr reference operator[](size_type __idx) const noexcept
{
- _LIBCPP_ASSERT(__idx >= 0 && __idx < size(), "span<T,N>[] index out of bounds");
+ _LIBCPP_ASSERT(__idx < size(), "span<T,N>[] index out of bounds");
return __data[__idx];
}
_LIBCPP_INLINE_VISIBILITY constexpr reference front() const noexcept
{
- static_assert(_Extent > 0, "span<T,N>[].front() on empty span");
+ _LIBCPP_ASSERT(!empty(), "span<T, N>::front() on empty span");
return __data[0];
}
_LIBCPP_INLINE_VISIBILITY constexpr reference back() const noexcept
{
- static_assert(_Extent > 0, "span<T,N>[].back() on empty span");
+ _LIBCPP_ASSERT(!empty(), "span<T, N>::back() on empty span");
return __data[size()-1];
}
@@ -322,25 +340,14 @@ public:
// [span.iter], span iterator support
_LIBCPP_INLINE_VISIBILITY constexpr iterator begin() const noexcept { return iterator(data()); }
_LIBCPP_INLINE_VISIBILITY constexpr iterator end() const noexcept { return iterator(data() + size()); }
- _LIBCPP_INLINE_VISIBILITY constexpr const_iterator cbegin() const noexcept { return const_iterator(data()); }
- _LIBCPP_INLINE_VISIBILITY constexpr const_iterator cend() const noexcept { return const_iterator(data() + size()); }
_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 constexpr const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(cend()); }
- _LIBCPP_INLINE_VISIBILITY constexpr const_reverse_iterator crend() const noexcept { return const_reverse_iterator(cbegin()); }
-
- _LIBCPP_INLINE_VISIBILITY constexpr void swap(span &__other) noexcept
- {
- pointer __p = __data;
- __data = __other.__data;
- __other.__data = __p;
- }
_LIBCPP_INLINE_VISIBILITY span<const byte, _Extent * sizeof(element_type)> __as_bytes() const noexcept
- { return {reinterpret_cast<const byte *>(data()), size_bytes()}; }
+ { return span<const byte, _Extent * sizeof(element_type)>{reinterpret_cast<const byte *>(data()), size_bytes()}; }
_LIBCPP_INLINE_VISIBILITY span<byte, _Extent * sizeof(element_type)> __as_writable_bytes() const noexcept
- { return {reinterpret_cast<byte *>(data()), size_bytes()}; }
+ { return span<byte, _Extent * sizeof(element_type)>{reinterpret_cast<byte *>(data()), size_bytes()}; }
private:
pointer __data;
@@ -363,9 +370,7 @@ public:
using reference = _Tp &;
using const_reference = const _Tp &;
using iterator = __wrap_iter<pointer>;
- using const_iterator = __wrap_iter<const_pointer>;
using reverse_iterator = _VSTD::reverse_iterator<iterator>;
- using const_reverse_iterator = _VSTD::reverse_iterator<const_iterator>;
static constexpr size_type extent = dynamic_extent;
@@ -382,13 +387,15 @@ public:
_LIBCPP_INLINE_VISIBILITY
constexpr span(element_type (&__arr)[_Sz]) noexcept : __data{__arr}, __size{_Sz} {}
- template <size_t _Sz>
+ template <class _OtherElementType, size_t _Sz,
+ enable_if_t<is_convertible_v<_OtherElementType(*)[], element_type (*)[]>, nullptr_t> = nullptr>
_LIBCPP_INLINE_VISIBILITY
- constexpr span(array<value_type, _Sz>& __arr) noexcept : __data{__arr.data()}, __size{_Sz} {}
+ constexpr span(array<_OtherElementType, _Sz>& __arr) noexcept : __data{__arr.data()}, __size{_Sz} {}
- template <size_t _Sz>
+ template <class _OtherElementType, size_t _Sz,
+ enable_if_t<is_convertible_v<const _OtherElementType(*)[], element_type (*)[]>, nullptr_t> = nullptr>
_LIBCPP_INLINE_VISIBILITY
- constexpr span(const array<value_type, _Sz>& __arr) noexcept : __data{__arr.data()}, __size{_Sz} {}
+ constexpr span(const array<_OtherElementType, _Sz>& __arr) noexcept : __data{__arr.data()}, __size{_Sz} {}
template <class _Container>
_LIBCPP_INLINE_VISIBILITY
@@ -418,7 +425,7 @@ public:
constexpr span<element_type, _Count> first() const noexcept
{
_LIBCPP_ASSERT(_Count <= size(), "Count out of range in span::first()");
- return {data(), _Count};
+ return span<element_type, _Count>{data(), _Count};
}
template <size_t _Count>
@@ -426,7 +433,7 @@ public:
constexpr span<element_type, _Count> last() const noexcept
{
_LIBCPP_ASSERT(_Count <= size(), "Count out of range in span::last()");
- return {data() + size() - _Count, _Count};
+ return span<element_type, _Count>{data() + size() - _Count, _Count};
}
_LIBCPP_INLINE_VISIBILITY
@@ -445,11 +452,11 @@ public:
template <size_t _Offset, size_t _Count = dynamic_extent>
_LIBCPP_INLINE_VISIBILITY
- constexpr span<_Tp, dynamic_extent> subspan() const noexcept
+ constexpr span<element_type, _Count> subspan() const noexcept
{
_LIBCPP_ASSERT(_Offset <= size(), "Offset out of range in span::subspan()");
- _LIBCPP_ASSERT(_Count == dynamic_extent || _Offset + _Count <= size(), "Count out of range in span::subspan()");
- return {data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count};
+ _LIBCPP_ASSERT(_Count == dynamic_extent || _Count <= size() - _Offset, "Offset + count out of range in span::subspan()");
+ return span<element_type, _Count>{data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count};
}
constexpr span<element_type, dynamic_extent>
@@ -460,7 +467,7 @@ public:
_LIBCPP_ASSERT(__count <= size() || __count == dynamic_extent, "count out of range in span::subspan(offset, count)");
if (__count == dynamic_extent)
return {data() + __offset, size() - __offset};
- _LIBCPP_ASSERT(__offset <= size() - __count, "Offset + count out of range in span::subspan(offset, count)");
+ _LIBCPP_ASSERT(__count <= size() - __offset, "Offset + count out of range in span::subspan(offset, count)");
return {data() + __offset, __count};
}
@@ -470,7 +477,7 @@ public:
_LIBCPP_INLINE_VISIBILITY constexpr reference operator[](size_type __idx) const noexcept
{
- _LIBCPP_ASSERT(__idx >= 0 && __idx < size(), "span<T>[] index out of bounds");
+ _LIBCPP_ASSERT(__idx < size(), "span<T>[] index out of bounds");
return __data[__idx];
}
@@ -492,23 +499,8 @@ public:
// [span.iter], span iterator support
_LIBCPP_INLINE_VISIBILITY constexpr iterator begin() const noexcept { return iterator(data()); }
_LIBCPP_INLINE_VISIBILITY constexpr iterator end() const noexcept { return iterator(data() + size()); }
- _LIBCPP_INLINE_VISIBILITY constexpr const_iterator cbegin() const noexcept { return const_iterator(data()); }
- _LIBCPP_INLINE_VISIBILITY constexpr const_iterator cend() const noexcept { return const_iterator(data() + size()); }
_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 constexpr const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(cend()); }
- _LIBCPP_INLINE_VISIBILITY constexpr const_reverse_iterator crend() const noexcept { return const_reverse_iterator(cbegin()); }
-
- _LIBCPP_INLINE_VISIBILITY constexpr void swap(span &__other) noexcept
- {
- pointer __p = __data;
- __data = __other.__data;
- __other.__data = __p;
-
- size_type __sz = __size;
- __size = __other.__size;
- __other.__size = __sz;
- }
_LIBCPP_INLINE_VISIBILITY span<const byte, dynamic_extent> __as_bytes() const noexcept
{ return {reinterpret_cast<const byte *>(data()), size_bytes()}; }
@@ -521,34 +513,6 @@ private:
size_type __size;
};
-// tuple interface
-template <class _Tp, size_t _Size>
-struct _LIBCPP_TEMPLATE_VIS tuple_size<span<_Tp, _Size>>
- : public integral_constant<size_t, _Size> {};
-
-template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS tuple_size<span<_Tp, dynamic_extent>>; // declared but not defined
-
-
-template <size_t _Ip, class _Tp, size_t _Size>
-struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, span<_Tp, _Size>>
-{
- static_assert( dynamic_extent != _Size, "std::tuple_element<> not supported for std::span<T, dynamic_extent>");
- static_assert(_Ip < _Size, "Index out of bounds in std::tuple_element<> (std::span)");
- typedef _Tp type;
-};
-
-template <size_t _Ip, class _Tp, size_t _Size>
-_LIBCPP_INLINE_VISIBILITY constexpr
-_Tp&
-get(span<_Tp, _Size> __s) noexcept
-{
- static_assert( dynamic_extent != _Size, "std::get<> not supported for std::span<T, dynamic_extent>");
- static_assert(_Ip < _Size, "Index out of bounds in std::get<> (std::span)");
- return __s[_Ip];
-}
-
-
// as_bytes & as_writable_bytes
template <class _Tp, size_t _Extent>
_LIBCPP_INLINE_VISIBILITY
@@ -562,12 +526,6 @@ auto as_writable_bytes(span<_Tp, _Extent> __s) noexcept
-> enable_if_t<!is_const_v<_Tp>, decltype(__s.__as_writable_bytes())>
{ return __s.__as_writable_bytes(); }
-template <class _Tp, size_t _Extent>
-_LIBCPP_INLINE_VISIBILITY
-constexpr void swap(span<_Tp, _Extent> &__lhs, span<_Tp, _Extent> &__rhs) noexcept
-{ __lhs.swap(__rhs); }
-
-
// Deduction guides
template<class _Tp, size_t _Sz>
span(_Tp (&)[_Sz]) -> span<_Tp, _Sz>;