Sets#

pw_containers: Generic collections of objects for embedded devices

A set is an unordered collection of items. Pigweed provides implementations that can insert, find, and remove items in logarithmic time.

pw::IntrusiveSet#

pw::IntrusiveSet provides an embedded-friendly, tree-based, intrusive set implementation. The intrusive aspect of the set is very similar to that of pw::IntrusiveList.

This class is similar to std::set<T>. Items to be added must derive from pw::IntrusiveSet<T>::Item or an equivalent type.

See also Using items with multiple containers.

Example#

 1class Book : public pw::IntrusiveSet<Book>::Item {
 2 private:
 3  using Item = pw::IntrusiveSet<Book>::Item;
 4
 5 public:
 6  explicit Book(const char* name) : name_(name) {}
 7  const char* name() const { return name_; }
 8  bool operator<(const Book& rhs) const {
 9    return strcmp(name_, rhs.name()) < 0;
10  }
11
12 private:
13  const char* name_;
14};
15
16std::array<Book, 8> books = {
17    Book("A Tale of Two Cities"),
18    Book("The Little Prince"),
19    Book("The Alchemist"),
20    Book("Harry Potter and the Philosopher's Stone"),
21    Book("And Then There Were None"),
22    Book("Dream of the Red Chamber"),
23    Book("The Hobbit"),
24    Book("Alice's Adventures in Wonderland"),
25};
26
27pw::IntrusiveSet<Book> library(books.begin(), books.end());
28
29void VisitLibrary(pw::IntrusiveSet<Book>& book_bag) {
30  // Return any books we previously checked out.
31  library.merge(book_bag);
32
33  // Pick out some new books to read to the kids, but only if they're available.
34  std::array<const char*, 3> titles = {
35      "The Hobbit",
36      "Curious George",
37      "Harry Potter and the Philosopher's Stone",
38  };
39  for (const char* title : titles) {
40    Book requested(title);
41    auto iter = library.find(requested);
42    if (iter != library.end()) {
43      Book& book = *iter;
44      library.erase(iter);
45      book_bag.insert(book);
46    }
47  }
48}

If you need to add this item to containers of more than one type, see Using items with multiple containers,

pw::IntrusiveMultiSet#

pw::IntrusiveMultiSet provides an embedded-friendly, tree-based, intrusive multiset implementation. This is very similar to pw::IntrusiveSet, except that the tree may contain multiple items with equivalent keys.

This class is similar to std::multiset<T>. Items to be added must derive from pw::IntrusiveMultiSet<T>::Item or an equivalent type.

See also Using items with multiple containers.

Example#

 1class Book : public pw::IntrusiveMultiSet<Book>::Item {
 2 private:
 3  using Item = pw::IntrusiveMultiSet<Book>::Item;
 4
 5 public:
 6  explicit Book(const char* name) : name_(name) {}
 7  const char* name() const { return name_; }
 8  bool operator<(const Book& rhs) const {
 9    return strcmp(name_, rhs.name()) < 0;
10  }
11
12 private:
13  const char* name_;
14};
15
16std::array<Book, 12> books = {
17    Book("The Little Prince"),
18    Book("Harry Potter and the Philosopher's Stone"),
19    Book("Harry Potter and the Philosopher's Stone"),
20    Book("Harry Potter and the Philosopher's Stone"),
21    Book("Harry Potter and the Philosopher's Stone"),
22    Book("Harry Potter and the Philosopher's Stone"),
23    Book("The Hobbit"),
24    Book("The Hobbit"),
25    Book("The Hobbit"),
26    Book("The Hobbit"),
27    Book("Alice's Adventures in Wonderland"),
28    Book("Alice's Adventures in Wonderland"),
29};
30pw::IntrusiveMultiSet<Book> library(books.begin(), books.end());
31
32void VisitLibrary(pw::IntrusiveMultiSet<Book>& book_bag) {
33  // Pick out some new books to read to the kids, but only if they're available.
34  std::array<const char*, 3> titles = {
35      "The Hobbit",
36      "Alice's Adventures in Wonderland",
37      "The Little Prince",
38  };
39  for (const char* title : titles) {
40    Book requested(title);
41    auto iter = library.find(requested);
42    if (iter != library.end()) {
43      Book& book = *iter;
44      library.erase(iter);
45      book_bag.insert(book);
46    }
47  }
48}

If you need to add this item to containers of more than one type, see Using items with multiple containers,

API reference#

Moved: pw_containers_sets

Size reports#

The tables below illustrate the following scenarios:

  • Scenarios related to IntrusiveSet:

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

    • The memory and code size cost incurred by adding another IntrusiveSet with a different type. As IntrusiveSet is templated on type, this results in additional code being generated.

  • Scenarios related to IntrusiveMultiSet:

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

    • The memory and code size cost incurred by adding another IntrusiveMultiSet with a different type. As IntrusiveMultiSet is templated on type, this results in additional code being generated.

  • The memory and code size cost incurred by a adding both an IntrusiveSet and an IntrusiveMultiSet of the same type. These types reuse code, so the combined sum is less than the sum of its parts.

Label

Segment

Delta

IntrusiveSet

FLASH

+356

[section .rodata]

+2

pw::containers::size_report::SetBaseline()

-2

pw::Allocator::Reallocate()

+4

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

+4

vClearInterruptMaskFromISR

NEW

+190

pw::containers::internal::KeyedAATree<>::InsertImpl()

NEW

+184

pw::containers::internal::AATreeItem::Rebalance()

NEW

+136

pw::containers::internal::AATreeItem::Unmap()

NEW

+130

_ZN2pw10containers11size_report19MeasureIntrusiveSetINS1_7SetItemIjEETpTnRiJENSt3__211__wrap_iterIPS4_EEEEiT1_SA_j

NEW

+104

pw::containers::internal::KeyedAATree<>::erase_all()

NEW

+98

pw::containers::internal::KeyedAATree<>::insert()

NEW

+90

pw::containers::internal::AATreeItem::Split()

NEW

+84

pw::containers::internal::KeyedAATree<>::GetLowerBoundImpl()

NEW

+84

pw::containers::internal::KeyedAATree<>::GetUpperBoundImpl()

NEW

+72

pw::containers::internal::AATreeIterator<>::operator++()

NEW

+68

pw::containers::internal::AATreeItem::Skew()

NEW

+60

fit::internal::target<>::ops

NEW

+60

pw::IntrusiveSet<>::IntrusiveSet<>()

NEW

+60

pw::containers::internal::AATree<>::AATree()

NEW

+56

pw::containers::internal::GenericAATree::erase_one()

NEW

+56

pw::containers::internal::KeyedAATree<>::KeyedAATree()

NEW

+56

pw::containers::internal::KeyedAATree<>::merge()

NEW

+46

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

NEW

+44

pw::PackedPtr<>::set()

NEW

+44

pw::PackedPtr<>::set_packed_value()

NEW

+44

pw::containers::internal::KeyedAATree<>::count()

NEW

+42

pw::containers::internal::AATreeItem::GetPredecessor()

NEW

+42

pw::containers::internal::AATreeItem::GetSuccessor()

NEW

+42

pw::containers::internal::AATreeItem::IsMapped()

NEW

+42

pw::containers::internal::GenericAATree::end()

NEW

+40

pw::containers::internal::AATreeItem::GetTreeSize()

NEW

+40

pw::containers::internal::AATreeItem::SetLevel()

NEW

+40

pw::containers::internal::CheckIntrusiveContainerIsEmpty()

NEW

+38

_ZNSt3__210__distanceB8nn210000IN2pw10containers8internal14AATreeIteratorINS3_10AATreeItemEEEEENS_15iterator_traitsIT_E15difference_typeES8_S8_NS_18input_iterator_tagE

NEW

+38

pw::containers::internal::AATreeItem::Replace()

NEW

+36

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

NEW

+34

fit::internal::target<>::invoke()

NEW

+34

pw::containers::internal::KeyedAATree<>::lower_bound()

NEW

+34

pw::containers::internal::KeyedAATree<>::upper_bound()

NEW

+32

pw::containers::internal::KeyedAATree<>::~KeyedAATree()

NEW

+30

pw::containers::internal::AATreeItem::SetRight()

NEW

+28

_ZNSt3__28distanceB8nn210000IN2pw10containers8internal14AATreeIteratorINS3_10AATreeItemEEEEENS_15iterator_traitsIT_E15difference_typeES8_S8_

NEW

+28

pw::containers::internal::AATreeItem::SetLeft()

NEW

+28

pw::containers::internal::KeyedAATree<>::insert<>()

NEW

+26

fit::internal::inline_trivial_target_move<>()

NEW

+26

pw::containers::internal::GenericAATree::begin()

NEW

+24

pw::IntrusiveSet<>::insert()

NEW

+22

pw::containers::internal::AATree<>::~AATree()

NEW

+22

pw::containers::internal::AATreeItem::GetLevel()

NEW

+18

pw::IntrusiveSet<>::begin()

NEW

+18

pw::containers::internal::GenericAATree::size()

NEW

+18

pw::containers::internal::GenericAATree::~GenericAATree()

NEW

+16

pw::containers::internal::GenericAATree::SetRoot()

NEW

+14

pw::containers::internal::AATreeItem::GetLeftmost()

NEW

+14

pw::containers::internal::AATreeItem::GetRightmost()

NEW

+14

pw::containers::internal::AATreeItem::GetRoot()

NEW

+10

pw::containers::internal::AATreeItem::Reset()

NEW

+10

pw::containers::internal::GenericAATree::swap()

NEW

+8

pw::IntrusiveSet<>::IntrusiveSet()

NEW

+2

fit::internal::inline_target_get()

+3,040

RAM

+1

__Thumbv6MABSLongThunk_best_effort_wfe_or_timeout

NEW

+159

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

NEW

+36

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

+196

Additional IntrusiveSet with different item type

FLASH

-2

pw::containers::size_report::SetBaseline()

+190

pw::containers::internal::KeyedAATree<>::InsertImpl()

+104

pw::containers::internal::KeyedAATree<>::erase_all()

+98

pw::containers::internal::KeyedAATree<>::insert()

+84

pw::containers::internal::KeyedAATree<>::GetLowerBoundImpl()

+84

pw::containers::internal::KeyedAATree<>::GetUpperBoundImpl()

+60

fit::internal::target<>::ops

+60

pw::IntrusiveSet<>::IntrusiveSet<>()

+60

pw::containers::internal::AATree<>::AATree()

+56

pw::containers::internal::KeyedAATree<>::KeyedAATree()

+56

pw::containers::internal::KeyedAATree<>::merge()

+46

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

+44

pw::containers::internal::KeyedAATree<>::count()

+36

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

+42

fit::internal::target<>::invoke()

+34

pw::containers::internal::KeyedAATree<>::lower_bound()

+34

pw::containers::internal::KeyedAATree<>::upper_bound()

+32

pw::containers::internal::KeyedAATree<>::~KeyedAATree()

+28

pw::containers::internal::KeyedAATree<>::insert<>()

+20

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

+24

pw::IntrusiveSet<>::insert()

+22

pw::containers::internal::AATree<>::~AATree()

+18

pw::IntrusiveSet<>::begin()

-4

__bi_84

+4

vClearInterruptMaskFromISR

+8

pw::IntrusiveSet<>::IntrusiveSet()

NEW

+130

_ZN2pw10containers11size_report19MeasureIntrusiveSetINS1_7SetItemIyEETpTnRiJENSt3__211__wrap_iterIPS4_EEEEiT1_SA_j

+1,368

RAM

+240

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

+36

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

+276

IntrusiveMultiSet

FLASH

+356

[section .rodata]

+2

pw::containers::size_report::SetBaseline()

-2

pw::Allocator::Reallocate()

+4

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

+8

vClearInterruptMaskFromISR

NEW

+190

pw::containers::internal::KeyedAATree<>::InsertImpl()

NEW

+184

pw::containers::internal::AATreeItem::Rebalance()

NEW

+136

pw::containers::internal::AATreeItem::Unmap()

NEW

+130

_ZN2pw10containers11size_report24MeasureIntrusiveMultiSetINS1_12MultiSetItemIjEETpTnRiJENSt3__211__wrap_iterIPS4_EEEEiT1_SA_j

NEW

+104

pw::containers::internal::KeyedAATree<>::erase_all()

NEW

+98

pw::containers::internal::KeyedAATree<>::insert()

NEW

+90

pw::containers::internal::AATreeItem::Split()

NEW

+84

pw::containers::internal::KeyedAATree<>::GetLowerBoundImpl()

NEW

+84

pw::containers::internal::KeyedAATree<>::GetUpperBoundImpl()

NEW

+72

pw::containers::internal::AATreeIterator<>::operator++()

NEW

+68

pw::containers::internal::AATreeItem::Skew()

NEW

+60

fit::internal::target<>::ops

NEW

+60

pw::IntrusiveMultiSet<>::IntrusiveMultiSet<>()

NEW

+60

pw::containers::internal::AATree<>::AATree()

NEW

+56

pw::containers::internal::GenericAATree::erase_one()

NEW

+56

pw::containers::internal::KeyedAATree<>::KeyedAATree()

NEW

+56

pw::containers::internal::KeyedAATree<>::merge()

NEW

+46

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

NEW

+44

pw::PackedPtr<>::set()

NEW

+44

pw::PackedPtr<>::set_packed_value()

NEW

+44

pw::containers::internal::KeyedAATree<>::count()

NEW

+42

pw::containers::internal::AATreeItem::GetPredecessor()

NEW

+42

pw::containers::internal::AATreeItem::GetSuccessor()

NEW

+42

pw::containers::internal::AATreeItem::IsMapped()

NEW

+42

pw::containers::internal::GenericAATree::end()

NEW

+40

pw::containers::internal::AATreeItem::GetTreeSize()

NEW

+40

pw::containers::internal::AATreeItem::SetLevel()

NEW

+40

pw::containers::internal::CheckIntrusiveContainerIsEmpty()

NEW

+38

_ZNSt3__210__distanceB8nn210000IN2pw10containers8internal14AATreeIteratorINS3_10AATreeItemEEEEENS_15iterator_traitsIT_E15difference_typeES8_S8_NS_18input_iterator_tagE

NEW

+38

pw::containers::internal::AATreeItem::Replace()

NEW

+36

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

NEW

+34

fit::internal::target<>::invoke()

NEW

+34

pw::containers::internal::KeyedAATree<>::lower_bound()

NEW

+34

pw::containers::internal::KeyedAATree<>::upper_bound()

NEW

+32

pw::containers::internal::KeyedAATree<>::~KeyedAATree()

NEW

+30

pw::containers::internal::AATreeItem::SetRight()

NEW

+28

_ZNSt3__28distanceB8nn210000IN2pw10containers8internal14AATreeIteratorINS3_10AATreeItemEEEEENS_15iterator_traitsIT_E15difference_typeES8_S8_

NEW

+28

pw::containers::internal::AATreeItem::SetLeft()

NEW

+28

pw::containers::internal::KeyedAATree<>::insert<>()

NEW

+26

fit::internal::inline_trivial_target_move<>()

NEW

+26

pw::containers::internal::GenericAATree::begin()

NEW

+22

pw::containers::internal::AATree<>::~AATree()

NEW

+22

pw::containers::internal::AATreeItem::GetLevel()

NEW

+20

pw::IntrusiveMultiSet<>::insert()

NEW

+18

pw::IntrusiveMultiSet<>::begin()

NEW

+18

pw::containers::internal::GenericAATree::size()

NEW

+18

pw::containers::internal::GenericAATree::~GenericAATree()

NEW

+16

pw::containers::internal::GenericAATree::SetRoot()

NEW

+14

pw::containers::internal::AATreeItem::GetLeftmost()

NEW

+14

pw::containers::internal::AATreeItem::GetRightmost()

NEW

+14

pw::containers::internal::AATreeItem::GetRoot()

NEW

+10

pw::containers::internal::AATreeItem::Reset()

NEW

+10

pw::containers::internal::GenericAATree::swap()

NEW

+8

pw::IntrusiveMultiSet<>::IntrusiveMultiSet()

NEW

+2

fit::internal::inline_target_get()

+3,040

RAM

+1

__Thumbv6MABSLongThunk_best_effort_wfe_or_timeout

NEW

+159

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

NEW

+36

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

+196

Additional IntrusiveMultiSet with different item type

FLASH

-2

pw::containers::size_report::SetBaseline()

+190

pw::containers::internal::KeyedAATree<>::InsertImpl()

+104

pw::containers::internal::KeyedAATree<>::erase_all()

+98

pw::containers::internal::KeyedAATree<>::insert()

+84

pw::containers::internal::KeyedAATree<>::GetLowerBoundImpl()

+84

pw::containers::internal::KeyedAATree<>::GetUpperBoundImpl()

+60

fit::internal::target<>::ops

+60

pw::IntrusiveMultiSet<>::IntrusiveMultiSet<>()

+60

pw::containers::internal::AATree<>::AATree()

+56

pw::containers::internal::KeyedAATree<>::KeyedAATree()

+56

pw::containers::internal::KeyedAATree<>::merge()

+46

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

+44

pw::containers::internal::KeyedAATree<>::count()

+36

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

+42

fit::internal::target<>::invoke()

+34

pw::containers::internal::KeyedAATree<>::lower_bound()

+34

pw::containers::internal::KeyedAATree<>::upper_bound()

+32

pw::containers::internal::KeyedAATree<>::~KeyedAATree()

+28

pw::containers::internal::KeyedAATree<>::insert<>()

+20

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

+22

pw::containers::internal::AATree<>::~AATree()

+20

pw::IntrusiveMultiSet<>::insert()

-8

vClearInterruptMaskFromISR

+18

pw::IntrusiveMultiSet<>::begin()

-4

__bi_84

+8

pw::IntrusiveMultiSet<>::IntrusiveMultiSet()

NEW

+130

_ZN2pw10containers11size_report24MeasureIntrusiveMultiSetINS1_12MultiSetItemIyEETpTnRiJENSt3__211__wrap_iterIPS4_EEEEiT1_SA_j

+1,352

RAM

+240

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

+36

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

+276

IntrusiveSet and IntrusiveMultiSet

FLASH

+356

[section .rodata]

-2

pw::Allocator::Reallocate()

+24

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

-4

__bi_84

+4

vClearInterruptMaskFromISR

NEW

+380

pw::containers::internal::KeyedAATree<>::InsertImpl()

NEW

+208

pw::containers::internal::KeyedAATree<>::erase_all()

NEW

+196

pw::containers::internal::KeyedAATree<>::insert()

NEW

+184

pw::containers::internal::AATreeItem::Rebalance()

NEW

+168

pw::containers::internal::KeyedAATree<>::GetLowerBoundImpl()

NEW

+168

pw::containers::internal::KeyedAATree<>::GetUpperBoundImpl()

NEW

+136

pw::containers::internal::AATreeItem::Unmap()

NEW

+130

_ZN2pw10containers11size_report19MeasureIntrusiveSetINS1_7SetItemIjEETpTnRiJENSt3__211__wrap_iterIPS4_EEEEiT1_SA_j

NEW

+130

_ZN2pw10containers11size_report24MeasureIntrusiveMultiSetINS1_12MultiSetItemIjEETpTnRiJENSt3__211__wrap_iterIPS4_EEEEiT1_SA_j

NEW

+120

fit::internal::target<>::ops

NEW

+120

pw::containers::internal::AATree<>::AATree()

NEW

+112

pw::containers::internal::KeyedAATree<>::KeyedAATree()

NEW

+112

pw::containers::internal::KeyedAATree<>::merge()

NEW

+92

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

NEW

+90

pw::containers::internal::AATreeItem::Split()

NEW

+88

pw::containers::internal::KeyedAATree<>::count()

NEW

+72

pw::containers::internal::AATreeIterator<>::operator++()

NEW

+72

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

NEW

+68

fit::internal::target<>::invoke()

NEW

+68

pw::containers::internal::AATreeItem::Skew()

NEW

+68

pw::containers::internal::KeyedAATree<>::lower_bound()

NEW

+68

pw::containers::internal::KeyedAATree<>::upper_bound()

NEW

+64

pw::containers::internal::KeyedAATree<>::~KeyedAATree()

NEW

+60

pw::IntrusiveMultiSet<>::IntrusiveMultiSet<>()

NEW

+60

pw::IntrusiveSet<>::IntrusiveSet<>()

NEW

+56

pw::containers::internal::GenericAATree::erase_one()

NEW

+56

pw::containers::internal::KeyedAATree<>::insert<>()

NEW

+44

pw::PackedPtr<>::set()

NEW

+44

pw::PackedPtr<>::set_packed_value()

NEW

+44

pw::containers::internal::AATree<>::~AATree()

NEW

+42

pw::containers::internal::AATreeItem::GetPredecessor()

NEW

+42

pw::containers::internal::AATreeItem::GetSuccessor()

NEW

+42

pw::containers::internal::AATreeItem::IsMapped()

NEW

+42

pw::containers::internal::GenericAATree::end()

NEW

+40

pw::containers::internal::AATreeItem::GetTreeSize()

NEW

+40

pw::containers::internal::AATreeItem::SetLevel()

NEW

+40

pw::containers::internal::CheckIntrusiveContainerIsEmpty()

NEW

+38

_ZNSt3__210__distanceB8nn210000IN2pw10containers8internal14AATreeIteratorINS3_10AATreeItemEEEEENS_15iterator_traitsIT_E15difference_typeES8_S8_NS_18input_iterator_tagE

NEW

+38

pw::containers::internal::AATreeItem::Replace()

NEW

+30

pw::containers::internal::AATreeItem::SetRight()

NEW

+28

_ZNSt3__28distanceB8nn210000IN2pw10containers8internal14AATreeIteratorINS3_10AATreeItemEEEEENS_15iterator_traitsIT_E15difference_typeES8_S8_

NEW

+28

pw::containers::internal::AATreeItem::SetLeft()

NEW

+26

fit::internal::inline_trivial_target_move<>()

NEW

+26

pw::containers::internal::GenericAATree::begin()

NEW

+24

pw::IntrusiveSet<>::insert()

NEW

+22

pw::containers::internal::AATreeItem::GetLevel()

NEW

+20

pw::IntrusiveMultiSet<>::insert()

NEW

+18

pw::IntrusiveMultiSet<>::begin()

NEW

+18

pw::IntrusiveSet<>::begin()

NEW

+18

pw::containers::internal::GenericAATree::size()

NEW

+18

pw::containers::internal::GenericAATree::~GenericAATree()

NEW

+16

pw::containers::internal::GenericAATree::SetRoot()

NEW

+14

pw::containers::internal::AATreeItem::GetLeftmost()

NEW

+14

pw::containers::internal::AATreeItem::GetRightmost()

NEW

+14

pw::containers::internal::AATreeItem::GetRoot()

NEW

+10

pw::containers::internal::AATreeItem::Reset()

NEW

+10

pw::containers::internal::GenericAATree::swap()

NEW

+8

pw::IntrusiveMultiSet<>::IntrusiveMultiSet()

NEW

+8

pw::IntrusiveSet<>::IntrusiveSet()

NEW

+2

fit::internal::inline_target_get()

+4,392

RAM

+1

__Thumbv6MABSLongThunk_best_effort_wfe_or_timeout

NEW

+319

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

NEW

+72

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

+392