Implement <span>. Reviewed as https://reviews.llvm.org/D49338

llvm-svn: 337804
This commit is contained in:
Marshall Clow 2018-07-24 03:01:02 +00:00
parent 0ed11a9792
commit 8a0794b722
42 changed files with 5020 additions and 0 deletions

View File

@ -128,6 +128,7 @@ set(files
set
setjmp.h
shared_mutex
span
sstream
stack
stdbool.h

View File

@ -559,6 +559,10 @@ module std [system] {
header "experimental/set"
export *
}
module span {
header "span"
export *
}
module string {
header "experimental/string"
export *

606
libcxx/include/span Normal file
View File

@ -0,0 +1,606 @@
// -*- C++ -*-
//===------------------------------ span ---------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
#ifndef _LIBCPP_SPAN
#define _LIBCPP_SPAN
/*
span synopsis
namespace std {
// constants
inline constexpr ptrdiff_t dynamic_extent = -1;
// [views.span], class template span
template <class ElementType, ptrdiff_t Extent = dynamic_extent>
class span;
// [span.comparison], span comparison operators
template <class T, ptrdiff_t X, class U, ptrdiff_t Y>
constexpr bool operator==(span<T, X> l, span<U, Y> r);
template <class T, ptrdiff_t X, class U, ptrdiff_t Y>
constexpr bool operator!=(span<T, X> l, span<U, Y> r);
template <class T, ptrdiff_t X, class U, ptrdiff_t Y>
constexpr bool operator<(span<T, X> l, span<U, Y> r);
template <class T, ptrdiff_t X, class U, ptrdiff_t Y>
constexpr bool operator<=(span<T, X> l, span<U, Y> r);
template <class T, ptrdiff_t X, class U, ptrdiff_t Y>
constexpr bool operator>(span<T, X> l, span<U, Y> r);
template <class T, ptrdiff_t X, class U, ptrdiff_t Y>
constexpr bool operator>=(span<T, X> l, span<U, Y> r);
// [span.objectrep], views of object representation
template <class ElementType, ptrdiff_t Extent>
span<const byte, ((Extent == dynamic_extent) ? dynamic_extent :
(static_cast<ptrdiff_t>(sizeof(ElementType)) * Extent))> as_bytes(span<ElementType, Extent> s) noexcept;
template <class ElementType, ptrdiff_t Extent>
span< byte, ((Extent == dynamic_extent) ? dynamic_extent :
(static_cast<ptrdiff_t>(sizeof(ElementType)) * Extent))> as_writable_bytes(span<ElementType, Extent> s) noexcept;
namespace std {
template <class ElementType, ptrdiff_t Extent = dynamic_extent>
class span {
public:
// constants and types
using element_type = ElementType;
using value_type = remove_cv_t<ElementType>;
using index_type = ptrdiff_t;
using difference_type = ptrdiff_t;
using pointer = element_type*;
using reference = 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 index_type extent = Extent;
// [span.cons], span constructors, copy, assignment, and destructor
constexpr span() noexcept;
constexpr span(pointer ptr, index_type count);
constexpr span(pointer firstElem, pointer lastElem);
template <size_t N>
constexpr span(element_type (&arr)[N]) noexcept;
template <size_t N>
constexpr span(array<value_type, N>& arr) noexcept;
template <size_t N>
constexpr span(const array<value_type, N>& arr) noexcept;
template <class Container>
constexpr span(Container& cont);
template <class Container>
constexpr span(const Container& cont);
constexpr span(const span& other) noexcept = default;
template <class OtherElementType, ptrdiff_t OtherExtent>
constexpr span(const span<OtherElementType, OtherExtent>& s) noexcept;
~span() noexcept = default;
constexpr span& operator=(const span& other) noexcept = default;
// [span.sub], span subviews
template <ptrdiff_t Count>
constexpr span<element_type, Count> first() const;
template <ptrdiff_t Count>
constexpr span<element_type, Count> last() const;
template <ptrdiff_t Offset, ptrdiff_t Count = dynamic_extent>
constexpr span<element_type, see below> subspan() const;
constexpr span<element_type, dynamic_extent> first(index_type count) const;
constexpr span<element_type, dynamic_extent> last(index_type count) const;
constexpr span<element_type, dynamic_extent> subspan(index_type offset, index_type count = dynamic_extent) const;
// [span.obs], span observers
constexpr index_type size() const noexcept;
constexpr index_type size_bytes() const noexcept;
constexpr bool empty() const noexcept;
// [span.elem], span element access
constexpr reference operator[](index_type idx) const;
constexpr reference operator()(index_type idx) const;
constexpr pointer data() const noexcept;
// [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
index_type size_; // exposition only
};
template<class T, size_t N>
span(T (&)[N]) -> span<T, N>;
template<class T, size_t N>
span(array<T, N>&) -> span<T, N>;
template<class T, size_t N>
span(const array<T, N>&) -> span<const T, N>;
template<class Container>
span(Container&) -> span<typename Container::value_type>;
template<class Container>
span(const Container&) -> span<const typename Container::value_type>;
} // namespace std
*/
#include <cstddef> // for ptrdiff_t
#include <iterator> // for iterators
#include <array> // for array
#include <type_traits> // for remove_cv, etc
#include <cstddef> // for byte
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER > 17
inline constexpr ptrdiff_t dynamic_extent = -1;
template <typename _Tp, ptrdiff_t _Extent = dynamic_extent> class span;
template <class _Tp>
struct __is_span_impl : public false_type {};
template <class _Tp, ptrdiff_t _Extent>
struct __is_span_impl<span<_Tp, _Extent>> : public true_type {};
template <class _Tp>
struct __is_span : public __is_span_impl<remove_cv_t<_Tp>> {};
template <class _Tp>
struct __is_std_array_impl : public false_type {};
template <class _Tp, size_t _Sz>
struct __is_std_array_impl<array<_Tp, _Sz>> : public true_type {};
template <class _Tp>
struct __is_std_array : public __is_std_array_impl<remove_cv_t<_Tp>> {};
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
typename enable_if<!__is_span<_Tp>::value, nullptr_t>::type,
// is not a specialization of array
typename enable_if<!__is_std_array<_Tp>::value, nullptr_t>::type,
// is_array_v<Container> is false,
typename enable_if<!is_array_v<_Tp>, nullptr_t>::type,
// 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(*)[]
typename enable_if<
is_convertible_v<remove_pointer_t<decltype(data(declval<_Tp &>()))>(*)[],
_ElementType(*)[]>,
nullptr_t>::type
>>
: public true_type {};
template <typename _Tp, ptrdiff_t _Extent>
class _LIBCPP_TEMPLATE_VIS span {
public:
// constants and types
using element_type = _Tp;
using value_type = remove_cv_t<_Tp>;
using index_type = ptrdiff_t;
using difference_type = ptrdiff_t;
using pointer = _Tp *;
using const_pointer = const _Tp *; // not in standard
using reference = _Tp &;
using const_reference = const _Tp &; // not in standard
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 index_type extent = _Extent;
static_assert (_Extent >= 0, "Can't have a span with an extent < 0");
// [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"); }
constexpr span (const span&) noexcept = default;
constexpr span& operator=(const span&) noexcept = default;
_LIBCPP_INLINE_VISIBILITY constexpr span(pointer __ptr, index_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}
{ (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 _Container>
inline _LIBCPP_INLINE_VISIBILITY
constexpr 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 (container))"); }
template <class _Container>
inline _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)}
{ _LIBCPP_ASSERT(_Extent == _VSTD::size(__c), "size mismatch in span's constructor (const container)"); }
template <class _OtherElementType>
inline _LIBCPP_INLINE_VISIBILITY
constexpr span(const span<_OtherElementType, _Extent>& __other,
enable_if_t<
is_convertible_v<_OtherElementType(*)[], element_type (*)[]>,
nullptr_t> = nullptr)
: __data{__other.data()} {}
template <class _OtherElementType>
inline _LIBCPP_INLINE_VISIBILITY
constexpr span(const span<_OtherElementType, dynamic_extent>& __other,
enable_if_t<
is_convertible_v<_OtherElementType(*)[], element_type (*)[]>,
nullptr_t> = nullptr) noexcept
: __data{__other.data()} { _LIBCPP_ASSERT(_Extent == __other.size(), "size mismatch in span's constructor (other span)"); }
// ~span() noexcept = default;
template <ptrdiff_t _Count>
inline _LIBCPP_INLINE_VISIBILITY
constexpr span<element_type, _Count> first() const noexcept
{
static_assert(_Count >= 0, "Count must be >= 0 in span::first()");
static_assert(_Count <= _Extent, "Count out of range in span::first()");
return {data(), _Count};
}
template <ptrdiff_t _Count>
inline _LIBCPP_INLINE_VISIBILITY
constexpr span<element_type, _Count> last() const noexcept
{
static_assert(_Count >= 0, "Count must be >= 0 in span::last()");
static_assert(_Count <= _Extent, "Count out of range in span::last()");
return {data() + size() - _Count, _Count};
}
_LIBCPP_INLINE_VISIBILITY
constexpr span<element_type, dynamic_extent> first(index_type __count) const noexcept
{
_LIBCPP_ASSERT(__count >= 0 && __count <= size(), "Count out of range in span::first(count)");
return {data(), __count};
}
_LIBCPP_INLINE_VISIBILITY
constexpr span<element_type, dynamic_extent> last(index_type __count) const noexcept
{
_LIBCPP_ASSERT(__count >= 0 && __count <= size(), "Count out of range in span::last(count)");
return {data() + size() - __count, __count};
}
template <ptrdiff_t _Offset, ptrdiff_t _Count = dynamic_extent>
inline _LIBCPP_INLINE_VISIBILITY
constexpr auto subspan() const noexcept
-> span<element_type, _Count != dynamic_extent ? _Count : _Extent - _Offset>
{
_LIBCPP_ASSERT(_Offset >= 0 && _Offset <= size(), "Offset out of range in span::subspan()");
return {data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count};
}
inline _LIBCPP_INLINE_VISIBILITY
constexpr span<element_type, dynamic_extent>
subspan(index_type __offset, index_type __count = dynamic_extent) const noexcept
{
_LIBCPP_ASSERT( __offset >= 0 && __offset <= size(), "Offset out of range in span::subspan(offset, count)");
_LIBCPP_ASSERT((__count >= 0 && __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 + __count <= size(), "count + offset out of range in span::subspan(offset, count)");
return {data() + __offset, __count};
}
_LIBCPP_INLINE_VISIBILITY constexpr index_type size() const noexcept { return _Extent; }
_LIBCPP_INLINE_VISIBILITY constexpr index_type size_bytes() const noexcept { return _Extent * sizeof(element_type); }
_LIBCPP_INLINE_VISIBILITY constexpr bool empty() const noexcept { return _Extent == 0; }
_LIBCPP_INLINE_VISIBILITY constexpr reference operator[](index_type __idx) const noexcept
{
_LIBCPP_ASSERT(__idx >= 0 && __idx < size(), "span<T,N>[] index out of bounds");
return __data[__idx];
}
_LIBCPP_INLINE_VISIBILITY constexpr reference operator()(index_type __idx) const noexcept
{
_LIBCPP_ASSERT(__idx >= 0 && __idx < size(), "span<T,N>() index out of bounds");
return __data[__idx];
}
_LIBCPP_INLINE_VISIBILITY constexpr pointer data() const noexcept { return __data; }
// [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()}; }
_LIBCPP_INLINE_VISIBILITY span<byte, _Extent * sizeof(element_type)> __as_writeable_bytes() const noexcept
{ return {reinterpret_cast<byte *>(data()), size_bytes()}; }
private:
pointer __data;
};
template <typename _Tp>
class _LIBCPP_TEMPLATE_VIS span<_Tp, dynamic_extent> {
private:
public:
// constants and types
using element_type = _Tp;
using value_type = remove_cv_t<_Tp>;
using index_type = ptrdiff_t;
using difference_type = ptrdiff_t;
using pointer = _Tp *;
using const_pointer = const _Tp *; // not in standard
using reference = _Tp &;
using const_reference = const _Tp &; // not in standard
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 index_type extent = dynamic_extent;
// [span.cons], span constructors, copy, assignment, and destructor
_LIBCPP_INLINE_VISIBILITY constexpr span() noexcept : __data{nullptr}, __size{0} {}
constexpr span (const span&) noexcept = default;
constexpr span& operator=(const span&) noexcept = default;
_LIBCPP_INLINE_VISIBILITY constexpr span(pointer __ptr, index_type __count) : __data{__ptr}, __size{__count} {}
_LIBCPP_INLINE_VISIBILITY constexpr span(pointer __f, pointer __l) : __data{__f}, __size{distance(__f, __l)} {}
template <size_t _Sz>
inline _LIBCPP_INLINE_VISIBILITY
constexpr span(element_type (&__arr)[_Sz]) noexcept : __data{__arr}, __size{_Sz} {}
template <size_t _Sz>
inline _LIBCPP_INLINE_VISIBILITY
constexpr span(array<value_type, _Sz>& __arr) noexcept : __data{__arr.data()}, __size{_Sz} {}
template <size_t _Sz>
inline _LIBCPP_INLINE_VISIBILITY
constexpr span(const array<value_type, _Sz>& __arr) noexcept : __data{__arr.data()}, __size{_Sz} {}
template <class _Container>
inline _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{(index_type) _VSTD::size(__c)} {}
template <class _Container>
inline _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{(index_type) _VSTD::size(__c)} {}
template <class _OtherElementType, ptrdiff_t _OtherExtent>
inline _LIBCPP_INLINE_VISIBILITY
constexpr span(const span<_OtherElementType, _OtherExtent>& __other,
enable_if_t<
is_convertible_v<_OtherElementType(*)[], element_type (*)[]>,
nullptr_t> = nullptr) noexcept
: __data{__other.data()}, __size{__other.size()} {}
// ~span() noexcept = default;
template <ptrdiff_t _Count>
inline _LIBCPP_INLINE_VISIBILITY
constexpr span<element_type, _Count> first() const noexcept
{
static_assert(_Count >= 0);
_LIBCPP_ASSERT(_Count <= size(), "Count out of range in span::first()");
return {data(), _Count};
}
template <ptrdiff_t _Count>
inline _LIBCPP_INLINE_VISIBILITY
constexpr span<element_type, _Count> last() const noexcept
{
static_assert(_Count >= 0);
_LIBCPP_ASSERT(_Count <= size(), "Count out of range in span::last()");
return {data() + size() - _Count, _Count};
}
_LIBCPP_INLINE_VISIBILITY
constexpr span<element_type, dynamic_extent> first(index_type __count) const noexcept
{
_LIBCPP_ASSERT(__count >= 0 && __count <= size(), "Count out of range in span::first(count)");
return {data(), __count};
}
_LIBCPP_INLINE_VISIBILITY
constexpr span<element_type, dynamic_extent> last (index_type __count) const noexcept
{
_LIBCPP_ASSERT(__count >= 0 && __count <= size(), "Count out of range in span::last(count)");
return {data() + size() - __count, __count};
}
template <ptrdiff_t _Offset, ptrdiff_t _Count = dynamic_extent>
inline _LIBCPP_INLINE_VISIBILITY
constexpr span<_Tp, dynamic_extent> subspan() const noexcept
{
_LIBCPP_ASSERT(_Offset >= 0 && _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};
}
constexpr span<element_type, dynamic_extent>
inline _LIBCPP_INLINE_VISIBILITY
subspan(index_type __offset, index_type __count = dynamic_extent) const noexcept
{
_LIBCPP_ASSERT( __offset >= 0 && __offset <= size(), "Offset out of range in span::subspan(offset, count)");
_LIBCPP_ASSERT((__count >= 0 && __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 + __count <= size(), "Offset + count out of range in span::subspan(offset, count)");
return {data() + __offset, __count};
}
_LIBCPP_INLINE_VISIBILITY constexpr index_type size() const noexcept { return __size; }
_LIBCPP_INLINE_VISIBILITY constexpr index_type size_bytes() const noexcept { return __size * sizeof(element_type); }
_LIBCPP_INLINE_VISIBILITY constexpr bool empty() const noexcept { return __size == 0; }
_LIBCPP_INLINE_VISIBILITY constexpr reference operator[](index_type __idx) const noexcept
{
_LIBCPP_ASSERT(__idx >= 0 && __idx < size(), "span<T>[] index out of bounds");
return __data[__idx];
}
_LIBCPP_INLINE_VISIBILITY constexpr reference operator()(index_type __idx) const noexcept
{
_LIBCPP_ASSERT(__idx >= 0 && __idx < size(), "span<T>() index out of bounds");
return __data[__idx];
}
_LIBCPP_INLINE_VISIBILITY constexpr pointer data() const noexcept { return __data; }
// [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;
index_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()}; }
_LIBCPP_INLINE_VISIBILITY span<byte, dynamic_extent> __as_writeable_bytes() const noexcept
{ return {reinterpret_cast<byte *>(data()), size_bytes()}; }
private:
pointer __data;
index_type __size;
};
template <class _Tp1, ptrdiff_t _Extent1, class _Tp2, ptrdiff_t _Extent2>
constexpr bool
operator==(const span<_Tp1, _Extent1>& __lhs, const span<_Tp2, _Extent2>& __rhs)
{ return equal(__lhs.begin(), __lhs.end(), __rhs.begin(), __rhs.end()); }
template <class _Tp1, ptrdiff_t _Extent1, class _Tp2, ptrdiff_t _Extent2>
constexpr bool
operator!=(const span<_Tp1, _Extent1>& __lhs, const span<_Tp2, _Extent2>& __rhs)
{ return !(__rhs == __lhs); }
template <class _Tp1, ptrdiff_t _Extent1, class _Tp2, ptrdiff_t _Extent2>
constexpr bool
operator< (const span<_Tp1, _Extent1>& __lhs, const span<_Tp2, _Extent2>& __rhs)
{ return lexicographical_compare (__lhs.begin(), __lhs.end(), __rhs.begin(), __rhs.end()); }
template <class _Tp1, ptrdiff_t _Extent1, class _Tp2, ptrdiff_t _Extent2>
constexpr bool
operator<=(const span<_Tp1, _Extent1>& __lhs, const span<_Tp2, _Extent2>& __rhs)
{ return !(__rhs < __lhs); }
template <class _Tp1, ptrdiff_t _Extent1, class _Tp2, ptrdiff_t _Extent2>
constexpr bool
operator> (const span<_Tp1, _Extent1>& __lhs, const span<_Tp2, _Extent2>& __rhs)
{ return __rhs < __lhs; }
template <class _Tp1, ptrdiff_t _Extent1, class _Tp2, ptrdiff_t _Extent2>
constexpr bool
operator>=(const span<_Tp1, _Extent1>& __lhs, const span<_Tp2, _Extent2>& __rhs)
{ return !(__lhs < __rhs); }
// as_bytes & as_writeable_bytes
template <class _Tp, ptrdiff_t _Extent>
auto as_bytes(span<_Tp, _Extent> __s) noexcept
-> decltype(__s.__as_bytes())
{ return __s.__as_bytes(); }
template <class _Tp, ptrdiff_t _Extent>
auto as_writeable_bytes(span<_Tp, _Extent> __s) noexcept
-> typename enable_if<!is_const_v<_Tp>, decltype(__s.__as_writeable_bytes())>::type
{ return __s.__as_writeable_bytes(); }
template <class _Tp, ptrdiff_t _Extent>
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>;
template<class _Tp, size_t _Sz>
span(array<_Tp, _Sz>&) -> span<_Tp, _Sz>;
template<class _Tp, size_t _Sz>
span(const array<_Tp, _Sz>&) -> span<const _Tp, _Sz>;
template<class _Container>
span(_Container&) -> span<typename _Container::value_type>;
template<class _Container>
span(const _Container&) -> span<const typename _Container::value_type>;
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_STD_VER > 17
#endif // _LIBCPP_SPAN

View File

@ -102,6 +102,7 @@
#ifndef _LIBCPP_HAS_NO_THREADS
#include <shared_mutex>
#endif
#include <span>
#include <sstream>
#include <stack>
#include <stdbool.h>

View File

@ -0,0 +1,168 @@
// -*- C++ -*-
//===------------------------------ span ---------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
// template<class T, ptrdiff_t X, class U, ptrdiff_t Y>
// constexpr bool operator==(span<T, X> l, span<U, Y> r);
//
//
// Effects: Equivalent to: return equal(l.begin(), l.end(), r.begin(), r.end());
//
#include <span>
#include <cassert>
#include "test_macros.h"
struct A{};
bool operator==(A, A) {return true;}
constexpr int iArr1[] = { 0, 1, 2, 1, 2, 5, 6, 7, 8, 9};
int iArr2[] = { 0, 1, 2, 1, 2, 5, 6, 7, 8, 9};
constexpr float fArr1[] = {0., 1., 2., 1., 2., 5., 6., 7., 8., 9.};
float fArr2[] = {0., 1., 2., 1., 2., 5., 6., 7., 8., 9.};
int main () {
constexpr std::span<const int> csp0d{};
constexpr std::span<const int> csp1d{iArr1, 10};
constexpr std::span<const int> csp2d{iArr1 + 3, 2};
constexpr std::span<const int> csp3d{iArr1 + 1, 2};
constexpr std::span<const int> csp4d{iArr1 + 6, 2};
constexpr std::span<const int, 0> csp0s{};
constexpr std::span<const int, 10> csp1s{iArr1, 10};
constexpr std::span<const int, 2> csp2s{iArr1 + 3, 2};
constexpr std::span<const int, 2> csp3s{iArr1 + 1, 2};
constexpr std::span<const int, 2> csp4s{iArr1 + 6, 2};
static_assert( (csp0d == csp0d), "");
static_assert( (csp0s == csp0s), "");
static_assert( (csp0s == csp0d), "");
static_assert( (csp0d == csp0s), "");
static_assert(!(csp0d == csp1d), "");
static_assert(!(csp0s == csp1s), "");
static_assert(!(csp0s == csp1d), "");
static_assert(!(csp0d == csp1s), "");
static_assert( (csp1d == csp1s), "");
static_assert( (csp1s == csp1d), "");
static_assert( (csp2d == csp3d), "");
static_assert( (csp2s == csp3s), "");
static_assert( (csp2d == csp3s), "");
static_assert( (csp2s == csp3d), "");
static_assert( (csp2d == csp3d), "");
static_assert( (csp2s == csp3s), "");
static_assert( (csp2d == csp3s), "");
static_assert( (csp2s == csp3d), "");
static_assert(!(csp2d == csp4d), "");
static_assert(!(csp2s == csp4s), "");
static_assert(!(csp2d == csp4s), "");
static_assert(!(csp2s == csp4d), "");
static_assert(!(csp4d == csp2d), "");
static_assert(!(csp4s == csp2s), "");
static_assert(!(csp4d == csp2s), "");
static_assert(!(csp4s == csp2d), "");
std::span<int> sp0d{};
std::span<int> sp1d{iArr2, 10};
std::span<int> sp2d{iArr2 + 3, 2};
std::span<int> sp3d{iArr2 + 1, 2};
std::span<int> sp4d{iArr2 + 6, 2};
std::span<int, 0> sp0s{};
std::span<int, 10> sp1s{iArr2, 10};
std::span<int, 2> sp2s{iArr2 + 3, 2};
std::span<int, 2> sp3s{iArr2 + 1, 2};
std::span<int, 2> sp4s{iArr2 + 6, 2};
assert( (sp0d == sp0d));
assert( (sp0s == sp0s));
assert( (sp0s == sp0d));
assert( (sp0d == sp0s));
assert(!(sp0d == sp1d));
assert(!(sp0s == sp1s));
assert(!(sp0s == sp1d));
assert(!(sp0d == sp1s));
assert( (sp1d == sp1s));
assert( (sp1s == sp1d));
assert( (sp2d == sp3d));
assert( (sp2s == sp3s));
assert( (sp2d == sp3s));
assert( (sp2s == sp3d));
assert( (sp2d == sp3d));
assert( (sp2s == sp3s));
assert( (sp2d == sp3s));
assert( (sp2s == sp3d));
assert(!(sp2d == sp4d));
assert(!(sp2s == sp4s));
assert(!(sp2d == sp4s));
assert(!(sp2s == sp4d));
assert(!(sp4d == sp2d));
assert(!(sp4s == sp2s));
assert(!(sp4d == sp2s));
assert(!(sp4s == sp2d));
// cross type comparisons
assert( (csp0d == sp0d));
assert( (csp0s == sp0s));
assert( (csp0s == sp0d));
assert( (csp0d == sp0s));
assert(!(csp0d == sp1d));
assert(!(csp0s == sp1s));
assert(!(csp0s == sp1d));
assert(!(csp0d == sp1s));
assert( (csp1d == sp1s));
assert( (csp1s == sp1d));
assert( (csp2d == sp3d));
assert( (csp2s == sp3s));
assert( (csp2d == sp3s));
assert( (csp2s == sp3d));
assert( (csp2d == sp3d));
assert( (csp2s == sp3s));
assert( (csp2d == sp3s));
assert( (csp2s == sp3d));
assert(!(csp2d == sp4d));
assert(!(csp2s == sp4s));
assert(!(csp2d == sp4s));
assert(!(csp2s == sp4d));
assert(!(csp4d == sp2d));
assert(!(csp4s == sp2s));
assert(!(csp4d == sp2s));
assert(!(csp4s == sp2d));
// More cross-type comparisons (int vs float)
static_assert(std::span<const float>{fArr1} == std::span<const int>{iArr1}, "");
static_assert(std::span<const int>{iArr1} == std::span<const float>{fArr1}, "");
assert(std::span<float>{fArr2} == std::span<int>{iArr2});
assert(std::span<int>{iArr2} == std::span<float>{fArr2});
static_assert(!(std::span<const int>{iArr1, 9} == std::span<const float>{fArr1, 8}), "");
}

View File

@ -0,0 +1,153 @@
// -*- C++ -*-
//===------------------------------ span ---------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
// template<class T, ptrdiff_t X, class U, ptrdiff_t Y>
// constexpr bool operator>=(span<T, X> l, span<U, Y> r);
//
//
// Effects: Equivalent to: return !(l < r);
//
#include <span>
#include <cassert>
#include "test_macros.h"
struct A{};
bool operator==(A, A) {return true;}
constexpr int iArr1[] = { 0, 1, 2, 1, 2, 5, 6, 7, 8, 9};
int iArr2[] = { 0, 1, 2, 1, 2, 5, 6, 7, 8, 9};
constexpr float fArr1[] = {0., 1., 2., 1., 2., 5., 6., 7., 8., 9.};
float fArr2[] = {0., 1., 2., 1., 2., 5., 6., 7., 8., 9.};
int main () {
constexpr std::span<const int> csp0d{};
constexpr std::span<const int> csp1d{iArr1, 10};
constexpr std::span<const int> csp2d{iArr1 + 3, 2};
constexpr std::span<const int> csp3d{iArr1 + 1, 2};
constexpr std::span<const int> csp4d{iArr1 + 6, 2};
constexpr std::span<const int, 0> csp0s{};
constexpr std::span<const int, 10> csp1s{iArr1, 10};
constexpr std::span<const int, 2> csp2s{iArr1 + 3, 2};
constexpr std::span<const int, 2> csp3s{iArr1 + 1, 2};
constexpr std::span<const int, 2> csp4s{iArr1 + 6, 2};
static_assert( (csp0d >= csp0d), "");
static_assert( (csp0s >= csp0s), "");
static_assert( (csp0s >= csp0d), "");
static_assert( (csp0d >= csp0s), "");
static_assert(!(csp0d >= csp1d), "");
static_assert(!(csp0s >= csp1s), "");
static_assert(!(csp0s >= csp1d), "");
static_assert(!(csp0d >= csp1s), "");
static_assert( (csp1d >= csp1s), "");
static_assert( (csp1s >= csp1d), "");
static_assert( (csp2d >= csp3d), "");
static_assert( (csp2s >= csp3s), "");
static_assert( (csp2d >= csp3s), "");
static_assert( (csp2s >= csp3d), "");
static_assert(!(csp2d >= csp4d), "");
static_assert(!(csp2s >= csp4s), "");
static_assert(!(csp2d >= csp4s), "");
static_assert(!(csp2s >= csp4d), "");
static_assert( (csp4d >= csp2d), "");
static_assert( (csp4s >= csp2s), "");
static_assert( (csp4d >= csp2s), "");
static_assert( (csp4s >= csp2d), "");
std::span<int> sp0d{};
std::span<int> sp1d{iArr2, 10};
std::span<int> sp2d{iArr2 + 3, 2};
std::span<int> sp3d{iArr2 + 1, 2};
std::span<int> sp4d{iArr2 + 6, 2};
std::span<int, 0> sp0s{};
std::span<int, 10> sp1s{iArr2, 10};
std::span<int, 2> sp2s{iArr2 + 3, 2};
std::span<int, 2> sp3s{iArr2 + 1, 2};
std::span<int, 2> sp4s{iArr2 + 6, 2};
assert( (sp0d >= sp0d));
assert( (sp0s >= sp0s));
assert( (sp0s >= sp0d));
assert( (sp0d >= sp0s));
assert(!(sp0d >= sp1d));
assert(!(sp0s >= sp1s));
assert(!(sp0s >= sp1d));
assert(!(sp0d >= sp1s));
assert( (sp1d >= sp1s));
assert( (sp1s >= sp1d));
assert( (sp2d >= sp3d));
assert( (sp2s >= sp3s));
assert( (sp2d >= sp3s));
assert( (sp2s >= sp3d));
assert(!(sp2d >= sp4d));
assert(!(sp2s >= sp4s));
assert(!(sp2d >= sp4s));
assert(!(sp2s >= sp4d));
assert( (sp4d > sp2d));
assert( (sp4s > sp2s));
assert( (sp4d > sp2s));
assert( (sp4s > sp2d));
// cross type comparisons
assert( (csp0d >= sp0d));
assert( (csp0s >= sp0s));
assert( (csp0s >= sp0d));
assert( (csp0d >= sp0s));
assert(!(csp0d >= sp1d));
assert(!(csp0s >= sp1s));
assert(!(csp0s >= sp1d));
assert(!(csp0d >= sp1s));
assert( (csp1d >= sp1s));
assert( (csp1s >= sp1d));
assert( (csp2d >= sp3d));
assert( (csp2s >= sp3s));
assert( (csp2d >= sp3s));
assert( (csp2s >= sp3d));
assert(!(csp2d >= sp4d));
assert(!(csp2s >= sp4s));
assert(!(csp2d >= sp4s));
assert(!(csp2s >= sp4d));
assert( (csp4d > sp2d));
assert( (csp4s > sp2s));
assert( (csp4d > sp2s));
assert( (csp4s > sp2d));
// More cross-type comparisons (int vs float)
static_assert(!(std::span<const float>{fArr1, 8} >= std::span<const int>{iArr1, 9}), "");
static_assert(!(std::span<const int>{iArr1, 8} >= std::span<const float>{fArr1, 9}), "");
assert( (std::span<float>{fArr2} >= std::span<int>{iArr2}));
assert( (std::span<int>{iArr2} >= std::span<float>{fArr2}));
static_assert( (std::span<const int>{iArr1, 9} >= std::span<const float>{fArr1, 8}), "");
}

View File

@ -0,0 +1,154 @@
// -*- C++ -*-
//===------------------------------ span ---------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
// template<class T, ptrdiff_t X, class U, ptrdiff_t Y>
// constexpr bool operator>(span<T, X> l, span<U, Y> r);
//
//
// Effects: Equivalent to: return (r < l);
//
#include <span>
#include <cassert>
#include "test_macros.h"
struct A{};
bool operator==(A, A) {return true;}
constexpr int iArr1[] = { 0, 1, 2, 1, 2, 5, 6, 7, 8, 9};
int iArr2[] = { 0, 1, 2, 1, 2, 5, 6, 7, 8, 9};
constexpr float fArr1[] = {0., 1., 2., 1., 2., 5., 6., 7., 8., 9.};
float fArr2[] = {0., 1., 2., 1., 2., 5., 6., 7., 8., 9.};
int main () {
constexpr std::span<const int> csp0d{};
constexpr std::span<const int> csp1d{iArr1, 10};
constexpr std::span<const int> csp2d{iArr1 + 3, 2};
constexpr std::span<const int> csp3d{iArr1 + 1, 2};
constexpr std::span<const int> csp4d{iArr1 + 6, 2};
constexpr std::span<const int, 0> csp0s{};
constexpr std::span<const int, 10> csp1s{iArr1, 10};
constexpr std::span<const int, 2> csp2s{iArr1 + 3, 2};
constexpr std::span<const int, 2> csp3s{iArr1 + 1, 2};
constexpr std::span<const int, 2> csp4s{iArr1 + 6, 2};
static_assert(!(csp0d > csp0d), "");
static_assert(!(csp0s > csp0s), "");
static_assert(!(csp0s > csp0d), "");
static_assert(!(csp0d > csp0s), "");
static_assert(!(csp0d > csp1d), "");
static_assert(!(csp0s > csp1s), "");
static_assert(!(csp0s > csp1d), "");
static_assert(!(csp0d > csp1s), "");
static_assert(!(csp1d > csp1s), "");
static_assert(!(csp1s > csp1d), "");
static_assert(!(csp2d > csp3d), "");
static_assert(!(csp2s > csp3s), "");
static_assert(!(csp2d > csp3s), "");
static_assert(!(csp2s > csp3d), "");
static_assert(!(csp2d > csp4d), "");
static_assert(!(csp2s > csp4s), "");
static_assert(!(csp2d > csp4s), "");
static_assert(!(csp2s > csp4d), "");
static_assert( (csp4d > csp2d), "");
static_assert( (csp4s > csp2s), "");
static_assert( (csp4d > csp2s), "");
static_assert( (csp4s > csp2d), "");
std::span<int> sp0d{};
std::span<int> sp1d{iArr2, 10};
std::span<int> sp2d{iArr2 + 3, 2};
std::span<int> sp3d{iArr2 + 1, 2};
std::span<int> sp4d{iArr2 + 6, 2};
std::span<int, 0> sp0s{};
std::span<int, 10> sp1s{iArr2, 10};
std::span<int, 2> sp2s{iArr2 + 3, 2};
std::span<int, 2> sp3s{iArr2 + 1, 2};
std::span<int, 2> sp4s{iArr2 + 6, 2};
assert(!(sp0d > sp0d));
assert(!(sp0s > sp0s));
assert(!(sp0s > sp0d));
assert(!(sp0d > sp0s));
assert(!(sp0d > sp1d));
assert(!(sp0s > sp1s));
assert(!(sp0s > sp1d));
assert(!(sp0d > sp1s));
assert(!(sp1d > sp1s));
assert(!(sp1s > sp1d));
assert(!(sp2d > sp3d));
assert(!(sp2s > sp3s));
assert(!(sp2d > sp3s));
assert(!(sp2s > sp3d));
assert(!(sp2d > sp4d));
assert(!(sp2s > sp4s));
assert(!(sp2d > sp4s));
assert(!(sp2s > sp4d));
assert( (sp4d > sp2d));
assert( (sp4s > sp2s));
assert( (sp4d > sp2s));
assert( (sp4s > sp2d));
// cross type comparisons
assert(!(csp0d > sp0d));
assert(!(csp0s > sp0s));
assert(!(csp0s > sp0d));
assert(!(csp0d > sp0s));
assert(!(csp0d > sp1d));
assert(!(csp0s > sp1s));
assert(!(csp0s > sp1d));
assert(!(csp0d > sp1s));
assert(!(csp1d > sp1s));
assert(!(csp1s > sp1d));
assert(!(csp2d > sp3d));
assert(!(csp2s > sp3s));
assert(!(csp2d > sp3s));
assert(!(csp2s > sp3d));
assert(!(csp2d > sp4d));
assert(!(csp2s > sp4s));
assert(!(csp2d > sp4s));
assert(!(csp2s > sp4d));
assert( (csp4d > sp2d));
assert( (csp4s > sp2s));
assert( (csp4d > sp2s));
assert( (csp4s > sp2d));
// More cross-type comparisons (int vs float)
static_assert(!(std::span<const float>{fArr1, 8} > std::span<const int>{iArr1, 9}), "");
static_assert(!(std::span<const int>{iArr1, 8} > std::span<const float>{fArr1, 9}), "");
assert(!(std::span<float>{fArr2} > std::span<int>{iArr2}));
assert(!(std::span<int>{iArr2} > std::span<float>{fArr2}));
static_assert( (std::span<const int>{iArr1, 9} > std::span<const float>{fArr1, 8}), "");
}

View File

@ -0,0 +1,153 @@
// -*- C++ -*-
//===------------------------------ span ---------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
// template<class T, ptrdiff_t X, class U, ptrdiff_t Y>
// constexpr bool operator<=(span<T, X> l, span<U, Y> r);
//
//
// Effects: Equivalent to: return !(r < l);
//
#include <span>
#include <cassert>
#include "test_macros.h"
struct A{};
bool operator==(A, A) {return true;}
constexpr int iArr1[] = { 0, 1, 2, 1, 2, 5, 6, 7, 8, 9};
int iArr2[] = { 0, 1, 2, 1, 2, 5, 6, 7, 8, 9};
constexpr float fArr1[] = {0., 1., 2., 1., 2., 5., 6., 7., 8., 9.};
float fArr2[] = {0., 1., 2., 1., 2., 5., 6., 7., 8., 9.};
int main () {
constexpr std::span<const int> csp0d{};
constexpr std::span<const int> csp1d{iArr1, 10};
constexpr std::span<const int> csp2d{iArr1 + 3, 2};
constexpr std::span<const int> csp3d{iArr1 + 1, 2};
constexpr std::span<const int> csp4d{iArr1 + 6, 2};
constexpr std::span<const int, 0> csp0s{};
constexpr std::span<const int, 10> csp1s{iArr1, 10};
constexpr std::span<const int, 2> csp2s{iArr1 + 3, 2};
constexpr std::span<const int, 2> csp3s{iArr1 + 1, 2};
constexpr std::span<const int, 2> csp4s{iArr1 + 6, 2};
static_assert( (csp0d <= csp0d), "");
static_assert( (csp0s <= csp0s), "");
static_assert( (csp0s <= csp0d), "");
static_assert( (csp0d <= csp0s), "");
static_assert( (csp0d <= csp1d), "");
static_assert( (csp0s <= csp1s), "");
static_assert( (csp0s <= csp1d), "");
static_assert( (csp0d <= csp1s), "");
static_assert( (csp1d <= csp1s), "");
static_assert( (csp1s <= csp1d), "");
static_assert( (csp2d <= csp3d), "");
static_assert( (csp2s <= csp3s), "");
static_assert( (csp2d <= csp3s), "");
static_assert( (csp2s <= csp3d), "");
static_assert( (csp2d <= csp4d), "");
static_assert( (csp2s <= csp4s), "");
static_assert( (csp2d <= csp4s), "");
static_assert( (csp2s <= csp4d), "");
static_assert(!(csp4d <= csp2d), "");
static_assert(!(csp4s <= csp2s), "");
static_assert(!(csp4d <= csp2s), "");
static_assert(!(csp4s <= csp2d), "");
std::span<int> sp0d{};
std::span<int> sp1d{iArr2, 10};
std::span<int> sp2d{iArr2 + 3, 2};
std::span<int> sp3d{iArr2 + 1, 2};
std::span<int> sp4d{iArr2 + 6, 2};
std::span<int, 0> sp0s{};
std::span<int, 10> sp1s{iArr2, 10};
std::span<int, 2> sp2s{iArr2 + 3, 2};
std::span<int, 2> sp3s{iArr2 + 1, 2};
std::span<int, 2> sp4s{iArr2 + 6, 2};
assert( (sp0d <= sp0d));
assert( (sp0s <= sp0s));
assert( (sp0s <= sp0d));
assert( (sp0d <= sp0s));
assert( (sp0d <= sp1d));
assert( (sp0s <= sp1s));
assert( (sp0s <= sp1d));
assert( (sp0d <= sp1s));
assert( (sp1d <= sp1s));
assert( (sp1s <= sp1d));
assert( (sp2d <= sp3d));
assert( (sp2s <= sp3s));
assert( (sp2d <= sp3s));
assert( (sp2s <= sp3d));
assert( (sp2d <= sp4d));
assert( (sp2s <= sp4s));
assert( (sp2d <= sp4s));
assert( (sp2s <= sp4d));
assert(!(sp4d <= sp2d));
assert(!(sp4s <= sp2s));
assert(!(sp4d <= sp2s));
assert(!(sp4s <= sp2d));
// cross type comparisons
assert( (csp0d <= sp0d));
assert( (csp0s <= sp0s));
assert( (csp0s <= sp0d));
assert( (csp0d <= sp0s));
assert( (csp0d <= sp1d));
assert( (csp0s <= sp1s));
assert( (csp0s <= sp1d));
assert( (csp0d <= sp1s));
assert( (csp1d <= sp1s));
assert( (csp1s <= sp1d));
assert( (csp2d <= sp3d));
assert( (csp2s <= sp3s));
assert( (csp2d <= sp3s));
assert( (csp2s <= sp3d));
assert( (csp2d <= sp4d));
assert( (csp2s <= sp4s));
assert( (csp2d <= sp4s));
assert( (csp2s <= sp4d));
assert(!(csp4d <= sp2d));
assert(!(csp4s <= sp2s));
assert(!(csp4d <= sp2s));
assert(!(csp4s <= sp2d));
// More cross-type comparisons (int vs float)
static_assert(std::span<const float>{fArr1, 8} <= std::span<const int>{iArr1, 9}, "");
static_assert(std::span<const int>{iArr1, 8} <= std::span<const float>{fArr1, 9}, "");
assert( (std::span<float>{fArr2} <= std::span<int>{iArr2}));
assert( (std::span<int>{iArr2} <= std::span<float>{fArr2}));
static_assert(!(std::span<const int>{iArr1, 9} <= std::span<const float>{fArr1, 8}), "");
}

View File

@ -0,0 +1,154 @@
// -*- C++ -*-
//===------------------------------ span ---------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
// template<class T, ptrdiff_t X, class U, ptrdiff_t Y>
// constexpr bool operator<(span<T, X> l, span<U, Y> r);
//
//
// Effects: Equivalent to:
// return lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
//
#include <span>
#include <cassert>
#include "test_macros.h"
struct A{};
bool operator==(A, A) {return true;}
constexpr int iArr1[] = { 0, 1, 2, 1, 2, 5, 6, 7, 8, 9};
int iArr2[] = { 0, 1, 2, 1, 2, 5, 6, 7, 8, 9};
constexpr float fArr1[] = {0., 1., 2., 1., 2., 5., 6., 7., 8., 9.};
float fArr2[] = {0., 1., 2., 1., 2., 5., 6., 7., 8., 9.};
int main () {
constexpr std::span<const int> csp0d{};
constexpr std::span<const int> csp1d{iArr1, 10};
constexpr std::span<const int> csp2d{iArr1 + 3, 2};
constexpr std::span<const int> csp3d{iArr1 + 1, 2};
constexpr std::span<const int> csp4d{iArr1 + 6, 2};
constexpr std::span<const int, 0> csp0s{};
constexpr std::span<const int, 10> csp1s{iArr1, 10};
constexpr std::span<const int, 2> csp2s{iArr1 + 3, 2};
constexpr std::span<const int, 2> csp3s{iArr1 + 1, 2};
constexpr std::span<const int, 2> csp4s{iArr1 + 6, 2};
static_assert(!(csp0d < csp0d), "");
static_assert(!(csp0s < csp0s), "");
static_assert(!(csp0s < csp0d), "");
static_assert(!(csp0d < csp0s), "");
static_assert( (csp0d < csp1d), "");
static_assert( (csp0s < csp1s), "");
static_assert( (csp0s < csp1d), "");
static_assert( (csp0d < csp1s), "");
static_assert(!(csp1d < csp1s), "");
static_assert(!(csp1s < csp1d), "");
static_assert(!(csp2d < csp3d), "");
static_assert(!(csp2s < csp3s), "");
static_assert(!(csp2d < csp3s), "");
static_assert(!(csp2s < csp3d), "");
static_assert( (csp2d < csp4d), "");
static_assert( (csp2s < csp4s), "");
static_assert( (csp2d < csp4s), "");
static_assert( (csp2s < csp4d), "");
static_assert(!(csp4d < csp2d), "");
static_assert(!(csp4s < csp2s), "");
static_assert(!(csp4d < csp2s), "");
static_assert(!(csp4s < csp2d), "");
std::span<int> sp0d{};
std::span<int> sp1d{iArr2, 10};
std::span<int> sp2d{iArr2 + 3, 2};
std::span<int> sp3d{iArr2 + 1, 2};
std::span<int> sp4d{iArr2 + 6, 2};
std::span<int, 0> sp0s{};
std::span<int, 10> sp1s{iArr2, 10};
std::span<int, 2> sp2s{iArr2 + 3, 2};
std::span<int, 2> sp3s{iArr2 + 1, 2};
std::span<int, 2> sp4s{iArr2 + 6, 2};
assert(!(sp0d < sp0d));
assert(!(sp0s < sp0s));
assert(!(sp0s < sp0d));
assert(!(sp0d < sp0s));
assert( (sp0d < sp1d));
assert( (sp0s < sp1s));
assert( (sp0s < sp1d));
assert( (sp0d < sp1s));
assert(!(sp1d < sp1s));
assert(!(sp1s < sp1d));
assert(!(sp2d < sp3d));
assert(!(sp2s < sp3s));
assert(!(sp2d < sp3s));
assert(!(sp2s < sp3d));
assert( (sp2d < sp4d));
assert( (sp2s < sp4s));
assert( (sp2d < sp4s));
assert( (sp2s < sp4d));
assert(!(sp4d < sp2d));
assert(!(sp4s < sp2s));
assert(!(sp4d < sp2s));
assert(!(sp4s < sp2d));
// cross type comparisons
assert(!(csp0d < sp0d));
assert(!(csp0s < sp0s));
assert(!(csp0s < sp0d));
assert(!(csp0d < sp0s));
assert( (csp0d < sp1d));
assert( (csp0s < sp1s));
assert( (csp0s < sp1d));
assert( (csp0d < sp1s));
assert(!(csp1d < sp1s));
assert(!(csp1s < sp1d));
assert(!(csp2d < sp3d));
assert(!(csp2s < sp3s));
assert(!(csp2d < sp3s));
assert(!(csp2s < sp3d));
assert( (csp2d < sp4d));
assert( (csp2s < sp4s));
assert( (csp2d < sp4s));
assert( (csp2s < sp4d));
assert(!(csp4d < sp2d));
assert(!(csp4s < sp2s));
assert(!(csp4d < sp2s));
assert(!(csp4s < sp2d));
// More cross-type comparisons (int vs float)
static_assert(std::span<const float>{fArr1, 8} < std::span<const int>{iArr1, 9}, "");
static_assert(std::span<const int>{iArr1, 8} < std::span<const float>{fArr1, 9}, "");
assert(!(std::span<float>{fArr2} < std::span<int>{iArr2}));
assert(!(std::span<int>{iArr2} < std::span<float>{fArr2}));
static_assert(!(std::span<const int>{iArr1, 9} < std::span<const float>{fArr1, 8}), "");
}

View File

@ -0,0 +1,168 @@
// -*- C++ -*-
//===------------------------------ span ---------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
// template<class T, ptrdiff_t X, class U, ptrdiff_t Y>
// constexpr bool operator!=(span<T, X> l, span<U, Y> r);
//
//
// Effects: Equivalent to: return !(l == r);
//
#include <span>
#include <cassert>
#include "test_macros.h"
struct A{};
bool operator==(A, A) {return true;}
constexpr int iArr1[] = { 0, 1, 2, 1, 2, 5, 6, 7, 8, 9};
int iArr2[] = { 0, 1, 2, 1, 2, 5, 6, 7, 8, 9};
constexpr float fArr1[] = {0., 1., 2., 1., 2., 5., 6., 7., 8., 9.};
float fArr2[] = {0., 1., 2., 1., 2., 5., 6., 7., 8., 9.};
int main () {
constexpr std::span<const int> csp0d{};
constexpr std::span<const int> csp1d{iArr1, 10};
constexpr std::span<const int> csp2d{iArr1 + 3, 2};
constexpr std::span<const int> csp3d{iArr1 + 1, 2};
constexpr std::span<const int> csp4d{iArr1 + 6, 2};
constexpr std::span<const int, 0> csp0s{};
constexpr std::span<const int, 10> csp1s{iArr1, 10};
constexpr std::span<const int, 2> csp2s{iArr1 + 3, 2};
constexpr std::span<const int, 2> csp3s{iArr1 + 1, 2};
constexpr std::span<const int, 2> csp4s{iArr1 + 6, 2};
static_assert(!(csp0d != csp0d), "");
static_assert(!(csp0s != csp0s), "");
static_assert(!(csp0s != csp0d), "");
static_assert(!(csp0d != csp0s), "");
static_assert( (csp0d != csp1d), "");
static_assert( (csp0s != csp1s), "");
static_assert( (csp0s != csp1d), "");
static_assert( (csp0d != csp1s), "");
static_assert(!(csp1d != csp1s), "");
static_assert(!(csp1s != csp1d), "");
static_assert(!(csp2d != csp3d), "");
static_assert(!(csp2s != csp3s), "");
static_assert(!(csp2d != csp3s), "");
static_assert(!(csp2s != csp3d), "");
static_assert(!(csp2d != csp3d), "");
static_assert(!(csp2s != csp3s), "");
static_assert(!(csp2d != csp3s), "");
static_assert(!(csp2s != csp3d), "");
static_assert( (csp2d != csp4d), "");
static_assert( (csp2s != csp4s), "");
static_assert( (csp2d != csp4s), "");
static_assert( (csp2s != csp4d), "");
static_assert( (csp4d != csp2d), "");
static_assert( (csp4s != csp2s), "");
static_assert( (csp4d != csp2s), "");
static_assert( (csp4s != csp2d), "");
std::span<int> sp0d{};
std::span<int> sp1d{iArr2, 10};
std::span<int> sp2d{iArr2 + 3, 2};
std::span<int> sp3d{iArr2 + 1, 2};
std::span<int> sp4d{iArr2 + 6, 2};
std::span<int, 0> sp0s{};
std::span<int, 10> sp1s{iArr2, 10};
std::span<int, 2> sp2s{iArr2 + 3, 2};
std::span<int, 2> sp3s{iArr2 + 1, 2};
std::span<int, 2> sp4s{iArr2 + 6, 2};
assert(!(sp0d != sp0d));
assert(!(sp0s != sp0s));
assert(!(sp0s != sp0d));
assert(!(sp0d != sp0s));
assert( (sp0d != sp1d));
assert( (sp0s != sp1s));
assert( (sp0s != sp1d));
assert( (sp0d != sp1s));
assert(!(sp1d != sp1s));
assert(!(sp1s != sp1d));
assert(!(sp2d != sp3d));
assert(!(sp2s != sp3s));
assert(!(sp2d != sp3s));
assert(!(sp2s != sp3d));
assert(!(sp2d != sp3d));
assert(!(sp2s != sp3s));
assert(!(sp2d != sp3s));
assert(!(sp2s != sp3d));
assert( (sp2d != sp4d));
assert( (sp2s != sp4s));
assert( (sp2d != sp4s));
assert( (sp2s != sp4d));
assert( (sp4d != sp2d));
assert( (sp4s != sp2s));
assert( (sp4d != sp2s));
assert( (sp4s != sp2d));
// cross type comparisons
assert(!(csp0d != sp0d));
assert(!(csp0s != sp0s));
assert(!(csp0s != sp0d));
assert(!(csp0d != sp0s));
assert( (csp0d != sp1d));
assert( (csp0s != sp1s));
assert( (csp0s != sp1d));
assert( (csp0d != sp1s));
assert(!(csp1d != sp1s));
assert(!(csp1s != sp1d));
assert(!(csp2d != sp3d));
assert(!(csp2s != sp3s));
assert(!(csp2d != sp3s));
assert(!(csp2s != sp3d));
assert(!(csp2d != sp3d));
assert(!(csp2s != sp3s));
assert(!(csp2d != sp3s));
assert(!(csp2s != sp3d));
assert( (csp2d != sp4d));
assert( (csp2s != sp4s));
assert( (csp2d != sp4s));
assert( (csp2s != sp4d));
assert( (csp4d != sp2d));
assert( (csp4s != sp2s));
assert( (csp4d != sp2s));
assert( (csp4s != sp2d));
// More cross-type comparisons (int vs float)
static_assert(!(std::span<const float>{fArr1} != std::span<const int>{iArr1}), "");
static_assert(!(std::span<const int>{iArr1} != std::span<const float>{fArr1}), "");
assert(!(std::span<float>{fArr2} != std::span<int>{iArr2}));
assert(!(std::span<int>{iArr2} != std::span<float>{fArr2}));
static_assert( (std::span<const int>{iArr1, 9} != std::span<const float>{fArr1, 8}), "");
}

View File

@ -0,0 +1,72 @@
// -*- C++ -*-
//===------------------------------ span ---------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
// template<size_t N>
// constexpr span(element_type (&arr)[N]) noexcept;
// template<size_t N>
// constexpr span(array<value_type, N>& arr) noexcept;
// template<size_t N>
// constexpr span(const array<value_type, N>& arr) noexcept;
//
// Remarks: These constructors shall not participate in overload resolution unless:
// — extent == dynamic_extent || N == extent is true, and
// — remove_pointer_t<decltype(data(arr))>(*)[] is convertible to ElementType(*)[].
//
#include <span>
#include <cassert>
#include <string>
#include "test_macros.h"
int arr[] = {1,2,3};
const int carr[] = {4,5,6};
volatile int varr[] = {7,8,9};
const volatile int cvarr[] = {1,3,5};
int main ()
{
// Size wrong
{
std::span<int, 2> s1(arr); // expected-error {{no matching constructor for initialization of 'std::span<int, 2>'}}
}
// Type wrong
{
std::span<float> s1(arr); // expected-error {{no matching constructor for initialization of 'std::span<float>'}}
std::span<float, 3> s2(arr); // expected-error {{no matching constructor for initialization of 'std::span<float, 3>'}}
}
// CV wrong (dynamically sized)
{
std::span< int> s1{ carr}; // expected-error {{no matching constructor for initialization of 'std::span<int>'}}
std::span< int> s2{ varr}; // expected-error {{no matching constructor for initialization of 'std::span<int>'}}
std::span< int> s3{cvarr}; // expected-error {{no matching constructor for initialization of 'std::span<int>'}}
std::span<const int> s4{ varr}; // expected-error {{no matching constructor for initialization of 'std::span<const int>'}}
std::span<const int> s5{cvarr}; // expected-error {{no matching constructor for initialization of 'std::span<const int>'}}
std::span< volatile int> s6{ carr}; // expected-error {{no matching constructor for initialization of 'std::span<volatile int>'}}
std::span< volatile int> s7{cvarr}; // expected-error {{no matching constructor for initialization of 'std::span<volatile int>'}}
}
// CV wrong (statically sized)
{
std::span< int,3> s1{ carr}; // expected-error {{no matching constructor for initialization of 'std::span<int, 3>'}}
std::span< int,3> s2{ varr}; // expected-error {{no matching constructor for initialization of 'std::span<int, 3>'}}
std::span< int,3> s3{cvarr}; // expected-error {{no matching constructor for initialization of 'std::span<int, 3>'}}
std::span<const int,3> s4{ varr}; // expected-error {{no matching constructor for initialization of 'std::span<const int, 3>'}}
std::span<const int,3> s5{cvarr}; // expected-error {{no matching constructor for initialization of 'std::span<const int, 3>'}}
std::span< volatile int,3> s6{ carr}; // expected-error {{no matching constructor for initialization of 'std::span<volatile int, 3>'}}
std::span< volatile int,3> s7{cvarr}; // expected-error {{no matching constructor for initialization of 'std::span<volatile int, 3>'}}
}
}

View File

@ -0,0 +1,123 @@
// -*- C++ -*-
//===------------------------------ span ---------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
// template<size_t N>
// constexpr span(element_type (&arr)[N]) noexcept;
//
// Remarks: These constructors shall not participate in overload resolution unless:
// — extent == dynamic_extent || N == extent is true, and
// — remove_pointer_t<decltype(data(arr))>(*)[] is convertible to ElementType(*)[].
//
#include <span>
#include <cassert>
#include <string>
#include "test_macros.h"
void checkCV()
{
int arr[] = {1,2,3};
const int carr[] = {4,5,6};
volatile int varr[] = {7,8,9};
const volatile int cvarr[] = {1,3,5};
// Types the same (dynamic sized)
{
std::span< int> s1{ arr}; // a span< int> pointing at int.
std::span<const int> s2{ carr}; // a span<const int> pointing at const int.
std::span< volatile int> s3{ varr}; // a span< volatile int> pointing at volatile int.
std::span<const volatile int> s4{cvarr}; // a span<const volatile int> pointing at const volatile int.
assert(s1.size() + s2.size() + s3.size() + s4.size() == 12);
}
// Types the same (static sized)
{
std::span< int,3> s1{ arr}; // a span< int> pointing at int.
std::span<const int,3> s2{ carr}; // a span<const int> pointing at const int.
std::span< volatile int,3> s3{ varr}; // a span< volatile int> pointing at volatile int.
std::span<const volatile int,3> s4{cvarr}; // a span<const volatile int> pointing at const volatile int.
assert(s1.size() + s2.size() + s3.size() + s4.size() == 12);
}
// types different (dynamic sized)
{
std::span<const int> s1{ arr}; // a span<const int> pointing at int.
std::span< volatile int> s2{ arr}; // a span< volatile int> pointing at int.
std::span< volatile int> s3{ arr}; // a span< volatile int> pointing at const int.
std::span<const volatile int> s4{ arr}; // a span<const volatile int> pointing at int.
std::span<const volatile int> s5{carr}; // a span<const volatile int> pointing at const int.
std::span<const volatile int> s6{varr}; // a span<const volatile int> pointing at volatile int.
assert(s1.size() + s2.size() + s3.size() + s4.size() + s5.size() + s6.size() == 18);
}
// types different (static sized)
{
std::span<const int,3> s1{ arr}; // a span<const int> pointing at int.
std::span< volatile int,3> s2{ arr}; // a span< volatile int> pointing at int.
std::span< volatile int,3> s3{ arr}; // a span< volatile int> pointing at const int.
std::span<const volatile int,3> s4{ arr}; // a span<const volatile int> pointing at int.
std::span<const volatile int,3> s5{carr}; // a span<const volatile int> pointing at const int.
std::span<const volatile int,3> s6{varr}; // a span<const volatile int> pointing at volatile int.
assert(s1.size() + s2.size() + s3.size() + s4.size() + s5.size() + s6.size() == 18);
}
}
template <typename T>
constexpr bool testConstexprSpan()
{
constexpr T val[2] = {};
ASSERT_NOEXCEPT(std::span<const T> {val});
ASSERT_NOEXCEPT(std::span<const T, 2>{val});
std::span<const T> s1{val};
std::span<const T, 2> s2{val};
return
s1.data() == &val[0] && s1.size() == 2
&& s2.data() == &val[0] && s2.size() == 2;
}
template <typename T>
void testRuntimeSpan()
{
T val[2] = {};
ASSERT_NOEXCEPT(std::span<T> {val});
ASSERT_NOEXCEPT(std::span<T, 2>{val});
std::span<T> s1{val};
std::span<T, 2> s2{val};
assert(s1.data() == &val[0] && s1.size() == 2);
assert(s2.data() == &val[0] && s2.size() == 2);
}
struct A{};
int main ()
{
static_assert(testConstexprSpan<int>(), "");
static_assert(testConstexprSpan<long>(), "");
static_assert(testConstexprSpan<double>(), "");
static_assert(testConstexprSpan<A>(), "");
testRuntimeSpan<int>();
testRuntimeSpan<long>();
testRuntimeSpan<double>();
testRuntimeSpan<std::string>();
testRuntimeSpan<A>();
checkCV();
}

View File

@ -0,0 +1,293 @@
// -*- C++ -*-
//===------------------------------ span ---------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
// constexpr span& operator=(const span& other) noexcept = default;
#include <span>
#include <cassert>
#include <string>
#include <utility>
#include "test_macros.h"
template <typename T>
constexpr bool doAssign(T lhs, T rhs)
{
ASSERT_NOEXCEPT(std::declval<T&>() = rhs);
lhs = rhs;
return lhs.data() == rhs.data()
&& lhs.size() == rhs.size();
}
struct A{};
constexpr int carr1[] = {1,2,3,4};
constexpr int carr2[] = {3,4,5};
constexpr int carr3[] = {7,8};
int arr[] = {5,6,7,9};
std::string strs[] = {"ABC", "DEF", "GHI"};
int main ()
{
// constexpr dynamically sized assignment
{
// On systems where 'ptrdiff_t' is a synonym for 'int',
// the call span(ptr, 0) selects the (pointer, index_type) constructor.
// On systems where 'ptrdiff_t' is NOT a synonym for 'int',
// it is ambiguous, because of 0 also being convertible to a null pointer
// and so the compiler can't choose between:
// span(pointer, index_type)
// and span(pointer, pointer)
// We cast zero to std::ptrdiff_t to remove that ambiguity.
// Example:
// On darwin x86_64, ptrdiff_t is the same as long int.
// On darwin i386, ptrdiff_t is the same as int.
constexpr std::span<const int> spans[] = {
{},
{carr1, static_cast<std::ptrdiff_t>(0)},
{carr1, 1},
{carr1, 2},
{carr1, 3},
{carr1, 4},
{carr2, static_cast<std::ptrdiff_t>(0)},
{carr2, 1},
{carr2, 2},
{carr2, 3},
{carr3, static_cast<std::ptrdiff_t>(0)},
{carr3, 1},
{carr3, 2}
};
static_assert(std::size(spans) == 13, "" );
// No for loops in constexpr land :-(
static_assert(doAssign(spans[0], spans[0]), "");
static_assert(doAssign(spans[0], spans[1]), "");
static_assert(doAssign(spans[0], spans[2]), "");
static_assert(doAssign(spans[0], spans[3]), "");
static_assert(doAssign(spans[0], spans[4]), "");
static_assert(doAssign(spans[0], spans[5]), "");
static_assert(doAssign(spans[0], spans[6]), "");
static_assert(doAssign(spans[0], spans[7]), "");
static_assert(doAssign(spans[0], spans[8]), "");
static_assert(doAssign(spans[0], spans[9]), "");
static_assert(doAssign(spans[0], spans[10]), "");
static_assert(doAssign(spans[0], spans[11]), "");
static_assert(doAssign(spans[0], spans[12]), "");
static_assert(doAssign(spans[1], spans[1]), "");
static_assert(doAssign(spans[1], spans[2]), "");
static_assert(doAssign(spans[1], spans[3]), "");
static_assert(doAssign(spans[1], spans[4]), "");
static_assert(doAssign(spans[1], spans[5]), "");
static_assert(doAssign(spans[1], spans[6]), "");
static_assert(doAssign(spans[1], spans[7]), "");
static_assert(doAssign(spans[1], spans[8]), "");
static_assert(doAssign(spans[1], spans[9]), "");
static_assert(doAssign(spans[1], spans[10]), "");
static_assert(doAssign(spans[1], spans[11]), "");
static_assert(doAssign(spans[1], spans[12]), "");
static_assert(doAssign(spans[2], spans[2]), "");
static_assert(doAssign(spans[2], spans[3]), "");
static_assert(doAssign(spans[2], spans[4]), "");
static_assert(doAssign(spans[2], spans[5]), "");
static_assert(doAssign(spans[2], spans[6]), "");
static_assert(doAssign(spans[2], spans[7]), "");
static_assert(doAssign(spans[2], spans[8]), "");
static_assert(doAssign(spans[2], spans[9]), "");
static_assert(doAssign(spans[2], spans[10]), "");
static_assert(doAssign(spans[2], spans[11]), "");
static_assert(doAssign(spans[2], spans[12]), "");
static_assert(doAssign(spans[3], spans[3]), "");
static_assert(doAssign(spans[3], spans[4]), "");
static_assert(doAssign(spans[3], spans[4]), "");
static_assert(doAssign(spans[3], spans[4]), "");
static_assert(doAssign(spans[3], spans[4]), "");
static_assert(doAssign(spans[3], spans[4]), "");
static_assert(doAssign(spans[3], spans[4]), "");
static_assert(doAssign(spans[3], spans[4]), "");
static_assert(doAssign(spans[3], spans[4]), "");
static_assert(doAssign(spans[3], spans[10]), "");
static_assert(doAssign(spans[3], spans[11]), "");
static_assert(doAssign(spans[3], spans[12]), "");
static_assert(doAssign(spans[4], spans[4]), "");
static_assert(doAssign(spans[4], spans[5]), "");
static_assert(doAssign(spans[4], spans[6]), "");
static_assert(doAssign(spans[4], spans[7]), "");
static_assert(doAssign(spans[4], spans[8]), "");
static_assert(doAssign(spans[4], spans[9]), "");
static_assert(doAssign(spans[4], spans[10]), "");
static_assert(doAssign(spans[4], spans[11]), "");
static_assert(doAssign(spans[4], spans[12]), "");
static_assert(doAssign(spans[5], spans[5]), "");
static_assert(doAssign(spans[5], spans[6]), "");
static_assert(doAssign(spans[5], spans[7]), "");
static_assert(doAssign(spans[5], spans[8]), "");
static_assert(doAssign(spans[5], spans[9]), "");
static_assert(doAssign(spans[5], spans[10]), "");
static_assert(doAssign(spans[5], spans[11]), "");
static_assert(doAssign(spans[5], spans[12]), "");
static_assert(doAssign(spans[6], spans[6]), "");
static_assert(doAssign(spans[6], spans[7]), "");
static_assert(doAssign(spans[6], spans[8]), "");
static_assert(doAssign(spans[6], spans[9]), "");
static_assert(doAssign(spans[6], spans[10]), "");
static_assert(doAssign(spans[6], spans[11]), "");
static_assert(doAssign(spans[6], spans[12]), "");
static_assert(doAssign(spans[7], spans[7]), "");
static_assert(doAssign(spans[7], spans[8]), "");
static_assert(doAssign(spans[7], spans[9]), "");
static_assert(doAssign(spans[7], spans[10]), "");
static_assert(doAssign(spans[7], spans[11]), "");
static_assert(doAssign(spans[7], spans[12]), "");
static_assert(doAssign(spans[8], spans[8]), "");
static_assert(doAssign(spans[8], spans[9]), "");
static_assert(doAssign(spans[8], spans[10]), "");
static_assert(doAssign(spans[8], spans[11]), "");
static_assert(doAssign(spans[8], spans[12]), "");
static_assert(doAssign(spans[9], spans[9]), "");
static_assert(doAssign(spans[9], spans[10]), "");
static_assert(doAssign(spans[9], spans[11]), "");
static_assert(doAssign(spans[9], spans[12]), "");
static_assert(doAssign(spans[10], spans[10]), "");
static_assert(doAssign(spans[10], spans[11]), "");
static_assert(doAssign(spans[10], spans[12]), "");
static_assert(doAssign(spans[11], spans[11]), "");
static_assert(doAssign(spans[11], spans[12]), "");
static_assert(doAssign(spans[12], spans[12]), "");
// for (size_t i = 0; i < std::size(spans); ++i)
// for (size_t j = i; j < std::size(spans); ++j)
// static_assert(doAssign(spans[i], spans[j]), "");
}
// constexpr statically sized assignment
{
constexpr std::span<const int,2> spans[] = {
{carr1, 2},
{carr1 + 1, 2},
{carr1 + 2, 2},
{carr2, 2},
{carr2 + 1, 2},
{carr3, 2}
};
static_assert(std::size(spans) == 6, "" );
// No for loops in constexpr land :-(
static_assert(doAssign(spans[0], spans[0]), "");
static_assert(doAssign(spans[0], spans[1]), "");
static_assert(doAssign(spans[0], spans[2]), "");
static_assert(doAssign(spans[0], spans[3]), "");
static_assert(doAssign(spans[0], spans[4]), "");
static_assert(doAssign(spans[0], spans[5]), "");
static_assert(doAssign(spans[1], spans[1]), "");
static_assert(doAssign(spans[1], spans[2]), "");
static_assert(doAssign(spans[1], spans[3]), "");
static_assert(doAssign(spans[1], spans[4]), "");
static_assert(doAssign(spans[1], spans[5]), "");
static_assert(doAssign(spans[2], spans[2]), "");
static_assert(doAssign(spans[2], spans[3]), "");
static_assert(doAssign(spans[2], spans[4]), "");
static_assert(doAssign(spans[2], spans[5]), "");
static_assert(doAssign(spans[3], spans[3]), "");
static_assert(doAssign(spans[3], spans[4]), "");
static_assert(doAssign(spans[3], spans[5]), "");
static_assert(doAssign(spans[4], spans[4]), "");
static_assert(doAssign(spans[4], spans[5]), "");
static_assert(doAssign(spans[5], spans[5]), "");
// for (size_t i = 0; i < std::size(spans); ++i)
// for (size_t j = i; j < std::size(spans); ++j)
// static_assert(doAssign(spans[i], spans[j]), "");
}
// dynamically sized assignment
{
std::span<int> spans[] = {
{},
{arr, arr + 1},
{arr, arr + 2},
{arr, arr + 3},
{arr + 1, arr + 3} // same size as s2
};
for (size_t i = 0; i < std::size(spans); ++i)
for (size_t j = i; j < std::size(spans); ++j)
assert((doAssign(spans[i], spans[j])));
}
// statically sized assignment
{
std::span<int,2> spans[] = {
{arr, arr + 2},
{arr + 1, arr + 3},
{arr + 2, arr + 4}
};
for (size_t i = 0; i < std::size(spans); ++i)
for (size_t j = i; j < std::size(spans); ++j)
assert((doAssign(spans[i], spans[j])));
}
// dynamically sized assignment
{
std::span<std::string> spans[] = {
{strs, strs},
{strs, strs + 1},
{strs, strs + 2},
{strs, strs + 3},
{strs + 1, strs + 1},
{strs + 1, strs + 2},
{strs + 1, strs + 3},
{strs + 2, strs + 2},
{strs + 2, strs + 3},
{strs + 3, strs + 3}
};
for (size_t i = 0; i < std::size(spans); ++i)
for (size_t j = i; j < std::size(spans); ++j)
assert((doAssign(spans[i], spans[j])));
}
{
std::span<std::string, 1> spans[] = {
{strs, strs + 1},
{strs + 1, strs + 2},
{strs + 2, strs + 3}
};
for (size_t i = 0; i < std::size(spans); ++i)
for (size_t j = i; j < std::size(spans); ++j)
assert((doAssign(spans[i], spans[j])));
}
}

View File

@ -0,0 +1,117 @@
// -*- C++ -*-
//===------------------------------ span ---------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
// template<class Container>
// constexpr span(Container& cont);
// template<class Container>
// constexpr span(const Container& cont);
//
// Remarks: These constructors shall not participate in overload resolution unless:
// — Container is not a specialization of span,
// — Container is not a specialization of array,
// — is_array_v<Container> is false,
// — data(cont) and size(cont) are both well-formed, and
// — remove_pointer_t<decltype(data(cont))>(*)[] is convertible to ElementType(*)[].
//
#include <span>
#include <cassert>
#include <list>
#include <forward_list>
#include <deque>
#include "test_macros.h"
// Look ma - I'm a container!
template <typename T>
struct IsAContainer {
constexpr IsAContainer() : v_{} {}
constexpr size_t size() const {return 1;}
constexpr T *data() {return &v_;}
constexpr const T *data() const {return &v_;}
constexpr const T *getV() const {return &v_;} // for checking
T v_;
};
template <typename T>
struct NotAContainerNoData {
size_t size() const {return 0;}
};
template <typename T>
struct NotAContainerNoSize {
const T *data() const {return nullptr;}
};
template <typename T>
struct NotAContainerPrivate {
private:
size_t size() const {return 0;}
const T *data() const {return nullptr;}
};
int main ()
{
// Missing size and/or data
{
std::span<int> s1{IsAContainer<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<int>'}}
std::span<int, 0> s2{IsAContainer<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<int, 0>'}}
std::span<int> s3{NotAContainerNoData<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<int>'}}
std::span<int, 0> s4{NotAContainerNoData<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<int, 0>'}}
std::span<int> s5{NotAContainerNoSize<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<int>'}}
std::span<int, 0> s6{NotAContainerNoSize<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<int, 0>'}}
std::span<int> s7{NotAContainerPrivate<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<int>'}}
std::span<int, 0> s8{NotAContainerPrivate<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<int, 0>'}}
// Again with the standard containers
std::span<int> s11{std::deque<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<int>'}}
std::span<int, 0> s12{std::deque<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<int, 0>'}}
std::span<int> s13{std::list<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<int>'}}
std::span<int, 0> s14{std::list<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<int, 0>'}}
std::span<int> s15{std::forward_list<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<int>'}}
std::span<int, 0> s16{std::forward_list<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<int, 0>'}}
}
// Not the same type
{
std::span<float> s1{IsAContainer<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<float>'}}
std::span<float, 0> s2{IsAContainer<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<float, 0>'}}
}
// CV wrong (dynamically sized)
{
std::span< int> s1{IsAContainer<const int>()}; // expected-error {{no matching constructor for initialization of 'std::span<int>'}}
std::span< int> s2{IsAContainer< volatile int>()}; // expected-error {{no matching constructor for initialization of 'std::span<int>'}}
std::span< int> s3{IsAContainer<const volatile int>()}; // expected-error {{no matching constructor for initialization of 'std::span<int>'}}
std::span<const int> s4{IsAContainer< volatile int>()}; // expected-error {{no matching constructor for initialization of 'std::span<const int>'}}
std::span<const int> s5{IsAContainer<const volatile int>()}; // expected-error {{no matching constructor for initialization of 'std::span<const int>'}}
std::span< volatile int> s6{IsAContainer<const int>()}; // expected-error {{no matching constructor for initialization of 'std::span<volatile int>'}}
std::span< volatile int> s7{IsAContainer<const volatile int>()}; // expected-error {{no matching constructor for initialization of 'std::span<volatile int>'}}
}
// CV wrong (statically sized)
{
std::span< int,1> s1{IsAContainer<const int>()}; // expected-error {{no matching constructor for initialization of 'std::span<int, 1>'}}
std::span< int,1> s2{IsAContainer< volatile int>()}; // expected-error {{no matching constructor for initialization of 'std::span<int, 1>'}}
std::span< int,1> s3{IsAContainer<const volatile int>()}; // expected-error {{no matching constructor for initialization of 'std::span<int, 1>'}}
std::span<const int,1> s4{IsAContainer< volatile int>()}; // expected-error {{no matching constructor for initialization of 'std::span<const int, 1>'}}
std::span<const int,1> s5{IsAContainer<const volatile int>()}; // expected-error {{no matching constructor for initialization of 'std::span<const int, 1>'}}
std::span< volatile int,1> s6{IsAContainer<const int>()}; // expected-error {{no matching constructor for initialization of 'std::span<volatile int, 1>'}}
std::span< volatile int,1> s7{IsAContainer<const volatile int>()}; // expected-error {{no matching constructor for initialization of 'std::span<volatile int, 1>'}}
}
}

View File

@ -0,0 +1,118 @@
// -*- C++ -*-
//===------------------------------ span ---------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
// template<class Container>
// constexpr span(Container& cont);
// template<class Container>
// constexpr span(const Container& cont);
//
// Remarks: These constructors shall not participate in overload resolution unless:
// — Container is not a specialization of span,
// — Container is not a specialization of array,
// — is_array_v<Container> is false,
// — data(cont) and size(cont) are both well-formed, and
// — remove_pointer_t<decltype(data(cont))>(*)[] is convertible to ElementType(*)[].
//
#include <span>
#include <cassert>
#include <string>
#include <vector>
#include "test_macros.h"
// Look ma - I'm a container!
template <typename T>
struct IsAContainer {
constexpr IsAContainer() : v_{} {}
constexpr size_t size() const {return 1;}
constexpr T *data() {return &v_;}
constexpr const T *data() const {return &v_;}
constexpr T const *getV() const {return &v_;} // for checking
T v_;
};
void checkCV()
{
std::vector<int> v = {1,2,3};
// Types the same (dynamic sized)
{
std::span< int> s1{v}; // a span< int> pointing at int.
}
// Types the same (static sized)
{
std::span< int,3> s1{v}; // a span< int> pointing at int.
}
// types different (dynamic sized)
{
std::span<const int> s1{v}; // a span<const int> pointing at int.
std::span< volatile int> s2{v}; // a span< volatile int> pointing at int.
std::span< volatile int> s3{v}; // a span< volatile int> pointing at const int.
std::span<const volatile int> s4{v}; // a span<const volatile int> pointing at int.
}
// types different (static sized)
{
std::span<const int,3> s1{v}; // a span<const int> pointing at int.
std::span< volatile int,3> s2{v}; // a span< volatile int> pointing at int.
std::span< volatile int,3> s3{v}; // a span< volatile int> pointing at const int.
std::span<const volatile int,3> s4{v}; // a span<const volatile int> pointing at int.
}
}
template <typename T>
constexpr bool testConstexprSpan()
{
constexpr IsAContainer<const T> val{};
std::span<const T> s1{val};
std::span<const T, 1> s2{val};
return
s1.data() == val.getV() && s1.size() == 1
&& s2.data() == val.getV() && s2.size() == 1;
}
template <typename T>
void testRuntimeSpan()
{
IsAContainer<T> val{};
std::span<const T> s1{val};
std::span<const T, 1> s2{val};
assert(s1.data() == val.getV() && s1.size() == 1);
assert(s2.data() == val.getV() && s2.size() == 1);
}
struct A{};
int main ()
{
static_assert(testConstexprSpan<int>(), "");
static_assert(testConstexprSpan<long>(), "");
static_assert(testConstexprSpan<double>(), "");
static_assert(testConstexprSpan<A>(), "");
testRuntimeSpan<int>();
testRuntimeSpan<long>();
testRuntimeSpan<double>();
testRuntimeSpan<std::string>();
testRuntimeSpan<A>();
checkCV();
}

View File

@ -0,0 +1,71 @@
// -*- C++ -*-
//===------------------------------ span ---------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
// constexpr span(const span& other) noexcept = default;
#include <span>
#include <cassert>
#include <string>
#include "test_macros.h"
template <typename T>
constexpr bool doCopy(const T &rhs)
{
ASSERT_NOEXCEPT(T{rhs});
T lhs{rhs};
return lhs.data() == rhs.data()
&& lhs.size() == rhs.size();
}
struct A{};
template <typename T>
void testCV ()
{
int arr[] = {1,2,3};
assert((doCopy(std::span<T> () )));
assert((doCopy(std::span<T,0>() )));
assert((doCopy(std::span<T> (&arr[0], 1))));
assert((doCopy(std::span<T,1>(&arr[0], 1))));
assert((doCopy(std::span<T> (&arr[0], 2))));
assert((doCopy(std::span<T,2>(&arr[0], 2))));
}
int main ()
{
constexpr int carr[] = {1,2,3};
static_assert(doCopy(std::span< int> ()), "");
static_assert(doCopy(std::span< int,0>()), "");
static_assert(doCopy(std::span<const int> (&carr[0], 1)), "");
static_assert(doCopy(std::span<const int,1>(&carr[0], 1)), "");
static_assert(doCopy(std::span<const int> (&carr[0], 2)), "");
static_assert(doCopy(std::span<const int,2>(&carr[0], 2)), "");
static_assert(doCopy(std::span<long>()), "");
static_assert(doCopy(std::span<double>()), "");
static_assert(doCopy(std::span<A>()), "");
std::string s;
assert(doCopy(std::span<std::string> () ));
assert(doCopy(std::span<std::string, 0>() ));
assert(doCopy(std::span<std::string> (&s, 1)));
assert(doCopy(std::span<std::string, 1>(&s, 1)));
testCV< int>();
testCV<const int>();
testCV< volatile int>();
testCV<const volatile int>();
}

View File

@ -0,0 +1,83 @@
// -*- C++ -*-
//===------------------------------ span ---------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
// template<class T, size_t N>
// span(T (&)[N]) -> span<T, N>;
//
// template<class T, size_t N>
// span(array<T, N>&) -> span<T, N>;
//
// template<class T, size_t N>
// span(const array<T, N>&) -> span<const T, N>;
//
// template<class Container>
// span(Container&) -> span<typename Container::value_type>;
//
// template<class Container>
// span(const Container&) -> span<const typename Container::value_type>;
#include <span>
#include <algorithm>
#include <array>
#include <cassert>
#include <string>
#include <type_traits>
#include "test_macros.h"
int main ()
{
{
int arr[] = {1,2,3};
std::span s{arr};
using S = decltype(s);
ASSERT_SAME_TYPE(S, std::span<int, 3>);
assert((std::equal(std::begin(arr), std::end(arr), s.begin(), s.end())));
}
{
std::array<double, 4> arr = {1.0, 2.0, 3.0, 4.0};
std::span s{arr};
using S = decltype(s);
ASSERT_SAME_TYPE(S, std::span<double, 4>);
assert((std::equal(std::begin(arr), std::end(arr), s.begin(), s.end())));
}
{
const std::array<long, 5> arr = {4, 5, 6, 7, 8};
std::span s{arr};
using S = decltype(s);
ASSERT_SAME_TYPE(S, std::span<const long, 5>);
assert((std::equal(std::begin(arr), std::end(arr), s.begin(), s.end())));
}
{
std::string str{"ABCDE"};
std::span s{str};
using S = decltype(s);
ASSERT_SAME_TYPE(S, std::span<char>);
assert((size_t)s.size() == str.size());
assert((std::equal(s.begin(), s.end(), std::begin(s), std::end(s))));
}
{
const std::string str{"QWERTYUIOP"};
std::span s{str};
using S = decltype(s);
ASSERT_SAME_TYPE(S, std::span<const char>);
assert((size_t)s.size() == str.size());
assert((std::equal(s.begin(), s.end(), std::begin(s), std::end(s))));
}
}

View File

@ -0,0 +1,32 @@
// -*- C++ -*-
//===------------------------------ span ---------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
// constexpr span() noexcept;
//
// Remarks: This constructor shall not participate in overload resolution
// unless Extent <= 0 is true.
#include <span>
#include <cassert>
#include <string>
#include "test_macros.h"
int main ()
{
std::span<int, 2> s; // expected-error@span:* {{static_assert failed "Can't default construct a statically sized span with size > 0"}}
// TODO: This is what I want:
// eXpected-error {{no matching constructor for initialization of 'std::span<int, 2>'}}
}

View File

@ -0,0 +1,82 @@
// -*- C++ -*-
//===------------------------------ span ---------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
// constexpr span() noexcept;
#include <span>
#include <cassert>
#include <string>
#include "test_macros.h"
void checkCV()
{
// Types the same (dynamic sized)
{
std::span< int> s1;
std::span<const int> s2;
std::span< volatile int> s3;
std::span<const volatile int> s4;
assert(s1.size() + s2.size() + s3.size() + s4.size() == 0);
}
// Types the same (static sized)
{
std::span< int,0> s1;
std::span<const int,0> s2;
std::span< volatile int,0> s3;
std::span<const volatile int,0> s4;
assert(s1.size() + s2.size() + s3.size() + s4.size() == 0);
}
}
template <typename T>
constexpr bool testConstexprSpan()
{
std::span<const T> s1;
std::span<const T, 0> s2;
return
s1.data() == nullptr && s1.size() == 0
&& s2.data() == nullptr && s2.size() == 0;
}
template <typename T>
void testRuntimeSpan()
{
ASSERT_NOEXCEPT(T{});
std::span<const T> s1;
std::span<const T, 0> s2;
assert(s1.data() == nullptr && s1.size() == 0);
assert(s2.data() == nullptr && s2.size() == 0);
}
struct A{};
int main ()
{
static_assert(testConstexprSpan<int>(), "");
static_assert(testConstexprSpan<long>(), "");
static_assert(testConstexprSpan<double>(), "");
static_assert(testConstexprSpan<A>(), "");
testRuntimeSpan<int>();
testRuntimeSpan<long>();
testRuntimeSpan<double>();
testRuntimeSpan<std::string>();
testRuntimeSpan<A>();
checkCV();
}

View File

@ -0,0 +1,63 @@
// -*- C++ -*-
//===------------------------------ span ---------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
// constexpr span(pointer ptr, index_type count);
// Requires: [ptr, ptr + count) shall be a valid range.
// If extent is not equal to dynamic_extent, then count shall be equal to extent.
//
#include <span>
#include <cassert>
#include <string>
#include "test_macros.h"
int arr[] = {1,2,3};
const int carr[] = {4,5,6};
volatile int varr[] = {7,8,9};
const volatile int cvarr[] = {1,3,5};
int main ()
{
// We can't check that the size doesn't match - because that's a runtime property
// std::span<int, 2> s1(arr, 3);
// Type wrong
{
std::span<float> s1(arr, 3); // expected-error {{no matching constructor for initialization of 'std::span<float>'}}
std::span<float, 3> s2(arr, 3); // expected-error {{no matching constructor for initialization of 'std::span<float, 3>'}}
}
// CV wrong (dynamically sized)
{
std::span< int> s1{ carr, 3}; // expected-error {{no matching constructor for initialization of 'std::span<int>'}}
std::span< int> s2{ varr, 3}; // expected-error {{no matching constructor for initialization of 'std::span<int>'}}
std::span< int> s3{cvarr, 3}; // expected-error {{no matching constructor for initialization of 'std::span<int>'}}
std::span<const int> s4{ varr, 3}; // expected-error {{no matching constructor for initialization of 'std::span<const int>'}}
std::span<const int> s5{cvarr, 3}; // expected-error {{no matching constructor for initialization of 'std::span<const int>'}}
std::span< volatile int> s6{ carr, 3}; // expected-error {{no matching constructor for initialization of 'std::span<volatile int>'}}
std::span< volatile int> s7{cvarr, 3}; // expected-error {{no matching constructor for initialization of 'std::span<volatile int>'}}
}
// CV wrong (statically sized)
{
std::span< int,3> s1{ carr, 3}; // expected-error {{no matching constructor for initialization of 'std::span<int, 3>'}}
std::span< int,3> s2{ varr, 3}; // expected-error {{no matching constructor for initialization of 'std::span<int, 3>'}}
std::span< int,3> s3{cvarr, 3}; // expected-error {{no matching constructor for initialization of 'std::span<int, 3>'}}
std::span<const int,3> s4{ varr, 3}; // expected-error {{no matching constructor for initialization of 'std::span<const int, 3>'}}
std::span<const int,3> s5{cvarr, 3}; // expected-error {{no matching constructor for initialization of 'std::span<const int, 3>'}}
std::span< volatile int,3> s6{ carr, 3}; // expected-error {{no matching constructor for initialization of 'std::span<volatile int, 3>'}}
std::span< volatile int,3> s7{cvarr, 3}; // expected-error {{no matching constructor for initialization of 'std::span<volatile int, 3>'}}
}
}

View File

@ -0,0 +1,113 @@
// -*- C++ -*-
//===------------------------------ span ---------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
// constexpr span(pointer ptr, index_type count);
// Requires: [ptr, ptr + count) shall be a valid range.
// If extent is not equal to dynamic_extent, then count shall be equal to extent.
//
#include <span>
#include <cassert>
#include <string>
#include "test_macros.h"
void checkCV()
{
int arr[] = {1,2,3};
const int carr[] = {4,5,6};
volatile int varr[] = {7,8,9};
const volatile int cvarr[] = {1,3,5};
// Types the same (dynamic sized)
{
std::span< int> s1{ arr, 3}; // a span< int> pointing at int.
std::span<const int> s2{ carr, 3}; // a span<const int> pointing at const int.
std::span< volatile int> s3{ varr, 3}; // a span< volatile int> pointing at volatile int.
std::span<const volatile int> s4{cvarr, 3}; // a span<const volatile int> pointing at const volatile int.
assert(s1.size() + s2.size() + s3.size() + s4.size() == 12);
}
// Types the same (static sized)
{
std::span< int,3> s1{ arr, 3}; // a span< int> pointing at int.
std::span<const int,3> s2{ carr, 3}; // a span<const int> pointing at const int.
std::span< volatile int,3> s3{ varr, 3}; // a span< volatile int> pointing at volatile int.
std::span<const volatile int,3> s4{cvarr, 3}; // a span<const volatile int> pointing at const volatile int.
assert(s1.size() + s2.size() + s3.size() + s4.size() == 12);
}
// types different (dynamic sized)
{
std::span<const int> s1{ arr, 3}; // a span<const int> pointing at int.
std::span< volatile int> s2{ arr, 3}; // a span< volatile int> pointing at int.
std::span< volatile int> s3{ arr, 3}; // a span< volatile int> pointing at const int.
std::span<const volatile int> s4{ arr, 3}; // a span<const volatile int> pointing at int.
std::span<const volatile int> s5{carr, 3}; // a span<const volatile int> pointing at const int.
std::span<const volatile int> s6{varr, 3}; // a span<const volatile int> pointing at volatile int.
assert(s1.size() + s2.size() + s3.size() + s4.size() + s5.size() + s6.size() == 18);
}
// types different (static sized)
{
std::span<const int,3> s1{ arr, 3}; // a span<const int> pointing at int.
std::span< volatile int,3> s2{ arr, 3}; // a span< volatile int> pointing at int.
std::span< volatile int,3> s3{ arr, 3}; // a span< volatile int> pointing at const int.
std::span<const volatile int,3> s4{ arr, 3}; // a span<const volatile int> pointing at int.
std::span<const volatile int,3> s5{carr, 3}; // a span<const volatile int> pointing at const int.
std::span<const volatile int,3> s6{varr, 3}; // a span<const volatile int> pointing at volatile int.
assert(s1.size() + s2.size() + s3.size() + s4.size() + s5.size() + s6.size() == 18);
}
}
template <typename T>
constexpr bool testConstexprSpan()
{
constexpr T val[2] = {};
std::span<const T> s1{val, 2};
std::span<const T,2> s2{val, 2};
return
s1.data() == &val[0] && s1.size() == 2
&& s2.data() == &val[0] && s2.size() == 2;
}
template <typename T>
void testRuntimeSpan()
{
T val[2] = {};
std::span<T> s1{val, 2};
std::span<T,2> s2{val, 2};
assert(s1.data() == &val[0] && s1.size() == 2);
assert(s2.data() == &val[0] && s2.size() == 2);
}
struct A{};
int main ()
{
static_assert(testConstexprSpan<int>(), "");
static_assert(testConstexprSpan<long>(), "");
static_assert(testConstexprSpan<double>(), "");
static_assert(testConstexprSpan<A>(), "");
testRuntimeSpan<int>();
testRuntimeSpan<long>();
testRuntimeSpan<double>();
testRuntimeSpan<std::string>();
testRuntimeSpan<A>();
checkCV();
}

View File

@ -0,0 +1,63 @@
// -*- C++ -*-
//===------------------------------ span ---------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
// constexpr span(pointer first, pointer last);
// Requires: [first, last) shall be a valid range.
// If extent is not equal to dynamic_extent, then last - first shall be equal to extent.
//
#include <span>
#include <cassert>
#include <string>
#include "test_macros.h"
int arr[] = {1,2,3};
const int carr[] = {4,5,6};
volatile int varr[] = {7,8,9};
const volatile int cvarr[] = {1,3,5};
int main ()
{
// We can't check that the size doesn't match - because that's a runtime property
// std::span<int, 2> s1(arr, arr + 3);
// Type wrong
{
std::span<float> s1(arr, arr + 3); // expected-error {{no matching constructor for initialization of 'std::span<float>'}}
std::span<float, 3> s2(arr, arr + 3); // expected-error {{no matching constructor for initialization of 'std::span<float, 3>'}}
}
// CV wrong (dynamically sized)
{
std::span< int> s1{ carr, carr + 3}; // expected-error {{no matching constructor for initialization of 'std::span<int>'}}
std::span< int> s2{ varr, varr + 3}; // expected-error {{no matching constructor for initialization of 'std::span<int>'}}
std::span< int> s3{cvarr, cvarr + 3}; // expected-error {{no matching constructor for initialization of 'std::span<int>'}}
std::span<const int> s4{ varr, varr + 3}; // expected-error {{no matching constructor for initialization of 'std::span<const int>'}}
std::span<const int> s5{cvarr, cvarr + 3}; // expected-error {{no matching constructor for initialization of 'std::span<const int>'}}
std::span< volatile int> s6{ carr, carr + 3}; // expected-error {{no matching constructor for initialization of 'std::span<volatile int>'}}
std::span< volatile int> s7{cvarr, cvarr + 3}; // expected-error {{no matching constructor for initialization of 'std::span<volatile int>'}}
}
// CV wrong (statically sized)
{
std::span< int,3> s1{ carr, carr + 3}; // expected-error {{no matching constructor for initialization of 'std::span<int, 3>'}}
std::span< int,3> s2{ varr, varr + 3}; // expected-error {{no matching constructor for initialization of 'std::span<int, 3>'}}
std::span< int,3> s3{cvarr, cvarr + 3}; // expected-error {{no matching constructor for initialization of 'std::span<int, 3>'}}
std::span<const int,3> s4{ varr, varr + 3}; // expected-error {{no matching constructor for initialization of 'std::span<const int, 3>'}}
std::span<const int,3> s5{cvarr, cvarr + 3}; // expected-error {{no matching constructor for initialization of 'std::span<const int, 3>'}}
std::span< volatile int,3> s6{ carr, carr + 3}; // expected-error {{no matching constructor for initialization of 'std::span<volatile int, 3>'}}
std::span< volatile int,3> s7{cvarr, cvarr + 3}; // expected-error {{no matching constructor for initialization of 'std::span<volatile int, 3>'}}
}
}

View File

@ -0,0 +1,113 @@
// -*- C++ -*-
//===------------------------------ span ---------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
// constexpr span(pointer first, pointer last);
// Requires: [first, last) shall be a valid range.
// If extent is not equal to dynamic_extent, then last - first shall be equal to extent.
//
#include <span>
#include <cassert>
#include <string>
#include "test_macros.h"
void checkCV()
{
int arr[] = {1,2,3};
const int carr[] = {4,5,6};
volatile int varr[] = {7,8,9};
const volatile int cvarr[] = {1,3,5};
// Types the same (dynamic sized)
{
std::span< int> s1{ arr, arr + 3}; // a span< int> pointing at int.
std::span<const int> s2{ carr, carr + 3}; // a span<const int> pointing at const int.
std::span< volatile int> s3{ varr, varr + 3}; // a span< volatile int> pointing at volatile int.
std::span<const volatile int> s4{cvarr, cvarr + 3}; // a span<const volatile int> pointing at const volatile int.
assert(s1.size() + s2.size() + s3.size() + s4.size() == 12);
}
// Types the same (static sized)
{
std::span< int,3> s1{ arr, arr + 3}; // a span< int> pointing at int.
std::span<const int,3> s2{ carr, carr + 3}; // a span<const int> pointing at const int.
std::span< volatile int,3> s3{ varr, varr + 3}; // a span< volatile int> pointing at volatile int.
std::span<const volatile int,3> s4{cvarr, cvarr + 3}; // a span<const volatile int> pointing at const volatile int.
assert(s1.size() + s2.size() + s3.size() + s4.size() == 12);
}
// types different (dynamic sized)
{
std::span<const int> s1{ arr, arr + 3}; // a span<const int> pointing at int.
std::span< volatile int> s2{ arr, arr + 3}; // a span< volatile int> pointing at int.
std::span< volatile int> s3{ arr, arr + 3}; // a span< volatile int> pointing at const int.
std::span<const volatile int> s4{ arr, arr + 3}; // a span<const volatile int> pointing at int.
std::span<const volatile int> s5{carr, carr + 3}; // a span<const volatile int> pointing at const int.
std::span<const volatile int> s6{varr, varr + 3}; // a span<const volatile int> pointing at volatile int.
assert(s1.size() + s2.size() + s3.size() + s4.size() + s5.size() + s6.size() == 18);
}
// types different (static sized)
{
std::span<const int,3> s1{ arr, arr + 3}; // a span<const int> pointing at int.
std::span< volatile int,3> s2{ arr, arr + 3}; // a span< volatile int> pointing at int.
std::span< volatile int,3> s3{ arr, arr + 3}; // a span< volatile int> pointing at const int.
std::span<const volatile int,3> s4{ arr, arr + 3}; // a span<const volatile int> pointing at int.
std::span<const volatile int,3> s5{carr, carr + 3}; // a span<const volatile int> pointing at const int.
std::span<const volatile int,3> s6{varr, varr + 3}; // a span<const volatile int> pointing at volatile int.
assert(s1.size() + s2.size() + s3.size() + s4.size() + s5.size() + s6.size() == 18);
}
}
template <typename T>
constexpr bool testConstexprSpan()
{
constexpr T val[2] = {};
std::span<const T> s1{val, val+2};
std::span<const T,2> s2{val, val+2};
return
s1.data() == &val[0] && s1.size() == 2
&& s2.data() == &val[0] && s2.size() == 2;
}
template <typename T>
void testRuntimeSpan()
{
T val[2] = {};
std::span<T> s1{val, val+2};
std::span<T,2> s2{val, val+2};
assert(s1.data() == &val[0] && s1.size() == 2);
assert(s2.data() == &val[0] && s2.size() == 2);
}
struct A{};
int main ()
{
static_assert(testConstexprSpan<int>(), "");
static_assert(testConstexprSpan<long>(), "");
static_assert(testConstexprSpan<double>(), "");
static_assert(testConstexprSpan<A>(), "");
testRuntimeSpan<int>();
testRuntimeSpan<long>();
testRuntimeSpan<double>();
testRuntimeSpan<std::string>();
testRuntimeSpan<A>();
checkCV();
}

View File

@ -0,0 +1,104 @@
// -*- C++ -*-
//===------------------------------ span ---------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
// template<class OtherElementType, ptrdiff_t OtherExtent>
// constexpr span(const span<OtherElementType, OtherExtent>& s) noexcept;
//
// Remarks: This constructor shall not participate in overload resolution unless:
// Extent == dynamic_extent || Extent == OtherExtent is true, and
// OtherElementType(*)[] is convertible to ElementType(*)[].
#include <span>
#include <cassert>
#include <string>
#include "test_macros.h"
void checkCV ()
{
// std::span< int> sp;
std::span<const int> csp;
std::span< volatile int> vsp;
std::span<const volatile int> cvsp;
// std::span< int, 0> sp0;
std::span<const int, 0> csp0;
std::span< volatile int, 0> vsp0;
std::span<const volatile int, 0> cvsp0;
// Try to remove const and/or volatile (dynamic -> dynamic)
{
std::span< int> s1{ csp}; // expected-error {{no matching constructor for initialization of 'std::span<int>'}}
std::span< int> s2{ vsp}; // expected-error {{no matching constructor for initialization of 'std::span<int>'}}
std::span< int> s3{cvsp}; // expected-error {{no matching constructor for initialization of 'std::span<int>'}}
std::span<const int> s4{ vsp}; // expected-error {{no matching constructor for initialization of 'std::span<const int>'}}
std::span<const int> s5{cvsp}; // expected-error {{no matching constructor for initialization of 'std::span<const int>'}}
std::span< volatile int> s6{ csp}; // expected-error {{no matching constructor for initialization of 'std::span<volatile int>'}}
std::span< volatile int> s7{cvsp}; // expected-error {{no matching constructor for initialization of 'std::span<volatile int>'}}
}
// Try to remove const and/or volatile (static -> static)
{
std::span< int, 0> s1{ csp0}; // expected-error {{no matching constructor for initialization of 'std::span<int, 0>'}}
std::span< int, 0> s2{ vsp0}; // expected-error {{no matching constructor for initialization of 'std::span<int, 0>'}}
std::span< int, 0> s3{cvsp0}; // expected-error {{no matching constructor for initialization of 'std::span<int, 0>'}}
std::span<const int, 0> s4{ vsp0}; // expected-error {{no matching constructor for initialization of 'std::span<const int, 0>'}}
std::span<const int, 0> s5{cvsp0}; // expected-error {{no matching constructor for initialization of 'std::span<const int, 0>'}}
std::span< volatile int, 0> s6{ csp0}; // expected-error {{no matching constructor for initialization of 'std::span<volatile int, 0>'}}
std::span< volatile int, 0> s7{cvsp0}; // expected-error {{no matching constructor for initialization of 'std::span<volatile int, 0>'}}
}
// Try to remove const and/or volatile (static -> dynamic)
{
std::span< int> s1{ csp0}; // expected-error {{no matching constructor for initialization of 'std::span<int>'}}
std::span< int> s2{ vsp0}; // expected-error {{no matching constructor for initialization of 'std::span<int>'}}
std::span< int> s3{cvsp0}; // expected-error {{no matching constructor for initialization of 'std::span<int>'}}
std::span<const int> s4{ vsp0}; // expected-error {{no matching constructor for initialization of 'std::span<const int>'}}
std::span<const int> s5{cvsp0}; // expected-error {{no matching constructor for initialization of 'std::span<const int>'}}
std::span< volatile int> s6{ csp0}; // expected-error {{no matching constructor for initialization of 'std::span<volatile int>'}}
std::span< volatile int> s7{cvsp0}; // expected-error {{no matching constructor for initialization of 'std::span<volatile int>'}}
}
// Try to remove const and/or volatile (static -> static)
{
std::span< int, 0> s1{ csp}; // expected-error {{no matching constructor for initialization of 'std::span<int, 0>'}}
std::span< int, 0> s2{ vsp}; // expected-error {{no matching constructor for initialization of 'std::span<int, 0>'}}
std::span< int, 0> s3{cvsp}; // expected-error {{no matching constructor for initialization of 'std::span<int, 0>'}}
std::span<const int, 0> s4{ vsp}; // expected-error {{no matching constructor for initialization of 'std::span<const int, 0>'}}
std::span<const int, 0> s5{cvsp}; // expected-error {{no matching constructor for initialization of 'std::span<const int, 0>'}}
std::span< volatile int, 0> s6{ csp}; // expected-error {{no matching constructor for initialization of 'std::span<volatile int, 0>'}}
std::span< volatile int, 0> s7{cvsp}; // expected-error {{no matching constructor for initialization of 'std::span<volatile int, 0>'}}
}
}
int main ()
{
std::span<int> sp;
std::span<int, 0> sp0;
std::span<float> s1{sp}; // expected-error {{no matching constructor for initialization of 'std::span<float>'}}
std::span<float> s2{sp0}; // expected-error {{no matching constructor for initialization of 'std::span<float>'}}
std::span<float, 0> s3{sp}; // expected-error {{no matching constructor for initialization of 'std::span<float, 0>'}}
std::span<float, 0> s4{sp0}; // expected-error {{no matching constructor for initialization of 'std::span<float, 0>'}}
checkCV();
}

View File

@ -0,0 +1,142 @@
// -*- C++ -*-
//===------------------------------ span ---------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
// template<class OtherElementType, ptrdiff_t OtherExtent>
// constexpr span(const span<OtherElementType, OtherExtent>& s) noexcept;
//
// Remarks: This constructor shall not participate in overload resolution unless:
// Extent == dynamic_extent || Extent == OtherExtent is true, and
// OtherElementType(*)[] is convertible to ElementType(*)[].
#include <span>
#include <cassert>
#include <string>
#include "test_macros.h"
void checkCV()
{
std::span< int> sp;
// std::span<const int> csp;
std::span< volatile int> vsp;
// std::span<const volatile int> cvsp;
std::span< int, 0> sp0;
// std::span<const int, 0> csp0;
std::span< volatile int, 0> vsp0;
// std::span<const volatile int, 0> cvsp0;
// dynamic -> dynamic
{
std::span<const int> s1{ sp}; // a span<const int> pointing at int.
std::span< volatile int> s2{ sp}; // a span< volatile int> pointing at int.
std::span<const volatile int> s3{ sp}; // a span<const volatile int> pointing at int.
std::span<const volatile int> s4{ vsp}; // a span<const volatile int> pointing at volatile int.
assert(s1.size() + s2.size() + s3.size() + s4.size() == 0);
}
// static -> static
{
std::span<const int, 0> s1{ sp0}; // a span<const int> pointing at int.
std::span< volatile int, 0> s2{ sp0}; // a span< volatile int> pointing at int.
std::span<const volatile int, 0> s3{ sp0}; // a span<const volatile int> pointing at int.
std::span<const volatile int, 0> s4{ vsp0}; // a span<const volatile int> pointing at volatile int.
assert(s1.size() + s2.size() + s3.size() + s4.size() == 0);
}
// static -> dynamic
{
std::span<const int> s1{ sp0}; // a span<const int> pointing at int.
std::span< volatile int> s2{ sp0}; // a span< volatile int> pointing at int.
std::span<const volatile int> s3{ sp0}; // a span<const volatile int> pointing at int.
std::span<const volatile int> s4{ vsp0}; // a span<const volatile int> pointing at volatile int.
assert(s1.size() + s2.size() + s3.size() + s4.size() == 0);
}
// dynamic -> static
{
std::span<const int, 0> s1{ sp}; // a span<const int> pointing at int.
std::span< volatile int, 0> s2{ sp}; // a span< volatile int> pointing at int.
std::span<const volatile int, 0> s3{ sp}; // a span<const volatile int> pointing at int.
std::span<const volatile int, 0> s4{ vsp}; // a span<const volatile int> pointing at volatile int.
assert(s1.size() + s2.size() + s3.size() + s4.size() == 0);
}
}
template <typename T>
constexpr bool testConstexprSpan()
{
std::span<T> s0{};
std::span<T, 0> s1(s0); // dynamic -> static
std::span<T> s2(s1); // static -> dynamic
ASSERT_NOEXCEPT(std::span<T> {s0});
ASSERT_NOEXCEPT(std::span<T, 0>{s1});
ASSERT_NOEXCEPT(std::span<T> {s1});
ASSERT_NOEXCEPT(std::span<T, 0>{s0});
return
s1.data() == nullptr && s1.size() == 0
&& s2.data() == nullptr && s2.size() == 0;
}
template <typename T>
void testRuntimeSpan()
{
std::span<T> s0{};
std::span<T, 0> s1(s0); // dynamic -> static
std::span<T> s2(s1); // static -> dynamic
ASSERT_NOEXCEPT(std::span<T> {s0});
ASSERT_NOEXCEPT(std::span<T, 0>{s1});
ASSERT_NOEXCEPT(std::span<T> {s1});
ASSERT_NOEXCEPT(std::span<T, 0>{s0});
assert(s1.data() == nullptr && s1.size() == 0);
assert(s2.data() == nullptr && s2.size() == 0);
}
template <typename Dest, typename Src>
bool testConversionSpan()
{
static_assert(std::is_convertible_v<Src(*)[], Dest(*)[]>, "Bad input types to 'testConversionSpan");
std::span<Src> s0d{};
std::span<Src> s0s{};
std::span<Dest, 0> s1(s0d); // dynamic -> static
std::span<Dest> s2(s0s); // static -> dynamic
s1.data() == nullptr && s1.size() == 0
&& s2.data() == nullptr && s2.size() == 0;
}
struct A{};
int main ()
{
static_assert(testConstexprSpan<int>(), "");
static_assert(testConstexprSpan<long>(), "");
static_assert(testConstexprSpan<double>(), "");
static_assert(testConstexprSpan<A>(), "");
testRuntimeSpan<int>();
testRuntimeSpan<long>();
testRuntimeSpan<double>();
testRuntimeSpan<std::string>();
testRuntimeSpan<A>();
// TODO: Add some conversion tests here that aren't "X --> const X"
// assert((testConversionSpan<unsigned char, char>()));
checkCV();
}

View File

@ -0,0 +1,111 @@
// -*- C++ -*-
//===------------------------------ span ---------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
// template<size_t N>
// constexpr span(array<value_type, N>& arr) noexcept;
// template<size_t N>
// constexpr span(const array<value_type, N>& arr) noexcept;
//
// Remarks: These constructors shall not participate in overload resolution unless:
// — extent == dynamic_extent || N == extent is true, and
// — remove_pointer_t<decltype(data(arr))>(*)[] is convertible to ElementType(*)[].
//
#include <span>
#include <cassert>
#include <string>
#include "test_macros.h"
void checkCV()
{
std::array<int, 3> arr = {1,2,3};
// STL says these are not cromulent
// std::array<const int,3> carr = {4,5,6};
// std::array<volatile int, 3> varr = {7,8,9};
// std::array<const volatile int, 3> cvarr = {1,3,5};
// Types the same (dynamic sized)
{
std::span< int> s1{ arr}; // a span< int> pointing at int.
}
// Types the same (static sized)
{
std::span< int,3> s1{ arr}; // a span< int> pointing at int.
}
// types different (dynamic sized)
{
std::span<const int> s1{ arr}; // a span<const int> pointing at int.
std::span< volatile int> s2{ arr}; // a span< volatile int> pointing at int.
std::span< volatile int> s3{ arr}; // a span< volatile int> pointing at const int.
std::span<const volatile int> s4{ arr}; // a span<const volatile int> pointing at int.
}
// types different (static sized)
{
std::span<const int,3> s1{ arr}; // a span<const int> pointing at int.
std::span< volatile int,3> s2{ arr}; // a span< volatile int> pointing at int.
std::span< volatile int,3> s3{ arr}; // a span< volatile int> pointing at const int.
std::span<const volatile int,3> s4{ arr}; // a span<const volatile int> pointing at int.
}
}
template <typename T>
constexpr bool testConstexprSpan()
{
constexpr std::array<T,2> val = { T(), T() };
ASSERT_NOEXCEPT(std::span<const T> {val});
ASSERT_NOEXCEPT(std::span<const T, 2>{val});
std::span<const T> s1{val};
std::span<const T, 2> s2{val};
return
s1.data() == &val[0] && s1.size() == 2
&& s2.data() == &val[0] && s2.size() == 2;
}
template <typename T>
void testRuntimeSpan()
{
std::array<T,2> val;
ASSERT_NOEXCEPT(std::span<T> {val});
ASSERT_NOEXCEPT(std::span<T, 2>{val});
std::span<T> s1{val};
std::span<T, 2> s2{val};
assert(s1.data() == &val[0] && s1.size() == 2);
assert(s2.data() == &val[0] && s2.size() == 2);
}
struct A{};
int main ()
{
static_assert(testConstexprSpan<int>(), "");
static_assert(testConstexprSpan<long>(), "");
static_assert(testConstexprSpan<double>(), "");
static_assert(testConstexprSpan<A>(), "");
testRuntimeSpan<int>();
testRuntimeSpan<long>();
testRuntimeSpan<double>();
testRuntimeSpan<std::string>();
testRuntimeSpan<A>();
checkCV();
}

View File

@ -0,0 +1,121 @@
// -*- C++ -*-
//===------------------------------ span ---------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
// constexpr pointer data() const noexcept;
//
#include <span>
#include <cassert>
#include <string>
#include "test_macros.h"
template <typename Span>
constexpr bool testConstexprSpan(Span sp, typename Span::pointer ptr)
{
ASSERT_NOEXCEPT(sp.data());
return sp.data() == ptr;
}
template <typename Span>
void testRuntimeSpan(Span sp, typename Span::pointer ptr)
{
ASSERT_NOEXCEPT(sp.data());
assert(sp.data() == ptr);
}
struct A{};
constexpr int iArr1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int iArr2[] = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19};
int main ()
{
// dynamic size
static_assert(testConstexprSpan(std::span<int>(), nullptr), "");
static_assert(testConstexprSpan(std::span<long>(), nullptr), "");
static_assert(testConstexprSpan(std::span<double>(), nullptr), "");
static_assert(testConstexprSpan(std::span<A>(), nullptr), "");
static_assert(testConstexprSpan(std::span<std::string>(), nullptr), "");
static_assert(testConstexprSpan(std::span<const int>(iArr1, 1), iArr1), "");
static_assert(testConstexprSpan(std::span<const int>(iArr1, 2), iArr1), "");
static_assert(testConstexprSpan(std::span<const int>(iArr1, 3), iArr1), "");
static_assert(testConstexprSpan(std::span<const int>(iArr1, 4), iArr1), "");
static_assert(testConstexprSpan(std::span<const int>(iArr1 + 1, 1), iArr1 + 1), "");
static_assert(testConstexprSpan(std::span<const int>(iArr1 + 2, 2), iArr1 + 2), "");
static_assert(testConstexprSpan(std::span<const int>(iArr1 + 3, 3), iArr1 + 3), "");
static_assert(testConstexprSpan(std::span<const int>(iArr1 + 4, 4), iArr1 + 4), "");
// static size
static_assert(testConstexprSpan(std::span<int, 0>(), nullptr), "");
static_assert(testConstexprSpan(std::span<long, 0>(), nullptr), "");
static_assert(testConstexprSpan(std::span<double, 0>(), nullptr), "");
static_assert(testConstexprSpan(std::span<A, 0>(), nullptr), "");
static_assert(testConstexprSpan(std::span<std::string, 0>(), nullptr), "");
static_assert(testConstexprSpan(std::span<const int, 1>(iArr1, 1), iArr1), "");
static_assert(testConstexprSpan(std::span<const int, 2>(iArr1, 2), iArr1), "");
static_assert(testConstexprSpan(std::span<const int, 3>(iArr1, 3), iArr1), "");
static_assert(testConstexprSpan(std::span<const int, 4>(iArr1, 4), iArr1), "");
static_assert(testConstexprSpan(std::span<const int, 1>(iArr1 + 1, 1), iArr1 + 1), "");
static_assert(testConstexprSpan(std::span<const int, 2>(iArr1 + 2, 2), iArr1 + 2), "");
static_assert(testConstexprSpan(std::span<const int, 3>(iArr1 + 3, 3), iArr1 + 3), "");
static_assert(testConstexprSpan(std::span<const int, 4>(iArr1 + 4, 4), iArr1 + 4), "");
// dynamic size
testRuntimeSpan(std::span<int>(), nullptr);
testRuntimeSpan(std::span<long>(), nullptr);
testRuntimeSpan(std::span<double>(), nullptr);
testRuntimeSpan(std::span<A>(), nullptr);
testRuntimeSpan(std::span<std::string>(), nullptr);
testRuntimeSpan(std::span<int>(iArr2, 1), iArr2);
testRuntimeSpan(std::span<int>(iArr2, 2), iArr2);
testRuntimeSpan(std::span<int>(iArr2, 3), iArr2);
testRuntimeSpan(std::span<int>(iArr2, 4), iArr2);
testRuntimeSpan(std::span<int>(iArr2 + 1, 1), iArr2 + 1);
testRuntimeSpan(std::span<int>(iArr2 + 2, 2), iArr2 + 2);
testRuntimeSpan(std::span<int>(iArr2 + 3, 3), iArr2 + 3);
testRuntimeSpan(std::span<int>(iArr2 + 4, 4), iArr2 + 4);
// static size
testRuntimeSpan(std::span<int, 0>(), nullptr);
testRuntimeSpan(std::span<long, 0>(), nullptr);
testRuntimeSpan(std::span<double, 0>(), nullptr);
testRuntimeSpan(std::span<A, 0>(), nullptr);
testRuntimeSpan(std::span<std::string, 0>(), nullptr);
testRuntimeSpan(std::span<int, 1>(iArr2, 1), iArr2);
testRuntimeSpan(std::span<int, 2>(iArr2, 2), iArr2);
testRuntimeSpan(std::span<int, 3>(iArr2, 3), iArr2);
testRuntimeSpan(std::span<int, 4>(iArr2, 4), iArr2);
testRuntimeSpan(std::span<int, 1>(iArr2 + 1, 1), iArr2 + 1);
testRuntimeSpan(std::span<int, 2>(iArr2 + 2, 2), iArr2 + 2);
testRuntimeSpan(std::span<int, 3>(iArr2 + 3, 3), iArr2 + 3);
testRuntimeSpan(std::span<int, 4>(iArr2 + 4, 4), iArr2 + 4);
std::string s;
testRuntimeSpan(std::span<std::string>(&s, 1), &s);
testRuntimeSpan(std::span<std::string, 1>(&s, 1), &s);
}

View File

@ -0,0 +1,119 @@
// -*- C++ -*-
//===------------------------------ span ---------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
// constexpr reference operator[](index_type idx) const;
// constexpr reference operator()(index_type idx) const;
//
#include <span>
#include <cassert>
#include <string>
#include "test_macros.h"
template <typename Span>
constexpr bool testConstexprSpan(Span sp, ptrdiff_t idx)
{
_LIBCPP_ASSERT(noexcept(sp[idx]), "");
_LIBCPP_ASSERT(noexcept(sp(idx)), "");
typename Span::reference r1 = sp[idx];
typename Span::reference r2 = sp(idx);
typename Span::reference r3 = *(sp.data() + idx);
return r1 == r2 && r2 == r3;
}
template <typename Span>
void testRuntimeSpan(Span sp, ptrdiff_t idx)
{
_LIBCPP_ASSERT(noexcept(sp[idx]), "");
_LIBCPP_ASSERT(noexcept(sp(idx)), "");
typename Span::reference r1 = sp[idx];
typename Span::reference r2 = sp(idx);
typename Span::reference r3 = *(sp.data() + idx);
assert(r1 == r2 && r2 == r3);
}
struct A{};
constexpr int iArr1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int iArr2[] = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19};
int main ()
{
static_assert(testConstexprSpan(std::span<const int>(iArr1, 1), 0), "");
static_assert(testConstexprSpan(std::span<const int>(iArr1, 2), 0), "");
static_assert(testConstexprSpan(std::span<const int>(iArr1, 2), 1), "");
static_assert(testConstexprSpan(std::span<const int>(iArr1, 3), 0), "");
static_assert(testConstexprSpan(std::span<const int>(iArr1, 3), 1), "");
static_assert(testConstexprSpan(std::span<const int>(iArr1, 3), 2), "");
static_assert(testConstexprSpan(std::span<const int>(iArr1, 4), 0), "");
static_assert(testConstexprSpan(std::span<const int>(iArr1, 4), 1), "");
static_assert(testConstexprSpan(std::span<const int>(iArr1, 4), 2), "");
static_assert(testConstexprSpan(std::span<const int>(iArr1, 4), 3), "");
static_assert(testConstexprSpan(std::span<const int, 1>(iArr1, 1), 0), "");
static_assert(testConstexprSpan(std::span<const int, 2>(iArr1, 2), 0), "");
static_assert(testConstexprSpan(std::span<const int, 2>(iArr1, 2), 1), "");
static_assert(testConstexprSpan(std::span<const int, 3>(iArr1, 3), 0), "");
static_assert(testConstexprSpan(std::span<const int, 3>(iArr1, 3), 1), "");
static_assert(testConstexprSpan(std::span<const int, 3>(iArr1, 3), 2), "");
static_assert(testConstexprSpan(std::span<const int, 4>(iArr1, 4), 0), "");
static_assert(testConstexprSpan(std::span<const int, 4>(iArr1, 4), 1), "");
static_assert(testConstexprSpan(std::span<const int, 4>(iArr1, 4), 2), "");
static_assert(testConstexprSpan(std::span<const int, 4>(iArr1, 4), 3), "");
testRuntimeSpan(std::span<int>(iArr2, 1), 0);
testRuntimeSpan(std::span<int>(iArr2, 2), 0);
testRuntimeSpan(std::span<int>(iArr2, 2), 1);
testRuntimeSpan(std::span<int>(iArr2, 3), 0);
testRuntimeSpan(std::span<int>(iArr2, 3), 1);
testRuntimeSpan(std::span<int>(iArr2, 3), 2);
testRuntimeSpan(std::span<int>(iArr2, 4), 0);
testRuntimeSpan(std::span<int>(iArr2, 4), 1);
testRuntimeSpan(std::span<int>(iArr2, 4), 2);
testRuntimeSpan(std::span<int>(iArr2, 4), 3);
testRuntimeSpan(std::span<int, 1>(iArr2, 1), 0);
testRuntimeSpan(std::span<int, 2>(iArr2, 2), 0);
testRuntimeSpan(std::span<int, 2>(iArr2, 2), 1);
testRuntimeSpan(std::span<int, 3>(iArr2, 3), 0);
testRuntimeSpan(std::span<int, 3>(iArr2, 3), 1);
testRuntimeSpan(std::span<int, 3>(iArr2, 3), 2);
testRuntimeSpan(std::span<int, 4>(iArr2, 4), 0);
testRuntimeSpan(std::span<int, 4>(iArr2, 4), 1);
testRuntimeSpan(std::span<int, 4>(iArr2, 4), 2);
testRuntimeSpan(std::span<int, 4>(iArr2, 4), 3);
std::string s;
testRuntimeSpan(std::span<std::string> (&s, 1), 0);
testRuntimeSpan(std::span<std::string, 1>(&s, 1), 0);
}

View File

@ -0,0 +1,116 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
// constexpr iterator begin() const noexcept;
// constexpr const_iterator cbegin() const noexcept;
#include <span>
#include <cassert>
#include <string>
#include "test_macros.h"
template <class Span>
constexpr bool testConstexprSpan(Span s)
{
bool ret = true;
typename Span::iterator b = s. begin();
typename Span::const_iterator cb = s.cbegin();
if (s.empty())
{
ret = ret && ( b == s.end());
ret = ret && (cb == s.cend());
}
else
{
ret = ret && ( *b == s[0]);
ret = ret && ( &*b == &s[0]);
ret = ret && ( *cb == s[0]);
ret = ret && (&*cb == &s[0]);
}
ret = ret && (b == cb);
return ret;
}
template <class Span>
void testRuntimeSpan(Span s)
{
typename Span::iterator b = s. begin();
typename Span::const_iterator cb = s.cbegin();
if (s.empty())
{
assert( b == s.end());
assert(cb == s.cend());
}
else
{
assert( *b == s[0]);
assert( &*b == &s[0]);
assert( *cb == s[0]);
assert(&*cb == &s[0]);
}
assert(b == cb);
}
struct A{};
bool operator==(A, A) {return true;}
constexpr int iArr1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int iArr2[] = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19};
int main()
{
static_assert(testConstexprSpan(std::span<int>()), "");
static_assert(testConstexprSpan(std::span<long>()), "");
static_assert(testConstexprSpan(std::span<double>()), "");
static_assert(testConstexprSpan(std::span<A>()), "");
static_assert(testConstexprSpan(std::span<std::string>()), "");
static_assert(testConstexprSpan(std::span<int, 0>()), "");
static_assert(testConstexprSpan(std::span<long, 0>()), "");
static_assert(testConstexprSpan(std::span<double, 0>()), "");
static_assert(testConstexprSpan(std::span<A, 0>()), "");
static_assert(testConstexprSpan(std::span<std::string, 0>()), "");
static_assert(testConstexprSpan(std::span<const int>(iArr1, 1)), "");
static_assert(testConstexprSpan(std::span<const int>(iArr1, 2)), "");
static_assert(testConstexprSpan(std::span<const int>(iArr1, 3)), "");
static_assert(testConstexprSpan(std::span<const int>(iArr1, 4)), "");
static_assert(testConstexprSpan(std::span<const int>(iArr1, 5)), "");
testRuntimeSpan(std::span<int> ());
testRuntimeSpan(std::span<long> ());
testRuntimeSpan(std::span<double> ());
testRuntimeSpan(std::span<A> ());
testRuntimeSpan(std::span<std::string>());
testRuntimeSpan(std::span<int, 0> ());
testRuntimeSpan(std::span<long, 0> ());
testRuntimeSpan(std::span<double, 0> ());
testRuntimeSpan(std::span<A, 0> ());
testRuntimeSpan(std::span<std::string, 0>());
testRuntimeSpan(std::span<int>(iArr2, 1));
testRuntimeSpan(std::span<int>(iArr2, 2));
testRuntimeSpan(std::span<int>(iArr2, 3));
testRuntimeSpan(std::span<int>(iArr2, 4));
testRuntimeSpan(std::span<int>(iArr2, 5));
std::string s;
testRuntimeSpan(std::span<std::string>(&s, (std::ptrdiff_t) 0));
testRuntimeSpan(std::span<std::string>(&s, 1));
}

View File

@ -0,0 +1,118 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
// constexpr iterator end() const noexcept;
// constexpr const_iterator cend() const noexcept;
#include <span>
#include <cassert>
#include <string>
#include "test_macros.h"
template <class Span>
constexpr bool testConstexprSpan(Span s)
{
bool ret = true;
typename Span::iterator e = s. end();
typename Span::const_iterator ce = s.cend();
if (s.empty())
{
ret = ret && ( e == s.begin());
ret = ret && (ce == s.cbegin());
}
else
{
ret = ret && ( e != s.begin());
ret = ret && (ce != s.cbegin());
}
ret = ret && (( e - s.begin()) == s.size());
ret = ret && ((ce - s.cbegin()) == s.size());
ret = ret && (e == ce);
return ret;
}
template <class Span>
void testRuntimeSpan(Span s)
{
typename Span::iterator e = s. end();
typename Span::const_iterator ce = s.cend();
if (s.empty())
{
assert( e == s.begin());
assert(ce == s.cbegin());
}
else
{
assert( e != s.begin());
assert(ce != s.cbegin());
}
assert(( e - s.begin()) == s.size());
assert((ce - s.cbegin()) == s.size());
assert(e == ce);
}
struct A{};
bool operator==(A, A) {return true;}
constexpr int iArr1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int iArr2[] = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19};
int main()
{
static_assert(testConstexprSpan(std::span<int>()), "");
static_assert(testConstexprSpan(std::span<long>()), "");
static_assert(testConstexprSpan(std::span<double>()), "");
static_assert(testConstexprSpan(std::span<A>()), "");
static_assert(testConstexprSpan(std::span<std::string>()), "");
static_assert(testConstexprSpan(std::span<int, 0>()), "");
static_assert(testConstexprSpan(std::span<long, 0>()), "");
static_assert(testConstexprSpan(std::span<double, 0>()), "");
static_assert(testConstexprSpan(std::span<A, 0>()), "");
static_assert(testConstexprSpan(std::span<std::string, 0>()), "");
static_assert(testConstexprSpan(std::span<const int>(iArr1, 1)), "");
static_assert(testConstexprSpan(std::span<const int>(iArr1, 2)), "");
static_assert(testConstexprSpan(std::span<const int>(iArr1, 3)), "");
static_assert(testConstexprSpan(std::span<const int>(iArr1, 4)), "");
static_assert(testConstexprSpan(std::span<const int>(iArr1, 5)), "");
testRuntimeSpan(std::span<int> ());
testRuntimeSpan(std::span<long> ());
testRuntimeSpan(std::span<double> ());
testRuntimeSpan(std::span<A> ());
testRuntimeSpan(std::span<std::string>());
testRuntimeSpan(std::span<int, 0> ());
testRuntimeSpan(std::span<long, 0> ());
testRuntimeSpan(std::span<double, 0> ());
testRuntimeSpan(std::span<A, 0> ());
testRuntimeSpan(std::span<std::string, 0>());
testRuntimeSpan(std::span<int>(iArr2, 1));
testRuntimeSpan(std::span<int>(iArr2, 2));
testRuntimeSpan(std::span<int>(iArr2, 3));
testRuntimeSpan(std::span<int>(iArr2, 4));
testRuntimeSpan(std::span<int>(iArr2, 5));
std::string s;
testRuntimeSpan(std::span<std::string>(&s, (std::ptrdiff_t) 0));
testRuntimeSpan(std::span<std::string>(&s, 1));
}

View File

@ -0,0 +1,117 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
// constexpr reverse_iterator rbegin() const noexcept;
// constexpr const_reverse_iterator crbegin() const noexcept;
#include <span>
#include <cassert>
#include <string>
#include "test_macros.h"
template <class Span>
constexpr bool testConstexprSpan(Span s)
{
bool ret = true;
typename Span::reverse_iterator b = s. rbegin();
typename Span::const_reverse_iterator cb = s.crbegin();
if (s.empty())
{
ret = ret && ( b == s.rend());
ret = ret && (cb == s.crend());
}
else
{
const typename Span::index_type last = s.size() - 1;
ret = ret && ( *b == s[last]);
ret = ret && ( &*b == &s[last]);
ret = ret && ( *cb == s[last]);
ret = ret && (&*cb == &s[last]);
}
ret = ret && (b == cb);
return ret;
}
template <class Span>
void testRuntimeSpan(Span s)
{
typename Span::reverse_iterator b = s. rbegin();
typename Span::const_reverse_iterator cb = s.crbegin();
if (s.empty())
{
assert( b == s.rend());
assert(cb == s.crend());
}
else
{
const typename Span::index_type last = s.size() - 1;
assert( *b == s[last]);
assert( &*b == &s[last]);
assert( *cb == s[last]);
assert(&*cb == &s[last]);
}
assert(b == cb);
}
struct A{};
bool operator==(A, A) {return true;}
constexpr int iArr1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int iArr2[] = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19};
int main()
{
static_assert(testConstexprSpan(std::span<int>()), "");
static_assert(testConstexprSpan(std::span<long>()), "");
static_assert(testConstexprSpan(std::span<double>()), "");
static_assert(testConstexprSpan(std::span<A>()), "");
static_assert(testConstexprSpan(std::span<std::string>()), "");
static_assert(testConstexprSpan(std::span<int, 0>()), "");
static_assert(testConstexprSpan(std::span<long, 0>()), "");
static_assert(testConstexprSpan(std::span<double, 0>()), "");
static_assert(testConstexprSpan(std::span<A, 0>()), "");
static_assert(testConstexprSpan(std::span<std::string, 0>()), "");
static_assert(testConstexprSpan(std::span<const int>(iArr1, 1)), "");
static_assert(testConstexprSpan(std::span<const int>(iArr1, 2)), "");
static_assert(testConstexprSpan(std::span<const int>(iArr1, 3)), "");
static_assert(testConstexprSpan(std::span<const int>(iArr1, 4)), "");
static_assert(testConstexprSpan(std::span<const int>(iArr1, 5)), "");
testRuntimeSpan(std::span<int> ());
testRuntimeSpan(std::span<long> ());
testRuntimeSpan(std::span<double> ());
testRuntimeSpan(std::span<A> ());
testRuntimeSpan(std::span<std::string>());
testRuntimeSpan(std::span<int, 0> ());
testRuntimeSpan(std::span<long, 0> ());
testRuntimeSpan(std::span<double, 0> ());
testRuntimeSpan(std::span<A, 0> ());
testRuntimeSpan(std::span<std::string, 0>());
testRuntimeSpan(std::span<int>(iArr2, 1));
testRuntimeSpan(std::span<int>(iArr2, 2));
testRuntimeSpan(std::span<int>(iArr2, 3));
testRuntimeSpan(std::span<int>(iArr2, 4));
testRuntimeSpan(std::span<int>(iArr2, 5));
std::string s;
testRuntimeSpan(std::span<std::string>(&s, static_cast<std::ptrdiff_t>(0)));
testRuntimeSpan(std::span<std::string>(&s, 1));
}

View File

@ -0,0 +1,118 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
// constexpr reverse_iterator rend() const noexcept;
// constexpr const_reverse_iterator crend() const noexcept;
#include <span>
#include <cassert>
#include <string>
#include "test_macros.h"
template <class Span>
constexpr bool testConstexprSpan(Span s)
{
bool ret = true;
typename Span::reverse_iterator e = s. rend();
typename Span::const_reverse_iterator ce = s.crend();
if (s.empty())
{
ret = ret && ( e == s.rbegin());
ret = ret && (ce == s.crbegin());
}
else
{
ret = ret && ( e != s.rbegin());
ret = ret && (ce != s.crbegin());
}
ret = ret && (( e - s.rbegin()) == s.size());
ret = ret && ((ce - s.crbegin()) == s.size());
ret = ret && (e == ce);
return ret;
}
template <class Span>
void testRuntimeSpan(Span s)
{
typename Span::reverse_iterator e = s. rend();
typename Span::const_reverse_iterator ce = s.crend();
if (s.empty())
{
assert( e == s.rbegin());
assert(ce == s.crbegin());
}
else
{
assert( e != s.rbegin());
assert(ce != s.crbegin());
}
assert(( e - s.rbegin()) == s.size());
assert((ce - s.crbegin()) == s.size());
assert(e == ce);
}
struct A{};
bool operator==(A, A) {return true;}
constexpr int iArr1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int iArr2[] = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19};
int main()
{
static_assert(testConstexprSpan(std::span<int>()), "");
static_assert(testConstexprSpan(std::span<long>()), "");
static_assert(testConstexprSpan(std::span<double>()), "");
static_assert(testConstexprSpan(std::span<A>()), "");
static_assert(testConstexprSpan(std::span<std::string>()), "");
static_assert(testConstexprSpan(std::span<int, 0>()), "");
static_assert(testConstexprSpan(std::span<long, 0>()), "");
static_assert(testConstexprSpan(std::span<double, 0>()), "");
static_assert(testConstexprSpan(std::span<A, 0>()), "");
static_assert(testConstexprSpan(std::span<std::string, 0>()), "");
static_assert(testConstexprSpan(std::span<const int>(iArr1, 1)), "");
static_assert(testConstexprSpan(std::span<const int>(iArr1, 2)), "");
static_assert(testConstexprSpan(std::span<const int>(iArr1, 3)), "");
static_assert(testConstexprSpan(std::span<const int>(iArr1, 4)), "");
static_assert(testConstexprSpan(std::span<const int>(iArr1, 5)), "");
testRuntimeSpan(std::span<int> ());
testRuntimeSpan(std::span<long> ());
testRuntimeSpan(std::span<double> ());
testRuntimeSpan(std::span<A> ());
testRuntimeSpan(std::span<std::string>());
testRuntimeSpan(std::span<int, 0> ());
testRuntimeSpan(std::span<long, 0> ());
testRuntimeSpan(std::span<double, 0> ());
testRuntimeSpan(std::span<A, 0> ());
testRuntimeSpan(std::span<std::string, 0>());
testRuntimeSpan(std::span<int>(iArr2, 1));
testRuntimeSpan(std::span<int>(iArr2, 2));
testRuntimeSpan(std::span<int>(iArr2, 3));
testRuntimeSpan(std::span<int>(iArr2, 4));
testRuntimeSpan(std::span<int>(iArr2, 5));
std::string s;
testRuntimeSpan(std::span<std::string>(&s, (std::ptrdiff_t) 0));
testRuntimeSpan(std::span<std::string>(&s, 1));
}

View File

@ -0,0 +1,78 @@
// -*- C++ -*-
//===------------------------------ span ---------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
// template <class ElementType, ptrdiff_t Extent>
// span<const byte,
// Extent == dynamic_extent
// ? dynamic_extent
// : static_cast<ptrdiff_t>(sizeof(ElementType)) * Extent>
// as_bytes(span<ElementType, Extent> s) noexcept;
#include <span>
#include <cassert>
#include <string>
#include "test_macros.h"
template<typename Span>
void testRuntimeSpan(Span sp)
{
ASSERT_NOEXCEPT(std::as_bytes(sp));
auto spBytes = std::as_bytes(sp);
using SB = decltype(spBytes);
ASSERT_SAME_TYPE(const std::byte, typename SB::element_type);
if (sp.extent == std::dynamic_extent)
assert(spBytes.extent == std::dynamic_extent);
else
assert(spBytes.extent == static_cast<std::ptrdiff_t>(sizeof(typename Span::element_type)) * sp.extent);
assert((void *) spBytes.data() == (void *) sp.data());
assert(spBytes.size() == sp.size_bytes());
}
struct A{};
int iArr2[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int main ()
{
testRuntimeSpan(std::span<int> ());
testRuntimeSpan(std::span<long> ());
testRuntimeSpan(std::span<double> ());
testRuntimeSpan(std::span<A> ());
testRuntimeSpan(std::span<std::string>());
testRuntimeSpan(std::span<int, 0> ());
testRuntimeSpan(std::span<long, 0> ());
testRuntimeSpan(std::span<double, 0> ());
testRuntimeSpan(std::span<A, 0> ());
testRuntimeSpan(std::span<std::string, 0>());
testRuntimeSpan(std::span<int>(iArr2, 1));
testRuntimeSpan(std::span<int>(iArr2, 2));
testRuntimeSpan(std::span<int>(iArr2, 3));
testRuntimeSpan(std::span<int>(iArr2, 4));
testRuntimeSpan(std::span<int>(iArr2, 5));
testRuntimeSpan(std::span<int, 1>(iArr2 + 5, 1));
testRuntimeSpan(std::span<int, 2>(iArr2 + 4, 2));
testRuntimeSpan(std::span<int, 3>(iArr2 + 3, 3));
testRuntimeSpan(std::span<int, 4>(iArr2 + 2, 4));
testRuntimeSpan(std::span<int, 5>(iArr2 + 1, 5));
std::string s;
testRuntimeSpan(std::span<std::string>(&s, (std::ptrdiff_t) 0));
testRuntimeSpan(std::span<std::string>(&s, 1));
}

View File

@ -0,0 +1,48 @@
// -*- C++ -*-
//===------------------------------ span ---------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
// template <class ElementType, ptrdiff_t Extent>
// span<byte,
// Extent == dynamic_extent
// ? dynamic_extent
// : static_cast<ptrdiff_t>(sizeof(ElementType)) * Extent>
// as_writeable_bytes(span<ElementType, Extent> s) noexcept;
#include <span>
#include <cassert>
#include <string>
#include "test_macros.h"
const int iArr2[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
struct A {};
int main ()
{
std::as_writeable_bytes(std::span<const int>()); // expected-error {{no matching function for call to 'as_writeable_bytes'}}
std::as_writeable_bytes(std::span<const long>()); // expected-error {{no matching function for call to 'as_writeable_bytes'}}
std::as_writeable_bytes(std::span<const double>()); // expected-error {{no matching function for call to 'as_writeable_bytes'}}
std::as_writeable_bytes(std::span<const A>()); // expected-error {{no matching function for call to 'as_writeable_bytes'}}
std::as_writeable_bytes(std::span<const std::string>()); // expected-error {{no matching function for call to 'as_writeable_bytes'}}
std::as_writeable_bytes(std::span<const int, 0>()); // expected-error {{no matching function for call to 'as_writeable_bytes'}}
std::as_writeable_bytes(std::span<const long, 0>()); // expected-error {{no matching function for call to 'as_writeable_bytes'}}
std::as_writeable_bytes(std::span<const double, 0>()); // expected-error {{no matching function for call to 'as_writeable_bytes'}}
std::as_writeable_bytes(std::span<const A, 0>()); // expected-error {{no matching function for call to 'as_writeable_bytes'}}
std::as_writeable_bytes(std::span<const std::string, 0>()); // expected-error {{no matching function for call to 'as_writeable_bytes'}}
std::as_writeable_bytes(std::span<const int> (iArr2, 1)); // expected-error {{no matching function for call to 'as_writeable_bytes'}}
std::as_writeable_bytes(std::span<const int, 1>(iArr2 + 5, 1)); // expected-error {{no matching function for call to 'as_writeable_bytes'}}
}

View File

@ -0,0 +1,78 @@
// -*- C++ -*-
//===------------------------------ span ---------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
// template <class ElementType, ptrdiff_t Extent>
// span<byte,
// Extent == dynamic_extent
// ? dynamic_extent
// : static_cast<ptrdiff_t>(sizeof(ElementType)) * Extent>
// as_writeable_bytes(span<ElementType, Extent> s) noexcept;
#include <span>
#include <cassert>
#include <string>
#include "test_macros.h"
template<typename Span>
void testRuntimeSpan(Span sp)
{
ASSERT_NOEXCEPT(std::as_writeable_bytes(sp));
auto spBytes = std::as_writeable_bytes(sp);
using SB = decltype(spBytes);
ASSERT_SAME_TYPE(std::byte, typename SB::element_type);
if (sp.extent == std::dynamic_extent)
assert(spBytes.extent == std::dynamic_extent);
else
assert(spBytes.extent == static_cast<std::ptrdiff_t>(sizeof(typename Span::element_type)) * sp.extent);
assert(static_cast<void*>(spBytes.data()) == static_cast<void*>(sp.data()));
assert(spBytes.size() == sp.size_bytes());
}
struct A{};
int iArr2[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int main ()
{
testRuntimeSpan(std::span<int> ());
testRuntimeSpan(std::span<long> ());
testRuntimeSpan(std::span<double> ());
testRuntimeSpan(std::span<A> ());
testRuntimeSpan(std::span<std::string>());
testRuntimeSpan(std::span<int, 0> ());
testRuntimeSpan(std::span<long, 0> ());
testRuntimeSpan(std::span<double, 0> ());
testRuntimeSpan(std::span<A, 0> ());
testRuntimeSpan(std::span<std::string, 0>());
testRuntimeSpan(std::span<int>(iArr2, 1));
testRuntimeSpan(std::span<int>(iArr2, 2));
testRuntimeSpan(std::span<int>(iArr2, 3));
testRuntimeSpan(std::span<int>(iArr2, 4));
testRuntimeSpan(std::span<int>(iArr2, 5));
testRuntimeSpan(std::span<int, 1>(iArr2 + 5, 1));
testRuntimeSpan(std::span<int, 2>(iArr2 + 4, 2));
testRuntimeSpan(std::span<int, 3>(iArr2 + 3, 3));
testRuntimeSpan(std::span<int, 4>(iArr2 + 2, 4));
testRuntimeSpan(std::span<int, 5>(iArr2 + 1, 5));
std::string s;
testRuntimeSpan(std::span<std::string>(&s, (std::ptrdiff_t) 0));
testRuntimeSpan(std::span<std::string>(&s, 1));
}

View File

@ -0,0 +1,73 @@
// -*- C++ -*-
//===------------------------------ span ---------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
// constexpr bool empty() const noexcept;
//
#include <span>
#include <cassert>
#include <string>
#include "test_macros.h"
struct A{};
constexpr int iArr1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int iArr2[] = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19};
int main ()
{
static_assert( noexcept(std::span<int> ().empty()), "");
static_assert( noexcept(std::span<int, 0>().empty()), "");
static_assert( std::span<int>().empty(), "");
static_assert( std::span<long>().empty(), "");
static_assert( std::span<double>().empty(), "");
static_assert( std::span<A>().empty(), "");
static_assert( std::span<std::string>().empty(), "");
static_assert( std::span<int, 0>().empty(), "");
static_assert( std::span<long, 0>().empty(), "");
static_assert( std::span<double, 0>().empty(), "");
static_assert( std::span<A, 0>().empty(), "");
static_assert( std::span<std::string, 0>().empty(), "");
static_assert(!std::span<const int>(iArr1, 1).empty(), "");
static_assert(!std::span<const int>(iArr1, 2).empty(), "");
static_assert(!std::span<const int>(iArr1, 3).empty(), "");
static_assert(!std::span<const int>(iArr1, 4).empty(), "");
static_assert(!std::span<const int>(iArr1, 5).empty(), "");
assert( (std::span<int>().empty() ));
assert( (std::span<long>().empty() ));
assert( (std::span<double>().empty() ));
assert( (std::span<A>().empty() ));
assert( (std::span<std::string>().empty() ));
assert( (std::span<int, 0>().empty() ));
assert( (std::span<long, 0>().empty() ));
assert( (std::span<double, 0>().empty() ));
assert( (std::span<A, 0>().empty() ));
assert( (std::span<std::string, 0>().empty()));
assert(!(std::span<int, 1>(iArr2, 1).empty()));
assert(!(std::span<int, 2>(iArr2, 2).empty()));
assert(!(std::span<int, 3>(iArr2, 3).empty()));
assert(!(std::span<int, 4>(iArr2, 4).empty()));
assert(!(std::span<int, 5>(iArr2, 5).empty()));
std::string s;
assert( ((std::span<std::string>(&s, (std::ptrdiff_t) 0)).empty()));
assert(!((std::span<std::string>(&s, 1).empty())));
}

View File

@ -0,0 +1,91 @@
// -*- C++ -*-
//===------------------------------ span ---------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
// constexpr index_type size() const noexcept;
//
#include <span>
#include <cassert>
#include <string>
#include "test_macros.h"
template <typename Span>
constexpr bool testConstexprSpan(Span sp, ptrdiff_t sz)
{
ASSERT_NOEXCEPT(sp.size());
return sp.size() == sz;
}
template <typename Span>
void testRuntimeSpan(Span sp, ptrdiff_t sz)
{
ASSERT_NOEXCEPT(sp.size());
assert(sp.size() == sz);
}
struct A{};
constexpr int iArr1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int iArr2[] = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19};
int main ()
{
static_assert(testConstexprSpan(std::span<int>(), 0), "");
static_assert(testConstexprSpan(std::span<long>(), 0), "");
static_assert(testConstexprSpan(std::span<double>(), 0), "");
static_assert(testConstexprSpan(std::span<A>(), 0), "");
static_assert(testConstexprSpan(std::span<std::string>(), 0), "");
static_assert(testConstexprSpan(std::span<int, 0>(), 0), "");
static_assert(testConstexprSpan(std::span<long, 0>(), 0), "");
static_assert(testConstexprSpan(std::span<double, 0>(), 0), "");
static_assert(testConstexprSpan(std::span<A, 0>(), 0), "");
static_assert(testConstexprSpan(std::span<std::string, 0>(), 0), "");
static_assert(testConstexprSpan(std::span<const int>(iArr1, 1), 1), "");
static_assert(testConstexprSpan(std::span<const int>(iArr1, 2), 2), "");
static_assert(testConstexprSpan(std::span<const int>(iArr1, 3), 3), "");
static_assert(testConstexprSpan(std::span<const int>(iArr1, 4), 4), "");
static_assert(testConstexprSpan(std::span<const int>(iArr1, 5), 5), "");
testRuntimeSpan(std::span<int> (), 0);
testRuntimeSpan(std::span<long> (), 0);
testRuntimeSpan(std::span<double> (), 0);
testRuntimeSpan(std::span<A> (), 0);
testRuntimeSpan(std::span<std::string>(), 0);
testRuntimeSpan(std::span<int, 0> (), 0);
testRuntimeSpan(std::span<long, 0> (), 0);
testRuntimeSpan(std::span<double, 0> (), 0);
testRuntimeSpan(std::span<A, 0> (), 0);
testRuntimeSpan(std::span<std::string, 0>(), 0);
testRuntimeSpan(std::span<int>(iArr2, 1), 1);
testRuntimeSpan(std::span<int>(iArr2, 2), 2);
testRuntimeSpan(std::span<int>(iArr2, 3), 3);
testRuntimeSpan(std::span<int>(iArr2, 4), 4);
testRuntimeSpan(std::span<int>(iArr2, 5), 5);
testRuntimeSpan(std::span<int, 1>(iArr2 + 5, 1), 1);
testRuntimeSpan(std::span<int, 2>(iArr2 + 4, 2), 2);
testRuntimeSpan(std::span<int, 3>(iArr2 + 3, 3), 3);
testRuntimeSpan(std::span<int, 4>(iArr2 + 2, 4), 4);
testRuntimeSpan(std::span<int, 5>(iArr2 + 1, 5), 5);
std::string s;
testRuntimeSpan(std::span<std::string>(&s, (std::ptrdiff_t) 0), 0);
testRuntimeSpan(std::span<std::string>(&s, 1), 1);
}

View File

@ -0,0 +1,92 @@
// -*- C++ -*-
//===------------------------------ span ---------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
// constexpr index_type size_bytes() const noexcept;
//
// Effects: Equivalent to: return size() * sizeof(element_type);
#include <span>
#include <cassert>
#include <string>
#include "test_macros.h"
template <typename Span>
constexpr bool testConstexprSpan(Span sp, ptrdiff_t sz)
{
ASSERT_NOEXCEPT(sp.size_bytes());
return (size_t) sp.size_bytes() == sz * sizeof(typename Span::element_type);
}
template <typename Span>
void testRuntimeSpan(Span sp, ptrdiff_t sz)
{
ASSERT_NOEXCEPT(sp.size_bytes());
assert((size_t) sp.size_bytes() == sz * sizeof(typename Span::element_type));
}
struct A{};
constexpr int iArr1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int iArr2[] = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19};
int main ()
{
static_assert(testConstexprSpan(std::span<int>(), 0), "");
static_assert(testConstexprSpan(std::span<long>(), 0), "");
static_assert(testConstexprSpan(std::span<double>(), 0), "");
static_assert(testConstexprSpan(std::span<A>(), 0), "");
static_assert(testConstexprSpan(std::span<std::string>(), 0), "");
static_assert(testConstexprSpan(std::span<int, 0>(), 0), "");
static_assert(testConstexprSpan(std::span<long, 0>(), 0), "");
static_assert(testConstexprSpan(std::span<double, 0>(), 0), "");
static_assert(testConstexprSpan(std::span<A, 0>(), 0), "");
static_assert(testConstexprSpan(std::span<std::string, 0>(), 0), "");
static_assert(testConstexprSpan(std::span<const int>(iArr1, 1), 1), "");
static_assert(testConstexprSpan(std::span<const int>(iArr1, 2), 2), "");
static_assert(testConstexprSpan(std::span<const int>(iArr1, 3), 3), "");
static_assert(testConstexprSpan(std::span<const int>(iArr1, 4), 4), "");
static_assert(testConstexprSpan(std::span<const int>(iArr1, 5), 5), "");
testRuntimeSpan(std::span<int> (), 0);
testRuntimeSpan(std::span<long> (), 0);
testRuntimeSpan(std::span<double> (), 0);
testRuntimeSpan(std::span<A> (), 0);
testRuntimeSpan(std::span<std::string>(), 0);
testRuntimeSpan(std::span<int, 0> (), 0);
testRuntimeSpan(std::span<long, 0> (), 0);
testRuntimeSpan(std::span<double, 0> (), 0);
testRuntimeSpan(std::span<A, 0> (), 0);
testRuntimeSpan(std::span<std::string, 0>(), 0);
testRuntimeSpan(std::span<int>(iArr2, 1), 1);
testRuntimeSpan(std::span<int>(iArr2, 2), 2);
testRuntimeSpan(std::span<int>(iArr2, 3), 3);
testRuntimeSpan(std::span<int>(iArr2, 4), 4);
testRuntimeSpan(std::span<int>(iArr2, 5), 5);
testRuntimeSpan(std::span<int, 1>(iArr2 + 5, 1), 1);
testRuntimeSpan(std::span<int, 2>(iArr2 + 4, 2), 2);
testRuntimeSpan(std::span<int, 3>(iArr2 + 3, 3), 3);
testRuntimeSpan(std::span<int, 4>(iArr2 + 2, 4), 4);
testRuntimeSpan(std::span<int, 5>(iArr2 + 1, 5), 5);
std::string s;
testRuntimeSpan(std::span<std::string>(&s, (std::ptrdiff_t) 0), 0);
testRuntimeSpan(std::span<std::string>(&s, 1), 1);
}

View File

@ -0,0 +1,136 @@
// -*- C++ -*-
//===------------------------------ span ---------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
// template<ptrdiff_t Count>
// constexpr span<element_type, Count> first() const;
//
// constexpr span<element_type, dynamic_extent> first(index_type count) const;
//
// Requires: 0 <= Count && Count <= size().
#include <span>
#include <cassert>
#include <algorithm>
#include <string>
#include "test_macros.h"
template <typename Span, ptrdiff_t Count>
constexpr bool testConstexprSpan(Span sp)
{
LIBCPP_ASSERT((noexcept(sp.template first<Count>())));
LIBCPP_ASSERT((noexcept(sp.first(Count))));
auto s1 = sp.template first<Count>();
auto s2 = sp.first(Count);
using S1 = decltype(s1);
using S2 = decltype(s2);
ASSERT_SAME_TYPE(typename Span::value_type, typename S1::value_type);
ASSERT_SAME_TYPE(typename Span::value_type, typename S2::value_type);
static_assert(S1::extent == Count, "");
static_assert(S2::extent == std::dynamic_extent, "");
return
s1.data() == s2.data()
&& s1.size() == s2.size()
&& std::equal(s1.begin(), s1.end(), sp.begin());
}
template <typename Span, ptrdiff_t Count>
void testRuntimeSpan(Span sp)
{
LIBCPP_ASSERT((noexcept(sp.template first<Count>())));
LIBCPP_ASSERT((noexcept(sp.first(Count))));
auto s1 = sp.template first<Count>();
auto s2 = sp.first(Count);
using S1 = decltype(s1);
using S2 = decltype(s2);
ASSERT_SAME_TYPE(typename Span::value_type, typename S1::value_type);
ASSERT_SAME_TYPE(typename Span::value_type, typename S2::value_type);
static_assert(S1::extent == Count, "");
static_assert(S2::extent == std::dynamic_extent, "");
assert(s1.data() == s2.data());
assert(s1.size() == s2.size());
assert(std::equal(s1.begin(), s1.end(), sp.begin()));
}
constexpr int carr1[] = {1,2,3,4};
int arr[] = {5,6,7};
std::string sarr [] = { "ABC", "DEF", "GHI", "JKL", "MNO"};
int main ()
{
{
using Sp = std::span<const int>;
static_assert(testConstexprSpan<Sp, 0>(Sp{}), "");
static_assert(testConstexprSpan<Sp, 0>(Sp{carr1}), "");
static_assert(testConstexprSpan<Sp, 1>(Sp{carr1}), "");
static_assert(testConstexprSpan<Sp, 2>(Sp{carr1}), "");
static_assert(testConstexprSpan<Sp, 3>(Sp{carr1}), "");
static_assert(testConstexprSpan<Sp, 4>(Sp{carr1}), "");
}
{
using Sp = std::span<const int, 4>;
static_assert(testConstexprSpan<Sp, 0>(Sp{carr1}), "");
static_assert(testConstexprSpan<Sp, 1>(Sp{carr1}), "");
static_assert(testConstexprSpan<Sp, 2>(Sp{carr1}), "");
static_assert(testConstexprSpan<Sp, 3>(Sp{carr1}), "");
static_assert(testConstexprSpan<Sp, 4>(Sp{carr1}), "");
}
{
using Sp = std::span<int>;
testRuntimeSpan<Sp, 0>(Sp{});
testRuntimeSpan<Sp, 0>(Sp{arr});
testRuntimeSpan<Sp, 1>(Sp{arr});
testRuntimeSpan<Sp, 2>(Sp{arr});
testRuntimeSpan<Sp, 3>(Sp{arr});
}
{
using Sp = std::span<int, 3>;
testRuntimeSpan<Sp, 0>(Sp{arr});
testRuntimeSpan<Sp, 1>(Sp{arr});
testRuntimeSpan<Sp, 2>(Sp{arr});
testRuntimeSpan<Sp, 3>(Sp{arr});
}
{
using Sp = std::span<std::string>;
testConstexprSpan<Sp, 0>(Sp{});
testRuntimeSpan<Sp, 0>(Sp{sarr});
testRuntimeSpan<Sp, 1>(Sp{sarr});
testRuntimeSpan<Sp, 2>(Sp{sarr});
testRuntimeSpan<Sp, 3>(Sp{sarr});
testRuntimeSpan<Sp, 4>(Sp{sarr});
testRuntimeSpan<Sp, 5>(Sp{sarr});
}
{
using Sp = std::span<std::string, 5>;
testRuntimeSpan<Sp, 0>(Sp{sarr});
testRuntimeSpan<Sp, 1>(Sp{sarr});
testRuntimeSpan<Sp, 2>(Sp{sarr});
testRuntimeSpan<Sp, 3>(Sp{sarr});
testRuntimeSpan<Sp, 4>(Sp{sarr});
testRuntimeSpan<Sp, 5>(Sp{sarr});
}
}

View File

@ -0,0 +1,136 @@
// -*- C++ -*-
//===------------------------------ span ---------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
// template<ptrdiff_t Count>
// constexpr span<element_type, Count> last() const;
//
// constexpr span<element_type, dynamic_extent> last(index_type count) const;
//
// Requires: 0 <= Count && Count <= size().
#include <span>
#include <cassert>
#include <algorithm>
#include <string>
#include "test_macros.h"
template <typename Span, ptrdiff_t Count>
constexpr bool testConstexprSpan(Span sp)
{
LIBCPP_ASSERT((noexcept(sp.template last<Count>())));
LIBCPP_ASSERT((noexcept(sp.last(Count))));
auto s1 = sp.template last<Count>();
auto s2 = sp.last(Count);
using S1 = decltype(s1);
using S2 = decltype(s2);
ASSERT_SAME_TYPE(typename Span::value_type, typename S1::value_type);
ASSERT_SAME_TYPE(typename Span::value_type, typename S2::value_type);
static_assert(S1::extent == Count, "");
static_assert(S2::extent == std::dynamic_extent, "");
return
s1.data() == s2.data()
&& s1.size() == s2.size()
&& std::equal(s1.begin(), s1.end(), sp.end() - Count);
}
template <typename Span, ptrdiff_t Count>
void testRuntimeSpan(Span sp)
{
LIBCPP_ASSERT((noexcept(sp.template last<Count>())));
LIBCPP_ASSERT((noexcept(sp.last(Count))));
auto s1 = sp.template last<Count>();
auto s2 = sp.last(Count);
using S1 = decltype(s1);
using S2 = decltype(s2);
ASSERT_SAME_TYPE(typename Span::value_type, typename S1::value_type);
ASSERT_SAME_TYPE(typename Span::value_type, typename S2::value_type);
static_assert(S1::extent == Count, "");
static_assert(S2::extent == std::dynamic_extent, "");
assert(s1.data() == s2.data());
assert(s1.size() == s2.size());
assert(std::equal(s1.begin(), s1.end(), sp.end() - Count));
}
constexpr int carr1[] = {1,2,3,4};
int arr[] = {5,6,7};
std::string sarr [] = { "ABC", "DEF", "GHI", "JKL", "MNO"};
int main ()
{
{
using Sp = std::span<const int>;
static_assert(testConstexprSpan<Sp, 0>(Sp{}), "");
static_assert(testConstexprSpan<Sp, 0>(Sp{carr1}), "");
static_assert(testConstexprSpan<Sp, 1>(Sp{carr1}), "");
static_assert(testConstexprSpan<Sp, 2>(Sp{carr1}), "");
static_assert(testConstexprSpan<Sp, 3>(Sp{carr1}), "");
static_assert(testConstexprSpan<Sp, 4>(Sp{carr1}), "");
}
{
using Sp = std::span<const int, 4>;
static_assert(testConstexprSpan<Sp, 0>(Sp{carr1}), "");
static_assert(testConstexprSpan<Sp, 1>(Sp{carr1}), "");
static_assert(testConstexprSpan<Sp, 2>(Sp{carr1}), "");
static_assert(testConstexprSpan<Sp, 3>(Sp{carr1}), "");
static_assert(testConstexprSpan<Sp, 4>(Sp{carr1}), "");
}
{
using Sp = std::span<int>;
testRuntimeSpan<Sp, 0>(Sp{});
testRuntimeSpan<Sp, 0>(Sp{arr});
testRuntimeSpan<Sp, 1>(Sp{arr});
testRuntimeSpan<Sp, 2>(Sp{arr});
testRuntimeSpan<Sp, 3>(Sp{arr});
}
{
using Sp = std::span<int, 3>;
testRuntimeSpan<Sp, 0>(Sp{arr});
testRuntimeSpan<Sp, 1>(Sp{arr});
testRuntimeSpan<Sp, 2>(Sp{arr});
testRuntimeSpan<Sp, 3>(Sp{arr});
}
{
using Sp = std::span<std::string>;
testConstexprSpan<Sp, 0>(Sp{});
testRuntimeSpan<Sp, 0>(Sp{sarr});
testRuntimeSpan<Sp, 1>(Sp{sarr});
testRuntimeSpan<Sp, 2>(Sp{sarr});
testRuntimeSpan<Sp, 3>(Sp{sarr});
testRuntimeSpan<Sp, 4>(Sp{sarr});
testRuntimeSpan<Sp, 5>(Sp{sarr});
}
{
using Sp = std::span<std::string, 5>;
testRuntimeSpan<Sp, 0>(Sp{sarr});
testRuntimeSpan<Sp, 1>(Sp{sarr});
testRuntimeSpan<Sp, 2>(Sp{sarr});
testRuntimeSpan<Sp, 3>(Sp{sarr});
testRuntimeSpan<Sp, 4>(Sp{sarr});
testRuntimeSpan<Sp, 5>(Sp{sarr});
}
}

View File

@ -0,0 +1,210 @@
// -*- C++ -*-
//===------------------------------ span ---------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
// template<ptrdiff_t Offset, ptrdiff_t Count = dynamic_extent>
// constexpr span<element_type, see below> subspan() const;
//
// constexpr span<element_type, dynamic_extent> subspan(
// index_type offset, index_type count = dynamic_extent) const;
//
// Requires: (0 <= Offset && Offset <= size())
// && (Count == dynamic_extent || Count >= 0 && Offset + Count <= size())
#include <span>
#include <cassert>
#include <algorithm>
#include <string>
#include "test_macros.h"
template <typename Span, ptrdiff_t Offset, ptrdiff_t Count>
constexpr bool testConstexprSpan(Span sp)
{
LIBCPP_ASSERT((noexcept(sp.template subspan<Offset, Count>())));
LIBCPP_ASSERT((noexcept(sp.subspan(Offset, Count))));
auto s1 = sp.template subspan<Offset, Count>();
auto s2 = sp.subspan(Offset, Count);
using S1 = decltype(s1);
using S2 = decltype(s2);
ASSERT_SAME_TYPE(typename Span::value_type, typename S1::value_type);
ASSERT_SAME_TYPE(typename Span::value_type, typename S2::value_type);
static_assert(S1::extent == (Span::extent == std::dynamic_extent ? std::dynamic_extent : Count), "");
static_assert(S2::extent == std::dynamic_extent, "");
return
s1.data() == s2.data()
&& s1.size() == s2.size()
&& std::equal(s1.begin(), s1.end(), sp.begin() + Offset);
}
template <typename Span, ptrdiff_t Offset>
constexpr bool testConstexprSpan(Span sp)
{
LIBCPP_ASSERT((noexcept(sp.template subspan<Offset>())));
LIBCPP_ASSERT((noexcept(sp.subspan(Offset))));
auto s1 = sp.template subspan<Offset>();
auto s2 = sp.subspan(Offset);
using S1 = decltype(s1);
using S2 = decltype(s2);
ASSERT_SAME_TYPE(typename Span::value_type, typename S1::value_type);
ASSERT_SAME_TYPE(typename Span::value_type, typename S2::value_type);
static_assert(S1::extent == (Span::extent == std::dynamic_extent ? std::dynamic_extent : Span::extent - Offset), "");
static_assert(S2::extent == std::dynamic_extent, "");
return
s1.data() == s2.data()
&& s1.size() == s2.size()
&& std::equal(s1.begin(), s1.end(), sp.begin() + Offset, sp.end());
}
template <typename Span, ptrdiff_t Offset, ptrdiff_t Count>
void testRuntimeSpan(Span sp)
{
LIBCPP_ASSERT((noexcept(sp.template subspan<Offset, Count>())));
LIBCPP_ASSERT((noexcept(sp.subspan(Offset, Count))));
auto s1 = sp.template subspan<Offset, Count>();
auto s2 = sp.subspan(Offset, Count);
using S1 = decltype(s1);
using S2 = decltype(s2);
ASSERT_SAME_TYPE(typename Span::value_type, typename S1::value_type);
ASSERT_SAME_TYPE(typename Span::value_type, typename S2::value_type);
static_assert(S1::extent == (Span::extent == std::dynamic_extent ? std::dynamic_extent : Count), "");
static_assert(S2::extent == std::dynamic_extent, "");
assert(s1.data() == s2.data());
assert(s1.size() == s2.size());
assert(std::equal(s1.begin(), s1.end(), sp.begin() + Offset));
}
template <typename Span, ptrdiff_t Offset>
void testRuntimeSpan(Span sp)
{
LIBCPP_ASSERT((noexcept(sp.template subspan<Offset>())));
LIBCPP_ASSERT((noexcept(sp.subspan(Offset))));
auto s1 = sp.template subspan<Offset>();
auto s2 = sp.subspan(Offset);
using S1 = decltype(s1);
using S2 = decltype(s2);
ASSERT_SAME_TYPE(typename Span::value_type, typename S1::value_type);
ASSERT_SAME_TYPE(typename Span::value_type, typename S2::value_type);
static_assert(S1::extent == (Span::extent == std::dynamic_extent ? std::dynamic_extent : Span::extent - Offset), "");
static_assert(S2::extent == std::dynamic_extent, "");
assert(s1.data() == s2.data());
assert(s1.size() == s2.size());
assert(std::equal(s1.begin(), s1.end(), sp.begin() + Offset, sp.end()));
}
constexpr int carr1[] = {1,2,3,4};
int arr1[] = {5,6,7};
int main ()
{
{
using Sp = std::span<const int>;
static_assert(testConstexprSpan<Sp, 0>(Sp{}), "");
static_assert(testConstexprSpan<Sp, 0, 4>(Sp{carr1}), "");
static_assert(testConstexprSpan<Sp, 0, 3>(Sp{carr1}), "");
static_assert(testConstexprSpan<Sp, 0, 2>(Sp{carr1}), "");
static_assert(testConstexprSpan<Sp, 0, 1>(Sp{carr1}), "");
static_assert(testConstexprSpan<Sp, 0, 0>(Sp{carr1}), "");
static_assert(testConstexprSpan<Sp, 1, 3>(Sp{carr1}), "");
static_assert(testConstexprSpan<Sp, 2, 2>(Sp{carr1}), "");
static_assert(testConstexprSpan<Sp, 3, 1>(Sp{carr1}), "");
static_assert(testConstexprSpan<Sp, 4, 0>(Sp{carr1}), "");
}
{
using Sp = std::span<const int, 4>;
static_assert(testConstexprSpan<Sp, 0, 4>(Sp{carr1}), "");
static_assert(testConstexprSpan<Sp, 0, 3>(Sp{carr1}), "");
static_assert(testConstexprSpan<Sp, 0, 2>(Sp{carr1}), "");
static_assert(testConstexprSpan<Sp, 0, 1>(Sp{carr1}), "");
static_assert(testConstexprSpan<Sp, 0, 0>(Sp{carr1}), "");
static_assert(testConstexprSpan<Sp, 1, 3>(Sp{carr1}), "");
static_assert(testConstexprSpan<Sp, 2, 2>(Sp{carr1}), "");
static_assert(testConstexprSpan<Sp, 3, 1>(Sp{carr1}), "");
static_assert(testConstexprSpan<Sp, 4, 0>(Sp{carr1}), "");
}
{
using Sp = std::span<const int>;
static_assert(testConstexprSpan<Sp, 0>(Sp{}), "");
static_assert(testConstexprSpan<Sp, 0>(Sp{carr1}), "");
static_assert(testConstexprSpan<Sp, 1>(Sp{carr1}), "");
static_assert(testConstexprSpan<Sp, 2>(Sp{carr1}), "");
static_assert(testConstexprSpan<Sp, 3>(Sp{carr1}), "");
static_assert(testConstexprSpan<Sp, 4>(Sp{carr1}), "");
}
{
using Sp = std::span<const int, 4>;
static_assert(testConstexprSpan<Sp, 0>(Sp{carr1}), "");
static_assert(testConstexprSpan<Sp, 1>(Sp{carr1}), "");
static_assert(testConstexprSpan<Sp, 2>(Sp{carr1}), "");
static_assert(testConstexprSpan<Sp, 3>(Sp{carr1}), "");
static_assert(testConstexprSpan<Sp, 4>(Sp{carr1}), "");
}
{
using Sp = std::span<int>;
testRuntimeSpan<Sp, 0>(Sp{});
testRuntimeSpan<Sp, 0, 3>(Sp{arr1});
testRuntimeSpan<Sp, 0, 2>(Sp{arr1});
testRuntimeSpan<Sp, 0, 1>(Sp{arr1});
testRuntimeSpan<Sp, 0, 0>(Sp{arr1});
testRuntimeSpan<Sp, 1, 2>(Sp{arr1});
testRuntimeSpan<Sp, 2, 1>(Sp{arr1});
testRuntimeSpan<Sp, 3, 0>(Sp{arr1});
}
{
using Sp = std::span<int, 3>;
testRuntimeSpan<Sp, 0, 3>(Sp{arr1});
testRuntimeSpan<Sp, 0, 2>(Sp{arr1});
testRuntimeSpan<Sp, 0, 1>(Sp{arr1});
testRuntimeSpan<Sp, 0, 0>(Sp{arr1});
testRuntimeSpan<Sp, 1, 2>(Sp{arr1});
testRuntimeSpan<Sp, 2, 1>(Sp{arr1});
testRuntimeSpan<Sp, 3, 0>(Sp{arr1});
}
{
using Sp = std::span<int>;
testRuntimeSpan<Sp, 0>(Sp{});
testRuntimeSpan<Sp, 0>(Sp{arr1});
testRuntimeSpan<Sp, 1>(Sp{arr1});
testRuntimeSpan<Sp, 2>(Sp{arr1});
testRuntimeSpan<Sp, 3>(Sp{arr1});
}
{
using Sp = std::span<int, 3>;
testRuntimeSpan<Sp, 0>(Sp{arr1});
testRuntimeSpan<Sp, 1>(Sp{arr1});
testRuntimeSpan<Sp, 2>(Sp{arr1});
testRuntimeSpan<Sp, 3>(Sp{arr1});
}
}

View File

@ -0,0 +1,107 @@
// -*- C++ -*-
//===------------------------------ span ---------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <span>
// template<class ElementType, ptrdiff_t Extent = dynamic_extent>
// class span {
// public:
// // constants and types
// using element_type = ElementType;
// using value_type = remove_cv_t<ElementType>;
// using index_type = ptrdiff_t;
// using difference_type = ptrdiff_t;
// using pointer = element_type *;
// using reference = 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 index_type extent = Extent;
//
#include <span>
#include <cassert>
#include <iterator>
#include <string>
#include "test_macros.h"
template <typename S, typename Iter>
void testIterator()
{
typedef std::iterator_traits<Iter> ItT;
ASSERT_SAME_TYPE(typename ItT::iterator_category, std::random_access_iterator_tag);
ASSERT_SAME_TYPE(typename ItT::value_type, typename S::value_type);
ASSERT_SAME_TYPE(typename ItT::reference, typename S::reference);
ASSERT_SAME_TYPE(typename ItT::pointer, typename S::pointer);
ASSERT_SAME_TYPE(typename ItT::difference_type, typename S::difference_type);
}
template <typename S, typename Iter>
void testConstIterator()
{
typedef std::iterator_traits<Iter> ItT;
ASSERT_SAME_TYPE(typename ItT::iterator_category, std::random_access_iterator_tag);
ASSERT_SAME_TYPE(typename ItT::value_type, typename S::value_type);
// I'd like to say 'const typename S::pointer' here, but that gives me
// a const pointer to a non-const value, which is not what I want.
ASSERT_SAME_TYPE(typename ItT::reference, typename S::element_type const &);
ASSERT_SAME_TYPE(typename ItT::pointer, typename S::element_type const *);
ASSERT_SAME_TYPE(typename ItT::difference_type, typename S::difference_type);
}
template <typename S, typename ElementType, std::ptrdiff_t Size>
void testSpan()
{
ASSERT_SAME_TYPE(typename S::element_type, ElementType);
ASSERT_SAME_TYPE(typename S::value_type, std::remove_cv_t<ElementType>);
ASSERT_SAME_TYPE(typename S::index_type, std::ptrdiff_t);
ASSERT_SAME_TYPE(typename S::difference_type, std::ptrdiff_t);
ASSERT_SAME_TYPE(typename S::pointer, ElementType *);
ASSERT_SAME_TYPE(typename S::reference, ElementType &);
static_assert(S::extent == Size); // check that it exists
testIterator<S, typename S::iterator>();
testIterator<S, typename S::reverse_iterator>();
testConstIterator<S, typename S::const_iterator>();
testConstIterator<S, typename S::const_reverse_iterator>();
}
template <typename T>
void test()
{
testSpan<std::span< T>, T, -1>();
testSpan<std::span<const T>, const T, -1>();
testSpan<std::span< volatile T>, volatile T, -1>();
testSpan<std::span<const volatile T>, const volatile T, -1>();
testSpan<std::span< T, 5>, T, 5>();
testSpan<std::span<const T, 5>, const T, 5>();
testSpan<std::span< volatile T, 5>, volatile T, 5>();
testSpan<std::span<const volatile T, 5>, const volatile T, 5>();
}
struct A{};
int main ()
{
test<int>();
test<long>();
test<double>();
test<std::string>();
test<A>();
}