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);
+}

Reply via email to