mirror of
https://github.com/microsoft/GSL.git
synced 2024-11-03 17:56:43 -05:00
Improved conformance of gsl::span for compile-time errors
as per 23.7.2.1: - span() and span(nullptr) can only be used if extent is dynamic or 0 - span( element_type(&arr)[N] ) can only be used if extent is dynamic or N - std::array can be used for initialization if extent is dynamic or size of the array - Containers can be used for initialization if pointer type is convertible as per 23.7.2.2 - first<N> and last<N> may no longer exceed the span extents
This commit is contained in:
parent
9d65e74400
commit
cdd9ee5a6a
@ -342,6 +342,7 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class = std::enable_if_t<Extent == dynamic_extent || Extent == 0>>
|
||||||
constexpr span(std::nullptr_t) GSL_NOEXCEPT : span() {}
|
constexpr span(std::nullptr_t) GSL_NOEXCEPT : span() {}
|
||||||
|
|
||||||
constexpr span(pointer ptr, index_type count) : storage_(ptr, count) {}
|
constexpr span(pointer ptr, index_type count) : storage_(ptr, count) {}
|
||||||
@ -351,19 +352,28 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
template <std::size_t N>
|
template <std::size_t N, class = std::enable_if_t<extent == dynamic_extent || N == extent>>
|
||||||
constexpr span(element_type (&arr)[N]) GSL_NOEXCEPT
|
constexpr span(element_type (&arr)[N]) GSL_NOEXCEPT
|
||||||
: storage_(&arr[0], details::extent_type<N>())
|
: storage_(&arr[0], details::extent_type<N>())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
template <std::size_t N, class ArrayElementType = std::remove_const_t<element_type>>
|
template <std::size_t N, class ArrayElementType = std::remove_const_t<element_type>,
|
||||||
constexpr span(std::array<ArrayElementType, N>& arr) GSL_NOEXCEPT
|
class = std::enable_if_t<
|
||||||
|
( extent == dynamic_extent || N == extent ) &&
|
||||||
|
std::is_convertible_v<std::add_pointer_t<ArrayElementType>, pointer>
|
||||||
|
>>
|
||||||
|
constexpr span( std::array<ArrayElementType, N>& arr )
|
||||||
: storage_(&arr[0], details::extent_type<N>())
|
: storage_(&arr[0], details::extent_type<N>())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
template <std::size_t N>
|
template <std::size_t N,
|
||||||
|
class = std::enable_if_t<
|
||||||
|
( extent == dynamic_extent || N == extent ) &&
|
||||||
|
std::is_const_v<element_type> &&
|
||||||
|
std::is_convertible_v<std::add_pointer_t<element_type>, pointer>
|
||||||
|
>>
|
||||||
constexpr span(const std::array<std::remove_const_t<element_type>, N>& arr) GSL_NOEXCEPT
|
constexpr span(const std::array<std::remove_const_t<element_type>, N>& arr) GSL_NOEXCEPT
|
||||||
: storage_(&arr[0], details::extent_type<N>())
|
: storage_(&arr[0], details::extent_type<N>())
|
||||||
{
|
{
|
||||||
@ -387,9 +397,7 @@ public:
|
|||||||
template <class Container,
|
template <class Container,
|
||||||
class = std::enable_if_t<
|
class = std::enable_if_t<
|
||||||
!details::is_span<Container>::value && !details::is_std_array<Container>::value &&
|
!details::is_span<Container>::value && !details::is_std_array<Container>::value &&
|
||||||
std::is_convertible<typename Container::pointer, pointer>::value &&
|
std::is_convertible<decltype(std::declval<Container>().data()), pointer>::value>>
|
||||||
std::is_convertible<typename Container::pointer,
|
|
||||||
decltype(std::declval<Container>().data())>::value>>
|
|
||||||
constexpr span(Container& cont) : span(cont.data(), narrow<index_type>(cont.size()))
|
constexpr span(Container& cont) : span(cont.data(), narrow<index_type>(cont.size()))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -397,9 +405,8 @@ public:
|
|||||||
template <class Container,
|
template <class Container,
|
||||||
class = std::enable_if_t<
|
class = std::enable_if_t<
|
||||||
std::is_const<element_type>::value && !details::is_span<Container>::value &&
|
std::is_const<element_type>::value && !details::is_span<Container>::value &&
|
||||||
std::is_convertible<typename Container::pointer, pointer>::value &&
|
!details::is_std_array<Container>::value &&
|
||||||
std::is_convertible<typename Container::pointer,
|
std::is_convertible<decltype(std::declval<Container>().data()), pointer>::value>>
|
||||||
decltype(std::declval<Container>().data())>::value>>
|
|
||||||
constexpr span(const Container& cont) : span(cont.data(), narrow<index_type>(cont.size()))
|
constexpr span(const Container& cont) : span(cont.data(), narrow<index_type>(cont.size()))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -433,14 +440,18 @@ public:
|
|||||||
constexpr span& operator=(span&& other) GSL_NOEXCEPT = default;
|
constexpr span& operator=(span&& other) GSL_NOEXCEPT = default;
|
||||||
|
|
||||||
// [span.sub], span subviews
|
// [span.sub], span subviews
|
||||||
template <std::ptrdiff_t Count>
|
template <std::ptrdiff_t Count,
|
||||||
|
class = std::enable_if_t<
|
||||||
|
Count >= 0 && ( extent == dynamic_extent || Count <= extent )>>
|
||||||
constexpr span<element_type, Count> first() const
|
constexpr span<element_type, Count> first() const
|
||||||
{
|
{
|
||||||
Expects(Count >= 0 && Count <= size());
|
Expects(Count >= 0 && Count <= size());
|
||||||
return {data(), Count};
|
return {data(), Count};
|
||||||
}
|
}
|
||||||
|
|
||||||
template <std::ptrdiff_t Count>
|
template <std::ptrdiff_t Count,
|
||||||
|
class = std::enable_if_t<
|
||||||
|
Count >= 0 && ( extent == dynamic_extent || Count <= extent )>>
|
||||||
constexpr span<element_type, Count> last() const
|
constexpr span<element_type, Count> last() const
|
||||||
{
|
{
|
||||||
Expects(Count >= 0 && size() - Count >= 0);
|
Expects(Count >= 0 && size() - Count >= 0);
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include <array> // for array
|
#include <array> // for array
|
||||||
#include <iostream> // for ptrdiff_t
|
#include <iostream> // for ptrdiff_t
|
||||||
#include <iterator> // for reverse_iterator, operator-, operator==
|
#include <iterator> // for reverse_iterator, operator-, operator==
|
||||||
|
#include <map> // for std::map
|
||||||
#include <memory> // for unique_ptr, shared_ptr, make_unique, allo...
|
#include <memory> // for unique_ptr, shared_ptr, make_unique, allo...
|
||||||
#include <regex> // for match_results, sub_match, match_results<>...
|
#include <regex> // for match_results, sub_match, match_results<>...
|
||||||
#include <stddef.h> // for ptrdiff_t
|
#include <stddef.h> // for ptrdiff_t
|
||||||
|
Loading…
Reference in New Issue
Block a user