Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
54 changes: 39 additions & 15 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,76 @@ 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{} {
LIBC_ASSERT(begin + CAPACITY >= end);
for (; begin != end; ++begin)
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{} {
LIBC_ASSERT(begin + CAPACITY >= end);
for (; begin != end; ++begin)
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{} {
LIBC_ASSERT(count <= CAPACITY);
for (size_t i = 0; i < count; ++i)
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 +103,9 @@ 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