diff --git a/libc/src/__support/CMakeLists.txt b/libc/src/__support/CMakeLists.txt --- a/libc/src/__support/CMakeLists.txt +++ b/libc/src/__support/CMakeLists.txt @@ -70,6 +70,14 @@ arg_list.h ) +add_header_library( + arraystore + HDRS + arraystore.h + DEPENDS + libc.src.__support.CPP.array +) + add_subdirectory(FPUtil) add_subdirectory(OSUtil) diff --git a/libc/src/__support/arraystore.h b/libc/src/__support/arraystore.h new file mode 100644 --- /dev/null +++ b/libc/src/__support/arraystore.h @@ -0,0 +1,49 @@ +//===-- A data structure for a fixed size data store ------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "src/__support/CPP/array.h" + +namespace __llvm_libc { + +// A fixed size data store backed by an underlying cpp::array data structure. It +// supports vector like API but is not resizable like a vector. +template class ArrayStore { + cpp::array store; + size_t item_count = 0; + +public: + constexpr ArrayStore() = default; + + bool push_back(const T &obj) { + if (item_count == SIZE) + return false; + store[item_count] = obj; + ++item_count; + return true; + } + + const T &back() const { return store[item_count - 1]; } + + T &back() { return store[item_count - 1]; } + + bool pop_back() { + if (item_count == 0) + return false; + --item_count; + return true; + } + + bool empty() const { return item_count == 0; } + + // Empties the store for all practical purposes. + void reset() { item_count = 0; } + + static void destroy(ArrayStore *store) { store->reset(); } +}; + +} // namespace __llvm_libc diff --git a/libc/test/src/__support/CMakeLists.txt b/libc/test/src/__support/CMakeLists.txt --- a/libc/test/src/__support/CMakeLists.txt +++ b/libc/test/src/__support/CMakeLists.txt @@ -63,6 +63,16 @@ libc.src.__support.CPP.uint ) +add_libc_unittest( + arraystore_test + SUITE + libc_support_unittests + SRCS + arraystore_test.cpp + DEPENDS + libc.src.__support.arraystore +) + add_executable( libc_str_to_float_comparison_test str_to_float_comparison_test.cpp diff --git a/libc/test/src/__support/arraystore_test.cpp b/libc/test/src/__support/arraystore_test.cpp new file mode 100644 --- /dev/null +++ b/libc/test/src/__support/arraystore_test.cpp @@ -0,0 +1,45 @@ +//===-- Unittests for ArrayStore ------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "src/__support/arraystore.h" +#include "utils/UnitTest/Test.h" + +TEST(LlvmLibcArrayStoreTest, PushAndPop) { + __llvm_libc::ArrayStore array_store; + ASSERT_TRUE(array_store.empty()); + for (int i = 0; i < 20; i++) + ASSERT_TRUE(array_store.push_back(i)); + ASSERT_FALSE(array_store.empty()); + ASSERT_FALSE(array_store.push_back(123)); + for (int i = 20; i > 0; --i) { + ASSERT_EQ(array_store.back(), i - 1); + ASSERT_TRUE(array_store.pop_back()); + } + ASSERT_FALSE(array_store.pop_back()); + ASSERT_TRUE(array_store.empty()); +} + +TEST(LlvmLibcArrayStoreTest, Reset) { + __llvm_libc::ArrayStore array_store; + ASSERT_TRUE(array_store.empty()); + for (int i = 0; i < 20; i++) + ASSERT_TRUE(array_store.push_back(i)); + ASSERT_FALSE(array_store.empty()); + array_store.reset(); + ASSERT_TRUE(array_store.empty()); +} + +TEST(LlvmLibcArrayStoreTest, Destroy) { + __llvm_libc::ArrayStore array_store; + ASSERT_TRUE(array_store.empty()); + for (int i = 0; i < 20; i++) + ASSERT_TRUE(array_store.push_back(i)); + ASSERT_FALSE(array_store.empty()); + __llvm_libc::ArrayStore::destroy(&array_store); + ASSERT_TRUE(array_store.empty()); +}