[libc-commits] [libc] d7c920e - [libc][BlockStore] Add back, pop_back and empty methods
Alex Brachet via libc-commits
libc-commits at lists.llvm.org
Tue Mar 15 08:13:58 PDT 2022
Author: Alex Brachet
Date: 2022-03-15T15:11:57Z
New Revision: d7c920e1a0eace5429e7bd191c0ec77da478f800
URL: https://github.com/llvm/llvm-project/commit/d7c920e1a0eace5429e7bd191c0ec77da478f800
DIFF: https://github.com/llvm/llvm-project/commit/d7c920e1a0eace5429e7bd191c0ec77da478f800.diff
LOG: [libc][BlockStore] Add back, pop_back and empty methods
Reviewed By: sivachandra
Differential Revision: https://reviews.llvm.org/D121656
Added:
Modified:
libc/src/__support/CPP/blockstore.h
libc/test/src/__support/CPP/blockstore_test.cpp
Removed:
################################################################################
diff --git a/libc/src/__support/CPP/blockstore.h b/libc/src/__support/CPP/blockstore.h
index b4c5998814820..a75f9311c6d95 100644
--- a/libc/src/__support/CPP/blockstore.h
+++ b/libc/src/__support/CPP/blockstore.h
@@ -13,6 +13,11 @@
#include <stdint.h>
#include <stdlib.h>
+// TODO: fix our assert.h to make it useable
+#define assert(x) \
+ if (!(x)) \
+ __builtin_trap()
+
namespace __llvm_libc {
namespace cpp {
@@ -40,6 +45,22 @@ class BlockStore {
Block *current = &first;
size_t fill_count = 0;
+ struct Pair {
+ Block *first, *second;
+ };
+ Pair getLastBlocks() {
+ if (REVERSE_ORDER)
+ return {current, current->next};
+ Block *prev = nullptr;
+ Block *curr = &first;
+ for (; curr->next; prev = curr, curr = curr->next)
+ ;
+ assert(curr == current);
+ return {curr, prev};
+ }
+
+ Block *getLastBlock() { return getLastBlocks().first; }
+
public:
constexpr BlockStore() = default;
~BlockStore() = default;
@@ -113,6 +134,31 @@ class BlockStore {
*ptr = value;
}
+ T &back() {
+ return *reinterpret_cast<T *>(getLastBlock()->data +
+ sizeof(T) * (fill_count - 1));
+ }
+
+ void pop_back() {
+ fill_count--;
+ if (fill_count || current == &first)
+ return;
+ auto [last, prev] = getLastBlocks();
+ if (REVERSE_ORDER) {
+ assert(last == current);
+ current = current->next;
+ } else {
+ assert(prev->next == last);
+ current = prev;
+ current->next = nullptr;
+ }
+ if (last != &first)
+ ::free(last);
+ fill_count = BLOCK_SIZE;
+ }
+
+ bool empty() const { return current == &first && !fill_count; }
+
iterator begin() {
if (REVERSE_ORDER)
return iterator(current, fill_count);
diff --git a/libc/test/src/__support/CPP/blockstore_test.cpp b/libc/test/src/__support/CPP/blockstore_test.cpp
index 1f44bcf7aaf07..a9f00283dad55 100644
--- a/libc/test/src/__support/CPP/blockstore_test.cpp
+++ b/libc/test/src/__support/CPP/blockstore_test.cpp
@@ -41,6 +41,27 @@ class LlvmLibcBlockStoreTest : public __llvm_libc::testing::Test {
__llvm_libc::cpp::BlockStore<Element, BLOCK_SIZE, REVERSE>::destroy(
&block_store);
}
+
+ template <bool REVERSE> void back_test() {
+ using __llvm_libc::cpp::BlockStore;
+ BlockStore<int, 4, REVERSE> block_store;
+ for (int i = 0; i < 20; i++)
+ block_store.push_back(i);
+ for (int i = 19; i >= 0; i--, block_store.pop_back())
+ ASSERT_EQ(block_store.back(), i);
+ block_store.destroy(&block_store);
+ }
+
+ template <bool REVERSE> void empty_test() {
+ using __llvm_libc::cpp::BlockStore;
+ BlockStore<int, 2, REVERSE> block_store;
+
+ ASSERT_TRUE(block_store.empty());
+ block_store.push_back(1);
+ for (int i = 0; i < 10; i++, block_store.push_back(1))
+ ASSERT_FALSE(block_store.empty());
+ block_store.destroy(&block_store);
+ }
};
TEST_F(LlvmLibcBlockStoreTest, PopulateAndIterate4) {
@@ -66,3 +87,13 @@ TEST_F(LlvmLibcBlockStoreTest, PopulateAndIterateReverse8) {
TEST_F(LlvmLibcBlockStoreTest, PopulateAndIterateReverse10) {
populate_and_iterate<4, 10, true>();
}
+
+TEST_F(LlvmLibcBlockStoreTest, Back) {
+ back_test<false>();
+ back_test<true>();
+}
+
+TEST_F(LlvmLibcBlockStoreTest, Empty) {
+ empty_test<false>();
+ empty_test<true>();
+}
More information about the libc-commits
mailing list