diff options
author | 2018-05-11 12:20:11 -0700 | |
---|---|---|
committer | 2018-05-11 12:20:11 -0700 | |
commit | 4fad281ce8affe27fb7428f264d2c3b9dfc45f2f (patch) | |
tree | ca96c9efd69afec56aa2e5fe072a9f758247d0a3 /src/core/lib/gprpp/inlined_vector.h | |
parent | ec445cc2bb270ed4acb1c710c3533fca14a50019 (diff) | |
parent | 61fdb46ac456027c79841949272ec540f66d2317 (diff) |
Merge remote-tracking branch 'upstream/master' into fork_exec_ctx_check
Diffstat (limited to 'src/core/lib/gprpp/inlined_vector.h')
-rw-r--r-- | src/core/lib/gprpp/inlined_vector.h | 64 |
1 files changed, 30 insertions, 34 deletions
diff --git a/src/core/lib/gprpp/inlined_vector.h b/src/core/lib/gprpp/inlined_vector.h index ca95aecddc..f36f6cb706 100644 --- a/src/core/lib/gprpp/inlined_vector.h +++ b/src/core/lib/gprpp/inlined_vector.h @@ -54,43 +54,43 @@ class InlinedVector { InlinedVector(const InlinedVector&) = delete; InlinedVector& operator=(const InlinedVector&) = delete; + T* data() { + return dynamic_ != nullptr ? dynamic_ : reinterpret_cast<T*>(inline_); + } + + const T* data() const { + return dynamic_ != nullptr ? dynamic_ : reinterpret_cast<const T*>(inline_); + } + T& operator[](size_t offset) { assert(offset < size_); - if (offset < N) { - return *reinterpret_cast<T*>(inline_ + offset); - } else { - return dynamic_[offset - N]; - } + return data()[offset]; } const T& operator[](size_t offset) const { assert(offset < size_); - if (offset < N) { - return *reinterpret_cast<const T*>(inline_ + offset); - } else { - return dynamic_[offset - N]; + return data()[offset]; + } + + 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(); + } + gpr_free(dynamic_); + dynamic_ = new_dynamic; + capacity_ = capacity; } } template <typename... Args> void emplace_back(Args&&... args) { - if (size_ < N) { - new (&inline_[size_]) T(std::forward<Args>(args)...); - } else { - if (size_ - N == dynamic_capacity_) { - size_t new_capacity = - dynamic_capacity_ == 0 ? 2 : dynamic_capacity_ * 2; - T* new_dynamic = static_cast<T*>(gpr_malloc(sizeof(T) * new_capacity)); - for (size_t i = 0; i < dynamic_capacity_; ++i) { - new (&new_dynamic[i]) T(std::move(dynamic_[i])); - dynamic_[i].~T(); - } - gpr_free(dynamic_); - dynamic_ = new_dynamic; - dynamic_capacity_ = new_capacity; - } - new (&dynamic_[size_ - N]) T(std::forward<Args>(args)...); + if (size_ == capacity_) { + reserve(capacity_ * 2); } + new (&(data()[size_])) T(std::forward<Args>(args)...); ++size_; } @@ -99,6 +99,7 @@ class InlinedVector { void push_back(T&& value) { emplace_back(std::move(value)); } size_t size() const { return size_; } + size_t capacity() const { return capacity_; } void clear() { destroy_elements(); @@ -109,26 +110,21 @@ class InlinedVector { void init_data() { dynamic_ = nullptr; size_ = 0; - dynamic_capacity_ = 0; + capacity_ = N; } void destroy_elements() { - for (size_t i = 0; i < size_ && i < N; ++i) { - T& value = *reinterpret_cast<T*>(inline_ + i); + for (size_t i = 0; i < size_; ++i) { + T& value = data()[i]; value.~T(); } - if (size_ > N) { // Avoid subtracting two signed values. - for (size_t i = 0; i < size_ - N; ++i) { - dynamic_[i].~T(); - } - } gpr_free(dynamic_); } typename std::aligned_storage<sizeof(T)>::type inline_[N]; T* dynamic_; size_t size_; - size_t dynamic_capacity_; + size_t capacity_; }; } // namespace grpc_core |