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