Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions libc/src/__support/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,9 @@ add_header_library(
HDRS
fixedvector.h
DEPENDS
.libc_assert
libc.src.__support.CPP.array
libc.src.string.memory_utils.inline_memset
)

add_header_library(
Expand Down
53 changes: 35 additions & 18 deletions libc/src/__support/fixedvector.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@
#define LLVM_LIBC_SRC___SUPPORT_FIXEDVECTOR_H

#include "src/__support/CPP/array.h"

#include "src/__support/CPP/iterator.h"
#include "src/__support/libc_assert.h"
#include "src/__support/macros/config.h"
#include "src/string/memory_utils/inline_memset.h"

namespace LIBC_NAMESPACE_DECL {

Expand All @@ -23,55 +24,71 @@ template <typename T, size_t CAPACITY> class FixedVector {
size_t item_count = 0;

public:
constexpr FixedVector() = default;
LIBC_INLINE constexpr FixedVector() = default;

using iterator = typename cpp::array<T, CAPACITY>::iterator;
constexpr FixedVector(iterator begin, iterator end) : store{}, item_count{} {
LIBC_INLINE constexpr FixedVector(iterator begin, iterator end) : store{}, item_count{} {
for (; begin != end; ++begin)
push_back(*begin);
LIBC_ASSERT(push_back(*begin));
}

using const_iterator = typename cpp::array<T, CAPACITY>::const_iterator;
constexpr FixedVector(const_iterator begin, const_iterator end)
LIBC_INLINE constexpr FixedVector(const_iterator begin, const_iterator end)
: store{}, item_count{} {
for (; begin != end; ++begin)
push_back(*begin);
LIBC_ASSERT(push_back(*begin));
}

constexpr FixedVector(size_t count, const T &value) : store{}, item_count{} {
LIBC_INLINE constexpr FixedVector(size_t count, const T &value) : store{}, item_count{} {
for (size_t i = 0; i < count; ++i)
push_back(value);
LIBC_ASSERT(push_back(value));
}

constexpr bool push_back(const T &obj) {
LIBC_INLINE constexpr bool push_back(const T &obj) {
if (item_count == CAPACITY)
return false;
store[item_count] = obj;
++item_count;
return true;
}

constexpr const T &back() const { return store[item_count - 1]; }
LIBC_INLINE constexpr const T &back() const {
LIBC_ASSERT(!empty());
return store[item_count - 1];
}

constexpr T &back() { return store[item_count - 1]; }
LIBC_INLINE constexpr T &back() {
LIBC_ASSERT(!empty());
return store[item_count - 1];
}

constexpr bool pop_back() {
LIBC_INLINE constexpr bool pop_back() {
if (item_count == 0)
return false;
inline_memset(&store[item_count - 1], 0, sizeof(T));
--item_count;
return true;
}

constexpr T &operator[](size_t idx) { return store[idx]; }
LIBC_INLINE constexpr T &operator[](size_t idx) {
LIBC_ASSERT(idx < item_count);
return store[idx];
}

constexpr const T &operator[](size_t idx) const { return store[idx]; }
LIBC_INLINE constexpr const T &operator[](size_t idx) const {
LIBC_ASSERT(idx < item_count);
return store[idx];
}

constexpr bool empty() const { return item_count == 0; }
LIBC_INLINE constexpr bool empty() const { return item_count == 0; }

constexpr size_t size() const { return item_count; }
LIBC_INLINE constexpr size_t size() const { return item_count; }

// Empties the store for all practical purposes.
constexpr void reset() { item_count = 0; }
LIBC_INLINE constexpr void reset() {
inline_memset(store.data(), 0, sizeof(T) * item_count);
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
Expand All @@ -81,7 +98,7 @@ template <typename T, size_t CAPACITY> class FixedVector {
// 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(); }
LIBC_INLINE static void destroy(FixedVector<T, CAPACITY> *store) { store->reset(); }

using reverse_iterator = typename cpp::array<T, CAPACITY>::reverse_iterator;
LIBC_INLINE constexpr reverse_iterator rbegin() {
Expand Down
2 changes: 1 addition & 1 deletion libc/src/stdlib/exit_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ LIBC_INLINE void stdc_at_exit_func(void *payload) {
LIBC_INLINE void call_exit_callbacks(ExitCallbackList &callbacks) {
handler_list_mtx.lock();
while (!callbacks.empty()) {
AtExitUnit &unit = callbacks.back();
AtExitUnit unit = callbacks.back();
callbacks.pop_back();
handler_list_mtx.unlock();
unit.callback(unit.payload);
Expand Down
2 changes: 2 additions & 0 deletions utils/bazel/llvm-project-overlay/libc/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -670,6 +670,8 @@ libc_support_library(
deps = [
":__support_cpp_array",
":__support_cpp_iterator",
":__support_libc_assert",
":string_memory_utils",
],
)

Expand Down
Loading