blob: 6d4209a79145248891438261fb16b1f144961b31 [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
Brian Silverman246cb222019-02-02 16:38:18 -080038 bool operator==(const SizedArray &other) const {
39 if (other.size() != size()) {
40 return false;
41 }
42 for (size_t i = 0; i < size(); ++i) {
43 if (other[i] != (*this)[i]) {
44 return false;
45 }
46 }
47 return true;
48 }
49 bool operator!=(const SizedArray &other) const {
50 return !(*this == other);
51 }
52
Brian Silvermand844a572019-01-26 15:59:00 -080053 reference at(size_t i) {
54 check_index(i);
55 return array_.at(i);
56 }
57 const_reference at(size_t i) const {
58 check_index(i);
59 return array_.at(i);
60 }
61
62 reference operator[](size_t i) { return array_[i]; }
63 const_reference operator[](size_t i) const { return array_[i]; }
64
65 reference front() { return array_.front(); }
66 const_reference front() const { return array_.front(); }
67
68 reference back() { return array_[size_ - 1]; }
69 const_reference back() const { return array_[size_ - 1]; }
70
71 T *data() { return array_.data(); }
72 const T *data() const { return array_.data(); }
73
74 iterator begin() { return array_.begin(); }
75 const_iterator begin() const { return array_.begin(); }
76 const_iterator cbegin() const { return array_.cbegin(); }
77
78 iterator end() { return array_.begin() + size_; }
79 const_iterator end() const { return array_.begin() + size_; }
80 const_iterator cend() const { return array_.cbegin() + size_; }
81
82 reverse_iterator rbegin() { return array_.rend() - size_; }
83 const_reverse_iterator rbegin() const { return array_.rend() - size_; }
84 const_reverse_iterator crbegin() const { return array_.crend() - size_; }
85
86 reverse_iterator rend() { return array_.rend(); }
87 const_reverse_iterator rend() const { return array_.rend(); }
88 const_reverse_iterator crend() const { return array_.crend(); }
89
90 bool empty() const { return size_ == 0; }
91 bool full() const { return size() == max_size(); }
92
93 size_t size() const { return size_; }
94 constexpr size_t max_size() const { return array_.max_size(); }
95
96 void push_back(const T &t) {
97 array_.at(size_) = t;
98 ++size_;
99 }
100 void push_back(T &&t) {
101 array_.at(size_) = std::move(t);
102 ++size_;
103 }
104
105 void pop_back() {
106 if (empty()) {
107 __builtin_trap();
108 }
109 --size_;
110 }
111
Brian Silverman2eb89762019-02-17 15:16:37 -0800112 // These allow access to the underlying storage. The data here may be outside
113 // the current logical extents of the container.
114 const array &backing_array() const { return array_; }
115 array *mutable_backing_array() { return &array_; }
116 void set_size(size_t size) { size_ = size; }
117
Brian Silvermand844a572019-01-26 15:59:00 -0800118 private:
119 void check_index(size_t i) const {
120 if (i >= size_) {
121 __builtin_trap();
122 }
123 }
124
125 array array_;
126 size_t size_ = 0;
127};
128
129} // namespace aos
130
131#endif // AOS_CONTAINERS_SIZED_ARRAY_H_