blob: 0b8b447ccea0eaab80df92f9eecbe5a9f20e9bdb [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;
James Kuszmaul48fb79f2019-01-27 13:27:55 -080033 SizedArray(const SizedArray &) = default;
34 SizedArray(SizedArray &&) = default;
Brian Silvermand844a572019-01-26 15:59:00 -080035 SizedArray &operator=(const SizedArray &) = default;
36 SizedArray &operator=(SizedArray &&) = default;
37
38 reference at(size_t i) {
39 check_index(i);
40 return array_.at(i);
41 }
42 const_reference at(size_t i) const {
43 check_index(i);
44 return array_.at(i);
45 }
46
47 reference operator[](size_t i) { return array_[i]; }
48 const_reference operator[](size_t i) const { return array_[i]; }
49
50 reference front() { return array_.front(); }
51 const_reference front() const { return array_.front(); }
52
53 reference back() { return array_[size_ - 1]; }
54 const_reference back() const { return array_[size_ - 1]; }
55
56 T *data() { return array_.data(); }
57 const T *data() const { return array_.data(); }
58
59 iterator begin() { return array_.begin(); }
60 const_iterator begin() const { return array_.begin(); }
61 const_iterator cbegin() const { return array_.cbegin(); }
62
63 iterator end() { return array_.begin() + size_; }
64 const_iterator end() const { return array_.begin() + size_; }
65 const_iterator cend() const { return array_.cbegin() + size_; }
66
67 reverse_iterator rbegin() { return array_.rend() - size_; }
68 const_reverse_iterator rbegin() const { return array_.rend() - size_; }
69 const_reverse_iterator crbegin() const { return array_.crend() - size_; }
70
71 reverse_iterator rend() { return array_.rend(); }
72 const_reverse_iterator rend() const { return array_.rend(); }
73 const_reverse_iterator crend() const { return array_.crend(); }
74
75 bool empty() const { return size_ == 0; }
76 bool full() const { return size() == max_size(); }
77
78 size_t size() const { return size_; }
79 constexpr size_t max_size() const { return array_.max_size(); }
80
81 void push_back(const T &t) {
82 array_.at(size_) = t;
83 ++size_;
84 }
85 void push_back(T &&t) {
86 array_.at(size_) = std::move(t);
87 ++size_;
88 }
89
90 void pop_back() {
91 if (empty()) {
92 __builtin_trap();
93 }
94 --size_;
95 }
96
97 private:
98 void check_index(size_t i) const {
99 if (i >= size_) {
100 __builtin_trap();
101 }
102 }
103
104 array array_;
105 size_t size_ = 0;
106};
107
108} // namespace aos
109
110#endif // AOS_CONTAINERS_SIZED_ARRAY_H_