From ed3fea6d9317305e27ff3022424791d78369a6ff Mon Sep 17 00:00:00 2001 From: Jordan Maples Date: Wed, 20 May 2020 13:11:37 -0700 Subject: [PATCH] implementing some of Casey's recommendations --- include/gsl/span | 65 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 44 insertions(+), 21 deletions(-) diff --git a/include/gsl/span b/include/gsl/span index f933493..1cb9e84 100644 --- a/include/gsl/span +++ b/include/gsl/span @@ -343,15 +343,9 @@ namespace details constexpr extent_type() noexcept = default; - template - constexpr extent_type(extent_type ext) - { - static_assert(Other == Ext, - "Mismatch between fixed-size extent and size of initializing data."); - Expects(ext.size() == Ext); - } + explicit constexpr extent_type(extent_type); - constexpr extent_type(size_type size) { Expects(size == Ext); } + explicit constexpr extent_type(size_type size) { Expects(size == Ext); } constexpr size_type size() const noexcept { return Ext; } }; @@ -377,6 +371,12 @@ namespace details size_type size_; }; + template + constexpr extent_type::extent_type(extent_type ext) + { + Expects(ext.size() == Ext); + } + template struct calculate_subspan_type { @@ -466,26 +466,51 @@ public: : storage_(KnownNotNull{arr.data()}, details::extent_type()) {} - // NB: the SFINAE here uses .data() as an incomplete/imperfect proxy for the requirement - // on Container to be a contiguous sequence container. - template ::value && !details::is_std_array::value && std::is_pointer().data())>::value && std::is_convertible< std::remove_pointer_t().data())> (*)[], - element_type (*)[]>::value>> + element_type (*)[]>::value, int> = 0> + constexpr explicit span(Container& cont) noexcept : span(cont.data(), cont.size()) + {} + + template ::value && !details::is_std_array::value && + std::is_pointer().data())>::value && + std::is_convertible< + std::remove_pointer_t().data())> (*)[], + element_type (*)[]>::value, int> = 0> constexpr span(Container& cont) noexcept : span(cont.data(), cont.size()) {} - template ::value && !details::is_span::value && !details::is_std_array::value && std::is_pointer().data())>::value && std::is_convertible().data())> (*)[], - element_type (*)[]>::value>> + decltype(std::declval().data())> (*)[], + element_type (*)[]>::value, int> = 0> + constexpr explicit span(const Container& cont) noexcept : span(cont.data(), cont.size()) + {} + + template ::value && !details::is_span::value && + !details::is_std_array::value && + std::is_pointer().data())>::value && + std::is_convertible().data())> (*)[], + element_type (*)[]>::value, int> = 0> constexpr span(const Container& cont) noexcept : span(cont.data(), cont.size()) {} @@ -494,8 +519,7 @@ public: template < class OtherElementType, std::size_t OtherExtent, std::size_t SpanExtent = Extent, std::enable_if_t< - !(SpanExtent != dynamic_extent && OtherExtent == dynamic_extent) && - (Extent == dynamic_extent || OtherExtent == dynamic_extent || Extent == OtherExtent) && + (SpanExtent == dynamic_extent || OtherExtent == dynamic_extent) && details::is_allowed_element_type_conversion::value, int> = 0> constexpr span(const span& other) noexcept : storage_(other.data(), details::extent_type(other.size())) @@ -504,8 +528,7 @@ public: template < class OtherElementType, std::size_t OtherExtent, std::size_t SpanExtent = Extent, std::enable_if_t< - (SpanExtent != dynamic_extent && OtherExtent == dynamic_extent) && - (Extent == dynamic_extent || OtherExtent == dynamic_extent || Extent == OtherExtent) && + SpanExtent != dynamic_extent && OtherExtent == dynamic_extent && details::is_allowed_element_type_conversion::value, int> = 0> constexpr explicit span(const span& other) noexcept : storage_(other.data(), details::extent_type(other.size()))