mirror of
https://github.com/microsoft/GSL.git
synced 2024-11-03 17:56:43 -05:00
Renamed byte header and tidied up string_span dependencies.
This commit is contained in:
parent
b72d7abfb0
commit
267472449c
@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
#include "gsl_assert.h"
|
#include "gsl_assert.h"
|
||||||
#include "gsl_util.h"
|
#include "gsl_util.h"
|
||||||
#include "byte.h"
|
#include "gsl_byte.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
126
include/span.h
126
include/span.h
@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
#include "gsl_assert.h"
|
#include "gsl_assert.h"
|
||||||
#include "gsl_util.h"
|
#include "gsl_util.h"
|
||||||
#include "byte.h"
|
#include "gsl_byte.h"
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
@ -154,18 +154,21 @@ struct is_allowed_element_type_conversion<From, const byte>
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <class Span>
|
template <class Span>
|
||||||
class span_iterator
|
class const_span_iterator
|
||||||
: public std::iterator<std::random_access_iterator_tag, typename Span::element_type>
|
|
||||||
{
|
{
|
||||||
using Base = std::iterator<std::random_access_iterator_tag, typename Span::element_type>;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using typename Base::reference;
|
using iterator_category = std::random_access_iterator_tag;
|
||||||
using typename Base::pointer;
|
using value_type = typename Span::element_type;
|
||||||
using typename Base::difference_type;
|
using difference_type = std::ptrdiff_t;
|
||||||
|
|
||||||
constexpr span_iterator() : span_iterator(nullptr, 0) {}
|
using const_pointer = std::add_const_t<value_type*>;
|
||||||
constexpr span_iterator(const Span* span, typename Span::index_type index) : span_(span), index_(index)
|
using pointer = const_pointer;
|
||||||
|
|
||||||
|
using const_reference = std::add_const_t<value_type&>;
|
||||||
|
using reference = const_reference;
|
||||||
|
|
||||||
|
constexpr const_span_iterator() : const_span_iterator(nullptr, 0) {}
|
||||||
|
constexpr const_span_iterator(const Span* span, typename Span::index_type index) : span_(span), index_(index)
|
||||||
{
|
{
|
||||||
Expects(span == nullptr || (index_ >= 0 && index <= span_->length()));
|
Expects(span == nullptr || (index_ >= 0 && index <= span_->length()));
|
||||||
}
|
}
|
||||||
@ -173,59 +176,59 @@ public:
|
|||||||
constexpr reference operator*() const { Expects(span_); return (*span_)[index_]; }
|
constexpr reference operator*() const { Expects(span_); return (*span_)[index_]; }
|
||||||
constexpr pointer operator->() const { Expects(span_); return &((*span_)[index_]); }
|
constexpr pointer operator->() const { Expects(span_); return &((*span_)[index_]); }
|
||||||
|
|
||||||
constexpr span_iterator& operator++() noexcept
|
constexpr const_span_iterator& operator++() noexcept
|
||||||
{
|
{
|
||||||
Expects(span_ && index_ >= 0 && index_ < span_->length());
|
Expects(span_ && index_ >= 0 && index_ < span_->length());
|
||||||
++index_;
|
++index_;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr span_iterator operator++(int) noexcept
|
constexpr const_span_iterator operator++(int) noexcept
|
||||||
{
|
{
|
||||||
auto ret = *this;
|
auto ret = *this;
|
||||||
++(*this);
|
++(*this);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr span_iterator& operator--() noexcept
|
constexpr const_span_iterator& operator--() noexcept
|
||||||
{
|
{
|
||||||
Expects(span_ && index > 0 && index_ <= span_->length());
|
Expects(span_ && index > 0 && index_ <= span_->length());
|
||||||
--index_;
|
--index_;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr span_iterator operator--(int) noexcept
|
constexpr const_span_iterator operator--(int) noexcept
|
||||||
{
|
{
|
||||||
auto ret = *this;
|
auto ret = *this;
|
||||||
--(*this);
|
--(*this);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr span_iterator operator+(difference_type n) const noexcept
|
constexpr const_span_iterator operator+(difference_type n) const noexcept
|
||||||
{
|
{
|
||||||
auto ret{*this};
|
auto ret{*this};
|
||||||
return ret += n;
|
return ret += n;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr span_iterator& operator+=(difference_type n) noexcept
|
constexpr const_span_iterator& operator+=(difference_type n) noexcept
|
||||||
{
|
{
|
||||||
index_ += n;
|
index_ += n;
|
||||||
Expects(span_ && index_ >= 0 && index_ <= span_->length());
|
Expects(span_ && index_ >= 0 && index_ <= span_->length());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr span_iterator operator-(difference_type n) const noexcept
|
constexpr const_span_iterator operator-(difference_type n) const noexcept
|
||||||
{
|
{
|
||||||
auto ret{*this};
|
auto ret{*this};
|
||||||
return ret -= n;
|
return ret -= n;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr span_iterator& operator-=(difference_type n) noexcept
|
constexpr const_span_iterator& operator-=(difference_type n) noexcept
|
||||||
{
|
{
|
||||||
return *this += -n;
|
return *this += -n;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr difference_type operator-(const span_iterator& rhs) const noexcept
|
constexpr difference_type operator-(const const_span_iterator& rhs) const noexcept
|
||||||
{
|
{
|
||||||
Expects(span_ == rhs.span_);
|
Expects(span_ == rhs.span_);
|
||||||
return index_ - rhs.index_;
|
return index_ - rhs.index_;
|
||||||
@ -236,26 +239,26 @@ public:
|
|||||||
return *(*this + n);
|
return *(*this + n);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr bool operator==(const span_iterator& rhs) const noexcept
|
constexpr bool operator==(const const_span_iterator& rhs) const noexcept
|
||||||
{
|
{
|
||||||
return span_ == rhs.span_ && index_ == rhs.index_;
|
return span_ == rhs.span_ && index_ == rhs.index_;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr bool operator!=(const span_iterator& rhs) const noexcept { return !(*this == rhs); }
|
constexpr bool operator!=(const const_span_iterator& rhs) const noexcept { return !(*this == rhs); }
|
||||||
|
|
||||||
constexpr bool operator<(const span_iterator& rhs) const noexcept
|
constexpr bool operator<(const const_span_iterator& rhs) const noexcept
|
||||||
{
|
{
|
||||||
Expects(span_ == rhs.span_);
|
Expects(span_ == rhs.span_);
|
||||||
return index_ < rhs.index_;
|
return index_ < rhs.index_;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr bool operator<=(const span_iterator& rhs) const noexcept { return !(rhs < *this); }
|
constexpr bool operator<=(const const_span_iterator& rhs) const noexcept { return !(rhs < *this); }
|
||||||
|
|
||||||
constexpr bool operator>(const span_iterator& rhs) const noexcept { return rhs < *this; }
|
constexpr bool operator>(const const_span_iterator& rhs) const noexcept { return rhs < *this; }
|
||||||
|
|
||||||
constexpr bool operator>=(const span_iterator& rhs) const noexcept { return !(rhs > *this); }
|
constexpr bool operator>=(const const_span_iterator& rhs) const noexcept { return !(rhs > *this); }
|
||||||
|
|
||||||
void swap(span_iterator& rhs) noexcept
|
void swap(const_span_iterator& rhs) noexcept
|
||||||
{
|
{
|
||||||
std::swap(index_, rhs.index_);
|
std::swap(index_, rhs.index_);
|
||||||
std::swap(m_span, rhs.m_span);
|
std::swap(m_span, rhs.m_span);
|
||||||
@ -266,6 +269,75 @@ private:
|
|||||||
ptrdiff_t index_;
|
ptrdiff_t index_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <class Span>
|
||||||
|
class span_iterator : public const_span_iterator<Span>
|
||||||
|
{
|
||||||
|
using base_type = const_span_iterator<Span>;
|
||||||
|
|
||||||
|
public:
|
||||||
|
using iterator_category = std::random_access_iterator_tag;
|
||||||
|
using value_type = typename Span::element_type;
|
||||||
|
using difference_type = std::ptrdiff_t;
|
||||||
|
|
||||||
|
using pointer = value_type*;
|
||||||
|
using reference = value_type&;
|
||||||
|
|
||||||
|
constexpr span_iterator() : base_type() {}
|
||||||
|
constexpr span_iterator(const Span* span, typename Span::index_type index) : base_type(span, index) {}
|
||||||
|
|
||||||
|
constexpr reference operator*() const { return reinterpret_cast<reference>(base_type::operator*()); }
|
||||||
|
constexpr pointer operator->() const { return reinterpret_cast<pointer>(base_type::operator->()); }
|
||||||
|
|
||||||
|
constexpr span_iterator& operator++() noexcept { base_type::operator++(); return *this; }
|
||||||
|
|
||||||
|
constexpr span_iterator operator++(int) noexcept { return base_type::operator++(1); }
|
||||||
|
|
||||||
|
constexpr span_iterator& operator--() noexcept { base_type::operator--(); return *this; }
|
||||||
|
|
||||||
|
constexpr span_iterator operator--(int) noexcept { return base_type::operator--(1); }
|
||||||
|
|
||||||
|
constexpr span_iterator operator+(difference_type n) const noexcept { return base_type::operator+(n); }
|
||||||
|
|
||||||
|
constexpr span_iterator& operator+=(difference_type n) noexcept { return base_type::operator+=(n); }
|
||||||
|
|
||||||
|
constexpr span_iterator operator-(difference_type n) const noexcept { return base_type::operator-(n); }
|
||||||
|
|
||||||
|
constexpr span_iterator& operator-=(difference_type n) noexcept { return base_type::operator-=(n); }
|
||||||
|
|
||||||
|
constexpr difference_type operator-(const span_iterator& rhs) const noexcept { return base_type::operator-(rhs); }
|
||||||
|
|
||||||
|
constexpr reference operator[](difference_type n) const noexcept { return *(*this + n); }
|
||||||
|
|
||||||
|
constexpr bool operator==(const span_iterator& rhs) const noexcept { return base_type::operator==(rhs); }
|
||||||
|
|
||||||
|
constexpr bool operator!=(const span_iterator& rhs) const noexcept { return !(*this == rhs); }
|
||||||
|
|
||||||
|
constexpr bool operator<(const span_iterator& rhs) const noexcept { return base_type::operator<(rhs); }
|
||||||
|
|
||||||
|
constexpr bool operator<=(const span_iterator& rhs) const noexcept { return !(rhs < *this); }
|
||||||
|
|
||||||
|
constexpr bool operator>(const span_iterator& rhs) const noexcept { return rhs < *this; }
|
||||||
|
|
||||||
|
constexpr bool operator>=(const span_iterator& rhs) const noexcept { return !(rhs > *this); }
|
||||||
|
|
||||||
|
void swap(span_iterator& rhs) noexcept { base_type::swap(rhs); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Span>
|
||||||
|
constexpr const_span_iterator<Span> operator+(typename const_span_iterator<Span>::difference_type n,
|
||||||
|
const const_span_iterator<Span>& rhs) noexcept
|
||||||
|
{
|
||||||
|
return rhs + n;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Span>
|
||||||
|
constexpr const_span_iterator<Span> operator-(typename const_span_iterator<Span>::difference_type n,
|
||||||
|
const const_span_iterator<Span>& rhs) noexcept
|
||||||
|
{
|
||||||
|
return rhs - n;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Span>
|
template <typename Span>
|
||||||
constexpr span_iterator<Span> operator+(typename span_iterator<Span>::difference_type n,
|
constexpr span_iterator<Span> operator+(typename span_iterator<Span>::difference_type n,
|
||||||
const span_iterator<Span>& rhs) noexcept
|
const span_iterator<Span>& rhs) noexcept
|
||||||
@ -294,7 +366,9 @@ public:
|
|||||||
using reference = element_type&;
|
using reference = element_type&;
|
||||||
|
|
||||||
using iterator = details::span_iterator<span<ElementType, Extent>>;
|
using iterator = details::span_iterator<span<ElementType, Extent>>;
|
||||||
|
using const_iterator = details::span_iterator<span>;
|
||||||
using reverse_iterator = std::reverse_iterator<iterator>;
|
using reverse_iterator = std::reverse_iterator<iterator>;
|
||||||
|
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
||||||
|
|
||||||
constexpr static const index_type extent = Extent;
|
constexpr static const index_type extent = Extent;
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
#include "gsl_assert.h"
|
#include "gsl_assert.h"
|
||||||
#include "gsl_util.h"
|
#include "gsl_util.h"
|
||||||
#include "multi_span.h"
|
#include "span.h"
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
@ -72,19 +72,19 @@ namespace gsl
|
|||||||
// (sometimes needlessly) break existing programs when introduced.
|
// (sometimes needlessly) break existing programs when introduced.
|
||||||
//
|
//
|
||||||
|
|
||||||
template<typename CharT, std::ptrdiff_t Extent = dynamic_range>
|
template<typename CharT, std::ptrdiff_t Extent = dynamic_extent>
|
||||||
using basic_zstring = CharT*;
|
using basic_zstring = CharT*;
|
||||||
|
|
||||||
template<std::ptrdiff_t Extent = dynamic_range>
|
template<std::ptrdiff_t Extent = dynamic_extent>
|
||||||
using czstring = basic_zstring<const char, Extent>;
|
using czstring = basic_zstring<const char, Extent>;
|
||||||
|
|
||||||
template<std::ptrdiff_t Extent = dynamic_range>
|
template<std::ptrdiff_t Extent = dynamic_extent>
|
||||||
using cwzstring = basic_zstring<const wchar_t, Extent>;
|
using cwzstring = basic_zstring<const wchar_t, Extent>;
|
||||||
|
|
||||||
template<std::ptrdiff_t Extent = dynamic_range>
|
template<std::ptrdiff_t Extent = dynamic_extent>
|
||||||
using zstring = basic_zstring<char, Extent>;
|
using zstring = basic_zstring<char, Extent>;
|
||||||
|
|
||||||
template<std::ptrdiff_t Extent = dynamic_range>
|
template<std::ptrdiff_t Extent = dynamic_extent>
|
||||||
using wzstring = basic_zstring<wchar_t, Extent>;
|
using wzstring = basic_zstring<wchar_t, Extent>;
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -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>
|
||||||
multi_span<T, dynamic_range> ensure_sentinel(T* seq, std::ptrdiff_t max = PTRDIFF_MAX)
|
span<T, dynamic_extent> 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 @@ multi_span<T, dynamic_range> ensure_sentinel(T* seq, std::ptrdiff_t max = PTRDIF
|
|||||||
// the limit of size_type.
|
// the limit of size_type.
|
||||||
//
|
//
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline multi_span<T, dynamic_range> ensure_z(T* const & sz, std::ptrdiff_t max = PTRDIFF_MAX)
|
inline span<T, dynamic_extent> 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 multi_span<char, dynamic_range> ensure_z(char* const& sz, std::ptrdiff_t max)
|
inline span<char, dynamic_extent> 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 multi_span<const char, dynamic_range> ensure_z(const char* const& sz, std::ptrdiff_t max)
|
inline span<const char, dynamic_extent> 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 multi_span<wchar_t, dynamic_range> ensure_z(wchar_t* const& sz, std::ptrdiff_t max)
|
inline span<wchar_t, dynamic_extent> 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 multi_span<const wchar_t, dynamic_range> ensure_z(const wchar_t* const& sz, std::ptrdiff_t max)
|
inline span<const wchar_t, dynamic_extent> 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 multi_span<const wchar_t, dynamic_range> ensure_z(const wchar_t* const& s
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, size_t N>
|
template<typename T, size_t N>
|
||||||
multi_span<T, dynamic_range> ensure_z(T(&sz)[N]) { return ensure_z(&sz[0], static_cast<std::ptrdiff_t>(N)); }
|
span<T, dynamic_extent> ensure_z(T(&sz)[N]) { return ensure_z(&sz[0], static_cast<std::ptrdiff_t>(N)); }
|
||||||
|
|
||||||
template<class Cont>
|
template<class Cont>
|
||||||
multi_span<typename std::remove_pointer<typename Cont::pointer>::type, dynamic_range> ensure_z(Cont& cont)
|
span<typename std::remove_pointer<typename Cont::pointer>::type, dynamic_extent> 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()));
|
||||||
}
|
}
|
||||||
@ -216,9 +216,7 @@ namespace details
|
|||||||
//
|
//
|
||||||
// string_span and relatives
|
// string_span and relatives
|
||||||
//
|
//
|
||||||
// Note that Extent is always single-dimension only
|
template <typename CharT, std::ptrdiff_t Extent = dynamic_extent>
|
||||||
//
|
|
||||||
template <typename CharT, std::ptrdiff_t Extent = dynamic_range>
|
|
||||||
class basic_string_span
|
class basic_string_span
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -227,8 +225,7 @@ public:
|
|||||||
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 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 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;
|
||||||
@ -296,52 +293,52 @@ public:
|
|||||||
{}
|
{}
|
||||||
|
|
||||||
// from containers. Containers must have .size() and .data() function signatures
|
// from containers. Containers must have .size() and .data() function signatures
|
||||||
template <typename Cont, typename DataType = typename Cont::value_type,
|
template <typename Cont,
|
||||||
typename Dummy = std::enable_if_t<!details::is_multi_span<Cont>::value
|
typename = std::enable_if_t<
|
||||||
&& !details::is_basic_string_span<Cont>::value
|
!details::is_basic_string_span<Cont>::value
|
||||||
&& !(!std::is_const<value_type>::value && std::is_const<Cont>::value) // no converting const containers to non-const span
|
&& !details::is_span<Cont>::value
|
||||||
&& std::is_convertible<DataType*, value_type*>::value
|
&& std::is_convertible<Cont::pointer, pointer>::value
|
||||||
&& std::is_same<std::decay_t<decltype(std::declval<Cont>().size(), *std::declval<Cont>().data())>, DataType>::value>
|
&& std::is_convertible<Cont::pointer, decltype(std::declval<Cont>().data())>::value>
|
||||||
>
|
>
|
||||||
constexpr basic_string_span(Cont& cont)
|
constexpr basic_string_span(Cont& cont) : span_(cont.data(), cont.size()) {}
|
||||||
: span_(cont.data(), cont.size())
|
|
||||||
{}
|
|
||||||
|
|
||||||
// disallow creation from temporary containers and strings
|
// disallow creation from temporary containers and strings
|
||||||
template <typename Cont, typename DataType = typename Cont::value_type,
|
template <typename Cont,
|
||||||
typename Dummy = std::enable_if_t<!details::is_multi_span<Cont>::value
|
typename = std::enable_if_t<
|
||||||
&& !details::is_basic_string_span<Cont>::value
|
!details::is_basic_string_span<Cont>::value
|
||||||
&& std::is_convertible<DataType*, value_type*>::value
|
&& !details::is_span<Cont>::value
|
||||||
&& std::is_same<std::decay_t<decltype(std::declval<Cont>().size(), *std::declval<Cont>().data())>, DataType>::value>
|
&& std::is_convertible<Cont::pointer, pointer>::value
|
||||||
|
&& std::is_convertible<Cont::pointer, decltype(std::declval<Cont>().data())>::value>
|
||||||
>
|
>
|
||||||
basic_string_span(Cont&& cont) = delete;
|
constexpr basic_string_span(const Cont& cont) : span_(cont.data(), cont.size()) {}
|
||||||
|
|
||||||
#ifndef GSL_MSVC_HAS_SFINAE_SUBSTITUTION_ICE
|
#ifndef GSL_MSVC_HAS_SFINAE_SUBSTITUTION_ICE
|
||||||
// from span
|
// from span
|
||||||
template <typename OtherValueType, std::ptrdiff_t OtherExtent,
|
template <typename OtherValueType, std::ptrdiff_t OtherExtent,
|
||||||
typename Dummy = std::enable_if_t<
|
typename Dummy = std::enable_if_t<
|
||||||
std::is_convertible<OtherValueType*, value_type*>::value
|
std::is_convertible<span<OtherValueType, OtherExtent>, impl_type>::value
|
||||||
&& std::is_convertible<static_bounds<OtherExtent>, bounds_type>::value>
|
|
||||||
>
|
>
|
||||||
constexpr basic_string_span(multi_span<OtherValueType, OtherExtent> other) noexcept
|
>
|
||||||
|
constexpr basic_string_span(span<OtherValueType, OtherExtent> other) noexcept
|
||||||
: span_(other)
|
: span_(other)
|
||||||
{}
|
{}
|
||||||
#else
|
#else
|
||||||
// from span
|
// from span
|
||||||
constexpr basic_string_span(multi_span<value_type, Extent> other) noexcept
|
constexpr basic_string_span(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 = std::enable_if_t<!std::is_same<std::remove_const_t<value_type>, value_type>::value>>
|
||||||
constexpr basic_string_span(multi_span<std::remove_const_t<value_type>, Extent> other) noexcept
|
constexpr basic_string_span(span<std::remove_const_t<value_type>, Extent> other) noexcept
|
||||||
: span_(other)
|
: span_(other)
|
||||||
{}
|
{}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// from string_span
|
// from string_span
|
||||||
template <typename OtherValueType, std::ptrdiff_t OtherExtent,
|
template <typename OtherValueType, std::ptrdiff_t OtherExtent,
|
||||||
typename OtherBounds = static_bounds<OtherExtent>,
|
typename = std::enable_if_t<
|
||||||
typename Dummy = std::enable_if_t<std::is_convertible<OtherValueType*, value_type*>::value && std::is_convertible<OtherBounds, bounds_type>::value>
|
std::is_convertible<basic_string_span<OtherValueType, OtherExtent>::impl_type, impl_type>::value
|
||||||
|
>
|
||||||
>
|
>
|
||||||
constexpr basic_string_span(basic_string_span<OtherValueType, OtherExtent> other) noexcept
|
constexpr basic_string_span(basic_string_span<OtherValueType, OtherExtent> other) noexcept
|
||||||
: span_(other.data(), other.length())
|
: span_(other.data(), other.length())
|
||||||
@ -359,7 +356,7 @@ public:
|
|||||||
return{ span_.template first<Count>() };
|
return{ span_.template first<Count>() };
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr basic_string_span<value_type, dynamic_range> first(size_type count) const noexcept
|
constexpr basic_string_span<value_type, dynamic_extent> first(size_type count) const noexcept
|
||||||
{
|
{
|
||||||
return{ span_.first(count) };
|
return{ span_.first(count) };
|
||||||
}
|
}
|
||||||
@ -371,7 +368,7 @@ public:
|
|||||||
return{ span_.template last<Count>() };
|
return{ span_.template last<Count>() };
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr basic_string_span<value_type, dynamic_range> last(size_type count) const noexcept
|
constexpr basic_string_span<value_type, dynamic_extent> last(size_type count) const noexcept
|
||||||
{
|
{
|
||||||
return{ span_.last(count) };
|
return{ span_.last(count) };
|
||||||
}
|
}
|
||||||
@ -383,7 +380,7 @@ public:
|
|||||||
return{ span_.template subspan<Offset, Count>() };
|
return{ span_.template subspan<Offset, Count>() };
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr basic_string_span<value_type, dynamic_range> subspan(size_type offset, size_type count = dynamic_range) const noexcept
|
constexpr basic_string_span<value_type, dynamic_extent> subspan(size_type offset, size_type count = dynamic_extent) const noexcept
|
||||||
{
|
{
|
||||||
return{ span_.subspan(offset, count) };
|
return{ span_.subspan(offset, count) };
|
||||||
}
|
}
|
||||||
@ -478,16 +475,16 @@ private:
|
|||||||
impl_type span_;
|
impl_type span_;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<std::ptrdiff_t Extent = dynamic_range>
|
template<std::ptrdiff_t Extent = dynamic_extent>
|
||||||
using string_span = basic_string_span<char, Extent>;
|
using string_span = basic_string_span<char, Extent>;
|
||||||
|
|
||||||
template<std::ptrdiff_t Extent = dynamic_range>
|
template<std::ptrdiff_t Extent = dynamic_extent>
|
||||||
using cstring_span = basic_string_span<const char, Extent>;
|
using cstring_span = basic_string_span<const char, Extent>;
|
||||||
|
|
||||||
template<std::ptrdiff_t Extent = dynamic_range>
|
template<std::ptrdiff_t Extent = dynamic_extent>
|
||||||
using wstring_span = basic_string_span<wchar_t, Extent>;
|
using wstring_span = basic_string_span<wchar_t, Extent>;
|
||||||
|
|
||||||
template<std::ptrdiff_t Extent = dynamic_range>
|
template<std::ptrdiff_t Extent = dynamic_extent>
|
||||||
using cwstring_span = basic_string_span<const wchar_t, Extent>;
|
using cwstring_span = basic_string_span<const wchar_t, Extent>;
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -527,7 +524,7 @@ inline std::wstring to_string(wstring_span<> view)
|
|||||||
|
|
||||||
// zero-terminated string span, used to convert
|
// zero-terminated string span, used to convert
|
||||||
// zero-terminated spans to legacy strings
|
// zero-terminated spans to legacy strings
|
||||||
template<typename CharT, std::ptrdiff_t Extent = dynamic_range>
|
template<typename CharT, std::ptrdiff_t Extent = dynamic_extent>
|
||||||
class basic_zstring_span
|
class basic_zstring_span
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -540,14 +537,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 = multi_span<value_type, Extent>;
|
using impl_type = 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 multi_span) noexcept
|
constexpr basic_zstring_span(impl_type s) noexcept
|
||||||
: span_(multi_span)
|
: span_(s)
|
||||||
{
|
{
|
||||||
// expects a zero-terminated span
|
// expects a zero-terminated span
|
||||||
Expects(multi_span[multi_span.size() - 1] == '\0');
|
Expects(s[s.size() - 1] == '\0');
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy
|
// copy
|
||||||
@ -588,22 +585,22 @@ private:
|
|||||||
impl_type span_;
|
impl_type span_;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <std::ptrdiff_t Max = dynamic_range>
|
template <std::ptrdiff_t Max = dynamic_extent>
|
||||||
using zstring_span = basic_zstring_span<char, Max>;
|
using zstring_span = basic_zstring_span<char, Max>;
|
||||||
|
|
||||||
template <std::ptrdiff_t Max = dynamic_range>
|
template <std::ptrdiff_t Max = dynamic_extent>
|
||||||
using wzstring_span = basic_zstring_span<wchar_t, Max>;
|
using wzstring_span = basic_zstring_span<wchar_t, Max>;
|
||||||
|
|
||||||
template <std::ptrdiff_t Max = dynamic_range>
|
template <std::ptrdiff_t Max = dynamic_extent>
|
||||||
using czstring_span = basic_zstring_span<const char, Max>;
|
using czstring_span = basic_zstring_span<const char, Max>;
|
||||||
|
|
||||||
template <std::ptrdiff_t Max = dynamic_range>
|
template <std::ptrdiff_t Max = dynamic_extent>
|
||||||
using cwzstring_span = basic_zstring_span<const wchar_t, Max>;
|
using cwzstring_span = basic_zstring_span<const wchar_t, Max>;
|
||||||
|
|
||||||
} // namespace GSL
|
} // namespace GSL
|
||||||
|
|
||||||
// operator ==
|
// operator ==
|
||||||
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_range, typename T,
|
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T,
|
||||||
typename = std::enable_if_t<
|
typename = std::enable_if_t<
|
||||||
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>
|
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>
|
||||||
>
|
>
|
||||||
@ -617,7 +614,7 @@ bool operator==(gsl::basic_string_span<CharT, Extent> one, const T& other) noexc
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_range, typename T,
|
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T,
|
||||||
typename Dummy = std::enable_if_t<
|
typename Dummy = std::enable_if_t<
|
||||||
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value
|
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value
|
||||||
&& !gsl::details::is_basic_string_span<T>::value>
|
&& !gsl::details::is_basic_string_span<T>::value>
|
||||||
@ -637,10 +634,10 @@ bool operator==(const T& one, gsl::basic_string_span<CharT, Extent> other) noexc
|
|||||||
// VS treats temp and const containers as convertible to basic_string_span,
|
// VS treats temp and const containers as convertible to basic_string_span,
|
||||||
// so the cases below are already covered by the previous operators
|
// so the cases below are already covered by the previous operators
|
||||||
|
|
||||||
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_range, typename T,
|
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T,
|
||||||
typename DataType = typename T::value_type,
|
typename DataType = typename T::value_type,
|
||||||
typename Dummy = std::enable_if_t<
|
typename Dummy = std::enable_if_t<
|
||||||
!gsl::details::is_multi_span<T>::value
|
!gsl::details::is_span<T>::value
|
||||||
&& !gsl::details::is_basic_string_span<T>::value
|
&& !gsl::details::is_basic_string_span<T>::value
|
||||||
&& std::is_convertible<DataType*, CharT*>::value
|
&& std::is_convertible<DataType*, CharT*>::value
|
||||||
&& std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, DataType>::value>
|
&& std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, DataType>::value>
|
||||||
@ -651,10 +648,10 @@ bool operator==(gsl::basic_string_span<CharT, Extent> one, const T& other) noexc
|
|||||||
return std::equal(one.begin(), one.end(), tmp.begin(), tmp.end());
|
return std::equal(one.begin(), one.end(), tmp.begin(), tmp.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_range, typename T,
|
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T,
|
||||||
typename DataType = typename T::value_type,
|
typename DataType = typename T::value_type,
|
||||||
typename Dummy = std::enable_if_t<
|
typename Dummy = std::enable_if_t<
|
||||||
!gsl::details::is_multi_span<T>::value
|
!gsl::details::is_span<T>::value
|
||||||
&& !gsl::details::is_basic_string_span<T>::value
|
&& !gsl::details::is_basic_string_span<T>::value
|
||||||
&& std::is_convertible<DataType*, CharT*>::value
|
&& std::is_convertible<DataType*, CharT*>::value
|
||||||
&& std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, DataType>::value>
|
&& std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, DataType>::value>
|
||||||
@ -667,7 +664,7 @@ bool operator==(const T& one, gsl::basic_string_span<CharT, Extent> other) noexc
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// operator !=
|
// operator !=
|
||||||
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_range, typename T,
|
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T,
|
||||||
typename = std::enable_if_t<
|
typename = std::enable_if_t<
|
||||||
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>
|
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>
|
||||||
>
|
>
|
||||||
@ -676,7 +673,7 @@ bool operator!=(gsl::basic_string_span<CharT, Extent> one, const T& other) noexc
|
|||||||
return !(one == other);
|
return !(one == other);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_range, typename T,
|
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T,
|
||||||
typename Dummy = std::enable_if_t<
|
typename Dummy = std::enable_if_t<
|
||||||
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value
|
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value
|
||||||
&& !gsl::details::is_basic_string_span<T>::value>
|
&& !gsl::details::is_basic_string_span<T>::value>
|
||||||
@ -691,10 +688,10 @@ bool operator!=(const T& one, gsl::basic_string_span<CharT, Extent> other) noexc
|
|||||||
// VS treats temp and const containers as convertible to basic_string_span,
|
// VS treats temp and const containers as convertible to basic_string_span,
|
||||||
// so the cases below are already covered by the previous operators
|
// so the cases below are already covered by the previous operators
|
||||||
|
|
||||||
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_range, typename T,
|
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T,
|
||||||
typename DataType = typename T::value_type,
|
typename DataType = typename T::value_type,
|
||||||
typename Dummy = std::enable_if_t<
|
typename Dummy = std::enable_if_t<
|
||||||
!gsl::details::is_multi_span<T>::value
|
!gsl::details::is_span<T>::value
|
||||||
&& !gsl::details::is_basic_string_span<T>::value
|
&& !gsl::details::is_basic_string_span<T>::value
|
||||||
&& std::is_convertible<DataType*, CharT*>::value
|
&& std::is_convertible<DataType*, CharT*>::value
|
||||||
&& std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, DataType>::value>
|
&& std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, DataType>::value>
|
||||||
@ -704,10 +701,10 @@ bool operator!=(gsl::basic_string_span<CharT, Extent> one, const T& other) noexc
|
|||||||
return !(one == other);
|
return !(one == other);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_range, typename T,
|
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T,
|
||||||
typename DataType = typename T::value_type,
|
typename DataType = typename T::value_type,
|
||||||
typename Dummy = std::enable_if_t<
|
typename Dummy = std::enable_if_t<
|
||||||
!gsl::details::is_multi_span<T>::value
|
!gsl::details::is_span<T>::value
|
||||||
&& !gsl::details::is_basic_string_span<T>::value
|
&& !gsl::details::is_basic_string_span<T>::value
|
||||||
&& std::is_convertible<DataType*, CharT*>::value
|
&& std::is_convertible<DataType*, CharT*>::value
|
||||||
&& std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, DataType>::value>
|
&& std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, DataType>::value>
|
||||||
@ -719,7 +716,7 @@ bool operator!=(const T& one, gsl::basic_string_span<CharT, Extent> other) noexc
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// operator<
|
// operator<
|
||||||
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_range, typename T,
|
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T,
|
||||||
typename = std::enable_if_t<
|
typename = std::enable_if_t<
|
||||||
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>
|
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>
|
||||||
>
|
>
|
||||||
@ -729,7 +726,7 @@ bool operator<(gsl::basic_string_span<CharT, Extent> one, const T& other) noexce
|
|||||||
return std::lexicographical_compare(one.begin(), one.end(), tmp.begin(), tmp.end());
|
return std::lexicographical_compare(one.begin(), one.end(), tmp.begin(), tmp.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_range, typename T,
|
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T,
|
||||||
typename Dummy = std::enable_if_t<
|
typename Dummy = std::enable_if_t<
|
||||||
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value
|
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value
|
||||||
&& !gsl::details::is_basic_string_span<T>::value>
|
&& !gsl::details::is_basic_string_span<T>::value>
|
||||||
@ -745,10 +742,10 @@ bool operator<(const T& one, gsl::basic_string_span<CharT, Extent> other) noexce
|
|||||||
// VS treats temp and const containers as convertible to basic_string_span,
|
// VS treats temp and const containers as convertible to basic_string_span,
|
||||||
// so the cases below are already covered by the previous operators
|
// so the cases below are already covered by the previous operators
|
||||||
|
|
||||||
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_range, typename T,
|
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T,
|
||||||
typename DataType = typename T::value_type,
|
typename DataType = typename T::value_type,
|
||||||
typename Dummy = std::enable_if_t<
|
typename Dummy = std::enable_if_t<
|
||||||
!gsl::details::is_multi_span<T>::value
|
!gsl::details::is_span<T>::value
|
||||||
&& !gsl::details::is_basic_string_span<T>::value
|
&& !gsl::details::is_basic_string_span<T>::value
|
||||||
&& std::is_convertible<DataType*, CharT*>::value
|
&& std::is_convertible<DataType*, CharT*>::value
|
||||||
&& std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, DataType>::value>
|
&& std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, DataType>::value>
|
||||||
@ -759,10 +756,10 @@ bool operator<(gsl::basic_string_span<CharT, Extent> one, const T& other) noexce
|
|||||||
return std::lexicographical_compare(one.begin(), one.end(), tmp.begin(), tmp.end());
|
return std::lexicographical_compare(one.begin(), one.end(), tmp.begin(), tmp.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_range, typename T,
|
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T,
|
||||||
typename DataType = typename T::value_type,
|
typename DataType = typename T::value_type,
|
||||||
typename Dummy = std::enable_if_t<
|
typename Dummy = std::enable_if_t<
|
||||||
!gsl::details::is_multi_span<T>::value
|
!gsl::details::is_span<T>::value
|
||||||
&& !gsl::details::is_basic_string_span<T>::value
|
&& !gsl::details::is_basic_string_span<T>::value
|
||||||
&& std::is_convertible<DataType*, CharT*>::value
|
&& std::is_convertible<DataType*, CharT*>::value
|
||||||
&& std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, DataType>::value>
|
&& std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, DataType>::value>
|
||||||
@ -775,7 +772,7 @@ bool operator<(const T& one, gsl::basic_string_span<CharT, Extent> other) noexce
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// operator <=
|
// operator <=
|
||||||
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_range, typename T,
|
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T,
|
||||||
typename = std::enable_if_t<
|
typename = std::enable_if_t<
|
||||||
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>
|
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>
|
||||||
>
|
>
|
||||||
@ -784,7 +781,7 @@ bool operator<=(gsl::basic_string_span<CharT, Extent> one, const T& other) noexc
|
|||||||
return !(other < one);
|
return !(other < one);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_range, typename T,
|
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T,
|
||||||
typename Dummy = std::enable_if_t<
|
typename Dummy = std::enable_if_t<
|
||||||
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value
|
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value
|
||||||
&& !gsl::details::is_basic_string_span<T>::value>
|
&& !gsl::details::is_basic_string_span<T>::value>
|
||||||
@ -799,10 +796,10 @@ bool operator<=(const T& one, gsl::basic_string_span<CharT, Extent> other) noexc
|
|||||||
// VS treats temp and const containers as convertible to basic_string_span,
|
// VS treats temp and const containers as convertible to basic_string_span,
|
||||||
// so the cases below are already covered by the previous operators
|
// so the cases below are already covered by the previous operators
|
||||||
|
|
||||||
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_range, typename T,
|
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T,
|
||||||
typename DataType = typename T::value_type,
|
typename DataType = typename T::value_type,
|
||||||
typename Dummy = std::enable_if_t<
|
typename Dummy = std::enable_if_t<
|
||||||
!gsl::details::is_multi_span<T>::value
|
!gsl::details::is_span<T>::value
|
||||||
&& !gsl::details::is_basic_string_span<T>::value
|
&& !gsl::details::is_basic_string_span<T>::value
|
||||||
&& std::is_convertible<DataType*, CharT*>::value
|
&& std::is_convertible<DataType*, CharT*>::value
|
||||||
&& std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, DataType>::value>
|
&& std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, DataType>::value>
|
||||||
@ -812,10 +809,10 @@ bool operator<=(gsl::basic_string_span<CharT, Extent> one, const T& other) noexc
|
|||||||
return !(other < one);
|
return !(other < one);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_range, typename T,
|
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T,
|
||||||
typename DataType = typename T::value_type,
|
typename DataType = typename T::value_type,
|
||||||
typename Dummy = std::enable_if_t<
|
typename Dummy = std::enable_if_t<
|
||||||
!gsl::details::is_multi_span<T>::value
|
!gsl::details::is_span<T>::value
|
||||||
&& !gsl::details::is_basic_string_span<T>::value
|
&& !gsl::details::is_basic_string_span<T>::value
|
||||||
&& std::is_convertible<DataType*, CharT*>::value
|
&& std::is_convertible<DataType*, CharT*>::value
|
||||||
&& std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, DataType>::value>
|
&& std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, DataType>::value>
|
||||||
@ -827,7 +824,7 @@ bool operator<=(const T& one, gsl::basic_string_span<CharT, Extent> other) noexc
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// operator>
|
// operator>
|
||||||
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_range, typename T,
|
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T,
|
||||||
typename = std::enable_if_t<
|
typename = std::enable_if_t<
|
||||||
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>
|
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>
|
||||||
>
|
>
|
||||||
@ -836,7 +833,7 @@ bool operator>(gsl::basic_string_span<CharT, Extent> one, const T& other) noexce
|
|||||||
return other < one;
|
return other < one;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_range, typename T,
|
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T,
|
||||||
typename Dummy = std::enable_if_t<
|
typename Dummy = std::enable_if_t<
|
||||||
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value
|
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value
|
||||||
&& !gsl::details::is_basic_string_span<T>::value>
|
&& !gsl::details::is_basic_string_span<T>::value>
|
||||||
@ -851,10 +848,10 @@ bool operator>(const T& one, gsl::basic_string_span<CharT, Extent> other) noexce
|
|||||||
// VS treats temp and const containers as convertible to basic_string_span,
|
// VS treats temp and const containers as convertible to basic_string_span,
|
||||||
// so the cases below are already covered by the previous operators
|
// so the cases below are already covered by the previous operators
|
||||||
|
|
||||||
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_range, typename T,
|
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T,
|
||||||
typename DataType = typename T::value_type,
|
typename DataType = typename T::value_type,
|
||||||
typename Dummy = std::enable_if_t<
|
typename Dummy = std::enable_if_t<
|
||||||
!gsl::details::is_multi_span<T>::value
|
!gsl::details::is_span<T>::value
|
||||||
&& !gsl::details::is_basic_string_span<T>::value
|
&& !gsl::details::is_basic_string_span<T>::value
|
||||||
&& std::is_convertible<DataType*, CharT*>::value
|
&& std::is_convertible<DataType*, CharT*>::value
|
||||||
&& std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, DataType>::value>
|
&& std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, DataType>::value>
|
||||||
@ -864,10 +861,10 @@ bool operator>(gsl::basic_string_span<CharT, Extent> one, const T& other) noexce
|
|||||||
return other < one;
|
return other < one;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_range, typename T,
|
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T,
|
||||||
typename DataType = typename T::value_type,
|
typename DataType = typename T::value_type,
|
||||||
typename Dummy = std::enable_if_t<
|
typename Dummy = std::enable_if_t<
|
||||||
!gsl::details::is_multi_span<T>::value
|
!gsl::details::is_span<T>::value
|
||||||
&& !gsl::details::is_basic_string_span<T>::value
|
&& !gsl::details::is_basic_string_span<T>::value
|
||||||
&& std::is_convertible<DataType*, CharT*>::value
|
&& std::is_convertible<DataType*, CharT*>::value
|
||||||
&& std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, DataType>::value>
|
&& std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, DataType>::value>
|
||||||
@ -879,7 +876,7 @@ bool operator>(const T& one, gsl::basic_string_span<CharT, Extent> other) noexce
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// operator >=
|
// operator >=
|
||||||
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_range, typename T,
|
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T,
|
||||||
typename = std::enable_if_t<
|
typename = std::enable_if_t<
|
||||||
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>
|
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>
|
||||||
>
|
>
|
||||||
@ -888,7 +885,7 @@ bool operator>=(gsl::basic_string_span<CharT, Extent> one, const T& other) noexc
|
|||||||
return !(one < other);
|
return !(one < other);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_range, typename T,
|
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T,
|
||||||
typename Dummy = std::enable_if_t<
|
typename Dummy = std::enable_if_t<
|
||||||
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value
|
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value
|
||||||
&& !gsl::details::is_basic_string_span<T>::value>
|
&& !gsl::details::is_basic_string_span<T>::value>
|
||||||
@ -903,10 +900,10 @@ bool operator>=(const T& one, gsl::basic_string_span<CharT, Extent> other) noexc
|
|||||||
// VS treats temp and const containers as convertible to basic_string_span,
|
// VS treats temp and const containers as convertible to basic_string_span,
|
||||||
// so the cases below are already covered by the previous operators
|
// so the cases below are already covered by the previous operators
|
||||||
|
|
||||||
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_range, typename T,
|
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T,
|
||||||
typename DataType = typename T::value_type,
|
typename DataType = typename T::value_type,
|
||||||
typename Dummy = std::enable_if_t<
|
typename Dummy = std::enable_if_t<
|
||||||
!gsl::details::is_multi_span<T>::value
|
!gsl::details::is_span<T>::value
|
||||||
&& !gsl::details::is_basic_string_span<T>::value
|
&& !gsl::details::is_basic_string_span<T>::value
|
||||||
&& std::is_convertible<DataType*, CharT*>::value
|
&& std::is_convertible<DataType*, CharT*>::value
|
||||||
&& std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, DataType>::value>
|
&& std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, DataType>::value>
|
||||||
@ -916,10 +913,10 @@ bool operator>=(gsl::basic_string_span<CharT, Extent> one, const T& other) noexc
|
|||||||
return !(one < other);
|
return !(one < other);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_range, typename T,
|
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T,
|
||||||
typename DataType = typename T::value_type,
|
typename DataType = typename T::value_type,
|
||||||
typename Dummy = std::enable_if_t<
|
typename Dummy = std::enable_if_t<
|
||||||
!gsl::details::is_multi_span<T>::value
|
!gsl::details::is_span<T>::value
|
||||||
&& !gsl::details::is_basic_string_span<T>::value
|
&& !gsl::details::is_basic_string_span<T>::value
|
||||||
&& std::is_convertible<DataType*, CharT*>::value
|
&& std::is_convertible<DataType*, CharT*>::value
|
||||||
&& std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, DataType>::value>
|
&& std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, DataType>::value>
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include <UnitTest++/UnitTest++.h>
|
#include <UnitTest++/UnitTest++.h>
|
||||||
#include <byte.h>
|
#include <gsl_byte.h>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
@ -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::multi_span<const char> sp = ensure_z("Hello");
|
gsl::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::multi_span<char> sp = ensure_z(ar1);
|
gsl::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::multi_span<const char> sp = ensure_z("Hello");
|
gsl::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::multi_span<char> _sp{ _ar, 5 };
|
gsl::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
|
||||||
{
|
{
|
||||||
multi_span<const char, 6> sp = "Hello";
|
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
|
||||||
{
|
{
|
||||||
multi_span<const char, 6> sp = "Hello";
|
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 multi_span<const char> inner = vec;
|
const 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' };
|
||||||
multi_span<char> inner = vec;
|
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 multi_span<const char> inner = vec;
|
const 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' };
|
||||||
multi_span<char> inner = vec;
|
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 multi_span<char> inner = vec;
|
const span<char> inner = vec;
|
||||||
string_span<> span = inner;
|
string_span<> span = inner;
|
||||||
CHECK(span.length() == 5);
|
CHECK(span.length() == 5);
|
||||||
#endif
|
#endif
|
||||||
@ -746,7 +746,7 @@ SUITE(string_span_tests)
|
|||||||
T create() { return T{}; }
|
T create() { return T{}; }
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
void use(basic_string_span<T, gsl::dynamic_range> s) {}
|
void use(basic_string_span<T, gsl::dynamic_extent> s) {}
|
||||||
|
|
||||||
TEST(MoveConstructors)
|
TEST(MoveConstructors)
|
||||||
{
|
{
|
||||||
@ -769,12 +769,12 @@ SUITE(string_span_tests)
|
|||||||
|
|
||||||
// move span
|
// move span
|
||||||
{
|
{
|
||||||
multi_span<const char> span = ensure_z("Hello");
|
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);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
multi_span<const char> span = ensure_z("Hello");
|
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);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user