blob: 0b8b447ccea0eaab80df92f9eecbe5a9f20e9bdb [file] [log] [blame]
#ifndef AOS_CONTAINERS_SIZED_ARRAY_H_
#define AOS_CONTAINERS_SIZED_ARRAY_H_
#include <array>
namespace aos {
// An array along with a variable size. This is a simple variable-size container
// with a fixed maximum size.
//
// Note that it default-constructs N T instances at construction time. This
// simplifies the internal bookkeeping a lot (I believe this can be
// all-constexpr in C++17), but makes it a poor choice for complex T.
template <typename T, size_t N>
class SizedArray {
private:
using array = std::array<T, N>;
public:
using value_type = typename array::value_type;
using size_type = typename array::size_type;
using difference_type = typename array::difference_type;
using reference = typename array::reference;
using const_reference = typename array::const_reference;
using pointer = typename array::pointer;
using const_pointer = typename array::const_pointer;
using iterator = typename array::iterator;
using const_iterator = typename array::const_iterator;
using reverse_iterator = typename array::reverse_iterator;
using const_reverse_iterator = typename array::const_reverse_iterator;
constexpr SizedArray() = default;
SizedArray(const SizedArray &) = default;
SizedArray(SizedArray &&) = default;
SizedArray &operator=(const SizedArray &) = default;
SizedArray &operator=(SizedArray &&) = default;
reference at(size_t i) {
check_index(i);
return array_.at(i);
}
const_reference at(size_t i) const {
check_index(i);
return array_.at(i);
}
reference operator[](size_t i) { return array_[i]; }
const_reference operator[](size_t i) const { return array_[i]; }
reference front() { return array_.front(); }
const_reference front() const { return array_.front(); }
reference back() { return array_[size_ - 1]; }
const_reference back() const { return array_[size_ - 1]; }
T *data() { return array_.data(); }
const T *data() const { return array_.data(); }
iterator begin() { return array_.begin(); }
const_iterator begin() const { return array_.begin(); }
const_iterator cbegin() const { return array_.cbegin(); }
iterator end() { return array_.begin() + size_; }
const_iterator end() const { return array_.begin() + size_; }
const_iterator cend() const { return array_.cbegin() + size_; }
reverse_iterator rbegin() { return array_.rend() - size_; }
const_reverse_iterator rbegin() const { return array_.rend() - size_; }
const_reverse_iterator crbegin() const { return array_.crend() - size_; }
reverse_iterator rend() { return array_.rend(); }
const_reverse_iterator rend() const { return array_.rend(); }
const_reverse_iterator crend() const { return array_.crend(); }
bool empty() const { return size_ == 0; }
bool full() const { return size() == max_size(); }
size_t size() const { return size_; }
constexpr size_t max_size() const { return array_.max_size(); }
void push_back(const T &t) {
array_.at(size_) = t;
++size_;
}
void push_back(T &&t) {
array_.at(size_) = std::move(t);
++size_;
}
void pop_back() {
if (empty()) {
__builtin_trap();
}
--size_;
}
private:
void check_index(size_t i) const {
if (i >= size_) {
__builtin_trap();
}
}
array array_;
size_t size_ = 0;
};
} // namespace aos
#endif // AOS_CONTAINERS_SIZED_ARRAY_H_