|
25 | 25 |
|
26 | 26 | namespace mbed {
|
27 | 27 |
|
| 28 | +// Internal details of span |
| 29 | +// It is used construct span from span of convertible types (non const -> const) |
| 30 | +namespace span_detail { |
| 31 | + |
| 32 | +// If From type is convertible to To type then the compilation constant value is |
| 33 | +// true otherwise it is false. |
| 34 | +template<typename From, typename To> |
| 35 | +class is_convertible |
| 36 | +{ |
| 37 | + struct true_type { char x[512]; }; |
| 38 | + struct false_type { }; |
| 39 | + |
| 40 | + static const From& generator(); |
| 41 | + static true_type sink(const To &); |
| 42 | + static false_type sink(...); |
| 43 | + |
| 44 | +public: |
| 45 | + static const bool value = sizeof(true_type) == sizeof(sink(generator())); |
| 46 | +}; |
| 47 | + |
| 48 | +template<bool Condition, typename ResultType = void> |
| 49 | +struct enable_if; |
| 50 | + |
| 51 | +template<typename ResultType> |
| 52 | +struct enable_if<true, ResultType> { |
| 53 | + typedef ResultType type; |
| 54 | +}; |
| 55 | + |
| 56 | +} |
| 57 | + |
28 | 58 | /**
|
29 | 59 | * Special value for the Extent parameter of Span.
|
30 | 60 | * If the type use this value then the size of the array is stored in the object
|
@@ -269,6 +299,24 @@ struct Span {
|
269 | 299 | Span(element_type (&elements)[Extent]):
|
270 | 300 | _data(elements) { }
|
271 | 301 |
|
| 302 | + /** |
| 303 | + * Construct a Span object from another Span of the same size. |
| 304 | + * |
| 305 | + * @param other The Span object used to construct this. |
| 306 | + * |
| 307 | + * @note For span with a positive extent, this function is not accessible. |
| 308 | + * |
| 309 | + * @note OtherElementType(*)[] should be convertible to ElementType(*)[]. |
| 310 | + */ |
| 311 | + template<typename OtherElementType> |
| 312 | + Span( |
| 313 | + const Span<OtherElementType, Extent> &other, |
| 314 | + typename span_detail::enable_if< |
| 315 | + span_detail::is_convertible<OtherElementType (*)[], ElementType (*)[]>::value |
| 316 | + >::type* = 0 |
| 317 | + ): |
| 318 | + _data(other.data()) { } |
| 319 | + |
272 | 320 | /**
|
273 | 321 | * Return the size of the sequence viewed.
|
274 | 322 | *
|
@@ -540,16 +588,22 @@ struct Span<ElementType, SPAN_DYNAMIC_EXTENT> {
|
540 | 588 | Span(element_type (&elements)[Count]):
|
541 | 589 | _data(elements), _size(Count) { }
|
542 | 590 |
|
543 |
| - |
544 | 591 | /**
|
545 | 592 | * Construct a Span object from another Span.
|
546 | 593 | *
|
547 | 594 | * @param other The Span object used to construct this.
|
548 | 595 | *
|
549 | 596 | * @note For span with a positive extent, this function is not accessible.
|
| 597 | + * |
| 598 | + * @note OtherElementType(*)[] should be convertible to ElementType(*)[]. |
550 | 599 | */
|
551 |
| - template<ptrdiff_t OtherExtent> |
552 |
| - Span(const Span<element_type, OtherExtent> &other): |
| 600 | + template<typename OtherElementType, ptrdiff_t OtherExtent> |
| 601 | + Span( |
| 602 | + const Span<OtherElementType, OtherExtent> &other, |
| 603 | + typename span_detail::enable_if< |
| 604 | + span_detail::is_convertible<OtherElementType (*)[], ElementType (*)[]>::value |
| 605 | + >::type* = NULL |
| 606 | + ): |
553 | 607 | _data(other.data()), _size(other.size()) { }
|
554 | 608 |
|
555 | 609 | /**
|
|
0 commit comments