Renamed existing span to multi_span.

This commit is contained in:
Neil MacIntosh 2016-02-24 10:29:29 -08:00
parent ad0905c08b
commit 49e80625c6
6 changed files with 356 additions and 356 deletions

View File

@ -1072,7 +1072,7 @@ struct dim<dynamic_range>
template <typename ValueType, std::ptrdiff_t FirstDimension = dynamic_range, template <typename ValueType, std::ptrdiff_t FirstDimension = dynamic_range,
std::ptrdiff_t... RestDimensions> std::ptrdiff_t... RestDimensions>
class span; class multi_span;
template <typename ValueType, size_t Rank> template <typename ValueType, size_t Rank>
class strided_span; class strided_span;
@ -1096,7 +1096,7 @@ namespace details
template <typename T, std::ptrdiff_t... Ranks> template <typename T, std::ptrdiff_t... Ranks>
struct SpanArrayTraits struct SpanArrayTraits
{ {
using type = span<T, Ranks...>; using type = multi_span<T, Ranks...>;
using value_type = T; using value_type = T;
using bounds_type = static_bounds<Ranks...>; using bounds_type = static_bounds<Ranks...>;
using pointer = T*; using pointer = T*;
@ -1161,7 +1161,7 @@ namespace details
}; };
template <typename ValueType, std::ptrdiff_t FirstDimension, std::ptrdiff_t... RestDimensions> template <typename ValueType, std::ptrdiff_t FirstDimension, std::ptrdiff_t... RestDimensions>
struct is_span_oracle<span<ValueType, FirstDimension, RestDimensions...>> : std::true_type struct is_span_oracle<multi_span<ValueType, FirstDimension, RestDimensions...>> : std::true_type
{ {
}; };
@ -1177,12 +1177,12 @@ namespace details
} }
template <typename ValueType, std::ptrdiff_t FirstDimension, std::ptrdiff_t... RestDimensions> template <typename ValueType, std::ptrdiff_t FirstDimension, std::ptrdiff_t... RestDimensions>
class span class multi_span
{ {
// TODO do we still need this? // TODO do we still need this?
template <typename ValueType2, std::ptrdiff_t FirstDimension2, template <typename ValueType2, std::ptrdiff_t FirstDimension2,
std::ptrdiff_t... RestDimensions2> std::ptrdiff_t... RestDimensions2>
friend class span; friend class multi_span;
public: public:
using bounds_type = static_bounds<FirstDimension, RestDimensions...>; using bounds_type = static_bounds<FirstDimension, RestDimensions...>;
@ -1193,13 +1193,13 @@ public:
using const_value_type = std::add_const_t<value_type>; using const_value_type = std::add_const_t<value_type>;
using pointer = std::add_pointer_t<value_type>; using pointer = std::add_pointer_t<value_type>;
using reference = std::add_lvalue_reference_t<value_type>; using reference = std::add_lvalue_reference_t<value_type>;
using iterator = contiguous_span_iterator<span>; using iterator = contiguous_span_iterator<multi_span>;
using const_span = span<const_value_type, FirstDimension, RestDimensions...>; using const_span = multi_span<const_value_type, FirstDimension, RestDimensions...>;
using const_iterator = contiguous_span_iterator<const_span>; using const_iterator = contiguous_span_iterator<const_span>;
using reverse_iterator = std::reverse_iterator<iterator>; using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>; using const_reverse_iterator = std::reverse_iterator<const_iterator>;
using sliced_type = using sliced_type =
std::conditional_t<Rank == 1, value_type, span<value_type, RestDimensions...>>; std::conditional_t<Rank == 1, value_type, multi_span<value_type, RestDimensions...>>;
private: private:
pointer data_; pointer data_;
@ -1210,36 +1210,36 @@ private:
public: public:
// default constructor - same as constructing from nullptr_t // default constructor - same as constructing from nullptr_t
constexpr span() noexcept : span(nullptr, bounds_type{}) constexpr multi_span() noexcept : multi_span(nullptr, bounds_type{})
{ {
static_assert(bounds_type::dynamic_rank != 0 || static_assert(bounds_type::dynamic_rank != 0 ||
(bounds_type::dynamic_rank == 0 && bounds_type::static_size == 0), (bounds_type::dynamic_rank == 0 && bounds_type::static_size == 0),
"Default construction of span<T> only possible " "Default construction of multi_span<T> only possible "
"for dynamic or fixed, zero-length spans."); "for dynamic or fixed, zero-length spans.");
} }
// construct from nullptr - get an empty span // construct from nullptr - get an empty multi_span
constexpr span(std::nullptr_t) noexcept : span(nullptr, bounds_type{}) constexpr multi_span(std::nullptr_t) noexcept : multi_span(nullptr, bounds_type{})
{ {
static_assert(bounds_type::dynamic_rank != 0 || static_assert(bounds_type::dynamic_rank != 0 ||
(bounds_type::dynamic_rank == 0 && bounds_type::static_size == 0), (bounds_type::dynamic_rank == 0 && bounds_type::static_size == 0),
"nullptr_t construction of span<T> only possible " "nullptr_t construction of multi_span<T> only possible "
"for dynamic or fixed, zero-length spans."); "for dynamic or fixed, zero-length spans.");
} }
// construct from nullptr with size of 0 (helps with template function calls) // construct from nullptr with size of 0 (helps with template function calls)
template <class IntType, typename = std::enable_if_t<std::is_integral<IntType>::value>> template <class IntType, typename = std::enable_if_t<std::is_integral<IntType>::value>>
constexpr span(std::nullptr_t, IntType size) noexcept : span(nullptr, bounds_type{}) constexpr multi_span(std::nullptr_t, IntType size) noexcept : multi_span(nullptr, bounds_type{})
{ {
static_assert(bounds_type::dynamic_rank != 0 || static_assert(bounds_type::dynamic_rank != 0 ||
(bounds_type::dynamic_rank == 0 && bounds_type::static_size == 0), (bounds_type::dynamic_rank == 0 && bounds_type::static_size == 0),
"nullptr_t construction of span<T> only possible " "nullptr_t construction of multi_span<T> only possible "
"for dynamic or fixed, zero-length spans."); "for dynamic or fixed, zero-length spans.");
Expects(size == 0); Expects(size == 0);
} }
// construct from a single element // construct from a single element
constexpr span(reference data) noexcept : span(&data, bounds_type{1}) constexpr multi_span(reference data) noexcept : multi_span(&data, bounds_type{1})
{ {
static_assert(bounds_type::dynamic_rank > 0 || bounds_type::static_size == 0 || static_assert(bounds_type::dynamic_rank > 0 || bounds_type::static_size == 0 ||
bounds_type::static_size == 1, bounds_type::static_size == 1,
@ -1248,13 +1248,13 @@ public:
} }
// prevent constructing from temporaries for single-elements // prevent constructing from temporaries for single-elements
constexpr span(value_type&&) = delete; constexpr multi_span(value_type&&) = delete;
// construct from pointer + length // construct from pointer + length
constexpr span(pointer ptr, size_type size) noexcept : span(ptr, bounds_type{size}) {} constexpr multi_span(pointer ptr, size_type size) noexcept : multi_span(ptr, bounds_type{size}) {}
// construct from pointer + length - multidimensional // construct from pointer + length - multidimensional
constexpr span(pointer data, bounds_type bounds) noexcept : data_(data), constexpr multi_span(pointer data, bounds_type bounds) noexcept : data_(data),
bounds_(std::move(bounds)) bounds_(std::move(bounds))
{ {
Expects((bounds_.size() > 0 && data != nullptr) || bounds_.size() == 0); Expects((bounds_.size() > 0 && data != nullptr) || bounds_.size() == 0);
@ -1264,60 +1264,60 @@ public:
template <typename Ptr, template <typename Ptr,
typename = std::enable_if_t<std::is_convertible<Ptr, pointer>::value && typename = std::enable_if_t<std::is_convertible<Ptr, pointer>::value &&
details::LessThan<bounds_type::dynamic_rank, 2>::value>> details::LessThan<bounds_type::dynamic_rank, 2>::value>>
constexpr span(pointer begin, Ptr end) constexpr multi_span(pointer begin, Ptr end)
: span(begin, details::newBoundsHelper<bounds_type>(static_cast<pointer>(end) - begin)) : multi_span(begin, details::newBoundsHelper<bounds_type>(static_cast<pointer>(end) - begin))
{ {
Expects(begin != nullptr && end != nullptr && begin <= static_cast<pointer>(end)); Expects(begin != nullptr && end != nullptr && begin <= static_cast<pointer>(end));
} }
// construct from n-dimensions static array // construct from n-dimensions static array
template <typename T, size_t N, typename Helper = details::SpanArrayTraits<T, N>> template <typename T, size_t N, typename Helper = details::SpanArrayTraits<T, N>>
constexpr span(T (&arr)[N]) constexpr multi_span(T (&arr)[N])
: span(reinterpret_cast<pointer>(arr), bounds_type{typename Helper::bounds_type{}}) : multi_span(reinterpret_cast<pointer>(arr), bounds_type{typename Helper::bounds_type{}})
{ {
static_assert( static_assert(
std::is_convertible<typename Helper::value_type(*) [], value_type(*) []>::value, std::is_convertible<typename Helper::value_type(*) [], value_type(*) []>::value,
"Cannot convert from source type to target span type."); "Cannot convert from source type to target multi_span type.");
static_assert(std::is_convertible<typename Helper::bounds_type, bounds_type>::value, static_assert(std::is_convertible<typename Helper::bounds_type, bounds_type>::value,
"Cannot construct a span from an array with fewer elements."); "Cannot construct a multi_span from an array with fewer elements.");
} }
// construct from n-dimensions dynamic array (e.g. new int[m][4]) // construct from n-dimensions dynamic array (e.g. new int[m][4])
// (precedence will be lower than the 1-dimension pointer) // (precedence will be lower than the 1-dimension pointer)
template <typename T, typename Helper = details::SpanArrayTraits<T, dynamic_range>> template <typename T, typename Helper = details::SpanArrayTraits<T, dynamic_range>>
constexpr span(T* const& data, size_type size) constexpr multi_span(T* const& data, size_type size)
: span(reinterpret_cast<pointer>(data), typename Helper::bounds_type{size}) : multi_span(reinterpret_cast<pointer>(data), typename Helper::bounds_type{size})
{ {
static_assert( static_assert(
std::is_convertible<typename Helper::value_type(*) [], value_type(*) []>::value, std::is_convertible<typename Helper::value_type(*) [], value_type(*) []>::value,
"Cannot convert from source type to target span type."); "Cannot convert from source type to target multi_span type.");
} }
// construct from std::array // construct from std::array
template <typename T, size_t N> template <typename T, size_t N>
constexpr span(std::array<T, N>& arr) : span(arr.data(), bounds_type{static_bounds<N>{}}) constexpr multi_span(std::array<T, N>& arr) : multi_span(arr.data(), bounds_type{static_bounds<N>{}})
{ {
static_assert( static_assert(
std::is_convertible<T(*) [], typename std::remove_const_t<value_type>(*) []>::value, std::is_convertible<T(*) [], typename std::remove_const_t<value_type>(*) []>::value,
"Cannot convert from source type to target span type."); "Cannot convert from source type to target multi_span type.");
static_assert(std::is_convertible<static_bounds<N>, bounds_type>::value, static_assert(std::is_convertible<static_bounds<N>, bounds_type>::value,
"You cannot construct a span from a std::array of smaller size."); "You cannot construct a multi_span from a std::array of smaller size.");
} }
// construct from const std::array // construct from const std::array
template <typename T, size_t N> template <typename T, size_t N>
constexpr span(const std::array<std::remove_const_t<value_type>, N>& arr) constexpr multi_span(const std::array<std::remove_const_t<value_type>, N>& arr)
: span(arr.data(), static_bounds<N>()) : multi_span(arr.data(), static_bounds<N>())
{ {
static_assert(std::is_convertible<T(*) [], std::remove_const_t<value_type>>::value, static_assert(std::is_convertible<T(*) [], std::remove_const_t<value_type>>::value,
"Cannot convert from source type to target span type."); "Cannot convert from source type to target multi_span type.");
static_assert(std::is_convertible<static_bounds<N>, bounds_type>::value, static_assert(std::is_convertible<static_bounds<N>, bounds_type>::value,
"You cannot construct a span from a std::array of smaller size."); "You cannot construct a multi_span from a std::array of smaller size.");
} }
// prevent constructing from temporary std::array // prevent constructing from temporary std::array
template <typename T, size_t N> template <typename T, size_t N>
constexpr span(std::array<T, N>&& arr) = delete; constexpr multi_span(std::array<T, N>&& arr) = delete;
// construct from containers // construct from containers
// future: could use contiguous_iterator_traits to identify only contiguous containers // future: could use contiguous_iterator_traits to identify only contiguous containers
@ -1329,8 +1329,8 @@ public:
std::is_same<std::decay_t<decltype(std::declval<Cont>().size(), std::is_same<std::decay_t<decltype(std::declval<Cont>().size(),
*std::declval<Cont>().data())>, *std::declval<Cont>().data())>,
DataType>::value>> DataType>::value>>
constexpr span(Cont& cont) constexpr multi_span(Cont& cont)
: span(static_cast<pointer>(cont.data()), : multi_span(static_cast<pointer>(cont.data()),
details::newBoundsHelper<bounds_type>(narrow_cast<size_type>(cont.size()))) details::newBoundsHelper<bounds_type>(narrow_cast<size_type>(cont.size())))
{ {
} }
@ -1343,33 +1343,33 @@ public:
std::is_same<std::decay_t<decltype(std::declval<Cont>().size(), std::is_same<std::decay_t<decltype(std::declval<Cont>().size(),
*std::declval<Cont>().data())>, *std::declval<Cont>().data())>,
DataType>::value>> DataType>::value>>
explicit constexpr span(Cont&& cont) = delete; explicit constexpr multi_span(Cont&& cont) = delete;
// construct from a convertible span // construct from a convertible multi_span
template <typename OtherValueType, std::ptrdiff_t... OtherDimensions, template <typename OtherValueType, std::ptrdiff_t... OtherDimensions,
typename OtherBounds = static_bounds<OtherDimensions...>, typename OtherBounds = static_bounds<OtherDimensions...>,
typename = std::enable_if_t<std::is_convertible<OtherValueType, ValueType>::value && typename = std::enable_if_t<std::is_convertible<OtherValueType, ValueType>::value &&
std::is_convertible<OtherBounds, bounds_type>::value>> std::is_convertible<OtherBounds, bounds_type>::value>>
constexpr span(span<OtherValueType, OtherDimensions...> other) noexcept : data_(other.data_), constexpr multi_span(multi_span<OtherValueType, OtherDimensions...> other) noexcept : data_(other.data_),
bounds_(other.bounds_) bounds_(other.bounds_)
{ {
} }
// trivial copy and move // trivial copy and move
#ifndef GSL_MSVC_NO_SUPPORT_FOR_MOVE_CTOR_DEFAULT #ifndef GSL_MSVC_NO_SUPPORT_FOR_MOVE_CTOR_DEFAULT
constexpr span(span&&) = default; constexpr multi_span(multi_span&&) = default;
#endif #endif
constexpr span(const span&) = default; constexpr multi_span(const multi_span&) = default;
// trivial assignment // trivial assignment
#ifndef GSL_MSVC_NO_SUPPORT_FOR_MOVE_CTOR_DEFAULT #ifndef GSL_MSVC_NO_SUPPORT_FOR_MOVE_CTOR_DEFAULT
constexpr span& operator=(span&&) = default; constexpr multi_span& operator=(multi_span&&) = default;
#endif #endif
constexpr span& operator=(const span&) = default; constexpr multi_span& operator=(const multi_span&) = default;
// first() - extract the first Count elements into a new span // first() - extract the first Count elements into a new multi_span
template <std::ptrdiff_t Count> template <std::ptrdiff_t Count>
constexpr span<ValueType, Count> first() const noexcept constexpr multi_span<ValueType, Count> first() const noexcept
{ {
static_assert(Count >= 0, "Count must be >= 0."); static_assert(Count >= 0, "Count must be >= 0.");
static_assert(bounds_type::static_size == dynamic_range || static_assert(bounds_type::static_size == dynamic_range ||
@ -1380,16 +1380,16 @@ public:
return {this->data(), Count}; return {this->data(), Count};
} }
// first() - extract the first count elements into a new span // first() - extract the first count elements into a new multi_span
constexpr span<ValueType, dynamic_range> first(size_type count) const noexcept constexpr multi_span<ValueType, dynamic_range> first(size_type count) const noexcept
{ {
Expects(count >= 0 && count <= this->size()); Expects(count >= 0 && count <= this->size());
return {this->data(), count}; return {this->data(), count};
} }
// last() - extract the last Count elements into a new span // last() - extract the last Count elements into a new multi_span
template <std::ptrdiff_t Count> template <std::ptrdiff_t Count>
constexpr span<ValueType, Count> last() const noexcept constexpr multi_span<ValueType, Count> last() const noexcept
{ {
static_assert(Count >= 0, "Count must be >= 0."); static_assert(Count >= 0, "Count must be >= 0.");
static_assert(bounds_type::static_size == dynamic_range || static_assert(bounds_type::static_size == dynamic_range ||
@ -1400,8 +1400,8 @@ public:
return {this->data() + this->size() - Count, Count}; return {this->data() + this->size() - Count, Count};
} }
// last() - extract the last count elements into a new span // last() - extract the last count elements into a new multi_span
constexpr span<ValueType, dynamic_range> last(size_type count) const noexcept constexpr multi_span<ValueType, dynamic_range> last(size_type count) const noexcept
{ {
Expects(count >= 0 && count <= this->size()); Expects(count >= 0 && count <= this->size());
return {this->data() + this->size() - count, count}; return {this->data() + this->size() - count, count};
@ -1409,14 +1409,14 @@ public:
// subspan() - create a subview of Count elements starting at Offset // subspan() - create a subview of Count elements starting at Offset
template <std::ptrdiff_t Offset, std::ptrdiff_t Count> template <std::ptrdiff_t Offset, std::ptrdiff_t Count>
constexpr span<ValueType, Count> subspan() const noexcept constexpr multi_span<ValueType, Count> subspan() const noexcept
{ {
static_assert(Count >= 0, "Count must be >= 0."); static_assert(Count >= 0, "Count must be >= 0.");
static_assert(Offset >= 0, "Offset must be >= 0."); static_assert(Offset >= 0, "Offset must be >= 0.");
static_assert(bounds_type::static_size == dynamic_range || static_assert(bounds_type::static_size == dynamic_range ||
((Offset <= bounds_type::static_size) && ((Offset <= bounds_type::static_size) &&
Count <= bounds_type::static_size - Offset), Count <= bounds_type::static_size - Offset),
"You must describe a sub-range within bounds of the span."); "You must describe a sub-range within bounds of the multi_span.");
Expects(bounds_type::static_size != dynamic_range || Expects(bounds_type::static_size != dynamic_range ||
(Offset <= this->size() && Count <= this->size() - Offset)); (Offset <= this->size() && Count <= this->size() - Offset));
@ -1425,7 +1425,7 @@ public:
// subspan() - create a subview of count elements starting at offset // subspan() - create a subview of count elements starting at offset
// supplying dynamic_range for count will consume all available elements from offset // supplying dynamic_range for count will consume all available elements from offset
constexpr span<ValueType, dynamic_range> subspan(size_type offset, constexpr multi_span<ValueType, dynamic_range> subspan(size_type offset,
size_type count = dynamic_range) const noexcept size_type count = dynamic_range) const noexcept
{ {
Expects((offset >= 0 && offset <= this->size()) && Expects((offset >= 0 && offset <= this->size()) &&
@ -1433,7 +1433,7 @@ public:
return {this->data() + offset, count == dynamic_range ? this->length() - offset : count}; return {this->data() + offset, count == dynamic_range ? this->length() - offset : count};
} }
// section - creates a non-contiguous, strided span from a contiguous one // section - creates a non-contiguous, strided multi_span from a contiguous one
constexpr strided_span<ValueType, Rank> section(index_type origin, index_type extents) const constexpr strided_span<ValueType, Rank> section(index_type origin, index_type extents) const
noexcept noexcept
{ {
@ -1442,16 +1442,16 @@ public:
strided_bounds<Rank>{extents, details::make_stride(bounds())}}; strided_bounds<Rank>{extents, details::make_stride(bounds())}};
} }
// length of the span in elements // length of the multi_span in elements
constexpr size_type size() const noexcept { return bounds_.size(); } constexpr size_type size() const noexcept { return bounds_.size(); }
// length of the span in elements // length of the multi_span in elements
constexpr size_type length() const noexcept { return this->size(); } constexpr size_type length() const noexcept { return this->size(); }
// length of the span in bytes // length of the multi_span in bytes
constexpr size_type size_bytes() const noexcept { return sizeof(value_type) * this->size(); } constexpr size_type size_bytes() const noexcept { return sizeof(value_type) * this->size(); }
// length of the span in bytes // length of the multi_span in bytes
constexpr size_type length_bytes() const noexcept { return this->size_bytes(); } constexpr size_type length_bytes() const noexcept { return this->size_bytes(); }
constexpr bool empty() const noexcept { return this->size() == 0; } constexpr bool empty() const noexcept { return this->size() == 0; }
@ -1537,7 +1537,7 @@ public:
template <typename OtherValueType, std::ptrdiff_t... OtherDimensions, template <typename OtherValueType, std::ptrdiff_t... OtherDimensions,
typename Dummy = std::enable_if_t<std::is_same< typename Dummy = std::enable_if_t<std::is_same<
std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>> std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>>
constexpr bool operator==(const span<OtherValueType, OtherDimensions...>& other) const noexcept constexpr bool operator==(const multi_span<OtherValueType, OtherDimensions...>& other) const noexcept
{ {
return bounds_.size() == other.bounds_.size() && return bounds_.size() == other.bounds_.size() &&
(data_ == other.data_ || std::equal(this->begin(), this->end(), other.begin())); (data_ == other.data_ || std::equal(this->begin(), this->end(), other.begin()));
@ -1546,7 +1546,7 @@ public:
template <typename OtherValueType, std::ptrdiff_t... OtherDimensions, template <typename OtherValueType, std::ptrdiff_t... OtherDimensions,
typename Dummy = std::enable_if_t<std::is_same< typename Dummy = std::enable_if_t<std::is_same<
std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>> std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>>
constexpr bool operator!=(const span<OtherValueType, OtherDimensions...>& other) const noexcept constexpr bool operator!=(const multi_span<OtherValueType, OtherDimensions...>& other) const noexcept
{ {
return !(*this == other); return !(*this == other);
} }
@ -1554,7 +1554,7 @@ public:
template <typename OtherValueType, std::ptrdiff_t... OtherDimensions, template <typename OtherValueType, std::ptrdiff_t... OtherDimensions,
typename Dummy = std::enable_if_t<std::is_same< typename Dummy = std::enable_if_t<std::is_same<
std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>> std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>>
constexpr bool operator<(const span<OtherValueType, OtherDimensions...>& other) const noexcept constexpr bool operator<(const multi_span<OtherValueType, OtherDimensions...>& other) const noexcept
{ {
return std::lexicographical_compare(this->begin(), this->end(), other.begin(), other.end()); return std::lexicographical_compare(this->begin(), this->end(), other.begin(), other.end());
} }
@ -1562,7 +1562,7 @@ public:
template <typename OtherValueType, std::ptrdiff_t... OtherDimensions, template <typename OtherValueType, std::ptrdiff_t... OtherDimensions,
typename Dummy = std::enable_if_t<std::is_same< typename Dummy = std::enable_if_t<std::is_same<
std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>> std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>>
constexpr bool operator<=(const span<OtherValueType, OtherDimensions...>& other) const noexcept constexpr bool operator<=(const multi_span<OtherValueType, OtherDimensions...>& other) const noexcept
{ {
return !(other < *this); return !(other < *this);
} }
@ -1570,7 +1570,7 @@ public:
template <typename OtherValueType, std::ptrdiff_t... OtherDimensions, template <typename OtherValueType, std::ptrdiff_t... OtherDimensions,
typename Dummy = std::enable_if_t<std::is_same< typename Dummy = std::enable_if_t<std::is_same<
std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>> std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>>
constexpr bool operator>(const span<OtherValueType, OtherDimensions...>& other) const noexcept constexpr bool operator>(const multi_span<OtherValueType, OtherDimensions...>& other) const noexcept
{ {
return (other < *this); return (other < *this);
} }
@ -1578,7 +1578,7 @@ public:
template <typename OtherValueType, std::ptrdiff_t... OtherDimensions, template <typename OtherValueType, std::ptrdiff_t... OtherDimensions,
typename Dummy = std::enable_if_t<std::is_same< typename Dummy = std::enable_if_t<std::is_same<
std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>> std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>>
constexpr bool operator>=(const span<OtherValueType, OtherDimensions...>& other) const noexcept constexpr bool operator>=(const multi_span<OtherValueType, OtherDimensions...>& other) const noexcept
{ {
return !(*this < other); return !(*this < other);
} }
@ -1588,57 +1588,57 @@ public:
// Free functions for manipulating spans // Free functions for manipulating spans
// //
// reshape a span into a different dimensionality // reshape a multi_span into a different dimensionality
// DimCount and Enabled here are workarounds for a bug in MSVC 2015 // DimCount and Enabled here are workarounds for a bug in MSVC 2015
template <typename SpanType, typename... Dimensions2, size_t DimCount = sizeof...(Dimensions2), template <typename SpanType, typename... Dimensions2, size_t DimCount = sizeof...(Dimensions2),
bool Enabled = (DimCount > 0), typename = std::enable_if_t<Enabled>> bool Enabled = (DimCount > 0), typename = std::enable_if_t<Enabled>>
constexpr span<typename SpanType::value_type, Dimensions2::value...> as_span(SpanType s, constexpr multi_span<typename SpanType::value_type, Dimensions2::value...> as_span(SpanType s,
Dimensions2... dims) Dimensions2... dims)
{ {
static_assert(details::is_span<SpanType>::value, static_assert(details::is_span<SpanType>::value,
"Variadic as_span() is for reshaping existing spans."); "Variadic as_span() is for reshaping existing spans.");
using BoundsType = using BoundsType =
typename span<typename SpanType::value_type, (Dimensions2::value)...>::bounds_type; typename multi_span<typename SpanType::value_type, (Dimensions2::value)...>::bounds_type;
auto tobounds = details::static_as_span_helper<BoundsType>(dims..., details::Sep{}); auto tobounds = details::static_as_span_helper<BoundsType>(dims..., details::Sep{});
details::verifyBoundsReshape(s.bounds(), tobounds); details::verifyBoundsReshape(s.bounds(), tobounds);
return {s.data(), tobounds}; return {s.data(), tobounds};
} }
// convert a span<T> to a span<const byte> // convert a multi_span<T> to a multi_span<const byte>
template <typename U, std::ptrdiff_t... Dimensions> template <typename U, std::ptrdiff_t... Dimensions>
span<const byte, dynamic_range> as_bytes(span<U, Dimensions...> s) noexcept multi_span<const byte, dynamic_range> as_bytes(multi_span<U, Dimensions...> s) noexcept
{ {
static_assert(std::is_trivial<std::decay_t<U>>::value, static_assert(std::is_trivial<std::decay_t<U>>::value,
"The value_type of span must be a trivial type."); "The value_type of multi_span must be a trivial type.");
return {reinterpret_cast<const byte*>(s.data()), s.size_bytes()}; return {reinterpret_cast<const byte*>(s.data()), s.size_bytes()};
} }
// convert a span<T> to a span<byte> (a writeable byte span) // convert a multi_span<T> to a multi_span<byte> (a writeable byte multi_span)
// this is not currently a portable function that can be relied upon to work // this is not currently a portable function that can be relied upon to work
// on all implementations. It should be considered an experimental extension // on all implementations. It should be considered an experimental extension
// to the standard GSL interface. // to the standard GSL interface.
template <typename U, std::ptrdiff_t... Dimensions> template <typename U, std::ptrdiff_t... Dimensions>
span<byte> as_writeable_bytes(span<U, Dimensions...> s) noexcept multi_span<byte> as_writeable_bytes(multi_span<U, Dimensions...> s) noexcept
{ {
static_assert(std::is_trivial<std::decay_t<U>>::value, static_assert(std::is_trivial<std::decay_t<U>>::value,
"The value_type of span must be a trivial type."); "The value_type of multi_span must be a trivial type.");
return {reinterpret_cast<byte*>(s.data()), s.size_bytes()}; return {reinterpret_cast<byte*>(s.data()), s.size_bytes()};
} }
// convert a span<const byte> to a span<const T> // convert a multi_span<const byte> to a multi_span<const T>
// this is not currently a portable function that can be relied upon to work // this is not currently a portable function that can be relied upon to work
// on all implementations. It should be considered an experimental extension // on all implementations. It should be considered an experimental extension
// to the standard GSL interface. // to the standard GSL interface.
template <typename U, std::ptrdiff_t... Dimensions> template <typename U, std::ptrdiff_t... Dimensions>
constexpr auto as_span(span<const byte, Dimensions...> s) noexcept constexpr auto as_span(multi_span<const byte, Dimensions...> s) noexcept
-> span<const U, static_cast<std::ptrdiff_t>( -> multi_span<const U, static_cast<std::ptrdiff_t>(
span<const byte, Dimensions...>::bounds_type::static_size != dynamic_range multi_span<const byte, Dimensions...>::bounds_type::static_size != dynamic_range
? (static_cast<size_t>( ? (static_cast<size_t>(
span<const byte, Dimensions...>::bounds_type::static_size) / multi_span<const byte, Dimensions...>::bounds_type::static_size) /
sizeof(U)) sizeof(U))
: dynamic_range)> : dynamic_range)>
{ {
using ConstByteSpan = span<const byte, Dimensions...>; using ConstByteSpan = multi_span<const byte, Dimensions...>;
static_assert( static_assert(
std::is_trivial<std::decay_t<U>>::value && std::is_trivial<std::decay_t<U>>::value &&
(ConstByteSpan::bounds_type::static_size == dynamic_range || (ConstByteSpan::bounds_type::static_size == dynamic_range ||
@ -1650,19 +1650,19 @@ constexpr auto as_span(span<const byte, Dimensions...> s) noexcept
s.size_bytes() / narrow_cast<std::ptrdiff_t>(sizeof(U))}; s.size_bytes() / narrow_cast<std::ptrdiff_t>(sizeof(U))};
} }
// convert a span<byte> to a span<T> // convert a multi_span<byte> to a multi_span<T>
// this is not currently a portable function that can be relied upon to work // this is not currently a portable function that can be relied upon to work
// on all implementations. It should be considered an experimental extension // on all implementations. It should be considered an experimental extension
// to the standard GSL interface. // to the standard GSL interface.
template <typename U, std::ptrdiff_t... Dimensions> template <typename U, std::ptrdiff_t... Dimensions>
constexpr auto as_span(span<byte, Dimensions...> s) noexcept -> span< constexpr auto as_span(multi_span<byte, Dimensions...> s) noexcept -> multi_span<
U, narrow_cast<std::ptrdiff_t>( U, narrow_cast<std::ptrdiff_t>(
span<byte, Dimensions...>::bounds_type::static_size != dynamic_range multi_span<byte, Dimensions...>::bounds_type::static_size != dynamic_range
? static_cast<std::size_t>(span<byte, Dimensions...>::bounds_type::static_size) / ? static_cast<std::size_t>(multi_span<byte, Dimensions...>::bounds_type::static_size) /
sizeof(U) sizeof(U)
: dynamic_range)> : dynamic_range)>
{ {
using ByteSpan = span<byte, Dimensions...>; using ByteSpan = multi_span<byte, Dimensions...>;
static_assert( static_assert(
std::is_trivial<std::decay_t<U>>::value && std::is_trivial<std::decay_t<U>>::value &&
(ByteSpan::bounds_type::static_size == dynamic_range || (ByteSpan::bounds_type::static_size == dynamic_range ||
@ -1676,7 +1676,7 @@ constexpr auto as_span(span<byte, Dimensions...> s) noexcept -> span<
template <typename T, std::ptrdiff_t... Dimensions> template <typename T, std::ptrdiff_t... Dimensions>
constexpr auto as_span(T* const& ptr, dim<Dimensions>... args) constexpr auto as_span(T* const& ptr, dim<Dimensions>... args)
-> span<std::remove_all_extents_t<T>, Dimensions...> -> multi_span<std::remove_all_extents_t<T>, Dimensions...>
{ {
return {reinterpret_cast<std::remove_all_extents_t<T>*>(ptr), return {reinterpret_cast<std::remove_all_extents_t<T>*>(ptr),
details::static_as_span_helper<static_bounds<Dimensions...>>(args..., details::Sep{})}; details::static_as_span_helper<static_bounds<Dimensions...>>(args..., details::Sep{})};
@ -1696,22 +1696,22 @@ constexpr auto as_span(T (&arr)[N]) -> typename details::SpanArrayTraits<T, N>::
} }
template <typename T, size_t N> template <typename T, size_t N>
constexpr span<const T, N> as_span(const std::array<T, N>& arr) constexpr multi_span<const T, N> as_span(const std::array<T, N>& arr)
{ {
return {arr}; return {arr};
} }
template <typename T, size_t N> template <typename T, size_t N>
constexpr span<const T, N> as_span(const std::array<T, N>&&) = delete; constexpr multi_span<const T, N> as_span(const std::array<T, N>&&) = delete;
template <typename T, size_t N> template <typename T, size_t N>
constexpr span<T, N> as_span(std::array<T, N>& arr) constexpr multi_span<T, N> as_span(std::array<T, N>& arr)
{ {
return {arr}; return {arr};
} }
template <typename T> template <typename T>
constexpr span<T, dynamic_range> as_span(T* begin, T* end) constexpr multi_span<T, dynamic_range> as_span(T* begin, T* end)
{ {
return {begin, end}; return {begin, end};
} }
@ -1719,7 +1719,7 @@ constexpr span<T, dynamic_range> as_span(T* begin, T* end)
template <typename Cont> template <typename Cont>
constexpr auto as_span(Cont& arr) -> std::enable_if_t< constexpr auto as_span(Cont& arr) -> std::enable_if_t<
!details::is_span<std::decay_t<Cont>>::value, !details::is_span<std::decay_t<Cont>>::value,
span<std::remove_reference_t<decltype(arr.size(), *arr.data())>, dynamic_range>> multi_span<std::remove_reference_t<decltype(arr.size(), *arr.data())>, dynamic_range>>
{ {
Expects(arr.size() < PTRDIFF_MAX); Expects(arr.size() < PTRDIFF_MAX);
return {arr.data(), narrow_cast<std::ptrdiff_t>(arr.size())}; return {arr.data(), narrow_cast<std::ptrdiff_t>(arr.size())};
@ -1728,12 +1728,12 @@ constexpr auto as_span(Cont& arr) -> std::enable_if_t<
template <typename Cont> template <typename Cont>
constexpr auto as_span(Cont&& arr) -> std::enable_if_t< constexpr auto as_span(Cont&& arr) -> std::enable_if_t<
!details::is_span<std::decay_t<Cont>>::value, !details::is_span<std::decay_t<Cont>>::value,
span<std::remove_reference_t<decltype(arr.size(), *arr.data())>, dynamic_range>> = delete; multi_span<std::remove_reference_t<decltype(arr.size(), *arr.data())>, dynamic_range>> = delete;
// from basic_string which doesn't have nonconst .data() member like other contiguous containers // from basic_string which doesn't have nonconst .data() member like other contiguous containers
template <typename CharT, typename Traits, typename Allocator> template <typename CharT, typename Traits, typename Allocator>
constexpr auto as_span(std::basic_string<CharT, Traits, Allocator>& str) constexpr auto as_span(std::basic_string<CharT, Traits, Allocator>& str)
-> span<CharT, dynamic_range> -> multi_span<CharT, dynamic_range>
{ {
Expects(str.size() < PTRDIFF_MAX); Expects(str.size() < PTRDIFF_MAX);
return {&str[0], narrow_cast<std::ptrdiff_t>(str.size())}; return {&str[0], narrow_cast<std::ptrdiff_t>(str.size())};
@ -1792,7 +1792,7 @@ public:
bool Enabled1 = (sizeof...(Dimensions) == Rank), bool Enabled1 = (sizeof...(Dimensions) == Rank),
bool Enabled2 = std::is_convertible<OtherValueType*, ValueType*>::value, bool Enabled2 = std::is_convertible<OtherValueType*, ValueType*>::value,
typename Dummy = std::enable_if_t<Enabled1 && Enabled2>> typename Dummy = std::enable_if_t<Enabled1 && Enabled2>>
constexpr strided_span(span<OtherValueType, Dimensions...> av, bounds_type bounds) constexpr strided_span(multi_span<OtherValueType, Dimensions...> av, bounds_type bounds)
: strided_span(av.data(), av.bounds().total_size(), std::move(bounds)) : strided_span(av.data(), av.bounds().total_size(), std::move(bounds))
{ {
} }
@ -1988,7 +1988,7 @@ public:
private: private:
template <typename ValueType, std::ptrdiff_t FirstDimension, std::ptrdiff_t... RestDimensions> template <typename ValueType, std::ptrdiff_t FirstDimension, std::ptrdiff_t... RestDimensions>
friend class span; friend class multi_span;
pointer data_; pointer data_;
const Span* m_validator; const Span* m_validator;

View File

@ -96,7 +96,7 @@ using wzstring = basic_zstring<wchar_t, Extent>;
// Will fail-fast if sentinel cannot be found before max elements are examined. // Will fail-fast if sentinel cannot be found before max elements are examined.
// //
template<typename T, const T Sentinel> template<typename T, const T Sentinel>
span<T, dynamic_range> ensure_sentinel(T* seq, std::ptrdiff_t max = PTRDIFF_MAX) multi_span<T, dynamic_range> ensure_sentinel(T* seq, std::ptrdiff_t max = PTRDIFF_MAX)
{ {
auto cur = seq; auto cur = seq;
while ((cur - seq) < max && *cur != Sentinel) ++cur; while ((cur - seq) < max && *cur != Sentinel) ++cur;
@ -111,34 +111,34 @@ span<T, dynamic_range> ensure_sentinel(T* seq, std::ptrdiff_t max = PTRDIFF_MAX)
// the limit of size_type. // the limit of size_type.
// //
template<typename T> template<typename T>
inline span<T, dynamic_range> ensure_z(T* const & sz, std::ptrdiff_t max = PTRDIFF_MAX) inline multi_span<T, dynamic_range> ensure_z(T* const & sz, std::ptrdiff_t max = PTRDIFF_MAX)
{ {
return ensure_sentinel<T, 0>(sz, max); return ensure_sentinel<T, 0>(sz, max);
} }
// TODO (neilmac) there is probably a better template-magic way to get the const and non-const overloads to share an implementation // TODO (neilmac) there is probably a better template-magic way to get the const and non-const overloads to share an implementation
inline span<char, dynamic_range> ensure_z(char* const& sz, std::ptrdiff_t max) inline multi_span<char, dynamic_range> ensure_z(char* const& sz, std::ptrdiff_t max)
{ {
auto len = strnlen(sz, narrow_cast<size_t>(max)); auto len = strnlen(sz, narrow_cast<size_t>(max));
Ensures(sz[len] == 0); Ensures(sz[len] == 0);
return{ sz, static_cast<std::ptrdiff_t>(len) }; return{ sz, static_cast<std::ptrdiff_t>(len) };
} }
inline span<const char, dynamic_range> ensure_z(const char* const& sz, std::ptrdiff_t max) inline multi_span<const char, dynamic_range> ensure_z(const char* const& sz, std::ptrdiff_t max)
{ {
auto len = strnlen(sz, narrow_cast<size_t>(max)); auto len = strnlen(sz, narrow_cast<size_t>(max));
Ensures(sz[len] == 0); Ensures(sz[len] == 0);
return{ sz, static_cast<std::ptrdiff_t>(len) }; return{ sz, static_cast<std::ptrdiff_t>(len) };
} }
inline span<wchar_t, dynamic_range> ensure_z(wchar_t* const& sz, std::ptrdiff_t max) inline multi_span<wchar_t, dynamic_range> ensure_z(wchar_t* const& sz, std::ptrdiff_t max)
{ {
auto len = wcsnlen(sz, narrow_cast<size_t>(max)); auto len = wcsnlen(sz, narrow_cast<size_t>(max));
Ensures(sz[len] == 0); Ensures(sz[len] == 0);
return{ sz, static_cast<std::ptrdiff_t>(len) }; return{ sz, static_cast<std::ptrdiff_t>(len) };
} }
inline span<const wchar_t, dynamic_range> ensure_z(const wchar_t* const& sz, std::ptrdiff_t max) inline multi_span<const wchar_t, dynamic_range> ensure_z(const wchar_t* const& sz, std::ptrdiff_t max)
{ {
auto len = wcsnlen(sz, narrow_cast<size_t>(max)); auto len = wcsnlen(sz, narrow_cast<size_t>(max));
Ensures(sz[len] == 0); Ensures(sz[len] == 0);
@ -146,10 +146,10 @@ inline span<const wchar_t, dynamic_range> ensure_z(const wchar_t* const& sz, std
} }
template<typename T, size_t N> template<typename T, size_t N>
span<T, dynamic_range> ensure_z(T(&sz)[N]) { return ensure_z(&sz[0], static_cast<std::ptrdiff_t>(N)); } multi_span<T, dynamic_range> ensure_z(T(&sz)[N]) { return ensure_z(&sz[0], static_cast<std::ptrdiff_t>(N)); }
template<class Cont> template<class Cont>
span<typename std::remove_pointer<typename Cont::pointer>::type, dynamic_range> ensure_z(Cont& cont) multi_span<typename std::remove_pointer<typename Cont::pointer>::type, dynamic_range> ensure_z(Cont& cont)
{ {
return ensure_z(cont.data(), static_cast<std::ptrdiff_t>(cont.length())); return ensure_z(cont.data(), static_cast<std::ptrdiff_t>(cont.length()));
} }
@ -228,7 +228,7 @@ public:
using reference = std::add_lvalue_reference_t<value_type>; using reference = std::add_lvalue_reference_t<value_type>;
using const_reference = std::add_lvalue_reference_t<const_value_type>; using const_reference = std::add_lvalue_reference_t<const_value_type>;
using bounds_type = static_bounds<Extent>; using bounds_type = static_bounds<Extent>;
using impl_type = span<value_type, Extent>; using impl_type = multi_span<value_type, Extent>;
using size_type = ptrdiff_t; using size_type = ptrdiff_t;
using iterator = typename impl_type::iterator; using iterator = typename impl_type::iterator;
@ -323,17 +323,17 @@ public:
std::is_convertible<OtherValueType*, value_type*>::value std::is_convertible<OtherValueType*, value_type*>::value
&& std::is_convertible<static_bounds<OtherExtent>, bounds_type>::value> && std::is_convertible<static_bounds<OtherExtent>, bounds_type>::value>
> >
constexpr basic_string_span(span<OtherValueType, OtherExtent> other) noexcept constexpr basic_string_span(multi_span<OtherValueType, OtherExtent> other) noexcept
: span_(other) : span_(other)
{} {}
#else #else
// from span // from span
constexpr basic_string_span(span<value_type, Extent> other) noexcept constexpr basic_string_span(multi_span<value_type, Extent> other) noexcept
: span_(other) : span_(other)
{} {}
template <typename Dummy = std::enable_if_t<!std::is_same<std::remove_const_t<value_type>, value_type>::value>> template <typename Dummy = std::enable_if_t<!std::is_same<std::remove_const_t<value_type>, value_type>::value>>
constexpr basic_string_span(span<std::remove_const_t<value_type>, Extent> other) noexcept constexpr basic_string_span(multi_span<std::remove_const_t<value_type>, Extent> other) noexcept
: span_(other) : span_(other)
{} {}
#endif #endif
@ -540,14 +540,14 @@ public:
using zstring_type = basic_zstring<value_type, Extent>; using zstring_type = basic_zstring<value_type, Extent>;
using const_zstring_type = basic_zstring<const_value_type, Extent>; using const_zstring_type = basic_zstring<const_value_type, Extent>;
using impl_type = span<value_type, Extent>; using impl_type = multi_span<value_type, Extent>;
using string_span_type = basic_string_span<value_type, Extent>; using string_span_type = basic_string_span<value_type, Extent>;
constexpr basic_zstring_span(impl_type span) noexcept constexpr basic_zstring_span(impl_type multi_span) noexcept
: span_(span) : span_(multi_span)
{ {
// expects a zero-terminated span // expects a zero-terminated span
Expects(span[span.size() - 1] == '\0'); Expects(multi_span[multi_span.size() - 1] == '\0');
} }
// copy // copy

View File

@ -58,7 +58,7 @@ SUITE(bounds_test)
auto itr = bounds.begin(); auto itr = bounds.begin();
(void)itr; (void)itr;
#ifdef CONFIRM_COMPILATION_ERRORS #ifdef CONFIRM_COMPILATION_ERRORS
span<int, 4, dynamic_range, 2> av(nullptr, bounds); multi_span<int, 4, dynamic_range, 2> av(nullptr, bounds);
auto itr2 = av.cbegin(); auto itr2 = av.cbegin();

File diff suppressed because it is too large Load Diff

View File

@ -49,7 +49,7 @@ SUITE(strided_span_tests)
{ {
std::vector<int> data(5 * 10); std::vector<int> data(5 * 10);
std::iota(begin(data), end(data), 0); std::iota(begin(data), end(data), 0);
const span<int, 5, 10> av = as_span(span<int>{data}, dim<5>(), dim<10>()); const multi_span<int, 5, 10> av = as_span(multi_span<int>{data}, dim<5>(), dim<10>());
strided_span<int, 2> av_section_1 = av.section({ 1, 2 }, { 3, 4 }); strided_span<int, 2> av_section_1 = av.section({ 1, 2 }, { 3, 4 });
CHECK((av_section_1[{0, 0}] == 12)); CHECK((av_section_1[{0, 0}] == 12));
@ -87,13 +87,13 @@ SUITE(strided_span_tests)
CHECK((sav3[{0, 0}] == 1 && sav3[{0, 1}] == 3 && sav3[{1, 0}] == 7)); CHECK((sav3[{0, 0}] == 1 && sav3[{0, 1}] == 3 && sav3[{1, 0}] == 7));
} }
// Check span constructor // Check multi_span constructor
{ {
int arr[] = { 1, 2 }; int arr[] = { 1, 2 };
// From non-cv-qualified source // From non-cv-qualified source
{ {
const span<int> src = arr; const multi_span<int> src = arr;
strided_span<int, 1> sav{ src, {2, 1} }; strided_span<int, 1> sav{ src, {2, 1} };
CHECK(sav.bounds().index_bounds() == index<1>{ 2 }); CHECK(sav.bounds().index_bounds() == index<1>{ 2 });
@ -102,9 +102,9 @@ SUITE(strided_span_tests)
#if _MSC_VER > 1800 #if _MSC_VER > 1800
//strided_span<const int, 1> sav_c{ {src}, {2, 1} }; //strided_span<const int, 1> sav_c{ {src}, {2, 1} };
strided_span<const int, 1> sav_c{ span<const int>{src}, strided_bounds<1>{2, 1} }; strided_span<const int, 1> sav_c{ multi_span<const int>{src}, strided_bounds<1>{2, 1} };
#else #else
strided_span<const int, 1> sav_c{ span<const int>{src}, strided_bounds<1>{2, 1} }; strided_span<const int, 1> sav_c{ multi_span<const int>{src}, strided_bounds<1>{2, 1} };
#endif #endif
CHECK(sav_c.bounds().index_bounds() == index<1>{ 2 }); CHECK(sav_c.bounds().index_bounds() == index<1>{ 2 });
CHECK(sav_c.bounds().strides() == index<1>{ 1 }); CHECK(sav_c.bounds().strides() == index<1>{ 1 });
@ -113,7 +113,7 @@ SUITE(strided_span_tests)
#if _MSC_VER > 1800 #if _MSC_VER > 1800
strided_span<volatile int, 1> sav_v{ src, {2, 1} }; strided_span<volatile int, 1> sav_v{ src, {2, 1} };
#else #else
strided_span<volatile int, 1> sav_v{ span<volatile int>{src}, strided_bounds<1>{2, 1} }; strided_span<volatile int, 1> sav_v{ multi_span<volatile int>{src}, strided_bounds<1>{2, 1} };
#endif #endif
CHECK(sav_v.bounds().index_bounds() == index<1>{ 2 }); CHECK(sav_v.bounds().index_bounds() == index<1>{ 2 });
CHECK(sav_v.bounds().strides() == index<1>{ 1 }); CHECK(sav_v.bounds().strides() == index<1>{ 1 });
@ -122,7 +122,7 @@ SUITE(strided_span_tests)
#if _MSC_VER > 1800 #if _MSC_VER > 1800
strided_span<const volatile int, 1> sav_cv{ src, {2, 1} }; strided_span<const volatile int, 1> sav_cv{ src, {2, 1} };
#else #else
strided_span<const volatile int, 1> sav_cv{ span<const volatile int>{src}, strided_bounds<1>{2, 1} }; strided_span<const volatile int, 1> sav_cv{ multi_span<const volatile int>{src}, strided_bounds<1>{2, 1} };
#endif #endif
CHECK(sav_cv.bounds().index_bounds() == index<1>{ 2 }); CHECK(sav_cv.bounds().index_bounds() == index<1>{ 2 });
CHECK(sav_cv.bounds().strides() == index<1>{ 1 }); CHECK(sav_cv.bounds().strides() == index<1>{ 1 });
@ -131,7 +131,7 @@ SUITE(strided_span_tests)
// From const-qualified source // From const-qualified source
{ {
const span<const int> src{ arr }; const multi_span<const int> src{ arr };
strided_span<const int, 1> sav_c{ src, {2, 1} }; strided_span<const int, 1> sav_c{ src, {2, 1} };
CHECK(sav_c.bounds().index_bounds() == index<1>{ 2 }); CHECK(sav_c.bounds().index_bounds() == index<1>{ 2 });
@ -141,7 +141,7 @@ SUITE(strided_span_tests)
#if _MSC_VER > 1800 #if _MSC_VER > 1800
strided_span<const volatile int, 1> sav_cv{ src, {2, 1} }; strided_span<const volatile int, 1> sav_cv{ src, {2, 1} };
#else #else
strided_span<const volatile int, 1> sav_cv{ span<const volatile int>{src}, strided_bounds<1>{2, 1} }; strided_span<const volatile int, 1> sav_cv{ multi_span<const volatile int>{src}, strided_bounds<1>{2, 1} };
#endif #endif
CHECK(sav_cv.bounds().index_bounds() == index<1>{ 2 }); CHECK(sav_cv.bounds().index_bounds() == index<1>{ 2 });
@ -151,7 +151,7 @@ SUITE(strided_span_tests)
// From volatile-qualified source // From volatile-qualified source
{ {
const span<volatile int> src{ arr }; const multi_span<volatile int> src{ arr };
strided_span<volatile int, 1> sav_v{ src, {2, 1} }; strided_span<volatile int, 1> sav_v{ src, {2, 1} };
CHECK(sav_v.bounds().index_bounds() == index<1>{ 2 }); CHECK(sav_v.bounds().index_bounds() == index<1>{ 2 });
@ -161,7 +161,7 @@ SUITE(strided_span_tests)
#if _MSC_VER > 1800 #if _MSC_VER > 1800
strided_span<const volatile int, 1> sav_cv{ src, {2, 1} }; strided_span<const volatile int, 1> sav_cv{ src, {2, 1} };
#else #else
strided_span<const volatile int, 1> sav_cv{ span<const volatile int>{src}, strided_bounds<1>{2, 1} }; strided_span<const volatile int, 1> sav_cv{ multi_span<const volatile int>{src}, strided_bounds<1>{2, 1} };
#endif #endif
CHECK(sav_cv.bounds().index_bounds() == index<1>{ 2 }); CHECK(sav_cv.bounds().index_bounds() == index<1>{ 2 });
CHECK(sav_cv.bounds().strides() == index<1>{ 1 }); CHECK(sav_cv.bounds().strides() == index<1>{ 1 });
@ -170,7 +170,7 @@ SUITE(strided_span_tests)
// From cv-qualified source // From cv-qualified source
{ {
const span<const volatile int> src{ arr }; const multi_span<const volatile int> src{ arr };
strided_span<const volatile int, 1> sav_cv{ src, {2, 1} }; strided_span<const volatile int, 1> sav_cv{ src, {2, 1} };
CHECK(sav_cv.bounds().index_bounds() == index<1>{ 2 }); CHECK(sav_cv.bounds().index_bounds() == index<1>{ 2 });
@ -183,11 +183,11 @@ SUITE(strided_span_tests)
{ {
int arr[2] = { 4, 5 }; int arr[2] = { 4, 5 };
const span<int, 2> av(arr, 2); const multi_span<int, 2> av(arr, 2);
span<const int, 2> av2{ av }; multi_span<const int, 2> av2{ av };
CHECK(av2[1] == 5); CHECK(av2[1] == 5);
static_assert(std::is_convertible<const span<int, 2>, span<const int, 2>>::value, "ctor is not implicit!"); static_assert(std::is_convertible<const multi_span<int, 2>, multi_span<const int, 2>>::value, "ctor is not implicit!");
const strided_span<int, 1> src{ arr, {2, 1} }; const strided_span<int, 1> src{ arr, {2, 1} };
strided_span<const int, 1> sav{ src }; strided_span<const int, 1> sav{ src };
@ -258,13 +258,13 @@ SUITE(strided_span_tests)
{ {
std::vector<int> data(5 * 10); std::vector<int> data(5 * 10);
std::iota(begin(data), end(data), 0); std::iota(begin(data), end(data), 0);
const span<int, 5, 10> src = as_span(span<int>{data}, dim<5>(), dim<10>()); const multi_span<int, 5, 10> src = as_span(multi_span<int>{data}, dim<5>(), dim<10>());
const strided_span<int, 2> sav{ src, {{5, 10}, {10, 1}} }; const strided_span<int, 2> sav{ src, {{5, 10}, {10, 1}} };
#ifdef CONFIRM_COMPILATION_ERRORS #ifdef CONFIRM_COMPILATION_ERRORS
const strided_span<const int, 2> csav{ {src},{ { 5, 10 },{ 10, 1 } } }; const strided_span<const int, 2> csav{ {src},{ { 5, 10 },{ 10, 1 } } };
#endif #endif
const strided_span<const int, 2> csav{ span<const int, 5, 10>{ src }, { { 5, 10 },{ 10, 1 } } }; const strided_span<const int, 2> csav{ multi_span<const int, 5, 10>{ src }, { { 5, 10 },{ 10, 1 } } };
strided_span<int, 1> sav_sl = sav[2]; strided_span<int, 1> sav_sl = sav[2];
CHECK(sav_sl[0] == 20); CHECK(sav_sl[0] == 20);
@ -317,7 +317,7 @@ SUITE(strided_span_tests)
TEST(strided_span_bounds) TEST(strided_span_bounds)
{ {
int arr[] = { 0, 1, 2, 3 }; int arr[] = { 0, 1, 2, 3 };
span<int> av(arr); multi_span<int> av(arr);
{ {
// incorrect sections // incorrect sections
@ -432,7 +432,7 @@ SUITE(strided_span_tests)
TEST(strided_span_type_conversion) TEST(strided_span_type_conversion)
{ {
int arr[] = { 0, 1, 2, 3 }; int arr[] = { 0, 1, 2, 3 };
span<int> av(arr); multi_span<int> av(arr);
{ {
strided_span<int, 1> sav{ av.data(), av.size(), { av.size() / 2, 2 } }; strided_span<int, 1> sav{ av.data(), av.size(), { av.size() / 2, 2 } };
@ -447,7 +447,7 @@ SUITE(strided_span_tests)
#endif #endif
} }
span<const byte, dynamic_range> bytes = as_bytes(av); multi_span<const byte, dynamic_range> bytes = as_bytes(av);
// retype strided array with regular strides - from raw data // retype strided array with regular strides - from raw data
{ {
@ -460,10 +460,10 @@ SUITE(strided_span_tests)
CHECK_THROW(sav3[0][1], fail_fast); CHECK_THROW(sav3[0][1], fail_fast);
} }
// retype strided array with regular strides - from span // retype strided array with regular strides - from multi_span
{ {
strided_bounds<2> bounds{ { 2, bytes.size() / 4 }, { bytes.size() / 2, 1 } }; strided_bounds<2> bounds{ { 2, bytes.size() / 4 }, { bytes.size() / 2, 1 } };
span<const byte, 2, dynamic_range> bytes2 = as_span(bytes, dim<2>(), dim<>(bytes.size() / 2)); multi_span<const byte, 2, dynamic_range> bytes2 = as_span(bytes, dim<2>(), dim<>(bytes.size() / 2));
strided_span<const byte, 2> sav2{ bytes2, bounds }; strided_span<const byte, 2> sav2{ bytes2, bounds };
strided_span<int, 2> sav3 = sav2.as_strided_span<int>(); strided_span<int, 2> sav3 = sav2.as_strided_span<int>();
CHECK(sav3[0][0] == 0); CHECK(sav3[0][0] == 0);
@ -475,7 +475,7 @@ SUITE(strided_span_tests)
// retype strided array with not enough elements - last dimension of the array is too small // retype strided array with not enough elements - last dimension of the array is too small
{ {
strided_bounds<2> bounds{ { 4,2 },{ 4, 1 } }; strided_bounds<2> bounds{ { 4,2 },{ 4, 1 } };
span<const byte, 2, dynamic_range> bytes2 = as_span(bytes, dim<2>(), dim<>(bytes.size() / 2)); multi_span<const byte, 2, dynamic_range> bytes2 = as_span(bytes, dim<2>(), dim<>(bytes.size() / 2));
strided_span<const byte, 2> sav2{ bytes2, bounds }; strided_span<const byte, 2> sav2{ bytes2, bounds };
CHECK_THROW(sav2.as_strided_span<int>(), fail_fast); CHECK_THROW(sav2.as_strided_span<int>(), fail_fast);
} }
@ -483,7 +483,7 @@ SUITE(strided_span_tests)
// retype strided array with not enough elements - strides are too small // retype strided array with not enough elements - strides are too small
{ {
strided_bounds<2> bounds{ { 4,2 },{ 2, 1 } }; strided_bounds<2> bounds{ { 4,2 },{ 2, 1 } };
span<const byte, 2, dynamic_range> bytes2 = as_span(bytes, dim<2>(), dim<>(bytes.size() / 2)); multi_span<const byte, 2, dynamic_range> bytes2 = as_span(bytes, dim<2>(), dim<>(bytes.size() / 2));
strided_span<const byte, 2> sav2{ bytes2, bounds }; strided_span<const byte, 2> sav2{ bytes2, bounds };
CHECK_THROW(sav2.as_strided_span<int>(), fail_fast); CHECK_THROW(sav2.as_strided_span<int>(), fail_fast);
} }
@ -491,7 +491,7 @@ SUITE(strided_span_tests)
// retype strided array with not enough elements - last dimension does not divide by the new typesize // retype strided array with not enough elements - last dimension does not divide by the new typesize
{ {
strided_bounds<2> bounds{ { 2,6 },{ 4, 1 } }; strided_bounds<2> bounds{ { 2,6 },{ 4, 1 } };
span<const byte, 2, dynamic_range> bytes2 = as_span(bytes, dim<2>(), dim<>(bytes.size() / 2)); multi_span<const byte, 2, dynamic_range> bytes2 = as_span(bytes, dim<2>(), dim<>(bytes.size() / 2));
strided_span<const byte, 2> sav2{ bytes2, bounds }; strided_span<const byte, 2> sav2{ bytes2, bounds };
CHECK_THROW(sav2.as_strided_span<int>(), fail_fast); CHECK_THROW(sav2.as_strided_span<int>(), fail_fast);
} }
@ -499,7 +499,7 @@ SUITE(strided_span_tests)
// retype strided array with not enough elements - strides does not divide by the new typesize // retype strided array with not enough elements - strides does not divide by the new typesize
{ {
strided_bounds<2> bounds{ { 2, 1 },{ 6, 1 } }; strided_bounds<2> bounds{ { 2, 1 },{ 6, 1 } };
span<const byte, 2, dynamic_range> bytes2 = as_span(bytes, dim<2>(), dim<>(bytes.size() / 2)); multi_span<const byte, 2, dynamic_range> bytes2 = as_span(bytes, dim<2>(), dim<>(bytes.size() / 2));
strided_span<const byte, 2> sav2{ bytes2, bounds }; strided_span<const byte, 2> sav2{ bytes2, bounds };
CHECK_THROW(sav2.as_strided_span<int>(), fail_fast); CHECK_THROW(sav2.as_strided_span<int>(), fail_fast);
} }
@ -511,7 +511,7 @@ SUITE(strided_span_tests)
CHECK_THROW(sav2.as_strided_span<int>(), fail_fast); CHECK_THROW(sav2.as_strided_span<int>(), fail_fast);
} }
// retype strided array with irregular strides - from span // retype strided array with irregular strides - from multi_span
{ {
strided_bounds<1> bounds{ bytes.size() / 2, 2 }; strided_bounds<1> bounds{ bytes.size() / 2, 2 };
strided_span<const byte, 1> sav2{ bytes, bounds }; strided_span<const byte, 1> sav2{ bytes, bounds };
@ -522,7 +522,7 @@ SUITE(strided_span_tests)
TEST(empty_strided_spans) TEST(empty_strided_spans)
{ {
{ {
span<int, 0> empty_av(nullptr); multi_span<int, 0> empty_av(nullptr);
strided_span<int, 1> empty_sav{ empty_av, { 0, 1 } }; strided_span<int, 1> empty_sav{ empty_av, { 0, 1 } };
CHECK(empty_sav.bounds().index_bounds() == index<1>{ 0 }); CHECK(empty_sav.bounds().index_bounds() == index<1>{ 0 });
@ -553,7 +553,7 @@ SUITE(strided_span_tests)
} }
} }
void iterate_every_other_element(span<int, dynamic_range> av) void iterate_every_other_element(multi_span<int, dynamic_range> av)
{ {
// pick every other element // pick every other element
@ -586,13 +586,13 @@ SUITE(strided_span_tests)
// static bounds // static bounds
{ {
span<int, 8> av(arr, 8); multi_span<int, 8> av(arr, 8);
iterate_every_other_element(av); iterate_every_other_element(av);
} }
// dynamic bounds // dynamic bounds
{ {
span<int, dynamic_range> av(arr, 8); multi_span<int, dynamic_range> av(arr, 8);
iterate_every_other_element(av); iterate_every_other_element(av);
} }
} }
@ -612,7 +612,7 @@ SUITE(strided_span_tests)
delete[] arr; delete[] arr;
} }
void iterate_second_slice(span<int, dynamic_range, dynamic_range, dynamic_range> av) void iterate_second_slice(multi_span<int, dynamic_range, dynamic_range, dynamic_range> av)
{ {
int expected[6] = {2,3,10,11,18,19}; int expected[6] = {2,3,10,11,18,19};
auto section = av.section({0,1,0}, {3,1,2}); auto section = av.section({0,1,0}, {3,1,2});
@ -653,7 +653,7 @@ SUITE(strided_span_tests)
} }
{ {
span<int, 3, 4, 2> av = arr; multi_span<int, 3, 4, 2> av = arr;
iterate_second_slice(av); iterate_second_slice(av);
} }
} }
@ -693,7 +693,7 @@ SUITE(strided_span_tests)
TEST(strided_span_conversion) TEST(strided_span_conversion)
{ {
// get an span of 'c' values from the list of X's // get an multi_span of 'c' values from the list of X's
struct X { int a; int b; int c; }; struct X { int a; int b; int c; };

View File

@ -142,7 +142,7 @@ SUITE(string_span_tests)
const char* ptr = "Hello"; const char* ptr = "Hello";
const std::string str = "Hello"; const std::string str = "Hello";
const std::vector<char> vec = { 'H', 'e', 'l', 'l', 'o' }; const std::vector<char> vec = { 'H', 'e', 'l', 'l', 'o' };
gsl::span<const char> sp = ensure_z("Hello"); gsl::multi_span<const char> sp = ensure_z("Hello");
// comparison to literal // comparison to literal
CHECK(span == cstring_span<>("Hello")); CHECK(span == cstring_span<>("Hello"));
@ -182,7 +182,7 @@ SUITE(string_span_tests)
char* ptr = ar; char* ptr = ar;
std::string str = "Hello"; std::string str = "Hello";
std::vector<char> vec = { 'H', 'e', 'l', 'l', 'o' }; std::vector<char> vec = { 'H', 'e', 'l', 'l', 'o' };
gsl::span<char> sp = ensure_z(ar1); gsl::multi_span<char> sp = ensure_z(ar1);
// comparison to static array with no null termination // comparison to static array with no null termination
CHECK(span == string_span<>(ar)); CHECK(span == string_span<>(ar));
@ -216,7 +216,7 @@ SUITE(string_span_tests)
const char ar2[10] = "Hello"; const char ar2[10] = "Hello";
const std::string str = "Hello"; const std::string str = "Hello";
const std::vector<char> vec = { 'H', 'e', 'l', 'l', 'o' }; const std::vector<char> vec = { 'H', 'e', 'l', 'l', 'o' };
gsl::span<const char> sp = ensure_z("Hello"); gsl::multi_span<const char> sp = ensure_z("Hello");
cstring_span<> span = "Hello"; cstring_span<> span = "Hello";
@ -253,7 +253,7 @@ SUITE(string_span_tests)
char* _ptr = _ar; char* _ptr = _ar;
std::string _str = "Hello"; std::string _str = "Hello";
std::vector<char> _vec = { 'H', 'e', 'l', 'l', 'o' }; std::vector<char> _vec = { 'H', 'e', 'l', 'l', 'o' };
gsl::span<char> _sp{ _ar, 5 }; gsl::multi_span<char> _sp{ _ar, 5 };
CHECK(span == _ar); CHECK(span == _ar);
CHECK(span == _ar1); CHECK(span == _ar1);
@ -447,7 +447,7 @@ SUITE(string_span_tests)
// from span of a final extent // from span of a final extent
{ {
span<const char, 6> sp = "Hello"; multi_span<const char, 6> sp = "Hello";
cstring_span<> span = sp; cstring_span<> span = sp;
CHECK(span.length() == 6); CHECK(span.length() == 6);
} }
@ -455,7 +455,7 @@ SUITE(string_span_tests)
// from const span of a final extent to non-const string_span // from const span of a final extent to non-const string_span
#ifdef CONFIRM_COMPILATION_ERRORS #ifdef CONFIRM_COMPILATION_ERRORS
{ {
span<const char, 6> sp = "Hello"; multi_span<const char, 6> sp = "Hello";
string_span<> span = sp; string_span<> span = sp;
CHECK(span.length() == 6); CHECK(span.length() == 6);
} }
@ -568,7 +568,7 @@ SUITE(string_span_tests)
// from const span // from const span
{ {
std::vector<char> vec = { 'H', 'e', 'l', 'l', 'o' }; std::vector<char> vec = { 'H', 'e', 'l', 'l', 'o' };
const span<const char> inner = vec; const multi_span<const char> inner = vec;
cstring_span<> span = inner; cstring_span<> span = inner;
CHECK(span.length() == 5); CHECK(span.length() == 5);
} }
@ -576,7 +576,7 @@ SUITE(string_span_tests)
// from non-const span // from non-const span
{ {
std::vector<char> vec = { 'H', 'e', 'l', 'l', 'o' }; std::vector<char> vec = { 'H', 'e', 'l', 'l', 'o' };
span<char> inner = vec; multi_span<char> inner = vec;
cstring_span<> span = inner; cstring_span<> span = inner;
CHECK(span.length() == 5); CHECK(span.length() == 5);
} }
@ -675,7 +675,7 @@ SUITE(string_span_tests)
{ {
#ifdef CONFIRM_COMPILATION_ERRORS #ifdef CONFIRM_COMPILATION_ERRORS
std::vector<char> vec = { 'H', 'e', 'l', 'l', 'o' }; std::vector<char> vec = { 'H', 'e', 'l', 'l', 'o' };
const span<const char> inner = vec; const multi_span<const char> inner = vec;
string_span<> span = inner; string_span<> span = inner;
CHECK(span.length() == 5); CHECK(span.length() == 5);
#endif #endif
@ -684,7 +684,7 @@ SUITE(string_span_tests)
// from non-const span // from non-const span
{ {
std::vector<char> vec = { 'H', 'e', 'l', 'l', 'o' }; std::vector<char> vec = { 'H', 'e', 'l', 'l', 'o' };
span<char> inner = vec; multi_span<char> inner = vec;
string_span<> span = inner; string_span<> span = inner;
CHECK(span.length() == 5); CHECK(span.length() == 5);
} }
@ -693,7 +693,7 @@ SUITE(string_span_tests)
{ {
#ifdef CONFIRM_COMPILATION_ERRORS #ifdef CONFIRM_COMPILATION_ERRORS
const std::vector<char> vec = { 'H', 'e', 'l', 'l', 'o' }; const std::vector<char> vec = { 'H', 'e', 'l', 'l', 'o' };
const span<char> inner = vec; const multi_span<char> inner = vec;
string_span<> span = inner; string_span<> span = inner;
CHECK(span.length() == 5); CHECK(span.length() == 5);
#endif #endif
@ -769,12 +769,12 @@ SUITE(string_span_tests)
// move span // move span
{ {
span<const char> span = ensure_z("Hello"); multi_span<const char> span = ensure_z("Hello");
cstring_span<> span1 = std::move(span); cstring_span<> span1 = std::move(span);
CHECK(span1.length() == 5); CHECK(span1.length() == 5);
} }
{ {
span<const char> span = ensure_z("Hello"); multi_span<const char> span = ensure_z("Hello");
cstring_span<> span2 = move_wrapper(std::move(span)); cstring_span<> span2 = move_wrapper(std::move(span));
CHECK(span2.length() == 5); CHECK(span2.length() == 5);
} }