From 2f0bfd605e4246f0a5c92b1f96abf235be80a3ab Mon Sep 17 00:00:00 2001 From: Marc Emmers Date: Fri, 6 Nov 2020 15:05:15 +0100 Subject: [PATCH 01/25] Adds basic span implementation --- platform/cxxsupport/mstd_span | 286 ++++++++++++++++++++++++++++++++++ 1 file changed, 286 insertions(+) create mode 100644 platform/cxxsupport/mstd_span diff --git a/platform/cxxsupport/mstd_span b/platform/cxxsupport/mstd_span new file mode 100644 index 00000000000..925f61465c4 --- /dev/null +++ b/platform/cxxsupport/mstd_span @@ -0,0 +1,286 @@ +/* mbed Microcontroller Library + * Copyright (c) 2019 ARM Limited + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MSTD_SPAN_ +#define MSTD_SPAN_ + +#include +#include + +namespace mstd { + +inline constexpr size_t dynamic_extent = -1; + +namespace detail { +template +class storage { +public: + constexpr storage() noexcept = default; + + constexpr storage(ElementType *ptr, size_t) noexcept : + _data(ptr) + {} + + ElementType* _data; + static constexpr size_t _size = Extent; +}; + +template +class storage { +public: + constexpr storage() noexcept = default; + + constexpr storage(ElementType *ptr, size_t size) noexcept : + _data(ptr), _size(size) + {} + + ElementType* _data; + size_t _size; +}; +} // namespace detail + +template +class span { +public: + using element_type = ElementType; + using value_type = typename mstd::remove_cv_t; + using index_type = size_t; + using difference_type = ptrdiff_t; + using pointer = element_type*; + using const_pointer = const element_type*; + using reference = element_type&; + using const_reference = const element_type&; + using iterator = pointer; + using reverse_iterator = std::reverse_iterator; + + static constexpr index_type extent = Extent; + + // Constructors, copy and assignment + template = 0> + constexpr span() noexcept + {} + + constexpr span(pointer ptr, index_type count) : + _storage(ptr, count) + { + MBED_ASSERT(extent == dynamic_extent || extent == count); + } + + constexpr span(pointer first, pointer last) : + _storage(first, last - first) + { + MBED_ASSERT(first <= last); + MBED_ASSERT(extent == dynamic_extent || extent == last - first); + MBED_ASSERT(extent == 0 || nullptr != first); + } + + template = 0> + constexpr span(element_type (&arr)[N]) noexcept: + _storage(arr, N) + {} + + template = 0> + constexpr span(array& arr) noexcept: + _storage(arr.data(), N) + {} + + template = 0> + constexpr span(const array& arr) noexcept: + _storage(arr.data(), N) + {} + + /* TODO + template + constexpr explicit(extent != dynamic_extent) span(R&& r) + */ + + constexpr span(const span& other) noexcept = default; + + template::value, int> = 0> + constexpr span(const span& s) noexcept: + _storage(s.data(), s.size()) + {} + + ~span() noexcept = default; + + constexpr span& operator=(const span& other) noexcept = default; + + // Subviews + template + constexpr span first() const + { + static_assert(Count <= extent); + MBED_ASSERT(Count <= size()); + return span(data(), Count); + } + + template + constexpr span last() const + { + static_assert(Count <= extent); + MBED_ASSERT(Count <= size()); + return span(data() + (size() - Count), Count); + } + + template + constexpr span subspan() const + { + static_assert(Offset <= extent && (Count == dynamic_extent || Count <= extent - Offset)); + MBED_ASSERT(Offset <= size() && (Count == dynamic_extent || Count <= size() - Offset)); + return {data() + Offset, Count != dynamic_extent ? Count : size() - Offset}; + } + + constexpr span first(index_type count) const + { + MBED_ASSERT(count <= size()); + return span(data(), count); + } + + constexpr span last(index_type count) const + { + MBED_ASSERT(count <= size()); + return span(data() + (size() - count), count); + } + + constexpr span + subspan(index_type offset, index_type count = dynamic_extent) const + { + MBED_ASSERT(offset <= size() && (count == dynamic_extent || count <= size() - offset )); + return span(data() + offset, count == dynamic_extent ? size() - offset : count ); + } + + // Observers + constexpr index_type size() const noexcept + { + return _storage._size; + } + + constexpr index_type size_bytes() const noexcept + { + return size() * sizeof(element_type); + } + + constexpr bool empty() const noexcept + { + return size() == 0; + } + + // Element access + constexpr reference operator[](index_type idx) const + { + MBED_ASSERT(idx < size()); + return *(data() + idx); + } + + constexpr reference front() const + { + MBED_ASSERT(not empty()); + return *data(); + } + + constexpr reference back() const + { + MBED_ASSERT(not empty()); + return *(data() + (size() - 1)); + } + + constexpr pointer data() const noexcept + { + return _storage._data; + } + + // Iterators + constexpr iterator begin() const noexcept + { + return data(); + } + + constexpr iterator end() const noexcept + { + return data() + size(); + } + + constexpr reverse_iterator rbegin() const noexcept + { + return reverse_iterator(end()); + } + + constexpr reverse_iterator rend() const noexcept + { + return reverse_iterator(begin()); + } + +private: + detail::storage _storage; +}; + +template +span +as_bytes(span s) noexcept +{ + return {reinterpret_cast(s.data()), s.size_bytes()}; +} + +template +span +as_writable_bytes(span s) noexcept +{ + static_assert(not is_const::value); + return {reinterpret_cast(s.data()), s.size_bytes()}; +} + +template +constexpr span make_span(ElementType (&arr)[Extent]) +{ + return span(arr); +} + +template +constexpr span make_span(const ElementType (&arr)[Extent]) +{ + return span(arr); +} + +template +constexpr span make_span(array& arr) +{ + return span(arr); +} + +template +constexpr span make_span(const array& arr) +{ + return span(arr); +} + +/* TODO +template +constexpr span make_span(R&& cont) +{ + return {cont}; +} +*/ + +} // namespace mstd + +#endif // MSTD_MUTEX_ \ No newline at end of file From c38df18dcc11e33369c2042b17482fe0d46029bc Mon Sep 17 00:00:00 2001 From: Marc Emmers Date: Fri, 6 Nov 2020 15:19:28 +0100 Subject: [PATCH 02/25] Fix endif comment --- platform/cxxsupport/mstd_span | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/cxxsupport/mstd_span b/platform/cxxsupport/mstd_span index 925f61465c4..91a954127aa 100644 --- a/platform/cxxsupport/mstd_span +++ b/platform/cxxsupport/mstd_span @@ -283,4 +283,4 @@ constexpr span make_span(R&& cont) } // namespace mstd -#endif // MSTD_MUTEX_ \ No newline at end of file +#endif // MSTD_SPAN_ \ No newline at end of file From 11573a92642f99c191fefbe53f07fd069c769d89 Mon Sep 17 00:00:00 2001 From: Marc Emmers Date: Mon, 9 Nov 2020 08:49:00 +0100 Subject: [PATCH 03/25] Add iter_reference_t to iterator header --- platform/cxxsupport/mstd_iterator | 3 +++ 1 file changed, 3 insertions(+) diff --git a/platform/cxxsupport/mstd_iterator b/platform/cxxsupport/mstd_iterator index 52c2092e503..a145023b447 100644 --- a/platform/cxxsupport/mstd_iterator +++ b/platform/cxxsupport/mstd_iterator @@ -144,6 +144,9 @@ constexpr ptrdiff_t ssize(const T (&)[N]) noexcept return N; } +template +using iter_reference_t = decltype(*std::declval()); + } From e93ebc4cd2d2bd1e0c4fdff0e71159be4f944718 Mon Sep 17 00:00:00 2001 From: Marc Emmers Date: Mon, 9 Nov 2020 08:50:33 +0100 Subject: [PATCH 04/25] Correct span constructors --- platform/cxxsupport/mstd_span | 58 +++++++++++++++++++++++++++-------- 1 file changed, 46 insertions(+), 12 deletions(-) diff --git a/platform/cxxsupport/mstd_span b/platform/cxxsupport/mstd_span index 91a954127aa..7703f3e68e7 100644 --- a/platform/cxxsupport/mstd_span +++ b/platform/cxxsupport/mstd_span @@ -24,7 +24,10 @@ namespace mstd { inline constexpr size_t dynamic_extent = -1; +template class span; + namespace detail { + template class storage { public: @@ -50,6 +53,24 @@ public: ElementType* _data; size_t _size; }; +template +using iterator_t = decltype(mstd::begin(std::declval())); + +template +using range_reference_t = mstd::iter_reference_t>; + +template +struct is_compatible : std::false_type {}; + +template +struct is_compatible())) + >, void>::value>>: +std::is_convertible()))> (*)[], E (*)[]>{}; + } // namespace detail template @@ -74,13 +95,20 @@ public: constexpr span() noexcept {} - constexpr span(pointer ptr, index_type count) : + template>(*)[], + ElementType(*)[]>::value, int> = 0> + constexpr span(It ptr, index_type count) : _storage(ptr, count) { MBED_ASSERT(extent == dynamic_extent || extent == count); } - constexpr span(pointer first, pointer last) : + template>(*)[], + ElementType(*)[]>::value, int> = 0> + constexpr span(It first, It last) : _storage(first, last - first) { MBED_ASSERT(first <= last); @@ -88,21 +116,27 @@ public: MBED_ASSERT(extent == 0 || nullptr != first); } - template = 0> - constexpr span(element_type (&arr)[N]) noexcept: + template + constexpr span(type_identity_t (&arr)[N], + typename mstd::enable_if_t<(Extent == dynamic_extent || Extent == N) && + is_convertible(*)[], + ElementType(*)[]>::value, int> = 0) noexcept: _storage(arr, N) {} - template = 0> - constexpr span(array& arr) noexcept: + template + constexpr span(array& arr, + typename mstd::enable_if_t<(Extent == dynamic_extent || Extent == N) && + is_convertible(*)[], + ElementType(*)[]>::value, int> = 0) noexcept: _storage(arr.data(), N) {} - template = 0> - constexpr span(const array& arr) noexcept: + template + constexpr span(const array& arr, + typename mstd::enable_if_t<(Extent == dynamic_extent || Extent == N) && + is_convertible(*)[], + ElementType(*)[]>::value, int> = 0) noexcept: _storage(arr.data(), N) {} @@ -115,7 +149,7 @@ public: template::value, int> = 0> + is_convertible::value, int> = 0> constexpr span(const span& s) noexcept: _storage(s.data(), s.size()) {} From 4097b9d956833c3b74b01b1faa784259bd20adf2 Mon Sep 17 00:00:00 2001 From: Marc Emmers Date: Mon, 9 Nov 2020 08:55:55 +0100 Subject: [PATCH 05/25] Add container constructor and make_span --- platform/cxxsupport/mstd_span | 57 ++++++++++++++++++++++++++++++----- 1 file changed, 50 insertions(+), 7 deletions(-) diff --git a/platform/cxxsupport/mstd_span b/platform/cxxsupport/mstd_span index 7703f3e68e7..79dd22d8cfc 100644 --- a/platform/cxxsupport/mstd_span +++ b/platform/cxxsupport/mstd_span @@ -53,6 +53,41 @@ public: ElementType* _data; size_t _size; }; + +template +struct is_span: false_type {}; + +template +struct is_span>: true_type {}; + +template +struct is_std_array: false_type {}; + +template +struct is_std_array>: true_type {}; + +template +struct has_size : std::false_type {}; + +template +struct has_size()))>>: + std::true_type {}; + +template +struct has_data : std::false_type {}; + +template +struct has_data()))>>: + std::true_type {}; + +template> +struct is_container{ + static constexpr bool value = + not is_span::value && not is_std_array::value && + not std::is_array::value && has_size::value && + has_data::value; +}; + template using iterator_t = decltype(mstd::begin(std::declval())); @@ -140,10 +175,14 @@ public: _storage(arr.data(), N) {} - /* TODO - template - constexpr explicit(extent != dynamic_extent) span(R&& r) - */ + template::value && + detail::is_compatible::value, int> = 0> + constexpr span(R&& r) : + _storage( mstd::data( r ), mstd::size( r )) + { + MBED_ASSERT(extent == dynamic_extent || extent == mstd::size( r )); + } constexpr span(const span& other) noexcept = default; @@ -307,13 +346,17 @@ constexpr span make_span(const array(arr); } -/* TODO template -constexpr span make_span(R&& cont) +constexpr span make_span(R& cont) +{ + return {cont}; +} + +template +constexpr span make_span(const R& cont) { return {cont}; } -*/ } // namespace mstd From c89c45877c34e51990e9fb4fa2a768805f12d868 Mon Sep 17 00:00:00 2001 From: Marc Emmers Date: Mon, 9 Nov 2020 12:56:51 +0100 Subject: [PATCH 06/25] Prevent warning on subspan<0,N> --- platform/cxxsupport/mstd_span | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/platform/cxxsupport/mstd_span b/platform/cxxsupport/mstd_span index 79dd22d8cfc..282d3474a31 100644 --- a/platform/cxxsupport/mstd_span +++ b/platform/cxxsupport/mstd_span @@ -219,7 +219,9 @@ public: : (Extent != dynamic_extent ? Extent - Offset : dynamic_extent)> subspan() const { static_assert(Offset <= extent && (Count == dynamic_extent || Count <= extent - Offset)); - MBED_ASSERT(Offset <= size() && (Count == dynamic_extent || Count <= size() - Offset)); + // Only check against Offset == 0 to prevent a warning for subspan<0, N> + MBED_ASSERT((Offset == 0 || Offset <= size()) + && (Count == dynamic_extent || Count <= size() - Offset)); return {data() + Offset, Count != dynamic_extent ? Count : size() - Offset}; } From 1931f4e0d0127e001d50b5666d2ff72b48df8264 Mon Sep 17 00:00:00 2001 From: Marc Emmers Date: Mon, 9 Nov 2020 13:07:50 +0100 Subject: [PATCH 07/25] Fix namespaces and span prototype --- platform/cxxsupport/mstd_span | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/platform/cxxsupport/mstd_span b/platform/cxxsupport/mstd_span index 282d3474a31..98acc16fe4a 100644 --- a/platform/cxxsupport/mstd_span +++ b/platform/cxxsupport/mstd_span @@ -24,7 +24,7 @@ namespace mstd { inline constexpr size_t dynamic_extent = -1; -template class span; +template class span; namespace detail { @@ -70,14 +70,14 @@ template struct has_size : std::false_type {}; template -struct has_size()))>>: +struct has_size()))>>: std::true_type {}; template struct has_data : std::false_type {}; template -struct has_data()))>>: +struct has_data()))>>: std::true_type {}; template> @@ -89,7 +89,7 @@ struct is_container{ }; template -using iterator_t = decltype(mstd::begin(std::declval())); +using iterator_t = decltype(mstd::begin(mstd::declval())); template using range_reference_t = mstd::iter_reference_t>; @@ -103,12 +103,12 @@ struct is_compatible())) >, void>::value>>: -std::is_convertible()))> (*)[], E (*)[]>{}; } // namespace detail -template +template class span { public: using element_type = ElementType; @@ -131,7 +131,7 @@ public: {} template>(*)[], ElementType(*)[]>::value, int> = 0> constexpr span(It ptr, index_type count) : @@ -140,7 +140,7 @@ public: MBED_ASSERT(extent == dynamic_extent || extent == count); } - template>(*)[], ElementType(*)[]>::value, int> = 0> constexpr span(It first, It last) : @@ -154,7 +154,7 @@ public: template constexpr span(type_identity_t (&arr)[N], typename mstd::enable_if_t<(Extent == dynamic_extent || Extent == N) && - is_convertible(*)[], + mstd::is_convertible(*)[], ElementType(*)[]>::value, int> = 0) noexcept: _storage(arr, N) {} @@ -162,7 +162,7 @@ public: template constexpr span(array& arr, typename mstd::enable_if_t<(Extent == dynamic_extent || Extent == N) && - is_convertible(*)[], + mstd::is_convertible(*)[], ElementType(*)[]>::value, int> = 0) noexcept: _storage(arr.data(), N) {} @@ -170,7 +170,7 @@ public: template constexpr span(const array& arr, typename mstd::enable_if_t<(Extent == dynamic_extent || Extent == N) && - is_convertible(*)[], + mstd::is_convertible(*)[], ElementType(*)[]>::value, int> = 0) noexcept: _storage(arr.data(), N) {} @@ -188,7 +188,7 @@ public: template::value, int> = 0> + mstd:is_convertible::value, int> = 0> constexpr span(const span& s) noexcept: _storage(s.data(), s.size()) {} From a5b66cf824ef056bc5c4c4291966eef6261daa99 Mon Sep 17 00:00:00 2001 From: Marc Emmers Date: Mon, 9 Nov 2020 15:44:30 +0100 Subject: [PATCH 08/25] Remove c++17 inline of constexpr --- platform/cxxsupport/mstd_span | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/cxxsupport/mstd_span b/platform/cxxsupport/mstd_span index 98acc16fe4a..8503fdb234f 100644 --- a/platform/cxxsupport/mstd_span +++ b/platform/cxxsupport/mstd_span @@ -22,7 +22,7 @@ namespace mstd { -inline constexpr size_t dynamic_extent = -1; +constexpr size_t dynamic_extent = -1; template class span; From 5231bec423a077041527fbdeaccbe47e76539df7 Mon Sep 17 00:00:00 2001 From: Marc Emmers Date: Mon, 9 Nov 2020 15:45:16 +0100 Subject: [PATCH 09/25] Fix remaining namespaces and add include files --- platform/cxxsupport/mstd_span | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/platform/cxxsupport/mstd_span b/platform/cxxsupport/mstd_span index 8503fdb234f..848e8b8976f 100644 --- a/platform/cxxsupport/mstd_span +++ b/platform/cxxsupport/mstd_span @@ -17,8 +17,10 @@ #ifndef MSTD_SPAN_ #define MSTD_SPAN_ +#include #include #include +#include "mbed_assert.h" namespace mstd { @@ -55,29 +57,29 @@ public: }; template -struct is_span: false_type {}; +struct is_span: std::false_type {}; template -struct is_span>: true_type {}; +struct is_span>: std::true_type {}; template -struct is_std_array: false_type {}; +struct is_std_array: std::false_type {}; template -struct is_std_array>: true_type {}; +struct is_std_array>: std::true_type {}; template struct has_size : std::false_type {}; template -struct has_size()))>>: +struct has_size()))>>: std::true_type {}; template struct has_data : std::false_type {}; template -struct has_data()))>>: +struct has_data()))>>: std::true_type {}; template> @@ -89,7 +91,7 @@ struct is_container{ }; template -using iterator_t = decltype(mstd::begin(mstd::declval())); +using iterator_t = decltype(mstd::begin(std::declval())); template using range_reference_t = mstd::iter_reference_t>; @@ -101,10 +103,10 @@ template struct is_compatible())) + decltype(mstd::data(std::declval())) >, void>::value>>: mstd::is_convertible()))> (*)[], E (*)[]>{}; + decltype(mstd::data(std::declval()))> (*)[], E (*)[]>{}; } // namespace detail @@ -160,7 +162,7 @@ public: {} template - constexpr span(array& arr, + constexpr span(std::array& arr, typename mstd::enable_if_t<(Extent == dynamic_extent || Extent == N) && mstd::is_convertible(*)[], ElementType(*)[]>::value, int> = 0) noexcept: @@ -168,7 +170,7 @@ public: {} template - constexpr span(const array& arr, + constexpr span(const std::array& arr, typename mstd::enable_if_t<(Extent == dynamic_extent || Extent == N) && mstd::is_convertible(*)[], ElementType(*)[]>::value, int> = 0) noexcept: @@ -188,7 +190,7 @@ public: template::value, int> = 0> + mstd::is_convertible::value, int> = 0> constexpr span(const span& s) noexcept: _storage(s.data(), s.size()) {} @@ -337,13 +339,13 @@ constexpr span make_span(const ElementType (&arr)[Ext } template -constexpr span make_span(array& arr) +constexpr span make_span(std::array& arr) { return span(arr); } template -constexpr span make_span(const array& arr) +constexpr span make_span(const std::array& arr) { return span(arr); } From 07da1a70058703934d06c2567d43629458d7fdc6 Mon Sep 17 00:00:00 2001 From: Marc Emmers Date: Mon, 9 Nov 2020 15:48:46 +0100 Subject: [PATCH 10/25] Remove explicit constructors --- platform/cxxsupport/mstd_span | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/platform/cxxsupport/mstd_span b/platform/cxxsupport/mstd_span index 848e8b8976f..ce5a3d602a2 100644 --- a/platform/cxxsupport/mstd_span +++ b/platform/cxxsupport/mstd_span @@ -205,7 +205,7 @@ public: { static_assert(Count <= extent); MBED_ASSERT(Count <= size()); - return span(data(), Count); + return {data(), Count}; } template @@ -213,7 +213,7 @@ public: { static_assert(Count <= extent); MBED_ASSERT(Count <= size()); - return span(data() + (size() - Count), Count); + return {data() + (size() - Count), Count}; } template @@ -230,20 +230,20 @@ public: constexpr span first(index_type count) const { MBED_ASSERT(count <= size()); - return span(data(), count); + return {data(), count}; } constexpr span last(index_type count) const { MBED_ASSERT(count <= size()); - return span(data() + (size() - count), count); + return {data() + (size() - count), count}; } constexpr span subspan(index_type offset, index_type count = dynamic_extent) const { MBED_ASSERT(offset <= size() && (count == dynamic_extent || count <= size() - offset )); - return span(data() + offset, count == dynamic_extent ? size() - offset : count ); + return {data() + offset, count == dynamic_extent ? size() - offset : count }; } // Observers @@ -329,37 +329,37 @@ as_writable_bytes(span s) noexcept template constexpr span make_span(ElementType (&arr)[Extent]) { - return span(arr); + return arr; } template constexpr span make_span(const ElementType (&arr)[Extent]) { - return span(arr); + return arr; } template constexpr span make_span(std::array& arr) { - return span(arr); + return arr; } template constexpr span make_span(const std::array& arr) { - return span(arr); + return arr; } template constexpr span make_span(R& cont) { - return {cont}; + return cont; } template constexpr span make_span(const R& cont) { - return {cont}; + return cont; } } // namespace mstd From e18ce022b8d6bf7886f1d7716312ed7f80c74aa5 Mon Sep 17 00:00:00 2001 From: Marc Emmers Date: Mon, 9 Nov 2020 15:59:48 +0100 Subject: [PATCH 11/25] Update default initializers --- platform/cxxsupport/mstd_span | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/cxxsupport/mstd_span b/platform/cxxsupport/mstd_span index ce5a3d602a2..6a31148afb6 100644 --- a/platform/cxxsupport/mstd_span +++ b/platform/cxxsupport/mstd_span @@ -39,7 +39,7 @@ public: _data(ptr) {} - ElementType* _data; + ElementType* _data = nullptr; static constexpr size_t _size = Extent; }; @@ -52,8 +52,8 @@ public: _data(ptr), _size(size) {} - ElementType* _data; - size_t _size; + ElementType* _data = nullptr; + size_t _size = 0; }; template From 405baeb559574307c5d755df96947614e26c8245 Mon Sep 17 00:00:00 2001 From: Marc Emmers Date: Mon, 9 Nov 2020 16:08:16 +0100 Subject: [PATCH 12/25] Fix newline at end of file --- platform/cxxsupport/mstd_span | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/cxxsupport/mstd_span b/platform/cxxsupport/mstd_span index 6a31148afb6..afe45a80d61 100644 --- a/platform/cxxsupport/mstd_span +++ b/platform/cxxsupport/mstd_span @@ -364,4 +364,4 @@ constexpr span make_span(const R& cont) } // namespace mstd -#endif // MSTD_SPAN_ \ No newline at end of file +#endif // MSTD_SPAN_ From 6389bcb2ee15e8b9324c21a02b44ecd3aded5223 Mon Sep 17 00:00:00 2001 From: Marc Emmers Date: Mon, 9 Nov 2020 16:20:07 +0100 Subject: [PATCH 13/25] Fix pointer and reference operator style --- platform/cxxsupport/mstd_span | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/platform/cxxsupport/mstd_span b/platform/cxxsupport/mstd_span index afe45a80d61..f477a76923c 100644 --- a/platform/cxxsupport/mstd_span +++ b/platform/cxxsupport/mstd_span @@ -52,7 +52,7 @@ public: _data(ptr), _size(size) {} - ElementType* _data = nullptr; + ElementType *_data = nullptr; size_t _size = 0; }; @@ -117,10 +117,10 @@ public: using value_type = typename mstd::remove_cv_t; using index_type = size_t; using difference_type = ptrdiff_t; - using pointer = element_type*; - using const_pointer = const element_type*; - using reference = element_type&; - using const_reference = const element_type&; + using pointer = element_type *; + using const_pointer = const element_type *; + using reference = element_type &; + using const_reference = const element_type &; using iterator = pointer; using reverse_iterator = std::reverse_iterator; @@ -154,7 +154,7 @@ public: } template - constexpr span(type_identity_t (&arr)[N], + constexpr span(type_identity_t(&arr)[N], typename mstd::enable_if_t<(Extent == dynamic_extent || Extent == N) && mstd::is_convertible(*)[], ElementType(*)[]>::value, int> = 0) noexcept: @@ -162,7 +162,7 @@ public: {} template - constexpr span(std::array& arr, + constexpr span(std::array &arr, typename mstd::enable_if_t<(Extent == dynamic_extent || Extent == N) && mstd::is_convertible(*)[], ElementType(*)[]>::value, int> = 0) noexcept: @@ -170,7 +170,7 @@ public: {} template - constexpr span(const std::array& arr, + constexpr span(const std::array &arr, typename mstd::enable_if_t<(Extent == dynamic_extent || Extent == N) && mstd::is_convertible(*)[], ElementType(*)[]>::value, int> = 0) noexcept: @@ -180,13 +180,13 @@ public: template::value && detail::is_compatible::value, int> = 0> - constexpr span(R&& r) : + constexpr span(R &&r) : _storage( mstd::data( r ), mstd::size( r )) { MBED_ASSERT(extent == dynamic_extent || extent == mstd::size( r )); } - constexpr span(const span& other) noexcept = default; + constexpr span(const span &other) noexcept = default; template @@ -315,7 +315,7 @@ template span as_bytes(span s) noexcept { - return {reinterpret_cast(s.data()), s.size_bytes()}; + return {reinterpret_cast(s.data()), s.size_bytes()}; } template @@ -323,7 +323,7 @@ span s) noexcept { static_assert(not is_const::value); - return {reinterpret_cast(s.data()), s.size_bytes()}; + return {reinterpret_cast(s.data()), s.size_bytes()}; } template @@ -339,25 +339,25 @@ constexpr span make_span(const ElementType (&arr)[Ext } template -constexpr span make_span(std::array& arr) +constexpr span make_span(std::array &arr) { return arr; } template -constexpr span make_span(const std::array& arr) +constexpr span make_span(const std::array &arr) { return arr; } template -constexpr span make_span(R& cont) +constexpr span make_span(R &cont) { return cont; } template -constexpr span make_span(const R& cont) +constexpr span make_span(const R &cont) { return cont; } From 1dac20cded0b77b203157771e58d1eadd5ae3249 Mon Sep 17 00:00:00 2001 From: Marc Emmers Date: Mon, 9 Nov 2020 17:58:53 +0100 Subject: [PATCH 14/25] Missed a pointer operator --- platform/cxxsupport/mstd_span | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/cxxsupport/mstd_span b/platform/cxxsupport/mstd_span index f477a76923c..fed416a8673 100644 --- a/platform/cxxsupport/mstd_span +++ b/platform/cxxsupport/mstd_span @@ -39,7 +39,7 @@ public: _data(ptr) {} - ElementType* _data = nullptr; + ElementType *_data = nullptr; static constexpr size_t _size = Extent; }; From e0299bd7a327fccc9b558e5e66288ca9492ccea8 Mon Sep 17 00:00:00 2001 From: Marc Emmers Date: Tue, 10 Nov 2020 08:39:35 +0100 Subject: [PATCH 15/25] Use original if present and the right version --- platform/cxxsupport/mstd_span | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/platform/cxxsupport/mstd_span b/platform/cxxsupport/mstd_span index fed416a8673..1cc4d4701a7 100644 --- a/platform/cxxsupport/mstd_span +++ b/platform/cxxsupport/mstd_span @@ -17,6 +17,19 @@ #ifndef MSTD_SPAN_ #define MSTD_SPAN_ +#if __cplusplus >= 201703L && __has_include() +#include +#endif + +#if __cpp_lib_span >= 202002L +#include + +namespace mstd { + using std::span; +} + +#else //__cpp_lib_span >= 202002L + #include #include #include @@ -364,4 +377,5 @@ constexpr span make_span(const R &cont) } // namespace mstd +#endif //__cpp_lib_span >= 202002L #endif // MSTD_SPAN_ From 96954d3319c31d564ed5aba4dfac3f16f991fb80 Mon Sep 17 00:00:00 2001 From: Marc Emmers Date: Sat, 16 Jan 2021 19:59:14 +0100 Subject: [PATCH 16/25] Replace classes with structs where applicable --- platform/cxxsupport/mstd_span | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/platform/cxxsupport/mstd_span b/platform/cxxsupport/mstd_span index 1cc4d4701a7..dbc4b5988ce 100644 --- a/platform/cxxsupport/mstd_span +++ b/platform/cxxsupport/mstd_span @@ -44,8 +44,7 @@ template class span; namespace detail { template -class storage { -public: +struct storage { constexpr storage() noexcept = default; constexpr storage(ElementType *ptr, size_t) noexcept : @@ -57,8 +56,7 @@ public: }; template -class storage { -public: +struct storage { constexpr storage() noexcept = default; constexpr storage(ElementType *ptr, size_t size) noexcept : From 69331b0cc0f88414abbca4c857481c41d038242b Mon Sep 17 00:00:00 2001 From: Marc Emmers Date: Sat, 16 Jan 2021 21:02:47 +0100 Subject: [PATCH 17/25] Fix minor style issues --- platform/cxxsupport/mstd_span | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/platform/cxxsupport/mstd_span b/platform/cxxsupport/mstd_span index dbc4b5988ce..f8c9aa8d119 100644 --- a/platform/cxxsupport/mstd_span +++ b/platform/cxxsupport/mstd_span @@ -39,7 +39,8 @@ namespace mstd { constexpr size_t dynamic_extent = -1; -template class span; +template +class span; namespace detail { @@ -96,8 +97,8 @@ struct has_data()))>>: template> struct is_container{ static constexpr bool value = - not is_span::value && not is_std_array::value && - not std::is_array::value && has_size::value && + !is_span::value && !is_std_array::value && + !std::is_array::value && has_size::value && has_data::value; }; @@ -112,7 +113,7 @@ struct is_compatible : std::false_type {}; template struct is_compatible())) >, void>::value>>: @@ -282,13 +283,13 @@ public: constexpr reference front() const { - MBED_ASSERT(not empty()); + MBED_ASSERT(!empty()); return *data(); } constexpr reference back() const { - MBED_ASSERT(not empty()); + MBED_ASSERT(!empty()); return *(data() + (size() - 1)); } From 2e1b360e67a5e48aed685f11aa276fc3667d6c28 Mon Sep 17 00:00:00 2001 From: Marc Emmers Date: Sat, 16 Jan 2021 21:03:29 +0100 Subject: [PATCH 18/25] Remove nonstandard as_bytes --- platform/cxxsupport/mstd_span | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/platform/cxxsupport/mstd_span b/platform/cxxsupport/mstd_span index f8c9aa8d119..0a1c7afe681 100644 --- a/platform/cxxsupport/mstd_span +++ b/platform/cxxsupport/mstd_span @@ -323,21 +323,6 @@ private: detail::storage _storage; }; -template -span -as_bytes(span s) noexcept -{ - return {reinterpret_cast(s.data()), s.size_bytes()}; -} - -template -span -as_writable_bytes(span s) noexcept -{ - static_assert(not is_const::value); - return {reinterpret_cast(s.data()), s.size_bytes()}; -} - template constexpr span make_span(ElementType (&arr)[Extent]) { From f7e19b5232c588f08c2b48a3a56f42494dd195d9 Mon Sep 17 00:00:00 2001 From: Marc Emmers Date: Sat, 16 Jan 2021 21:04:05 +0100 Subject: [PATCH 19/25] Add deduction guides --- platform/cxxsupport/mstd_span | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/platform/cxxsupport/mstd_span b/platform/cxxsupport/mstd_span index 0a1c7afe681..ccf545f43f5 100644 --- a/platform/cxxsupport/mstd_span +++ b/platform/cxxsupport/mstd_span @@ -323,6 +323,24 @@ private: detail::storage _storage; }; +#if __cplusplus >= 201703L || __cpp_deduction_guides >= 201703L +// Deduction guides +template +span(It, EndOrSize) -> span>>; + +template +span(T (&)[N]) -> span; + +template +span(std::array&) -> span; + +template +span(const std::array&) -> span; + +template +span(R&&) -> span>>; +#endif + template constexpr span make_span(ElementType (&arr)[Extent]) { From 78f2cfc0d9ebe1359ea2993d7ebed4d2a1f9ffda Mon Sep 17 00:00:00 2001 From: Marc Emmers Date: Sat, 16 Jan 2021 21:04:16 +0100 Subject: [PATCH 20/25] Add some comment blocks --- platform/cxxsupport/mstd_span | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/platform/cxxsupport/mstd_span b/platform/cxxsupport/mstd_span index ccf545f43f5..4594a7c2eb7 100644 --- a/platform/cxxsupport/mstd_span +++ b/platform/cxxsupport/mstd_span @@ -17,6 +17,14 @@ #ifndef MSTD_SPAN_ #define MSTD_SPAN_ +/* + * + * - Includes toolchain's if available + * - Otherwise provides an implementation of a C++20 equivalent std::span + * - deduction guides available from C++17 and on + * - provides nonstandard mstd::make_span functions to allow deduction pre C++17 + */ + #if __cplusplus >= 201703L && __has_include() #include #endif @@ -341,6 +349,11 @@ template span(R&&) -> span>>; #endif +/** Create a span class with type and size inferred from the argument + * + * @param arr Reference to a c-style array + * @return Span with inferred type and size Extent + */ template constexpr span make_span(ElementType (&arr)[Extent]) { @@ -353,6 +366,11 @@ constexpr span make_span(const ElementType (&arr)[Ext return arr; } +/** Create a span class with type and size inferred from the argument + * + * @param arr Reference to an std::array + * @return Span with inferred type and size Extent + */ template constexpr span make_span(std::array &arr) { @@ -365,6 +383,11 @@ constexpr span make_span(const std::array constexpr span make_span(R &cont) { From 8f94feb0ed5c3a50fe82b5f86abc3b7733051232 Mon Sep 17 00:00:00 2001 From: Marc Emmers Date: Mon, 18 Jan 2021 14:33:20 +0100 Subject: [PATCH 21/25] Add to list of backports --- platform/cxxsupport/mstd_iterator | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/cxxsupport/mstd_iterator b/platform/cxxsupport/mstd_iterator index a145023b447..9082702347f 100644 --- a/platform/cxxsupport/mstd_iterator +++ b/platform/cxxsupport/mstd_iterator @@ -29,6 +29,7 @@ * - mstd::ssize * - mstd::empty * - mstd::data + * - mstd::iter_reference_t */ #include From d5459ea3803b7f643bc829fa7d8dc25bcdea8cd5 Mon Sep 17 00:00:00 2001 From: Marc Emmers Date: Mon, 18 Jan 2021 14:34:26 +0100 Subject: [PATCH 22/25] Fix missing defintion --- platform/cxxsupport/mstd_span | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/platform/cxxsupport/mstd_span b/platform/cxxsupport/mstd_span index 4594a7c2eb7..c95ed43b734 100644 --- a/platform/cxxsupport/mstd_span +++ b/platform/cxxsupport/mstd_span @@ -63,6 +63,8 @@ struct storage { ElementType *_data = nullptr; static constexpr size_t _size = Extent; }; +template +constexpr size_t storage::_size; template struct storage { @@ -331,6 +333,9 @@ private: detail::storage _storage; }; +template +constexpr span::index_type span::extent; + #if __cplusplus >= 201703L || __cpp_deduction_guides >= 201703L // Deduction guides template From a826c89b1088a554f6f57e5cc13034ecf2f719f8 Mon Sep 17 00:00:00 2001 From: Marc Emmers Date: Mon, 18 Jan 2021 14:35:47 +0100 Subject: [PATCH 23/25] Backport dynamic extent when including Keep make_span functions even when is available for compatibility --- platform/cxxsupport/mstd_span | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/platform/cxxsupport/mstd_span b/platform/cxxsupport/mstd_span index c95ed43b734..d459d94bfd3 100644 --- a/platform/cxxsupport/mstd_span +++ b/platform/cxxsupport/mstd_span @@ -34,6 +34,7 @@ namespace mstd { using std::span; + using std::dynamic_extent; } #else //__cpp_lib_span >= 202002L @@ -352,7 +353,13 @@ span(const std::array&) -> span; template span(R&&) -> span>>; -#endif +#endif //__cplusplus >= 201703L || __cpp_deduction_guides >= 201703L + +} // namespace mstd + +#endif //__cpp_lib_span >= 202002L + +namespace mstd { /** Create a span class with type and size inferred from the argument * @@ -407,5 +414,4 @@ constexpr span make_span(const R &cont) } // namespace mstd -#endif //__cpp_lib_span >= 202002L #endif // MSTD_SPAN_ From 8551e93bf2d195442816aed6df5fb4203700d4ff Mon Sep 17 00:00:00 2001 From: Marc Emmers Date: Mon, 18 Jan 2021 14:36:17 +0100 Subject: [PATCH 24/25] Fix last extra space issues --- platform/cxxsupport/mstd_span | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/cxxsupport/mstd_span b/platform/cxxsupport/mstd_span index d459d94bfd3..a64d4a13106 100644 --- a/platform/cxxsupport/mstd_span +++ b/platform/cxxsupport/mstd_span @@ -204,9 +204,9 @@ public: typename mstd::enable_if_t::value && detail::is_compatible::value, int> = 0> constexpr span(R &&r) : - _storage( mstd::data( r ), mstd::size( r )) + _storage(mstd::data(r), mstd::size(r)) { - MBED_ASSERT(extent == dynamic_extent || extent == mstd::size( r )); + MBED_ASSERT(extent == dynamic_extent || extent == mstd::size(r)); } constexpr span(const span &other) noexcept = default; @@ -265,7 +265,7 @@ public: constexpr span subspan(index_type offset, index_type count = dynamic_extent) const { - MBED_ASSERT(offset <= size() && (count == dynamic_extent || count <= size() - offset )); + MBED_ASSERT(offset <= size() && (count == dynamic_extent || count <= size() - offset)); return {data() + offset, count == dynamic_extent ? size() - offset : count }; } From a8ea7758c35ca755e0da5bba596ec70190281c4a Mon Sep 17 00:00:00 2001 From: Marc Emmers Date: Mon, 18 Jan 2021 15:49:29 +0100 Subject: [PATCH 25/25] Fix make_span text in comment block --- platform/cxxsupport/mstd_span | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/cxxsupport/mstd_span b/platform/cxxsupport/mstd_span index a64d4a13106..184f14ee32a 100644 --- a/platform/cxxsupport/mstd_span +++ b/platform/cxxsupport/mstd_span @@ -22,7 +22,8 @@ * - Includes toolchain's if available * - Otherwise provides an implementation of a C++20 equivalent std::span * - deduction guides available from C++17 and on - * - provides nonstandard mstd::make_span functions to allow deduction pre C++17 + * - Provides nonstandard mstd::make_span functions to allow deduction pre C++17 + * - mstd::make_span functions stay available after C++17 for backwards compatibility */ #if __cplusplus >= 201703L && __has_include()