This is an automated email from the ASF dual-hosted git repository. bneradt pushed a commit to branch training in repository https://gitbox.apache.org/repos/asf/trafficserver-libswoc.git
commit be8ff888b5f14f6e87606933a08b8bd7fa1abcc4 Author: Alan M. Carroll <a...@apache.org> AuthorDate: Tue Jul 27 17:28:20 2021 -0500 Checkpoint - vectray. --- code/include/swoc/MemSpan.h | 32 +++++++++++++++++++++++++++++++- code/include/swoc/Vectray.h | 22 ++++++++++++++++++---- unit_tests/test_MemSpan.cc | 16 ++++++++++++++++ 3 files changed, 65 insertions(+), 5 deletions(-) diff --git a/code/include/swoc/MemSpan.h b/code/include/swoc/MemSpan.h index 326a59d..c5ff7f4 100644 --- a/code/include/swoc/MemSpan.h +++ b/code/include/swoc/MemSpan.h @@ -17,8 +17,9 @@ #include <type_traits> #include <ratio> #include <tuple> +#include <array> #include <exception> - +#include <vector> #include "swoc/swoc_version.h" namespace swoc { inline namespace SWOC_VERSION_NS { @@ -51,6 +52,18 @@ public: /// Copy constructor. constexpr MemSpan(self_type const &that) = default; + /// Construct constant span from non-constant span of the same basic type. + /// @internal Must be inline here because it doesn't always exist. + template < typename U + , typename META = std::enable_if_t< + std::conjunction_v< + std::is_const<T> + , std::is_same<U, std::remove_const_t<T>> + > + > + > + constexpr MemSpan(MemSpan<U> const& that) : _ptr(that.data()), _count(that.count()) {} + /** Construct from a first element @a start and a @a count of elements. * * @param start First element. @@ -72,6 +85,20 @@ public: */ template <size_t N> MemSpan(T (&a)[N]); + /** Construct from a @c std::array. + * + * @tparam N Array size. + * @param a Array instance. + */ + template <auto N> constexpr MemSpan(std::array<T, N> const& a); + + /** Construct from a @c std::array. + * + * @tparam N Array size. + * @param a Array instance. + */ + template <auto N> constexpr MemSpan(std::array<T, N> & a); + /** Construct from nullptr. This implicitly makes the length 0. */ @@ -599,6 +626,9 @@ template <typename T> constexpr MemSpan<T>::MemSpan(T *first, T *last) : _ptr{fi template <typename T> template <size_t N> MemSpan<T>::MemSpan(T (&a)[N]) : _ptr{a}, _count{N} {} +template <typename T> template <auto N> constexpr MemSpan<T>::MemSpan(std::array<T,N> const& a) : _ptr{a.data()} , _count{a.size()} {} +template <typename T> template <auto N> constexpr MemSpan<T>::MemSpan(std::array<T,N> & a) : _ptr{a.data()} , _count{a.size()} {} + template <typename T> constexpr MemSpan<T>::MemSpan(std::nullptr_t) {} template <typename T> diff --git a/code/include/swoc/Vectray.h b/code/include/swoc/Vectray.h index 4bf0149..5252127 100644 --- a/code/include/swoc/Vectray.h +++ b/code/include/swoc/Vectray.h @@ -47,6 +47,7 @@ protected: FixedStore() = default; explicit FixedStore(allocator_type const& a) : _a(a) {} + MemSpan<T> span(); }; using DynamicStore = vector_type; ///< Dynamic (heap) storage. @@ -68,12 +69,20 @@ public: */ explicit Vectray(size_type n, allocator_type const& alloc = allocator_type{}); - Vectray(self_type && that) { + template < size_t M > + Vectray(Vectray<T, M, A> && that) { // If @a that is already a vector, always move that here. if (DYNAMIC == that._store.index()) { _store = std::move(std::get<DYNAMIC>(that._store)); } else { - auto & fixed = std::get<FIXED>(_store); + auto span = std::get<FIXED>(that._store).span(); + if (span.size() > N) { + + } else { + for ( auto && item : span ) { + this->template emplace_back(std::move(item)); + } + } } } @@ -170,6 +179,11 @@ Vectray<T, N, A>::Vectray(Vectray::size_type n, allocator_type const& alloc) : V } } +template<typename T, size_t N, class A> +MemSpan<T> Vectray<T, N, A>::FixedStore::span() { + return MemSpan(_raw).template rebind<T>(); +} + template<typename T, size_t N, typename A> T& Vectray<T,N,A>::operator[](size_type idx) { return this->items()[idx]; @@ -250,7 +264,7 @@ void Vectray<T, N, A>::transfer(size_type rN) { template<typename T, size_t N, class A> auto Vectray<T, N, A>::items() const -> const_span { return std::visit(swoc::meta::vary{ - [](FixedStore const& fs) { return const_span(reinterpret_cast<T const *>(fs._raw.data()), fs._count); } + [](FixedStore const& fs) { fs.span(); } , [](DynamicStore const& ds) { return const_span(ds.data(), ds.size()); } }, _store); } @@ -258,7 +272,7 @@ auto Vectray<T, N, A>::items() const -> const_span { template<typename T, size_t N, class A> auto Vectray<T, N, A>::items() -> span { return std::visit(swoc::meta::vary{ - [](FixedStore & fs) { return span(reinterpret_cast<T *>(fs._raw.data()), fs._count); } + [](FixedStore & fs) { return fs.span(); } , [](DynamicStore & ds) { return span(ds.data(), ds.size()); } }, _store); } diff --git a/unit_tests/test_MemSpan.cc b/unit_tests/test_MemSpan.cc index 64aaf72..64a44ad 100644 --- a/unit_tests/test_MemSpan.cc +++ b/unit_tests/test_MemSpan.cc @@ -112,3 +112,19 @@ TEST_CASE("MemSpan<void>", "[libswoc][MemSpan]") REQUIRE(left.size() + span.size() == 1024); }; + +TEST_CASE("MemSpan Construction", "[libswoc][MemSpan]") +{ + std::array<int, 3> a{ 1, 2, 3 }; + // Automatic construction from an array. + MemSpan aspan{a}; + + REQUIRE(a[1] == 2); + aspan[1] = 56; + REQUIRE(a[1] == 56); + + // automatic conversion from @c T* to @c T @c const* + MemSpan<const int> nc{aspan}; + REQUIRE(nc[0] == 1); + REQUIRE(nc[1] == 56); +}