blob: 4264cf60aad67a7e16565c82bd7bbe053b6d5b5e [file] [log] [blame]
Brian Silvermand844a572019-01-26 15:59:00 -08001#ifndef AOS_CONTAINERS_SIZED_ARRAY_H_
2#define AOS_CONTAINERS_SIZED_ARRAY_H_
3
4#include <array>
Brian Silverman4c7235a2021-11-17 19:04:37 -08005#include <cstddef>
Brian Silvermand844a572019-01-26 15:59:00 -08006
7namespace aos {
8
9// An array along with a variable size. This is a simple variable-size container
10// with a fixed maximum size.
11//
12// Note that it default-constructs N T instances at construction time. This
13// simplifies the internal bookkeeping a lot (I believe this can be
14// all-constexpr in C++17), but makes it a poor choice for complex T.
15template <typename T, size_t N>
16class SizedArray {
17 private:
18 using array = std::array<T, N>;
19
20 public:
21 using value_type = typename array::value_type;
22 using size_type = typename array::size_type;
23 using difference_type = typename array::difference_type;
24 using reference = typename array::reference;
25 using const_reference = typename array::const_reference;
26 using pointer = typename array::pointer;
27 using const_pointer = typename array::const_pointer;
28 using iterator = typename array::iterator;
29 using const_iterator = typename array::const_iterator;
30 using reverse_iterator = typename array::reverse_iterator;
31 using const_reverse_iterator = typename array::const_reverse_iterator;
32
33 constexpr SizedArray() = default;
James Kuszmaul48fb79f2019-01-27 13:27:55 -080034 SizedArray(const SizedArray &) = default;
35 SizedArray(SizedArray &&) = default;
Brian Silvermand844a572019-01-26 15:59:00 -080036 SizedArray &operator=(const SizedArray &) = default;
37 SizedArray &operator=(SizedArray &&) = default;
38
Brian Silverman246cb222019-02-02 16:38:18 -080039 bool operator==(const SizedArray &other) const {
40 if (other.size() != size()) {
41 return false;
42 }
43 for (size_t i = 0; i < size(); ++i) {
44 if (other[i] != (*this)[i]) {
45 return false;
46 }
47 }
48 return true;
49 }
50 bool operator!=(const SizedArray &other) const {
51 return !(*this == other);
52 }
53
Brian Silvermand844a572019-01-26 15:59:00 -080054 reference at(size_t i) {
55 check_index(i);
56 return array_.at(i);
57 }
58 const_reference at(size_t i) const {
59 check_index(i);
60 return array_.at(i);
61 }
62
63 reference operator[](size_t i) { return array_[i]; }
64 const_reference operator[](size_t i) const { return array_[i]; }
65
66 reference front() { return array_.front(); }
67 const_reference front() const { return array_.front(); }
68
69 reference back() { return array_[size_ - 1]; }
70 const_reference back() const { return array_[size_ - 1]; }
71
72 T *data() { return array_.data(); }
73 const T *data() const { return array_.data(); }
74
75 iterator begin() { return array_.begin(); }
76 const_iterator begin() const { return array_.begin(); }
77 const_iterator cbegin() const { return array_.cbegin(); }
78
79 iterator end() { return array_.begin() + size_; }
80 const_iterator end() const { return array_.begin() + size_; }
81 const_iterator cend() const { return array_.cbegin() + size_; }
82
83 reverse_iterator rbegin() { return array_.rend() - size_; }
84 const_reverse_iterator rbegin() const { return array_.rend() - size_; }
85 const_reverse_iterator crbegin() const { return array_.crend() - size_; }
86
87 reverse_iterator rend() { return array_.rend(); }
88 const_reverse_iterator rend() const { return array_.rend(); }
89 const_reverse_iterator crend() const { return array_.crend(); }
90
91 bool empty() const { return size_ == 0; }
92 bool full() const { return size() == max_size(); }
93
94 size_t size() const { return size_; }
95 constexpr size_t max_size() const { return array_.max_size(); }
96
97 void push_back(const T &t) {
98 array_.at(size_) = t;
99 ++size_;
100 }
101 void push_back(T &&t) {
102 array_.at(size_) = std::move(t);
103 ++size_;
104 }
105
106 void pop_back() {
107 if (empty()) {
108 __builtin_trap();
109 }
110 --size_;
111 }
112
Brian Silverman28a71ae2019-02-23 20:58:59 -0800113 void clear() { size_ = 0; }
114
Brian Silverman2eb89762019-02-17 15:16:37 -0800115 // These allow access to the underlying storage. The data here may be outside
116 // the current logical extents of the container.
117 const array &backing_array() const { return array_; }
118 array *mutable_backing_array() { return &array_; }
119 void set_size(size_t size) { size_ = size; }
120
Brian Silvermand844a572019-01-26 15:59:00 -0800121 private:
122 void check_index(size_t i) const {
123 if (i >= size_) {
124 __builtin_trap();
125 }
126 }
127
128 array array_;
129 size_t size_ = 0;
130};
131
132} // namespace aos
133
134#endif // AOS_CONTAINERS_SIZED_ARRAY_H_