Vectors#

pw_containers: Generic collections of objects for embedded devices

A vector is a one-dimensional array with a variable length.

pw::Vector#

Vectors must be declared with an explicit maximum size (e.g. Vector<int, 10>) but vectors can be used and referred to without the max size template parameter (e.g. Vector<int>).

To allow referring to a pw::Vector without an explicit maximum size, all Vector classes inherit from the generic Vector<T>, which stores the maximum size in a variable. This allows Vectors to be used without having to know their maximum size at compile time. It also keeps code size small since function implementations are shared for all maximum sizes.

Example#

 1class Publisher {
 2 public:
 3  using Subscriber = pw::Function<void(const Message&)>;
 4  static constexpr size_t kMaxSubscribers = 10;
 5
 6  pw::Status Subscribe(Subscriber&& subscriber) {
 7    // Check if the vector's fixed capacity has been exhausted.
 8    if (subscribers_.full()) {
 9      return pw::Status::ResourceExhausted();
10    }
11
12    // Add the subscriber to the vector.
13    subscribers_.emplace_back(std::move(subscriber));
14    return pw::OkStatus();
15  }
16
17  void Publish(const Message& message) {
18    // Iterate over the vector.
19    for (auto& subscriber : subscribers_) {
20      subscriber(message);
21    }
22  }
23
24 private:
25  pw::Vector<Subscriber, kMaxSubscribers> subscribers_;
26};

API reference#

The Vector class is similar to std::vector, except it is backed by a fixed-size buffer.

template<typename T, size_t kMaxSize = vector_impl::kGeneric>
class Vector : public pw::VectorStorage<T, vector_impl::kGeneric, std::is_trivially_destructible_v<T>>#

Size report#

The tables below illustrate the following scenarios:

  • The memory and code size cost incurred by a adding a single Vector.

  • The memory and code size cost incurred by adding another Vector with the same type as the first scenario, but with a different size. As Vector is templated on both type and size, a different size results in additional code being generated.

  • The memory and code size cost incurred by adding another Vector with the same size as the first scenario, but with a different type. As Vector is templated on both type and size, a different size results in additional code being generated.

Label

Segment

Delta

Vector

FLASH

+124

[section .rodata]

+4

pw::containers::size_report::Measure()

-8

vClearInterruptMaskFromISR

-4

__bi_84

DEL

-8

__aeabi_memmove

+2

main

NEW

+120

pw::Vector<>::insert()

NEW

+106

_ZN2pw10containers11size_report13MeasureVectorIjLj10ETpTnRiJENSt3__211__wrap_iterIPjEEEEiT2_S8_j

NEW

+88

pw::Vector<>::resize()

NEW

+56

pw::Vector<>::ShiftEntriesForInsert()

NEW

+44

pw::Vector<>::emplace_back<>()

NEW

+44

pw::containers::size_report::MeasureContainer<>()

NEW

+40

pw::Vector<>::erase()

NEW

+32

pw::containers::size_report::GetContainer<>()

NEW

+26

pw::Vector<>::Append()

NEW

+26

pw::Vector<>::CopyFrom<>()

NEW

+12

pw::Vector<>::assign<>()

NEW

+8

__aeabi_memmove4

+712

RAM

-8

[section .data]

+1

__Thumbv6MABSLongThunk_best_effort_wfe_or_timeout

NEW

+48

pw::containers::size_report::GetContainer<>()::container

NEW

+39

pw::containers::size_report::GetItems<>()::items

+80

Additional Vector with the same item type but different size

FLASH

+44

pw::containers::size_report::MeasureContainer<>()

+32

pw::containers::size_report::GetContainer<>()

+16

pw::containers::size_report::Measure()

-4

vClearInterruptMaskFromISR

-2

main

NEW

+106

_ZN2pw10containers11size_report13MeasureVectorIjLj9ETpTnRiJENSt3__211__wrap_iterIPjEEEEiT2_S8_j

+192

RAM

+44

pw::containers::size_report::GetContainer<>()::container

+44

Additional Vector with different item type but same size

FLASH

+124

pw::Vector<>::insert()

+88

pw::Vector<>::resize()

+68

pw::Vector<>::ShiftEntriesForInsert()

+54

pw::Vector<>::emplace_back<>()

+44

pw::containers::size_report::MeasureContainer<>()

+42

pw::Vector<>::erase()

+32

pw::containers::size_report::GetContainer<>()

+20

pw::containers::size_report::Measure()

+26

pw::Vector<>::Append()

+26

pw::Vector<>::CopyFrom<>()

+12

pw::Vector<>::assign<>()

+8

vClearInterruptMaskFromISR

NEW

+112

_ZN2pw10containers11size_report13MeasureVectorIyLj10ETpTnRiJENSt3__211__wrap_iterIPyEEEEiT2_S8_j

+656

RAM

+92

pw::containers::size_report::GetContainer<>()::container

+80

pw::containers::size_report::GetItems<>()::items

+172

pw::DynamicVector#

template<typename T, typename SizeType = uint16_t>
class DynamicVector#

Array-backed list similar to std::vector, but optimized for embedded.

Key features of pw::DynamicVector.

Note

pw::DynamicVector is currently implemented as a wrapper around pw::DynamicDeque. Some operations are more expensive than they need to be, and DynamicVector objects are larger than necessary. This overhead will be eliminated in the future (see b/424613355).

Public Types

using value_type = T#
using size_type = SizeType#
using reference = value_type&#
using const_reference = const value_type&#
using pointer = value_type*#
using const_pointer = const value_type*#
using iterator = containers::PtrIterator<DynamicVector>#
using const_iterator = containers::ConstPtrIterator<DynamicVector>#
using reverse_iterator = std::reverse_iterator<iterator>#
using const_reverse_iterator = std::reverse_iterator<const_iterator>#
using allocator_type = Allocator#

Public Functions

inline explicit constexpr DynamicVector(Allocator &allocator)#

Constructs an empty DynamicVector using the provided allocator.

Parameters:

allocator – The allocator to use for memory management.

DynamicVector(const DynamicVector&) = delete#
DynamicVector &operator=(const DynamicVector&) = delete#
constexpr DynamicVector(DynamicVector&&) = default#
constexpr DynamicVector &operator=(DynamicVector&&) = default#
inline iterator begin()#
inline const_iterator begin() const#
inline const_iterator cbegin() const#
inline iterator end()#
inline const_iterator end() const#
inline const_iterator cend() const#
inline reverse_iterator rbegin()#
inline const_reverse_iterator rbegin() const#
inline const_reverse_iterator crbegin() const#
inline reverse_iterator rend()#
inline const_reverse_iterator rend() const#
inline const_reverse_iterator crend() const#
inline constexpr allocator_type &get_allocator() const#

Returns the vector’s allocator.

inline bool empty() const#

Checks if the vector is empty.

inline size_type size() const#

Returns the number of elements in the vector.

inline size_type capacity() const#

Returns the total number of elements that the vector can hold without requiring reallocation.

inline size_type max_size() const#

Maximum possible value of size(), ignoring allocator limitations.

inline void reserve(size_type new_capacity)#

Requests that the vector capacity be at least new_capacity elements.

Note: This operation is potentially fallible if memory allocation is required and fails. Depending on the underlying DynamicDeque implementation and Pigweed configuration, allocation failure may result in a panic or assertion failure. Use try_reserve() for a fallible version.

Parameters:

new_capacity – The minimum desired capacity.

inline bool try_reserve(size_type new_capacity)#

Attempts to request that the vector capacity be at least new_capacity elements.

Returns true on success, or false if allocation fails.

Parameters:

new_capacity – The minimum desired capacity.

Returns:

true if successful, false otherwise.

inline void shrink_to_fit()#

Reduces memory usage by releasing unused capacity.

inline reference operator[](size_type pos)#

Returns a reference to the element at specified location pos.

No bounds checking is performed.

Parameters:

pos – The index of the element to access.

Returns:

Reference to the element.

inline const_reference operator[](size_type pos) const#

Returns a const reference to the element at specified location pos.

No bounds checking is performed.

Parameters:

pos – The index of the element to access.

Returns:

Const reference to the element.

inline reference at(size_type pos)#

Returns a reference to the element at specified location pos, with bounds checking.

Crashes if pos is not within the range [0, size()).

Parameters:

pos – The index of the element to access.

Returns:

Reference to the element.

inline const_reference at(size_type pos) const#

Returns a const reference to the element at specified location pos, with bounds checking.

Crashes if pos is not within the range [0, size()).

Parameters:

pos – The index of the element to access.

Returns:

Const reference to the element.

inline reference front()#

Returns a reference to the first element in the vector.

Calling front() on an empty vector is undefined behavior.

inline const_reference front() const#

Returns a const reference to the first element in the vector.

Calling front() on an empty vector is undefined behavior.

inline reference back()#

Returns a reference to the last element in the vector.

Calling back() on an empty vector is undefined behavior.

inline const_reference back() const#

Returns a const reference to the last element in the vector.

Calling back() on an empty vector is undefined behavior.

inline pointer data()#

Returns a pointer to the underlying array serving as element storage.

The pointer is such that [data(), data() + size()) is a valid range.

Returns:

A pointer to the first element, or nullptr if the vector is empty.

inline const_pointer data() const#

Returns a const pointer to the underlying array serving as element storage.

Returns:

A const pointer to the first element, or nullptr if the vector is empty.

inline void assign(size_type count, const value_type &value)#

Assigns new contents to the vector, replacing its current contents.

Parameters:
  • count – The number of elements to assign.

  • value – The value to copy.

Returns:

true if successful, false otherwise.

inline bool try_assign(size_type count, const value_type &value)#
inline void assign(std::initializer_list<T> init)#

Assigns new contents to the vector from an initializer list.

Parameters:

init – The initializer list to copy elements from.

Returns:

true if successful, false otherwise.

inline bool try_assign(std::initializer_list<T> init)#
inline void push_back(const value_type &value)#

Adds an element to the back of the vector.

Note: This operation is potentially fallible if memory allocation is required and fails. Use try_push_back() for a fallible version.

inline void push_back(value_type &&value)#

Adds an element to the back of the vector (move version).

Note: This operation is potentially fallible if memory allocation is required and fails.

inline bool try_push_back(const value_type &value)#

Attempts to add an element to the back of the vector.

Returns true on success, or false if allocation fails.

Parameters:

value – The value to add.

Returns:

true if successful, false otherwise.

inline bool try_push_back(value_type &&value)#

Attempts to add an element to the back of the vector (move version).

Returns true on success, or false if allocation fails.

Parameters:

value – The value to add.

Returns:

true if successful, false otherwise.

inline void pop_back()#

Removes the last element from the vector.

Calling pop_back() on an empty vector is undefined behavior.

template<typename ...Args>
inline void emplace_back(Args&&... args)#

Constructs an element in place at the back of the vector.

Note: This operation is potentially fallible if memory allocation is required and fails. Use try_emplace_back() for a fallible version.

template<typename ...Args>
inline bool try_emplace_back(Args&&... args)#

Attempts to construct an element in place at the back of the vector.

Returns true on success, or false if allocation fails.

Parameters:

args – Arguments to forward to the element’s constructor.

Returns:

true if successful, false otherwise.

inline void resize(size_type count)#

Resizes the vector to contain count elements.

If count is smaller than the current size, the content is reduced to the first count elements. If count is greater than the current size, new elements are appended and default-constructed.

Parameters:

count – New size of the vector.

inline void resize(size_type count, const value_type &value)#

Resizes the vector to contain count elements, value-initializing new elements.

If count is smaller than the current size, the content is reduced to the first count elements. If count is greater than the current size, new elements are appended and copy-constructed from value.

Parameters:
  • count – New size of the vector.

  • value – Value to initialize new elements with.

inline bool try_resize(size_type count)#

Attempts to resize the vector to contain count elements.

Parameters:

count – New size of the vector.

Returns:

true if successful, false otherwise.

inline bool try_resize(size_type count, const value_type &value)#

Attempts to resize the vector to contain count elements, value-initializing new elements.

Parameters:
  • count – New size of the vector.

  • value – Value to initialize new elements with.

Returns:

true if successful, false otherwise.

inline void clear()#

Removes all elements from the vector.

inline void swap(DynamicVector &other)#

Swaps the contents with another DynamicVector.

Parameters:

other – The other vector to swap with.