summaryrefslogtreecommitdiff
path: root/libc/src/__support/fixedvector.h
diff options
context:
space:
mode:
authorNAKAMURA Takumi <geek4civic@gmail.com>2025-01-09 18:49:54 +0900
committerNAKAMURA Takumi <geek4civic@gmail.com>2025-01-09 18:49:54 +0900
commite2810c9a248f4c7fbfae84bb32b6f7e01027458b (patch)
treeae0b02a8491b969a1cee94ea16ffe42c559143c5 /libc/src/__support/fixedvector.h
parentfa04eb4af95c1ca7377279728cb004bcd2324d01 (diff)
parentbdcf47e4bcb92889665825654bb80a8bbe30379e (diff)
Merge branch 'users/chapuni/cov/single/base' into users/chapuni/cov/single/switchusers/chapuni/cov/single/switch
Diffstat (limited to 'libc/src/__support/fixedvector.h')
-rw-r--r--libc/src/__support/fixedvector.h54
1 files changed, 39 insertions, 15 deletions
diff --git a/libc/src/__support/fixedvector.h b/libc/src/__support/fixedvector.h
index 7ac0c230f9c5..34601f86dc01 100644
--- a/libc/src/__support/fixedvector.h
+++ b/libc/src/__support/fixedvector.h
@@ -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 {
@@ -23,27 +24,32 @@ 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;
@@ -51,27 +57,43 @@ public:
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
@@ -81,7 +103,9 @@ public:
// 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() {