mirror of https://github.com/ARMmbed/mbed-os.git
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<T> -> Span<const T>. 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<size_t N> 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.pull/7828/head
parent
d5051a8ca7
commit
af69e1fb8b
|
|
@ -45,14 +45,6 @@ public:
|
|||
static const bool value = sizeof(true_type) == sizeof(sink(generator()));
|
||||
};
|
||||
|
||||
template<bool Condition, typename ResultType = void>
|
||||
struct enable_if;
|
||||
|
||||
template<typename ResultType>
|
||||
struct enable_if<true, ResultType> {
|
||||
typedef ResultType type;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -309,13 +301,14 @@ struct Span {
|
|||
* @note OtherElementType(*)[] should be convertible to ElementType(*)[].
|
||||
*/
|
||||
template<typename OtherElementType>
|
||||
Span(
|
||||
const Span<OtherElementType, Extent> &other,
|
||||
typename span_detail::enable_if<
|
||||
span_detail::is_convertible<OtherElementType (*)[], ElementType (*)[]>::value
|
||||
>::type* = 0
|
||||
):
|
||||
_data(other.data()) { }
|
||||
Span(const Span<OtherElementType, Extent> &other):
|
||||
_data(other.data())
|
||||
{
|
||||
MBED_STATIC_ASSERT(
|
||||
(span_detail::is_convertible<OtherElementType (*)[], ElementType (*)[]>::value),
|
||||
"OtherElementType(*)[] should be convertible to ElementType (*)[]"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the size of the sequence viewed.
|
||||
|
|
@ -499,7 +492,6 @@ private:
|
|||
*/
|
||||
template<typename ElementType>
|
||||
struct Span<ElementType, SPAN_DYNAMIC_EXTENT> {
|
||||
|
||||
/**
|
||||
* Type of the element contained
|
||||
*/
|
||||
|
|
@ -598,13 +590,14 @@ struct Span<ElementType, SPAN_DYNAMIC_EXTENT> {
|
|||
* @note OtherElementType(*)[] should be convertible to ElementType(*)[].
|
||||
*/
|
||||
template<typename OtherElementType, ptrdiff_t OtherExtent>
|
||||
Span(
|
||||
const Span<OtherElementType, OtherExtent> &other,
|
||||
typename span_detail::enable_if<
|
||||
span_detail::is_convertible<OtherElementType (*)[], ElementType (*)[]>::value
|
||||
>::type* = NULL
|
||||
):
|
||||
_data(other.data()), _size(other.size()) { }
|
||||
Span(const Span<OtherElementType, OtherExtent> &other):
|
||||
_data(other.data()), _size(other.size())
|
||||
{
|
||||
MBED_STATIC_ASSERT(
|
||||
(span_detail::is_convertible<OtherElementType (*)[], ElementType (*)[]>::value),
|
||||
"OtherElementType(*)[] should be convertible to ElementType (*)[]"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the size of the array viewed.
|
||||
|
|
|
|||
Loading…
Reference in New Issue