1 | //===-- A data structure for a fixed capacity data store --------*- C++ -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #ifndef LLVM_LIBC_SRC___SUPPORT_FIXEDVECTOR_H |
10 | #define LLVM_LIBC_SRC___SUPPORT_FIXEDVECTOR_H |
11 | |
12 | #include "src/__support/CPP/array.h" |
13 | |
14 | #include "src/__support/CPP/iterator.h" |
15 | |
16 | namespace LIBC_NAMESPACE { |
17 | |
18 | // A fixed size data store backed by an underlying cpp::array data structure. It |
19 | // supports vector like API but is not resizable like a vector. |
20 | template <typename T, size_t CAPACITY> class FixedVector { |
21 | cpp::array<T, CAPACITY> store; |
22 | size_t item_count = 0; |
23 | |
24 | public: |
25 | constexpr FixedVector() = default; |
26 | |
27 | bool push_back(const T &obj) { |
28 | if (item_count == CAPACITY) |
29 | return false; |
30 | store[item_count] = obj; |
31 | ++item_count; |
32 | return true; |
33 | } |
34 | |
35 | const T &back() const { return store[item_count - 1]; } |
36 | |
37 | T &back() { return store[item_count - 1]; } |
38 | |
39 | bool pop_back() { |
40 | if (item_count == 0) |
41 | return false; |
42 | --item_count; |
43 | return true; |
44 | } |
45 | |
46 | bool empty() const { return item_count == 0; } |
47 | |
48 | // Empties the store for all practical purposes. |
49 | void reset() { item_count = 0; } |
50 | |
51 | // This static method does not free up the resources held by |store|, |
52 | // say by calling `free` or something similar. It just does the equivalent |
53 | // of the `reset` method. Considering that FixedVector is of fixed storage, |
54 | // a `destroy` method like this should not be required. However, FixedVector |
55 | // is used in a few places as an alternate for data structures which use |
56 | // dynamically allocated storate. So, the `destroy` method like this |
57 | // matches the `destroy` API of those other data structures so that users |
58 | // can easily swap one data structure for the other. |
59 | static void destroy(FixedVector<T, CAPACITY> *store) { store->reset(); } |
60 | |
61 | using reverse_iterator = typename cpp::array<T, CAPACITY>::reverse_iterator; |
62 | LIBC_INLINE constexpr reverse_iterator rbegin() { |
63 | return reverse_iterator{&store[item_count]}; |
64 | } |
65 | LIBC_INLINE constexpr reverse_iterator rend() { return store.rend(); } |
66 | }; |
67 | |
68 | } // namespace LIBC_NAMESPACE |
69 | |
70 | #endif // LLVM_LIBC_SRC___SUPPORT_FIXEDVECTOR_H |
71 | |