• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2025 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14 #pragma once
15 
16 #include "pw_bloat/bloat_this_binary.h"
17 #include "pw_containers/intrusive_multimap.h"
18 #include "pw_containers/size_report/size_report.h"
19 
20 namespace pw::containers::size_report {
21 
22 /// A simple pair for intrusive multimaps that wraps a copyable key and value.
23 template <typename K, typename V>
24 struct MultiMapPair : public IntrusiveMultiMap<K, MultiMapPair<K, V>>::Pair {
25   using Base = typename IntrusiveMultiMap<K, MultiMapPair<K, V>>::Pair;
26   using KeyType = K;
27 
MultiMapPairMultiMapPair28   constexpr MultiMapPair(K key, V value) : Base(key), value_(value) {}
29 
30   V value_;
31 };
32 
33 /// Invokes methods of the pw::IntrusiveMultiMap type.
34 ///
35 /// This method is used both to measure intrusive multimaps directly, as well as
36 /// to provide a baseline for measuring other types that use intrusive multimaps
37 /// and want to only measure their contributions to code size.
38 template <typename KeyType,
39           typename PairType,
40           int&... kExplicitGuard,
41           typename Iterator>
MeasureIntrusiveMultiMap(Iterator first,Iterator last,uint32_t mask)42 int MeasureIntrusiveMultiMap(Iterator first, Iterator last, uint32_t mask) {
43   mask = SetBaseline(mask);
44   auto& map1 = GetContainer<IntrusiveMultiMap<KeyType, PairType>>();
45   map1.insert(first, last);
46   mask = MeasureContainer(map1, mask);
47 
48   auto iter = map1.find(1U);
49   PW_BLOAT_COND(iter != map1.end(), mask);
50 
51   auto iters = map1.equal_range(1U);
52   PW_BLOAT_COND(iters.first != iters.second, mask);
53 
54   IntrusiveMultiMap<KeyType, PairType> map2;
55   auto& item0 = *(map1.begin());
56   PW_BLOAT_EXPR(map2.swap(map1), mask);
57   PW_BLOAT_EXPR(map2.erase(item0), mask);
58   PW_BLOAT_EXPR(map1.merge(map2), mask);
59   PW_BLOAT_EXPR(map1.insert(item0), mask);
60 
61   return map1.count(item0.key()) != 0 ? 0 : 1;
62 }
63 
64 }  // namespace pw::containers::size_report
65