forked from OSchip/llvm-project
[libc] Add a utility data structure named FixedVector.
This data structure uses a backing cpp::array object and supports a vector like push_back API. In comparison with a traditional vector data structure, it is of a fixed capacity and cannot be resized. Differential Revision: https://reviews.llvm.org/D131377
This commit is contained in:
parent
cab6cd6834
commit
daa44a2309
|
@ -70,6 +70,14 @@ add_header_library(
|
|||
arg_list.h
|
||||
)
|
||||
|
||||
add_header_library(
|
||||
fixedvector
|
||||
HDRS
|
||||
fixedvector.h
|
||||
DEPENDS
|
||||
libc.src.__support.CPP.array
|
||||
)
|
||||
|
||||
add_subdirectory(FPUtil)
|
||||
add_subdirectory(OSUtil)
|
||||
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
//===-- A data structure for a fixed capacity 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIBC_SUPPORT_FIXEDVECTOR_H
|
||||
#define LLVM_LIBC_SUPPORT_FIXEDVECTOR_H
|
||||
|
||||
#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 <typename T, size_t CAPACITY> class FixedVector {
|
||||
cpp::array<T, CAPACITY> store;
|
||||
size_t item_count = 0;
|
||||
|
||||
public:
|
||||
constexpr FixedVector() = default;
|
||||
|
||||
bool push_back(const T &obj) {
|
||||
if (item_count == CAPACITY)
|
||||
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; }
|
||||
|
||||
// This static method does not free up the resources held by |store|,
|
||||
// say by calling `free` or something similar. It just does the equivalent
|
||||
// of the `reset` method. Considering that FixedVector is of fixed storage,
|
||||
// a `destroy` method like this should not be required. However, FixedVector
|
||||
// is used in a few places as an alternate for data structures which use
|
||||
// dynamically allocated storate. So, the `destroy` method like this
|
||||
// matches the `destroy` API of those other data structures so that users
|
||||
// can easily swap one data structure for the other.
|
||||
static void destroy(FixedVector<T, CAPACITY> *store) { store->reset(); }
|
||||
};
|
||||
|
||||
} // namespace __llvm_libc
|
||||
|
||||
#endif // LLVM_LIBC_SUPPORT_FIXEDVECTOR_H
|
|
@ -63,6 +63,16 @@ add_libc_unittest(
|
|||
libc.src.__support.CPP.uint
|
||||
)
|
||||
|
||||
add_libc_unittest(
|
||||
fixedvector_test
|
||||
SUITE
|
||||
libc_support_unittests
|
||||
SRCS
|
||||
fixedvector_test.cpp
|
||||
DEPENDS
|
||||
libc.src.__support.fixedvector
|
||||
)
|
||||
|
||||
add_executable(
|
||||
libc_str_to_float_comparison_test
|
||||
str_to_float_comparison_test.cpp
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
//===-- Unittests for FixedVector -----------------------------------------===//
|
||||
//
|
||||
// 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/fixedvector.h"
|
||||
#include "utils/UnitTest/Test.h"
|
||||
|
||||
TEST(LlvmLibcFixedVectorTest, PushAndPop) {
|
||||
__llvm_libc::FixedVector<int, 20> fixed_vector;
|
||||
ASSERT_TRUE(fixed_vector.empty());
|
||||
for (int i = 0; i < 20; i++)
|
||||
ASSERT_TRUE(fixed_vector.push_back(i));
|
||||
ASSERT_FALSE(fixed_vector.empty());
|
||||
ASSERT_FALSE(fixed_vector.push_back(123));
|
||||
for (int i = 20; i > 0; --i) {
|
||||
ASSERT_EQ(fixed_vector.back(), i - 1);
|
||||
ASSERT_TRUE(fixed_vector.pop_back());
|
||||
}
|
||||
ASSERT_FALSE(fixed_vector.pop_back());
|
||||
ASSERT_TRUE(fixed_vector.empty());
|
||||
}
|
||||
|
||||
TEST(LlvmLibcFixedVectorTest, Reset) {
|
||||
__llvm_libc::FixedVector<int, 20> fixed_vector;
|
||||
ASSERT_TRUE(fixed_vector.empty());
|
||||
for (int i = 0; i < 20; i++)
|
||||
ASSERT_TRUE(fixed_vector.push_back(i));
|
||||
ASSERT_FALSE(fixed_vector.empty());
|
||||
fixed_vector.reset();
|
||||
ASSERT_TRUE(fixed_vector.empty());
|
||||
}
|
||||
|
||||
TEST(LlvmLibcFixedVectorTest, Destroy) {
|
||||
__llvm_libc::FixedVector<int, 20> fixed_vector;
|
||||
ASSERT_TRUE(fixed_vector.empty());
|
||||
for (int i = 0; i < 20; i++)
|
||||
ASSERT_TRUE(fixed_vector.push_back(i));
|
||||
ASSERT_FALSE(fixed_vector.empty());
|
||||
__llvm_libc::FixedVector<int, 20>::destroy(&fixed_vector);
|
||||
ASSERT_TRUE(fixed_vector.empty());
|
||||
}
|
Loading…
Reference in New Issue