diff options
author | Mark D. Roth <roth@google.com> | 2018-11-29 07:55:12 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-11-29 07:55:12 -0800 |
commit | f3844ec79ee14dfddf6162dff173af7861a06eae (patch) | |
tree | b2a83c7dbf8a334c8ada10cf6ce79bed65c06cdb /src/core/lib | |
parent | 8b7323df1c36bb855b749985ca301c5531d2e263 (diff) | |
parent | 5214f8bc57ed327235bcd949589e6da58b2c10ca (diff) |
Merge pull request #17323 from markdroth/inlined_vector_copy_and_move_fix
Fix InlinedVector to use its elements' move and copy methods.
Diffstat (limited to 'src/core/lib')
-rw-r--r-- | src/core/lib/gprpp/inlined_vector.h | 44 |
1 files changed, 25 insertions, 19 deletions
diff --git a/src/core/lib/gprpp/inlined_vector.h b/src/core/lib/gprpp/inlined_vector.h index 65c2b9634f..66dc751a56 100644 --- a/src/core/lib/gprpp/inlined_vector.h +++ b/src/core/lib/gprpp/inlined_vector.h @@ -100,10 +100,7 @@ class InlinedVector { void reserve(size_t capacity) { if (capacity > capacity_) { T* new_dynamic = static_cast<T*>(gpr_malloc(sizeof(T) * capacity)); - for (size_t i = 0; i < size_; ++i) { - new (&new_dynamic[i]) T(std::move(data()[i])); - data()[i].~T(); - } + move_elements(data(), new_dynamic, size_); gpr_free(dynamic_); dynamic_ = new_dynamic; capacity_ = capacity; @@ -131,13 +128,25 @@ class InlinedVector { size_--; } + size_t size() const { return size_; } + bool empty() const { return size_ == 0; } + + size_t capacity() const { return capacity_; } + + void clear() { + destroy_elements(); + init_data(); + } + + private: void copy_from(const InlinedVector& v) { - // if v is allocated, copy over the buffer. + // if v is allocated, make sure we have enough capacity. if (v.dynamic_ != nullptr) { reserve(v.capacity_); - memcpy(dynamic_, v.dynamic_, v.size_ * sizeof(T)); - } else { - memcpy(inline_, v.inline_, v.size_ * sizeof(T)); + } + // copy over elements + for (size_t i = 0; i < v.size_; ++i) { + new (&(data()[i])) T(v[i]); } // copy over metadata size_ = v.size_; @@ -145,11 +154,12 @@ class InlinedVector { } void move_from(InlinedVector& v) { - // if v is allocated, then we steal its buffer, else we copy it. + // if v is allocated, then we steal its dynamic array; otherwise, we + // move the elements individually. if (v.dynamic_ != nullptr) { dynamic_ = v.dynamic_; } else { - memcpy(inline_, v.inline_, v.size_ * sizeof(T)); + move_elements(v.data(), data(), v.size_); } // copy over metadata size_ = v.size_; @@ -158,17 +168,13 @@ class InlinedVector { v.init_data(); } - size_t size() const { return size_; } - bool empty() const { return size_ == 0; } - - size_t capacity() const { return capacity_; } - - void clear() { - destroy_elements(); - init_data(); + static void move_elements(T* src, T* dst, size_t num_elements) { + for (size_t i = 0; i < num_elements; ++i) { + new (&dst[i]) T(std::move(src[i])); + src[i].~T(); + } } - private: void init_data() { dynamic_ = nullptr; size_ = 0; |