Merge pull request #14146 from markdroth/inlined_vector_clear

Add clear() method for InlinedVector<>.
reviewable/pr14179/r1
Mark D. Roth 7 years ago committed by GitHub
commit 8ddc6b2658
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 58
      src/core/lib/gprpp/inlined_vector.h
  2. 38
      test/core/gprpp/inlined_vector_test.cc

@ -40,24 +40,13 @@ namespace grpc_core {
// ANY METHOD ADDED HERE MUST COMPLY WITH THE INTERFACE IN THE absl
// IMPLEMENTATION!
//
// TODO(ctiller, nnoble, roth): Replace this with absl::InlinedVector
// once we integrate absl into the gRPC build system in a usable way.
// TODO(nnoble, roth): Replace this with absl::InlinedVector once we
// integrate absl into the gRPC build system in a usable way.
template <typename T, size_t N>
class InlinedVector {
public:
InlinedVector() {}
~InlinedVector() {
for (size_t i = 0; i < size_ && i < N; ++i) {
T& value = *reinterpret_cast<T*>(inline_ + 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_);
}
InlinedVector() { init_data(); }
~InlinedVector() { destroy_elements(); }
// For now, we do not support copying.
InlinedVector(const InlinedVector&) = delete;
@ -72,6 +61,15 @@ class InlinedVector {
}
}
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];
}
}
template <typename... Args>
void emplace_back(Args&&... args) {
if (size_ < N) {
@ -100,11 +98,35 @@ class InlinedVector {
size_t size() const { return size_; }
void clear() {
destroy_elements();
init_data();
}
private:
void init_data() {
dynamic_ = nullptr;
size_ = 0;
dynamic_capacity_ = 0;
}
void destroy_elements() {
for (size_t i = 0; i < size_ && i < N; ++i) {
T& value = *reinterpret_cast<T*>(inline_ + 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_ = nullptr;
size_t size_ = 0;
size_t dynamic_capacity_ = 0;
T* dynamic_;
size_t size_;
size_t dynamic_capacity_;
};
} // namespace grpc_core

@ -64,6 +64,44 @@ TEST(InlinedVectorTest, EmplaceBack) {
EXPECT_EQ(3, *v[0]);
}
TEST(InlinedVectorTest, ClearAndRepopulate) {
const int kNumElements = 10;
InlinedVector<int, 5> v;
EXPECT_EQ(0UL, v.size());
for (int i = 0; i < kNumElements; ++i) {
v.push_back(i);
EXPECT_EQ(i + 1UL, v.size());
}
for (int i = 0; i < kNumElements; ++i) {
EXPECT_EQ(i, v[i]);
}
v.clear();
EXPECT_EQ(0UL, v.size());
for (int i = 0; i < kNumElements; ++i) {
v.push_back(kNumElements + i);
EXPECT_EQ(i + 1UL, v.size());
}
for (int i = 0; i < kNumElements; ++i) {
EXPECT_EQ(kNumElements + i, v[i]);
}
}
TEST(InlinedVectorTest, ConstIndexOperator) {
const int kNumElements = 10;
InlinedVector<int, 5> v;
EXPECT_EQ(0UL, v.size());
for (int i = 0; i < kNumElements; ++i) {
v.push_back(i);
EXPECT_EQ(i + 1UL, v.size());
}
auto const_func = [kNumElements](const InlinedVector<int, 5>& v) {
for (int i = 0; i < kNumElements; ++i) {
EXPECT_EQ(i, v[i]);
}
};
const_func(v);
}
} // namespace testing
} // namespace grpc_core

Loading…
Cancel
Save