mirror of
https://github.com/microsoft/GSL.git
synced 2024-11-03 17:56:43 -05:00
Added from-container constructors.
This commit is contained in:
parent
f61a9bba48
commit
c40094a532
@ -1156,22 +1156,22 @@ namespace details
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct is_span_oracle : std::false_type
|
||||
struct is_multi_span_oracle : std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
template <typename ValueType, std::ptrdiff_t FirstDimension, std::ptrdiff_t... RestDimensions>
|
||||
struct is_span_oracle<multi_span<ValueType, FirstDimension, RestDimensions...>> : std::true_type
|
||||
struct is_multi_span_oracle<multi_span<ValueType, FirstDimension, RestDimensions...>> : std::true_type
|
||||
{
|
||||
};
|
||||
|
||||
template <typename ValueType, std::ptrdiff_t Rank>
|
||||
struct is_span_oracle<strided_span<ValueType, Rank>> : std::true_type
|
||||
struct is_multi_span_oracle<strided_span<ValueType, Rank>> : std::true_type
|
||||
{
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct is_span : is_span_oracle<std::remove_cv_t<T>>
|
||||
struct is_multi_span : is_multi_span_oracle<std::remove_cv_t<T>>
|
||||
{
|
||||
};
|
||||
}
|
||||
@ -1324,7 +1324,7 @@ public:
|
||||
// type-requirements: container must have .size(), operator[] which are value_type compatible
|
||||
template <typename Cont, typename DataType = typename Cont::value_type,
|
||||
typename = std::enable_if_t<
|
||||
!details::is_span<Cont>::value &&
|
||||
!details::is_multi_span<Cont>::value &&
|
||||
std::is_convertible<DataType (*)[], value_type (*)[]>::value &&
|
||||
std::is_same<std::decay_t<decltype(std::declval<Cont>().size(),
|
||||
*std::declval<Cont>().data())>,
|
||||
@ -1338,7 +1338,7 @@ public:
|
||||
// prevent constructing from temporary containers
|
||||
template <typename Cont, typename DataType = typename Cont::value_type,
|
||||
typename = std::enable_if_t<
|
||||
!details::is_span<Cont>::value &&
|
||||
!details::is_multi_span<Cont>::value &&
|
||||
std::is_convertible<DataType (*)[], value_type (*)[]>::value &&
|
||||
std::is_same<std::decay_t<decltype(std::declval<Cont>().size(),
|
||||
*std::declval<Cont>().data())>,
|
||||
@ -1595,7 +1595,7 @@ template <typename SpanType, typename... Dimensions2, size_t DimCount = sizeof..
|
||||
constexpr multi_span<typename SpanType::value_type, Dimensions2::value...> as_span(SpanType s,
|
||||
Dimensions2... dims)
|
||||
{
|
||||
static_assert(details::is_span<SpanType>::value,
|
||||
static_assert(details::is_multi_span<SpanType>::value,
|
||||
"Variadic as_span() is for reshaping existing spans.");
|
||||
using BoundsType =
|
||||
typename multi_span<typename SpanType::value_type, (Dimensions2::value)...>::bounds_type;
|
||||
@ -1718,7 +1718,7 @@ constexpr multi_span<T, dynamic_range> as_span(T* begin, T* end)
|
||||
|
||||
template <typename Cont>
|
||||
constexpr auto as_span(Cont& arr) -> std::enable_if_t<
|
||||
!details::is_span<std::decay_t<Cont>>::value,
|
||||
!details::is_multi_span<std::decay_t<Cont>>::value,
|
||||
multi_span<std::remove_reference_t<decltype(arr.size(), *arr.data())>, dynamic_range>>
|
||||
{
|
||||
Expects(arr.size() < PTRDIFF_MAX);
|
||||
@ -1727,7 +1727,7 @@ constexpr auto as_span(Cont& arr) -> std::enable_if_t<
|
||||
|
||||
template <typename Cont>
|
||||
constexpr auto as_span(Cont&& arr) -> std::enable_if_t<
|
||||
!details::is_span<std::decay_t<Cont>>::value,
|
||||
!details::is_multi_span<std::decay_t<Cont>>::value,
|
||||
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
|
||||
|
@ -72,12 +72,35 @@
|
||||
namespace gsl
|
||||
{
|
||||
|
||||
template <class ElementType, std::ptrdiff_t Extent = dynamic_extent>
|
||||
class span;
|
||||
|
||||
|
||||
namespace details
|
||||
{
|
||||
template <class T>
|
||||
struct is_span_oracle : std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
template <class ElementType, std::ptrdiff_t Extent>
|
||||
struct is_span_oracle<gsl::span<ElementType, Extent>> : std::true_type
|
||||
{
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_span : is_span_oracle<std::remove_cv_t<T>>
|
||||
{
|
||||
};
|
||||
} // namespace details
|
||||
|
||||
|
||||
// [views.constants], constants
|
||||
constexpr const std::ptrdiff_t dynamic_extent = -1;
|
||||
|
||||
|
||||
// [span], class template span
|
||||
template <class ElementType, std::ptrdiff_t Extent = dynamic_extent>
|
||||
template <class ElementType, std::ptrdiff_t Extent>
|
||||
class span {
|
||||
public:
|
||||
// constants and types
|
||||
@ -122,11 +145,25 @@ public:
|
||||
: storage_(&arr[0], extent_type<N>())
|
||||
{}
|
||||
|
||||
#if 0 // TODO
|
||||
template <class Container>
|
||||
constexpr span(Container& cont);
|
||||
template <class Container>
|
||||
// NB: the SFINAE here uses .data() as a incomplete/imperfect proxy for the requirement
|
||||
// on Container to be a contiguous sequence container.
|
||||
template <class Container,
|
||||
class = std::enable_if_t<!details::is_span<Container>::value &&
|
||||
std::is_convertible<Container::pointer, pointer>::value &&
|
||||
std::is_convertible<Container::pointer, decltype(std::declval<Container>().data())>::value>
|
||||
>
|
||||
constexpr span(Container& cont) : span(cont.data(), cont.size()) {}
|
||||
|
||||
// NB: the SFINAE here uses .data() as an incomplete/imperfect proxy for the requirement
|
||||
// on Container to be a contiguous sequence container.
|
||||
template <class Container,
|
||||
class = std::enable_if_t<!details::is_span<Container>::value &&
|
||||
std::is_convertible<Container::pointer, pointer>::value &&
|
||||
std::is_convertible<Container::pointer, decltype(std::declval<Container>().data())>::value>
|
||||
>
|
||||
span(const Container&&) = delete;
|
||||
|
||||
#if 0 // TODO
|
||||
constexpr span(const span& other) noexcept = default;
|
||||
constexpr span(span&& other) noexcept = default;
|
||||
template <class OtherElementType, ptrdiff_t OtherExtent>
|
||||
@ -231,9 +268,6 @@ private:
|
||||
storage_type(pointer data, OtherExtentType ext)
|
||||
: ExtentType(ext), data_(data) {}
|
||||
|
||||
//storage_type(pointer data, ExtentType ext)
|
||||
// : ExtentType(ext), data_(data) {}
|
||||
|
||||
constexpr inline pointer data() const noexcept
|
||||
{ return data_; }
|
||||
|
||||
|
@ -297,7 +297,7 @@ public:
|
||||
|
||||
// from containers. Containers must have .size() and .data() function signatures
|
||||
template <typename Cont, typename DataType = typename Cont::value_type,
|
||||
typename Dummy = std::enable_if_t<!details::is_span<Cont>::value
|
||||
typename Dummy = std::enable_if_t<!details::is_multi_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
|
||||
&& std::is_convertible<DataType*, value_type*>::value
|
||||
@ -309,7 +309,7 @@ public:
|
||||
|
||||
// disallow creation from temporary containers and strings
|
||||
template <typename Cont, typename DataType = typename Cont::value_type,
|
||||
typename Dummy = std::enable_if_t<!details::is_span<Cont>::value
|
||||
typename Dummy = std::enable_if_t<!details::is_multi_span<Cont>::value
|
||||
&& !details::is_basic_string_span<Cont>::value
|
||||
&& std::is_convertible<DataType*, value_type*>::value
|
||||
&& std::is_same<std::decay_t<decltype(std::declval<Cont>().size(), *std::declval<Cont>().data())>, DataType>::value>
|
||||
@ -640,7 +640,7 @@ bool operator==(const T& one, gsl::basic_string_span<CharT, Extent> other) noexc
|
||||
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_range, typename T,
|
||||
typename DataType = typename T::value_type,
|
||||
typename Dummy = std::enable_if_t<
|
||||
!gsl::details::is_span<T>::value
|
||||
!gsl::details::is_multi_span<T>::value
|
||||
&& !gsl::details::is_basic_string_span<T>::value
|
||||
&& std::is_convertible<DataType*, CharT*>::value
|
||||
&& std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, DataType>::value>
|
||||
@ -654,7 +654,7 @@ bool operator==(gsl::basic_string_span<CharT, Extent> one, const T& other) noexc
|
||||
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_range, typename T,
|
||||
typename DataType = typename T::value_type,
|
||||
typename Dummy = std::enable_if_t<
|
||||
!gsl::details::is_span<T>::value
|
||||
!gsl::details::is_multi_span<T>::value
|
||||
&& !gsl::details::is_basic_string_span<T>::value
|
||||
&& std::is_convertible<DataType*, CharT*>::value
|
||||
&& std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, DataType>::value>
|
||||
@ -694,7 +694,7 @@ bool operator!=(const T& one, gsl::basic_string_span<CharT, Extent> other) noexc
|
||||
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_range, typename T,
|
||||
typename DataType = typename T::value_type,
|
||||
typename Dummy = std::enable_if_t<
|
||||
!gsl::details::is_span<T>::value
|
||||
!gsl::details::is_multi_span<T>::value
|
||||
&& !gsl::details::is_basic_string_span<T>::value
|
||||
&& std::is_convertible<DataType*, CharT*>::value
|
||||
&& std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, DataType>::value>
|
||||
@ -707,7 +707,7 @@ bool operator!=(gsl::basic_string_span<CharT, Extent> one, const T& other) noexc
|
||||
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_range, typename T,
|
||||
typename DataType = typename T::value_type,
|
||||
typename Dummy = std::enable_if_t<
|
||||
!gsl::details::is_span<T>::value
|
||||
!gsl::details::is_multi_span<T>::value
|
||||
&& !gsl::details::is_basic_string_span<T>::value
|
||||
&& std::is_convertible<DataType*, CharT*>::value
|
||||
&& std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, DataType>::value>
|
||||
@ -748,7 +748,7 @@ bool operator<(const T& one, gsl::basic_string_span<CharT, Extent> other) noexce
|
||||
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_range, typename T,
|
||||
typename DataType = typename T::value_type,
|
||||
typename Dummy = std::enable_if_t<
|
||||
!gsl::details::is_span<T>::value
|
||||
!gsl::details::is_multi_span<T>::value
|
||||
&& !gsl::details::is_basic_string_span<T>::value
|
||||
&& std::is_convertible<DataType*, CharT*>::value
|
||||
&& std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, DataType>::value>
|
||||
@ -762,7 +762,7 @@ bool operator<(gsl::basic_string_span<CharT, Extent> one, const T& other) noexce
|
||||
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_range, typename T,
|
||||
typename DataType = typename T::value_type,
|
||||
typename Dummy = std::enable_if_t<
|
||||
!gsl::details::is_span<T>::value
|
||||
!gsl::details::is_multi_span<T>::value
|
||||
&& !gsl::details::is_basic_string_span<T>::value
|
||||
&& std::is_convertible<DataType*, CharT*>::value
|
||||
&& std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, DataType>::value>
|
||||
@ -802,7 +802,7 @@ bool operator<=(const T& one, gsl::basic_string_span<CharT, Extent> other) noexc
|
||||
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_range, typename T,
|
||||
typename DataType = typename T::value_type,
|
||||
typename Dummy = std::enable_if_t<
|
||||
!gsl::details::is_span<T>::value
|
||||
!gsl::details::is_multi_span<T>::value
|
||||
&& !gsl::details::is_basic_string_span<T>::value
|
||||
&& std::is_convertible<DataType*, CharT*>::value
|
||||
&& std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, DataType>::value>
|
||||
@ -815,7 +815,7 @@ bool operator<=(gsl::basic_string_span<CharT, Extent> one, const T& other) noexc
|
||||
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_range, typename T,
|
||||
typename DataType = typename T::value_type,
|
||||
typename Dummy = std::enable_if_t<
|
||||
!gsl::details::is_span<T>::value
|
||||
!gsl::details::is_multi_span<T>::value
|
||||
&& !gsl::details::is_basic_string_span<T>::value
|
||||
&& std::is_convertible<DataType*, CharT*>::value
|
||||
&& std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, DataType>::value>
|
||||
@ -854,7 +854,7 @@ bool operator>(const T& one, gsl::basic_string_span<CharT, Extent> other) noexce
|
||||
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_range, typename T,
|
||||
typename DataType = typename T::value_type,
|
||||
typename Dummy = std::enable_if_t<
|
||||
!gsl::details::is_span<T>::value
|
||||
!gsl::details::is_multi_span<T>::value
|
||||
&& !gsl::details::is_basic_string_span<T>::value
|
||||
&& std::is_convertible<DataType*, CharT*>::value
|
||||
&& std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, DataType>::value>
|
||||
@ -867,7 +867,7 @@ bool operator>(gsl::basic_string_span<CharT, Extent> one, const T& other) noexce
|
||||
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_range, typename T,
|
||||
typename DataType = typename T::value_type,
|
||||
typename Dummy = std::enable_if_t<
|
||||
!gsl::details::is_span<T>::value
|
||||
!gsl::details::is_multi_span<T>::value
|
||||
&& !gsl::details::is_basic_string_span<T>::value
|
||||
&& std::is_convertible<DataType*, CharT*>::value
|
||||
&& std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, DataType>::value>
|
||||
@ -906,7 +906,7 @@ bool operator>=(const T& one, gsl::basic_string_span<CharT, Extent> other) noexc
|
||||
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_range, typename T,
|
||||
typename DataType = typename T::value_type,
|
||||
typename Dummy = std::enable_if_t<
|
||||
!gsl::details::is_span<T>::value
|
||||
!gsl::details::is_multi_span<T>::value
|
||||
&& !gsl::details::is_basic_string_span<T>::value
|
||||
&& std::is_convertible<DataType*, CharT*>::value
|
||||
&& std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, DataType>::value>
|
||||
@ -919,7 +919,7 @@ bool operator>=(gsl::basic_string_span<CharT, Extent> one, const T& other) noexc
|
||||
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_range, typename T,
|
||||
typename DataType = typename T::value_type,
|
||||
typename Dummy = std::enable_if_t<
|
||||
!gsl::details::is_span<T>::value
|
||||
!gsl::details::is_multi_span<T>::value
|
||||
&& !gsl::details::is_basic_string_span<T>::value
|
||||
&& std::is_convertible<DataType*, CharT*>::value
|
||||
&& std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, DataType>::value>
|
||||
|
@ -438,7 +438,7 @@ SUITE(span_tests)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#if 0
|
||||
|
||||
TEST(from_container_constructor)
|
||||
{
|
||||
std::vector<int> v = {1, 2, 3};
|
||||
@ -512,7 +512,7 @@ SUITE(span_tests)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
TEST(from_convertible_span_constructor)
|
||||
{
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
|
@ -46,7 +46,7 @@ SUITE(string_span_tests)
|
||||
TEST(TestConstructFromStdVector)
|
||||
{
|
||||
std::vector<char> vec(5, 'h');
|
||||
string_span<> v = vec;
|
||||
string_span<> v {vec};
|
||||
CHECK(v.length() == static_cast<string_span<>::size_type>(vec.size()));
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user