13#ifndef IOX2_INCLUDE_GUARD_BB_STATIC_VECTOR_HPP
14#define IOX2_INCLUDE_GUARD_BB_STATIC_VECTOR_HPP
26#include <initializer_list>
34template <
typename T, u
int64_t Capacity>
36 static_assert(Capacity > 0,
"Static container with capacity 0 is not allowed.");
37 static_assert(std::is_standard_layout<T>::value,
"Containers can only be used with standard layout types.");
127 template <
typename, u
int64_t>
139 template <uint64_t M, std::enable_if_t<(Capacity >= M),
bool> = true>
142 : m_storage(rhs.m_storage) {
146 template <u
int64_t M, std::enable_if_t<(Capacity >= M),
bool> =
true>
149 for (
auto& element : element_array) {
161 template <u
int64_t N>
163 static_assert(N <= Capacity,
"Trying to initialize a StaticVector beyond its capacity!");
173 template <typename U = T, std::enable_if_t<std::is_default_constructible<U>::value,
bool> =
true>
175 if (count <= Capacity) {
186 if (count <= Capacity) {
188 ret->m_storage.
insert_at(0, count, value);
199 template <
typename Iter,
202 std::is_constructible<T, decltype(*std::declval<Iter>())>::value
203 && std::is_convertible<
decltype(std::declval<Iter>() == std::declval<Sentinel>()),
bool>::value,
208 for (
auto it = it_begin; it != it_end; ++it) {
209 if (!ret->try_push_back(*it)) {
221 template <
typename Range>
233 if (init_list.size() > Capacity) {
243 template <
typename... Args, std::enable_if_t<std::is_constructible<T, Args...>::value,
bool> =
true>
245 if (m_storage.
size() < Capacity) {
257 template <
typename... Args, std::enable_if_t<std::is_constructible<T, Args...>::value,
bool> =
true>
259 if ((m_storage.
size() < Capacity) && (index <= m_storage.
size())) {
260 m_storage.
emplace_at(index, std::forward<Args>(args)...);
271 if (index < m_storage.
size()) {
283 if ((end_index <= m_storage.
size()) && (begin_index <= end_index)) {
284 m_storage.
erase_at(begin_index, end_index);
312 if ((index <= m_storage.
size()) && (m_storage.
size() + count <= Capacity)) {
313 m_storage.
insert_at(index, count, value);
325 template <
typename Iter,
328 std::is_constructible<T, decltype(*std::declval<Iter>())>::value
329 && std::is_convertible<
decltype(std::declval<Iter>() == std::declval<Sentinel>()),
bool>::value,
332 if (index <= m_storage.
size()) {
333 auto const old_size =
size();
334 for (
auto it = it_begin; it != it_end; ++it) {
381 if (m_storage.
size() > 0) {
396 return m_storage.
size();
400 constexpr auto empty() const ->
bool {
408 if (index < m_storage.
size()) {
419 if (index < m_storage.
size()) {
482 return std::equal(lhs.unchecked_access().begin(),
483 lhs.unchecked_access().end(),
484 rhs.unchecked_access().begin(),
485 rhs.unchecked_access().end());
489 return !(lhs == rhs);
495 struct VectorMemoryLayoutMetrics {
496 size_t vector_alignment;
500 using Self = std::remove_reference_t<
decltype(*this)>;
501 ret.vector_size =
sizeof(Self);
502 ret.vector_alignment =
alignof(Self);
511template <
typename T, u
int64_t N>
517template <
typename T, u
int64_t N>
519 stream <<
"StaticVector::<" << N <<
"> { m_size: " << value.size() <<
", m_data: [ ";
520 if (!value.empty()) {
521 stream << value.unchecked_access()[0];
523 for (uint64_t idx = 1; idx < value.size(); ++idx) {
524 stream <<
", " << value.unchecked_access()[idx];
#define IOX2_CONSTEXPR_DTOR
Users of this class must ensure that all memory accesses stay within bounds of the accessed vector's ...
UncheckedAccessor(UncheckedAccessor const &)=delete
auto operator=(UncheckedAccessor &&) -> UncheckedAccessor &=delete
~UncheckedAccessor()=default
UncheckedAccessor(UncheckedAccessor &&)=default
constexpr auto operator[](SizeType index) &&-> Reference
auto operator=(UncheckedAccessor const &) -> UncheckedAccessor &=delete
constexpr auto data() &&noexcept -> Pointer
constexpr auto end() &&noexcept -> Iterator
constexpr auto begin() &&noexcept -> Iterator
constexpr auto data() const &&noexcept -> ConstPointer
UncheckedConstAccessor(UncheckedConstAccessor &&)=default
~UncheckedConstAccessor()=default
constexpr auto operator[](SizeType index) const &&-> ConstReference
auto operator=(UncheckedConstAccessor &&) -> UncheckedConstAccessor &=delete
constexpr auto begin() const &&noexcept -> ConstIterator
constexpr auto end() const &&noexcept -> ConstIterator
UncheckedConstAccessor(UncheckedConstAccessor const &)=delete
auto operator=(UncheckedConstAccessor const &) -> UncheckedConstAccessor &=delete
A resizable container with compile-time fixed static capacity and contiguous inplace storage.
constexpr StaticVector(T const (&element_array)[M])
Construct from a C-style array.
auto back_element() -> OptionalReference
auto operator=(StaticVector &&) -> StaticVector &=default
auto unchecked_access() -> UncheckedAccessor
Unchecked mutable access to the vector contents.
constexpr auto try_erase_at(SizeType begin_index, SizeType end_index) -> bool
bb::Optional< std::reference_wrapper< T const > > OptionalConstReference
constexpr auto empty() const -> bool
Checks whether the vector is currently empty.
constexpr auto try_insert_at(SizeType index, T const &value) -> bool
constexpr auto try_emplace_at(SizeType index, Args &&... args) -> bool
auto unchecked_access() const -> UncheckedConstAccessor
Unchecked immutable access to the vector contents.
constexpr auto try_insert_at_unchecked(SizeType index, Iter it_begin, Sentinel it_end) -> bool
constexpr StaticVector() noexcept=default
friend auto operator!=(StaticVector const &lhs, StaticVector const &rhs) -> bool
constexpr auto try_insert_at_unchecked(SizeType index, std::initializer_list< T > init_list)
static constexpr auto from_range_unchecked(Range const &rng) -> bb::Optional< StaticVector >
static constexpr auto capacity() noexcept -> SizeType
Retrieves the static capacity of the vector.
constexpr auto try_erase_at(SizeType index) -> bool
constexpr auto try_insert_at(SizeType index, SizeType count, T const &value) -> bool
static constexpr auto from_initializer_list(std::initializer_list< T > init_list) -> bb::Optional< StaticVector >
ConstPointer ConstIterator
static constexpr auto from_value(const T &value) -> StaticVector
constexpr auto try_pop_back() -> bool
auto operator=(StaticVector const &) -> StaticVector &=default
auto element_at(SizeType index) -> OptionalReference
constexpr auto static_memory_layout_metrics() noexcept
static constexpr auto from_value(SizeType count) -> bb::Optional< StaticVector >
auto back_element() const -> OptionalConstReference
static constexpr auto from_value(SizeType count, T const &value) -> bb::Optional< StaticVector >
Construct a new vector with count copies of value.
auto element_at(SizeType index) const -> OptionalConstReference
static constexpr auto from_range_unchecked(Iter it_begin, Sentinel it_end) -> bb::Optional< StaticVector >
constexpr auto try_emplace_back(Args &&... args) -> bool
friend auto operator==(StaticVector const &lhs, StaticVector const &rhs) -> bool
constexpr auto try_push_back(T const &value) -> bool
constexpr auto try_insert_at(SizeType index, T &&value) -> bool
constexpr auto try_push_back(T &&value) -> bool
constexpr auto size() const noexcept -> SizeType
Retrieves the size of the vector.
IOX2_CONSTEXPR_DTOR ~StaticVector()=default
bb::Optional< std::reference_wrapper< T > > OptionalReference
auto front_element() -> OptionalReference
auto front_element() const -> OptionalConstReference
constexpr void insert_at(uint64_t index, uint64_t count, T const &value)
auto constexpr size() const noexcept -> uint64_t
constexpr void shrink_from_back(uint64_t target_size)
auto pointer_from_index(uint64_t idx) -> T *
constexpr void emplace_back(Args &&... args)
constexpr void erase_at(uint64_t index)
constexpr void rotate_from_back(uint64_t index_to, uint64_t index_first_from)
constexpr auto static_memory_layout_metrics() noexcept -> StorageMemoryLayoutMetrics
constexpr void emplace_at(uint64_t index, Args &&... args)
constexpr NulloptT NULLOPT
iox2::bb::variation::Optional< T > Optional
auto operator<<(std::ostream &stream, const iox2::bb::StaticVector< T, N > &value) -> std::ostream &