From af69e1fb8bfc2c4f53abc0bffed852a3394eb245 Mon Sep 17 00:00:00 2001 From: Vincent Coubard Date: Fri, 24 Aug 2018 11:10:17 +0100 Subject: [PATCH] Span: use static assert to kill copy construction from an incompatible span type. Copy construction between Span of compatible type is allowed to fulfil the use case Span -> Span. This is achieved by a templated copy constructor like constructor. In p0122, the overload is discarded from the constructor set if the ElementType of the Span in input is not convertible into the ElementType of the Span being constructed. To discard function overload, SFINAE has to be used which polutes the documentation and make the code harder to read and maintain. Unlike p0122, our Span class doesn't exposes (yet) functions with default argument or functions that convert container in input into span the only overload with the a single parameter that we exposes are: - template Span(ElementType (&element)[N]) - Span(const Span& other): <- generated by the compiler. For both of this functions we expect exact match and their resolution should not interfere with the constructor that converts from another type of Span. As a result it is possible to rely solely on C++ default resolution rules as we won't hit cases were constructors convert from another type (std::array, std container, span) and raise an error with a static assert if the element type can't be converted. If another copy - conversion - constructor is added then SFINAE has to be reintroduced. --- platform/Span.h | 39 ++++++++++++++++----------------------- 1 file changed, 16 insertions(+), 23 deletions(-) diff --git a/platform/Span.h b/platform/Span.h index eb46c8afb4..3e04b1ea92 100644 --- a/platform/Span.h +++ b/platform/Span.h @@ -45,14 +45,6 @@ public: static const bool value = sizeof(true_type) == sizeof(sink(generator())); }; -template -struct enable_if; - -template -struct enable_if { - typedef ResultType type; -}; - } /** @@ -309,13 +301,14 @@ struct Span { * @note OtherElementType(*)[] should be convertible to ElementType(*)[]. */ template - Span( - const Span &other, - typename span_detail::enable_if< - span_detail::is_convertible::value - >::type* = 0 - ): - _data(other.data()) { } + Span(const Span &other): + _data(other.data()) + { + MBED_STATIC_ASSERT( + (span_detail::is_convertible::value), + "OtherElementType(*)[] should be convertible to ElementType (*)[]" + ); + } /** * Return the size of the sequence viewed. @@ -499,7 +492,6 @@ private: */ template struct Span { - /** * Type of the element contained */ @@ -598,13 +590,14 @@ struct Span { * @note OtherElementType(*)[] should be convertible to ElementType(*)[]. */ template - Span( - const Span &other, - typename span_detail::enable_if< - span_detail::is_convertible::value - >::type* = NULL - ): - _data(other.data()), _size(other.size()) { } + Span(const Span &other): + _data(other.data()), _size(other.size()) + { + MBED_STATIC_ASSERT( + (span_detail::is_convertible::value), + "OtherElementType(*)[] should be convertible to ElementType (*)[]" + ); + } /** * Return the size of the array viewed.