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 48b4c392a8512599e55c2a425a846ae35c4de584
Author: Alan M. Carroll <[email protected]>
AuthorDate: Wed Jun 16 07:09:11 2021 -0500

    Working on constructors.
---
 code/include/swoc/Vectray.h | 55 +++++++++++++++++++++++++++++++++++++++------
 1 file changed, 48 insertions(+), 7 deletions(-)

diff --git a/code/include/swoc/Vectray.h b/code/include/swoc/Vectray.h
index dc8deb9..4bf0149 100644
--- a/code/include/swoc/Vectray.h
+++ b/code/include/swoc/Vectray.h
@@ -59,9 +59,25 @@ public:
   Vectray();
 
   /// Construct empty instance with allocator.
-  explicit Vectray(allocator_type const& a) : 
_store(std::in_place_type_t<FixedStore>{}, a) {}
+  constexpr explicit Vectray(allocator_type const& a) : 
_store(std::in_place_type_t<FixedStore>{}, a) {}
 
-  explicit Vectray(size_type n, allocator_type const& alloc = 
allocator_type());
+  /** Construct with @a n default constructed elements.
+   *
+   * @param n Number of elements.
+   * @param alloc Allocator (optional - default constructed if not a 
parameter).
+   */
+  explicit Vectray(size_type n, allocator_type const& alloc = 
allocator_type{});
+
+  Vectray(self_type && 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);
+    }
+  }
+
+  Vectray(self_type && that, allocator_type const& a);
 
   /// @return The number of elements in the container.
   size_type size() const;
@@ -128,9 +144,17 @@ protected:
   /// Get the span of the valid items.
   const_span items() const;
 
-  /// Transfer from fixed storage to dynamic storage.
-  /// Must not be called more than once per instance.
-  void transfer();
+  /// Default size to reserve in the vector when switching to dynamic.
+  static constexpr size_type BASE_DYNAMIC_SIZE = (7 * N) / 5;
+
+
+  /** Transfer from fixed storage to dynamic storage.
+   *
+   * @param rN Numer of elements of storage to reserve in the vector.
+   *
+   * @note Must be called at most once for any instance.
+   */
+  void transfer(size_type rN = BASE_DYNAMIC_SIZE);
 };
 
 // --- Implementation ---
@@ -138,6 +162,14 @@ protected:
 template<typename T, size_t N, typename A>
 Vectray<T,N,A>::Vectray() {}
 
+template<typename T, size_t N, class A>
+Vectray<T, N, A>::Vectray(Vectray::size_type n, allocator_type const& alloc) : 
Vectray() {
+  this->reserve(n);
+  while (n-- > 0) {
+    this->emplace_back();
+  }
+}
+
 template<typename T, size_t N, typename A>
 T& Vectray<T,N,A>::operator[](size_type idx) {
   return this->items()[idx];
@@ -204,9 +236,9 @@ auto Vectray<T,N,A>::end() -> iterator { return 
this->items().end(); }
 // --- iterators
 
 template<typename T, size_t N, class A>
-void Vectray<T, N, A>::transfer() {
+void Vectray<T, N, A>::transfer(size_type rN) {
   DynamicStore tmp{std::get<FIXED>(_store)._a};
-  tmp.reserve((14 * N) / 10); // bump by approximately sqrt(2).
+  tmp.reserve(rN);
 
   for (auto&& item : this->items()) {
     tmp.emplace_back(item); // move if supported, copy if not.
@@ -231,5 +263,14 @@ auto Vectray<T, N, A>::items() -> span {
   }, _store);
 }
 
+template<typename T, size_t N, class A>
+void Vectray<T, N, A>::reserve(Vectray::size_type n) {
+  if (DYNAMIC == _store.index()) {
+    std::get<DYNAMIC>(_store).reserve(n);
+  } else if (n > N) {
+    this->transfer(n);
+  }
+}
+
 }} // namespace swoc
 

Reply via email to