#ifndef LLVM_LIBC_SUPPORT_BLOCKSTORE_H
#define LLVM_LIBC_SUPPORT_BLOCKSTORE_H
+#include <src/__support/CPP/new.h>
+
#include <stddef.h>
#include <stdint.h>
-#include <stdlib.h>
// TODO: fix our assert.h to make it useable
#define assert(x) \
T *new_obj() {
if (fill_count == BLOCK_SIZE) {
- auto new_block = reinterpret_cast<Block *>(::malloc(sizeof(Block)));
+ AllocChecker ac;
+ auto new_block = new (ac) Block();
+ if (!ac)
+ return nullptr;
if (REVERSE_ORDER) {
new_block->next = current;
} else {
return obj;
}
- void push_back(const T &value) {
+ [[nodiscard]] bool push_back(const T &value) {
T *ptr = new_obj();
+ if (ptr == nullptr)
+ return false;
*ptr = value;
+ return true;
}
T &back() {
current->next = nullptr;
}
if (last != &first)
- ::free(last);
+ delete last;
fill_count = BLOCK_SIZE;
}
while (current->next != nullptr) {
auto temp = current;
current = current->next;
- free(temp);
+ delete temp;
}
} else {
auto current = block_store->first.next;
while (current != nullptr) {
auto temp = current;
current = current->next;
- free(temp);
+ delete temp;
}
}
block_store->current = nullptr;
} // namespace internal
static int add_atexit_unit(const AtExitUnit &unit) {
- // TODO: Use the return value of push_back and bubble it to the public
- // function as error return value. Note that a BlockStore push_back can
- // fail because of allocation failure. Likewise, a FixedVector push_back
- // can fail when it is full.
- handler_list_mtx.lock();
- exit_callbacks.push_back(unit);
- handler_list_mtx.unlock();
+ MutexLock lock(&handler_list_mtx);
+ if (!exit_callbacks.push_back(unit))
+ return -1;
return 0;
}
void populate_and_iterate() {
__llvm_libc::cpp::BlockStore<Element, BLOCK_SIZE, REVERSE> block_store;
for (int i = 0; i < int(ELEMENT_COUNT); ++i)
- block_store.push_back({i, 2 * i, 3 * unsigned(i)});
+ ASSERT_TRUE(block_store.push_back({i, 2 * i, 3 * unsigned(i)}));
auto end = block_store.end();
int i = 0;
for (auto iter = block_store.begin(); iter != end; ++iter, ++i) {
using __llvm_libc::cpp::BlockStore;
BlockStore<int, 4, REVERSE> block_store;
for (int i = 0; i < 20; i++)
- block_store.push_back(i);
+ ASSERT_TRUE(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);
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_TRUE(block_store.push_back(1));
+ for (int i = 0; i < 10; i++) {
ASSERT_FALSE(block_store.empty());
+ ASSERT_TRUE(block_store.push_back(1));
+ }
block_store.destroy(&block_store);
}
};