blob: 264d466219fe37b1fccb4838e4a9587d111784fe [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>
5
6namespace aos {
7
8// An array along with a variable size. This is a simple variable-size container
9// with a fixed maximum size.
10//
11// Note that it default-constructs N T instances at construction time. This
12// simplifies the internal bookkeeping a lot (I believe this can be
13// all-constexpr in C++17), but makes it a poor choice for complex T.
14template <typename T, size_t N>
15class SizedArray {
16 private:
17 using array = std::array<T, N>;
18
19 public:
20 using value_type = typename array::value_type;
21 using size_type = typename array::size_type;
22 using difference_type = typename array::difference_type;
23 using reference = typename array::reference;
24 using const_reference = typename array::const_reference;
25 using pointer = typename array::pointer;
26 using const_pointer = typename array::const_pointer;
27 using iterator = typename array::iterator;
28 using const_iterator = typename array::const_iterator;
29 using reverse_iterator = typename array::reverse_iterator;
30 using const_reverse_iterator = typename array::const_reverse_iterator;
31
32 constexpr SizedArray() = default;
33 SizedArray &operator=(const SizedArray &) = default;
34 SizedArray &operator=(SizedArray &&) = default;
35
36 reference at(size_t i) {
37 check_index(i);
38 return array_.at(i);
39 }
40 const_reference at(size_t i) const {
41 check_index(i);
42 return array_.at(i);
43 }
44
45 reference operator[](size_t i) { return array_[i]; }
46 const_reference operator[](size_t i) const { return array_[i]; }
47
48 reference front() { return array_.front(); }
49 const_reference front() const { return array_.front(); }
50
51 reference back() { return array_[size_ - 1]; }
52 const_reference back() const { return array_[size_ - 1]; }
53
54 T *data() { return array_.data(); }
55 const T *data() const { return array_.data(); }
56
57 iterator begin() { return array_.begin(); }
58 const_iterator begin() const { return array_.begin(); }
59 const_iterator cbegin() const { return array_.cbegin(); }
60
61 iterator end() { return array_.begin() + size_; }
62 const_iterator end() const { return array_.begin() + size_; }
63 const_iterator cend() const { return array_.cbegin() + size_; }
64
65 reverse_iterator rbegin() { return array_.rend() - size_; }
66 const_reverse_iterator rbegin() const { return array_.rend() - size_; }
67 const_reverse_iterator crbegin() const { return array_.crend() - size_; }
68
69 reverse_iterator rend() { return array_.rend(); }
70 const_reverse_iterator rend() const { return array_.rend(); }
71 const_reverse_iterator crend() const { return array_.crend(); }
72
73 bool empty() const { return size_ == 0; }
74 bool full() const { return size() == max_size(); }
75
76 size_t size() const { return size_; }
77 constexpr size_t max_size() const { return array_.max_size(); }
78
79 void push_back(const T &t) {
80 array_.at(size_) = t;
81 ++size_;
82 }
83 void push_back(T &&t) {
84 array_.at(size_) = std::move(t);
85 ++size_;
86 }
87
88 void pop_back() {
89 if (empty()) {
90 __builtin_trap();
91 }
92 --size_;
93 }
94
95 private:
96 void check_index(size_t i) const {
97 if (i >= size_) {
98 __builtin_trap();
99 }
100 }
101
102 array array_;
103 size_t size_ = 0;
104};
105
106} // namespace aos
107
108#endif // AOS_CONTAINERS_SIZED_ARRAY_H_