1*74a9c6d7SMark de Wever //===----------------------------------------------------------------------===//
2*74a9c6d7SMark de Wever //
3*74a9c6d7SMark de Wever // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*74a9c6d7SMark de Wever // See https://llvm.org/LICENSE.txt for license information.
5*74a9c6d7SMark de Wever // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*74a9c6d7SMark de Wever //
7*74a9c6d7SMark de Wever //===----------------------------------------------------------------------===//
8*74a9c6d7SMark de Wever 
9*74a9c6d7SMark de Wever #include <algorithm>
10*74a9c6d7SMark de Wever #include <cstdint>
11*74a9c6d7SMark de Wever #include <map>
12*74a9c6d7SMark de Wever #include <random>
13*74a9c6d7SMark de Wever #include <vector>
14*74a9c6d7SMark de Wever 
15*74a9c6d7SMark de Wever #include "CartesianBenchmarks.h"
16*74a9c6d7SMark de Wever #include "benchmark/benchmark.h"
17*74a9c6d7SMark de Wever #include "test_macros.h"
18*74a9c6d7SMark de Wever 
19*74a9c6d7SMark de Wever // When VALIDATE is defined the benchmark will run to validate the benchmarks.
20*74a9c6d7SMark de Wever // The time taken by several operations depend on whether or not an element
21*74a9c6d7SMark de Wever // exists. To avoid errors in the benchmark these operations have a validation
22*74a9c6d7SMark de Wever // mode to test the benchmark. Since they are not meant to be benchmarked the
23*74a9c6d7SMark de Wever // number of sizes tested is limited to 1.
24*74a9c6d7SMark de Wever //#define VALIDATE
25*74a9c6d7SMark de Wever 
26*74a9c6d7SMark de Wever namespace {
27*74a9c6d7SMark de Wever 
28*74a9c6d7SMark de Wever enum class Mode { Hit, Miss };
29*74a9c6d7SMark de Wever 
30*74a9c6d7SMark de Wever struct AllModes : EnumValuesAsTuple<AllModes, Mode, 2> {
31*74a9c6d7SMark de Wever   static constexpr const char* Names[] = {"ExistingElement", "NewElement"};
32*74a9c6d7SMark de Wever };
33*74a9c6d7SMark de Wever 
34*74a9c6d7SMark de Wever // The positions of the hints to pick:
35*74a9c6d7SMark de Wever // - Begin picks the first item. The item cannot be put before this element.
36*74a9c6d7SMark de Wever // - Thrid picks the third item. This is just an element with a valid entry
37*74a9c6d7SMark de Wever //   before and after it.
38*74a9c6d7SMark de Wever // - Correct contains the correct hint.
39*74a9c6d7SMark de Wever // - End contains a hint to the end of the map.
40*74a9c6d7SMark de Wever enum class Hint { Begin, Third, Correct, End };
41*74a9c6d7SMark de Wever struct AllHints : EnumValuesAsTuple<AllHints, Hint, 4> {
42*74a9c6d7SMark de Wever   static constexpr const char* Names[] = {"Begin", "Third", "Correct", "End"};
43*74a9c6d7SMark de Wever };
44*74a9c6d7SMark de Wever 
45*74a9c6d7SMark de Wever enum class Order { Sorted, Random };
46*74a9c6d7SMark de Wever struct AllOrders : EnumValuesAsTuple<AllOrders, Order, 2> {
47*74a9c6d7SMark de Wever   static constexpr const char* Names[] = {"Sorted", "Random"};
48*74a9c6d7SMark de Wever };
49*74a9c6d7SMark de Wever 
50*74a9c6d7SMark de Wever struct TestSets {
51*74a9c6d7SMark de Wever   std::vector<uint64_t> Keys;
52*74a9c6d7SMark de Wever   std::vector<std::map<uint64_t, int64_t> > Maps;
53*74a9c6d7SMark de Wever   std::vector<
54*74a9c6d7SMark de Wever       std::vector<typename std::map<uint64_t, int64_t>::const_iterator> >
55*74a9c6d7SMark de Wever       Hints;
56*74a9c6d7SMark de Wever };
57*74a9c6d7SMark de Wever 
58*74a9c6d7SMark de Wever enum class Shuffle { None, Keys, Hints };
59*74a9c6d7SMark de Wever 
makeTestingSets(size_t MapSize,Mode mode,Shuffle shuffle,size_t max_maps)60*74a9c6d7SMark de Wever TestSets makeTestingSets(size_t MapSize, Mode mode, Shuffle shuffle,
61*74a9c6d7SMark de Wever                          size_t max_maps) {
62*74a9c6d7SMark de Wever   /*
63*74a9c6d7SMark de Wever    * The shuffle does not retain the random number generator to use the same
64*74a9c6d7SMark de Wever    * set of random numbers for every iteration.
65*74a9c6d7SMark de Wever    */
66*74a9c6d7SMark de Wever   TestSets R;
67*74a9c6d7SMark de Wever 
68*74a9c6d7SMark de Wever   int MapCount = std::min(max_maps, 1000000 / MapSize);
69*74a9c6d7SMark de Wever 
70*74a9c6d7SMark de Wever   for (uint64_t I = 0; I < MapSize; ++I) {
71*74a9c6d7SMark de Wever     R.Keys.push_back(mode == Mode::Hit ? 2 * I + 2 : 2 * I + 1);
72*74a9c6d7SMark de Wever   }
73*74a9c6d7SMark de Wever   if (shuffle == Shuffle::Keys)
74*74a9c6d7SMark de Wever     std::shuffle(R.Keys.begin(), R.Keys.end(), std::mt19937());
75*74a9c6d7SMark de Wever 
76*74a9c6d7SMark de Wever   for (int M = 0; M < MapCount; ++M) {
77*74a9c6d7SMark de Wever     auto& map = R.Maps.emplace_back();
78*74a9c6d7SMark de Wever     auto& hints = R.Hints.emplace_back();
79*74a9c6d7SMark de Wever     for (uint64_t I = 0; I < MapSize; ++I) {
80*74a9c6d7SMark de Wever       hints.push_back(map.insert(std::make_pair(2 * I + 2, 0)).first);
81*74a9c6d7SMark de Wever     }
82*74a9c6d7SMark de Wever     if (shuffle == Shuffle::Hints)
83*74a9c6d7SMark de Wever       std::shuffle(hints.begin(), hints.end(), std::mt19937());
84*74a9c6d7SMark de Wever   }
85*74a9c6d7SMark de Wever 
86*74a9c6d7SMark de Wever   return R;
87*74a9c6d7SMark de Wever }
88*74a9c6d7SMark de Wever 
89*74a9c6d7SMark de Wever struct Base {
90*74a9c6d7SMark de Wever   size_t MapSize;
Base__anon8b67eae20111::Base91*74a9c6d7SMark de Wever   Base(size_t T) : MapSize(T) {}
92*74a9c6d7SMark de Wever 
baseName__anon8b67eae20111::Base93*74a9c6d7SMark de Wever   std::string baseName() const { return "_MapSize=" + std::to_string(MapSize); }
94*74a9c6d7SMark de Wever };
95*74a9c6d7SMark de Wever 
96*74a9c6d7SMark de Wever //*******************************************************************|
97*74a9c6d7SMark de Wever //                       Member functions                            |
98*74a9c6d7SMark de Wever //*******************************************************************|
99*74a9c6d7SMark de Wever 
100*74a9c6d7SMark de Wever struct ConstructorDefault {
run__anon8b67eae20111::ConstructorDefault101*74a9c6d7SMark de Wever   void run(benchmark::State& State) const {
102*74a9c6d7SMark de Wever     for (auto _ : State) {
103*74a9c6d7SMark de Wever       benchmark::DoNotOptimize(std::map<uint64_t, int64_t>());
104*74a9c6d7SMark de Wever     }
105*74a9c6d7SMark de Wever   }
106*74a9c6d7SMark de Wever 
name__anon8b67eae20111::ConstructorDefault107*74a9c6d7SMark de Wever   std::string name() const { return "BM_ConstructorDefault"; }
108*74a9c6d7SMark de Wever };
109*74a9c6d7SMark de Wever 
110*74a9c6d7SMark de Wever struct ConstructorIterator : Base {
111*74a9c6d7SMark de Wever   using Base::Base;
112*74a9c6d7SMark de Wever 
run__anon8b67eae20111::ConstructorIterator113*74a9c6d7SMark de Wever   void run(benchmark::State& State) const {
114*74a9c6d7SMark de Wever     auto Data = makeTestingSets(MapSize, Mode::Hit, Shuffle::None, 1);
115*74a9c6d7SMark de Wever     auto& Map = Data.Maps.front();
116*74a9c6d7SMark de Wever     while (State.KeepRunningBatch(MapSize)) {
117*74a9c6d7SMark de Wever #ifndef VALIDATE
118*74a9c6d7SMark de Wever       benchmark::DoNotOptimize(
119*74a9c6d7SMark de Wever           std::map<uint64_t, int64_t>(Map.begin(), Map.end()));
120*74a9c6d7SMark de Wever #else
121*74a9c6d7SMark de Wever       std::map<uint64_t, int64_t> M{Map.begin(), Map.end()};
122*74a9c6d7SMark de Wever       if (M != Map)
123*74a9c6d7SMark de Wever         State.SkipWithError("Map copy not identical");
124*74a9c6d7SMark de Wever #endif
125*74a9c6d7SMark de Wever     }
126*74a9c6d7SMark de Wever   }
127*74a9c6d7SMark de Wever 
name__anon8b67eae20111::ConstructorIterator128*74a9c6d7SMark de Wever   std::string name() const { return "BM_ConstructorIterator" + baseName(); }
129*74a9c6d7SMark de Wever };
130*74a9c6d7SMark de Wever 
131*74a9c6d7SMark de Wever struct ConstructorCopy : Base {
132*74a9c6d7SMark de Wever   using Base::Base;
133*74a9c6d7SMark de Wever 
run__anon8b67eae20111::ConstructorCopy134*74a9c6d7SMark de Wever   void run(benchmark::State& State) const {
135*74a9c6d7SMark de Wever     auto Data = makeTestingSets(MapSize, Mode::Hit, Shuffle::None, 1);
136*74a9c6d7SMark de Wever     auto& Map = Data.Maps.front();
137*74a9c6d7SMark de Wever     while (State.KeepRunningBatch(MapSize)) {
138*74a9c6d7SMark de Wever #ifndef VALIDATE
139*74a9c6d7SMark de Wever       std::map<uint64_t, int64_t> M(Map);
140*74a9c6d7SMark de Wever       benchmark::DoNotOptimize(M);
141*74a9c6d7SMark de Wever #else
142*74a9c6d7SMark de Wever       std::map<uint64_t, int64_t> M(Map);
143*74a9c6d7SMark de Wever       if (M != Map)
144*74a9c6d7SMark de Wever         State.SkipWithError("Map copy not identical");
145*74a9c6d7SMark de Wever #endif
146*74a9c6d7SMark de Wever     }
147*74a9c6d7SMark de Wever   }
148*74a9c6d7SMark de Wever 
name__anon8b67eae20111::ConstructorCopy149*74a9c6d7SMark de Wever   std::string name() const { return "BM_ConstructorCopy" + baseName(); }
150*74a9c6d7SMark de Wever };
151*74a9c6d7SMark de Wever 
152*74a9c6d7SMark de Wever struct ConstructorMove : Base {
153*74a9c6d7SMark de Wever   using Base::Base;
154*74a9c6d7SMark de Wever 
run__anon8b67eae20111::ConstructorMove155*74a9c6d7SMark de Wever   void run(benchmark::State& State) const {
156*74a9c6d7SMark de Wever     auto Data = makeTestingSets(MapSize, Mode::Hit, Shuffle::None, 1000);
157*74a9c6d7SMark de Wever     while (State.KeepRunningBatch(MapSize * Data.Maps.size())) {
158*74a9c6d7SMark de Wever       for (auto& Map : Data.Maps) {
159*74a9c6d7SMark de Wever         std::map<uint64_t, int64_t> M(std::move(Map));
160*74a9c6d7SMark de Wever         benchmark::DoNotOptimize(M);
161*74a9c6d7SMark de Wever       }
162*74a9c6d7SMark de Wever       State.PauseTiming();
163*74a9c6d7SMark de Wever       Data = makeTestingSets(MapSize, Mode::Hit, Shuffle::None, 1000);
164*74a9c6d7SMark de Wever       State.ResumeTiming();
165*74a9c6d7SMark de Wever     }
166*74a9c6d7SMark de Wever   }
167*74a9c6d7SMark de Wever 
name__anon8b67eae20111::ConstructorMove168*74a9c6d7SMark de Wever   std::string name() const { return "BM_ConstructorMove" + baseName(); }
169*74a9c6d7SMark de Wever };
170*74a9c6d7SMark de Wever 
171*74a9c6d7SMark de Wever //*******************************************************************|
172*74a9c6d7SMark de Wever //                           Capacity                                |
173*74a9c6d7SMark de Wever //*******************************************************************|
174*74a9c6d7SMark de Wever 
175*74a9c6d7SMark de Wever struct Empty : Base {
176*74a9c6d7SMark de Wever   using Base::Base;
177*74a9c6d7SMark de Wever 
run__anon8b67eae20111::Empty178*74a9c6d7SMark de Wever   void run(benchmark::State& State) const {
179*74a9c6d7SMark de Wever     auto Data = makeTestingSets(MapSize, Mode::Hit, Shuffle::None, 1);
180*74a9c6d7SMark de Wever     auto& Map = Data.Maps.front();
181*74a9c6d7SMark de Wever     for (auto _ : State) {
182*74a9c6d7SMark de Wever #ifndef VALIDATE
183*74a9c6d7SMark de Wever       benchmark::DoNotOptimize(Map.empty());
184*74a9c6d7SMark de Wever #else
185*74a9c6d7SMark de Wever       if (Map.empty())
186*74a9c6d7SMark de Wever         State.SkipWithError("Map contains an invalid number of elements.");
187*74a9c6d7SMark de Wever #endif
188*74a9c6d7SMark de Wever     }
189*74a9c6d7SMark de Wever   }
190*74a9c6d7SMark de Wever 
name__anon8b67eae20111::Empty191*74a9c6d7SMark de Wever   std::string name() const { return "BM_Empty" + baseName(); }
192*74a9c6d7SMark de Wever };
193*74a9c6d7SMark de Wever 
194*74a9c6d7SMark de Wever struct Size : Base {
195*74a9c6d7SMark de Wever   using Base::Base;
196*74a9c6d7SMark de Wever 
run__anon8b67eae20111::Size197*74a9c6d7SMark de Wever   void run(benchmark::State& State) const {
198*74a9c6d7SMark de Wever     auto Data = makeTestingSets(MapSize, Mode::Hit, Shuffle::None, 1);
199*74a9c6d7SMark de Wever     auto& Map = Data.Maps.front();
200*74a9c6d7SMark de Wever     for (auto _ : State) {
201*74a9c6d7SMark de Wever #ifndef VALIDATE
202*74a9c6d7SMark de Wever       benchmark::DoNotOptimize(Map.size());
203*74a9c6d7SMark de Wever #else
204*74a9c6d7SMark de Wever       if (Map.size() != MapSize)
205*74a9c6d7SMark de Wever         State.SkipWithError("Map contains an invalid number of elements.");
206*74a9c6d7SMark de Wever #endif
207*74a9c6d7SMark de Wever     }
208*74a9c6d7SMark de Wever   }
209*74a9c6d7SMark de Wever 
name__anon8b67eae20111::Size210*74a9c6d7SMark de Wever   std::string name() const { return "BM_Size" + baseName(); }
211*74a9c6d7SMark de Wever };
212*74a9c6d7SMark de Wever 
213*74a9c6d7SMark de Wever //*******************************************************************|
214*74a9c6d7SMark de Wever //                           Modifiers                               |
215*74a9c6d7SMark de Wever //*******************************************************************|
216*74a9c6d7SMark de Wever 
217*74a9c6d7SMark de Wever struct Clear : Base {
218*74a9c6d7SMark de Wever   using Base::Base;
219*74a9c6d7SMark de Wever 
run__anon8b67eae20111::Clear220*74a9c6d7SMark de Wever   void run(benchmark::State& State) const {
221*74a9c6d7SMark de Wever     auto Data = makeTestingSets(MapSize, Mode::Hit, Shuffle::None, 1000);
222*74a9c6d7SMark de Wever     while (State.KeepRunningBatch(MapSize * Data.Maps.size())) {
223*74a9c6d7SMark de Wever       for (auto& Map : Data.Maps) {
224*74a9c6d7SMark de Wever         Map.clear();
225*74a9c6d7SMark de Wever         benchmark::DoNotOptimize(Map);
226*74a9c6d7SMark de Wever       }
227*74a9c6d7SMark de Wever       State.PauseTiming();
228*74a9c6d7SMark de Wever       Data = makeTestingSets(MapSize, Mode::Hit, Shuffle::None, 1000);
229*74a9c6d7SMark de Wever       State.ResumeTiming();
230*74a9c6d7SMark de Wever     }
231*74a9c6d7SMark de Wever   }
232*74a9c6d7SMark de Wever 
name__anon8b67eae20111::Clear233*74a9c6d7SMark de Wever   std::string name() const { return "BM_Clear" + baseName(); }
234*74a9c6d7SMark de Wever };
235*74a9c6d7SMark de Wever 
236*74a9c6d7SMark de Wever template <class Mode, class Order>
237*74a9c6d7SMark de Wever struct Insert : Base {
238*74a9c6d7SMark de Wever   using Base::Base;
239*74a9c6d7SMark de Wever 
run__anon8b67eae20111::Insert240*74a9c6d7SMark de Wever   void run(benchmark::State& State) const {
241*74a9c6d7SMark de Wever     auto Data = makeTestingSets(
242*74a9c6d7SMark de Wever         MapSize, Mode(),
243*74a9c6d7SMark de Wever         Order::value == ::Order::Random ? Shuffle::Keys : Shuffle::None, 1000);
244*74a9c6d7SMark de Wever     while (State.KeepRunningBatch(MapSize * Data.Maps.size())) {
245*74a9c6d7SMark de Wever       for (auto& Map : Data.Maps) {
246*74a9c6d7SMark de Wever         for (auto K : Data.Keys) {
247*74a9c6d7SMark de Wever #ifndef VALIDATE
248*74a9c6d7SMark de Wever           benchmark::DoNotOptimize(Map.insert(std::make_pair(K, 1)));
249*74a9c6d7SMark de Wever #else
250*74a9c6d7SMark de Wever           bool Inserted = Map.insert(std::make_pair(K, 1)).second;
251*74a9c6d7SMark de Wever           if (Mode() == ::Mode::Hit) {
252*74a9c6d7SMark de Wever             if (Inserted)
253*74a9c6d7SMark de Wever               State.SkipWithError("Inserted a duplicate element");
254*74a9c6d7SMark de Wever           } else {
255*74a9c6d7SMark de Wever             if (!Inserted)
256*74a9c6d7SMark de Wever               State.SkipWithError("Failed to insert e new element");
257*74a9c6d7SMark de Wever           }
258*74a9c6d7SMark de Wever #endif
259*74a9c6d7SMark de Wever         }
260*74a9c6d7SMark de Wever       }
261*74a9c6d7SMark de Wever 
262*74a9c6d7SMark de Wever       State.PauseTiming();
263*74a9c6d7SMark de Wever       Data = makeTestingSets(MapSize, Mode(),
264*74a9c6d7SMark de Wever                              Order::value == ::Order::Random ? Shuffle::Keys
265*74a9c6d7SMark de Wever                                                              : Shuffle::None,
266*74a9c6d7SMark de Wever                              1000);
267*74a9c6d7SMark de Wever       State.ResumeTiming();
268*74a9c6d7SMark de Wever     }
269*74a9c6d7SMark de Wever   }
270*74a9c6d7SMark de Wever 
name__anon8b67eae20111::Insert271*74a9c6d7SMark de Wever   std::string name() const {
272*74a9c6d7SMark de Wever     return "BM_Insert" + baseName() + Mode::name() + Order::name();
273*74a9c6d7SMark de Wever   }
274*74a9c6d7SMark de Wever };
275*74a9c6d7SMark de Wever 
276*74a9c6d7SMark de Wever template <class Mode, class Hint>
277*74a9c6d7SMark de Wever struct InsertHint : Base {
278*74a9c6d7SMark de Wever   using Base::Base;
279*74a9c6d7SMark de Wever 
280*74a9c6d7SMark de Wever   template < ::Hint hint>
281*74a9c6d7SMark de Wever   typename std::enable_if<hint == ::Hint::Correct>::type
run__anon8b67eae20111::InsertHint282*74a9c6d7SMark de Wever   run(benchmark::State& State) const {
283*74a9c6d7SMark de Wever     auto Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000);
284*74a9c6d7SMark de Wever     while (State.KeepRunningBatch(MapSize * Data.Maps.size())) {
285*74a9c6d7SMark de Wever       for (size_t I = 0; I < Data.Maps.size(); ++I) {
286*74a9c6d7SMark de Wever         auto& Map = Data.Maps[I];
287*74a9c6d7SMark de Wever         auto H = Data.Hints[I].begin();
288*74a9c6d7SMark de Wever         for (auto K : Data.Keys) {
289*74a9c6d7SMark de Wever #ifndef VALIDATE
290*74a9c6d7SMark de Wever           benchmark::DoNotOptimize(Map.insert(*H, std::make_pair(K, 1)));
291*74a9c6d7SMark de Wever #else
292*74a9c6d7SMark de Wever           auto Inserted = Map.insert(*H, std::make_pair(K, 1));
293*74a9c6d7SMark de Wever           if (Mode() == ::Mode::Hit) {
294*74a9c6d7SMark de Wever             if (Inserted != *H)
295*74a9c6d7SMark de Wever               State.SkipWithError("Inserted a duplicate element");
296*74a9c6d7SMark de Wever           } else {
297*74a9c6d7SMark de Wever             if (++Inserted != *H)
298*74a9c6d7SMark de Wever               State.SkipWithError("Failed to insert a new element");
299*74a9c6d7SMark de Wever           }
300*74a9c6d7SMark de Wever #endif
301*74a9c6d7SMark de Wever           ++H;
302*74a9c6d7SMark de Wever         }
303*74a9c6d7SMark de Wever       }
304*74a9c6d7SMark de Wever 
305*74a9c6d7SMark de Wever       State.PauseTiming();
306*74a9c6d7SMark de Wever       Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000);
307*74a9c6d7SMark de Wever       State.ResumeTiming();
308*74a9c6d7SMark de Wever     }
309*74a9c6d7SMark de Wever   }
310*74a9c6d7SMark de Wever 
311*74a9c6d7SMark de Wever   template < ::Hint hint>
312*74a9c6d7SMark de Wever   typename std::enable_if<hint != ::Hint::Correct>::type
run__anon8b67eae20111::InsertHint313*74a9c6d7SMark de Wever   run(benchmark::State& State) const {
314*74a9c6d7SMark de Wever     auto Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000);
315*74a9c6d7SMark de Wever     while (State.KeepRunningBatch(MapSize * Data.Maps.size())) {
316*74a9c6d7SMark de Wever       for (size_t I = 0; I < Data.Maps.size(); ++I) {
317*74a9c6d7SMark de Wever         auto& Map = Data.Maps[I];
318*74a9c6d7SMark de Wever         auto Third = *(Data.Hints[I].begin() + 2);
319*74a9c6d7SMark de Wever         for (auto K : Data.Keys) {
320*74a9c6d7SMark de Wever           auto Itor = hint == ::Hint::Begin
321*74a9c6d7SMark de Wever                           ? Map.begin()
322*74a9c6d7SMark de Wever                           : hint == ::Hint::Third ? Third : Map.end();
323*74a9c6d7SMark de Wever #ifndef VALIDATE
324*74a9c6d7SMark de Wever           benchmark::DoNotOptimize(Map.insert(Itor, std::make_pair(K, 1)));
325*74a9c6d7SMark de Wever #else
326*74a9c6d7SMark de Wever           size_t Size = Map.size();
327*74a9c6d7SMark de Wever           Map.insert(Itor, std::make_pair(K, 1));
328*74a9c6d7SMark de Wever           if (Mode() == ::Mode::Hit) {
329*74a9c6d7SMark de Wever             if (Size != Map.size())
330*74a9c6d7SMark de Wever               State.SkipWithError("Inserted a duplicate element");
331*74a9c6d7SMark de Wever           } else {
332*74a9c6d7SMark de Wever             if (Size + 1 != Map.size())
333*74a9c6d7SMark de Wever               State.SkipWithError("Failed to insert a new element");
334*74a9c6d7SMark de Wever           }
335*74a9c6d7SMark de Wever #endif
336*74a9c6d7SMark de Wever         }
337*74a9c6d7SMark de Wever       }
338*74a9c6d7SMark de Wever 
339*74a9c6d7SMark de Wever       State.PauseTiming();
340*74a9c6d7SMark de Wever       Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000);
341*74a9c6d7SMark de Wever       State.ResumeTiming();
342*74a9c6d7SMark de Wever     }
343*74a9c6d7SMark de Wever   }
344*74a9c6d7SMark de Wever 
run__anon8b67eae20111::InsertHint345*74a9c6d7SMark de Wever   void run(benchmark::State& State) const {
346*74a9c6d7SMark de Wever     static constexpr auto h = Hint();
347*74a9c6d7SMark de Wever     run<h>(State);
348*74a9c6d7SMark de Wever   }
349*74a9c6d7SMark de Wever 
name__anon8b67eae20111::InsertHint350*74a9c6d7SMark de Wever   std::string name() const {
351*74a9c6d7SMark de Wever     return "BM_InsertHint" + baseName() + Mode::name() + Hint::name();
352*74a9c6d7SMark de Wever   }
353*74a9c6d7SMark de Wever };
354*74a9c6d7SMark de Wever 
355*74a9c6d7SMark de Wever template <class Mode, class Order>
356*74a9c6d7SMark de Wever struct InsertAssign : Base {
357*74a9c6d7SMark de Wever   using Base::Base;
358*74a9c6d7SMark de Wever 
run__anon8b67eae20111::InsertAssign359*74a9c6d7SMark de Wever   void run(benchmark::State& State) const {
360*74a9c6d7SMark de Wever     auto Data = makeTestingSets(
361*74a9c6d7SMark de Wever         MapSize, Mode(),
362*74a9c6d7SMark de Wever         Order::value == ::Order::Random ? Shuffle::Keys : Shuffle::None, 1000);
363*74a9c6d7SMark de Wever     while (State.KeepRunningBatch(MapSize * Data.Maps.size())) {
364*74a9c6d7SMark de Wever       for (auto& Map : Data.Maps) {
365*74a9c6d7SMark de Wever         for (auto K : Data.Keys) {
366*74a9c6d7SMark de Wever #ifndef VALIDATE
367*74a9c6d7SMark de Wever           benchmark::DoNotOptimize(Map.insert_or_assign(K, 1));
368*74a9c6d7SMark de Wever #else
369*74a9c6d7SMark de Wever           bool Inserted = Map.insert_or_assign(K, 1).second;
370*74a9c6d7SMark de Wever           if (Mode() == ::Mode::Hit) {
371*74a9c6d7SMark de Wever             if (Inserted)
372*74a9c6d7SMark de Wever               State.SkipWithError("Inserted a duplicate element");
373*74a9c6d7SMark de Wever           } else {
374*74a9c6d7SMark de Wever             if (!Inserted)
375*74a9c6d7SMark de Wever               State.SkipWithError("Failed to insert e new element");
376*74a9c6d7SMark de Wever           }
377*74a9c6d7SMark de Wever #endif
378*74a9c6d7SMark de Wever         }
379*74a9c6d7SMark de Wever       }
380*74a9c6d7SMark de Wever 
381*74a9c6d7SMark de Wever       State.PauseTiming();
382*74a9c6d7SMark de Wever       Data = makeTestingSets(MapSize, Mode(),
383*74a9c6d7SMark de Wever                              Order::value == ::Order::Random ? Shuffle::Keys
384*74a9c6d7SMark de Wever                                                              : Shuffle::None,
385*74a9c6d7SMark de Wever                              1000);
386*74a9c6d7SMark de Wever       State.ResumeTiming();
387*74a9c6d7SMark de Wever     }
388*74a9c6d7SMark de Wever   }
389*74a9c6d7SMark de Wever 
name__anon8b67eae20111::InsertAssign390*74a9c6d7SMark de Wever   std::string name() const {
391*74a9c6d7SMark de Wever     return "BM_InsertAssign" + baseName() + Mode::name() + Order::name();
392*74a9c6d7SMark de Wever   }
393*74a9c6d7SMark de Wever };
394*74a9c6d7SMark de Wever 
395*74a9c6d7SMark de Wever template <class Mode, class Hint>
396*74a9c6d7SMark de Wever struct InsertAssignHint : Base {
397*74a9c6d7SMark de Wever   using Base::Base;
398*74a9c6d7SMark de Wever 
399*74a9c6d7SMark de Wever   template < ::Hint hint>
400*74a9c6d7SMark de Wever   typename std::enable_if<hint == ::Hint::Correct>::type
run__anon8b67eae20111::InsertAssignHint401*74a9c6d7SMark de Wever   run(benchmark::State& State) const {
402*74a9c6d7SMark de Wever     auto Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000);
403*74a9c6d7SMark de Wever     while (State.KeepRunningBatch(MapSize * Data.Maps.size())) {
404*74a9c6d7SMark de Wever       for (size_t I = 0; I < Data.Maps.size(); ++I) {
405*74a9c6d7SMark de Wever         auto& Map = Data.Maps[I];
406*74a9c6d7SMark de Wever         auto H = Data.Hints[I].begin();
407*74a9c6d7SMark de Wever         for (auto K : Data.Keys) {
408*74a9c6d7SMark de Wever #ifndef VALIDATE
409*74a9c6d7SMark de Wever           benchmark::DoNotOptimize(Map.insert_or_assign(*H, K, 1));
410*74a9c6d7SMark de Wever #else
411*74a9c6d7SMark de Wever           auto Inserted = Map.insert_or_assign(*H, K, 1);
412*74a9c6d7SMark de Wever           if (Mode() == ::Mode::Hit) {
413*74a9c6d7SMark de Wever             if (Inserted != *H)
414*74a9c6d7SMark de Wever               State.SkipWithError("Inserted a duplicate element");
415*74a9c6d7SMark de Wever           } else {
416*74a9c6d7SMark de Wever             if (++Inserted != *H)
417*74a9c6d7SMark de Wever               State.SkipWithError("Failed to insert a new element");
418*74a9c6d7SMark de Wever           }
419*74a9c6d7SMark de Wever #endif
420*74a9c6d7SMark de Wever           ++H;
421*74a9c6d7SMark de Wever         }
422*74a9c6d7SMark de Wever       }
423*74a9c6d7SMark de Wever 
424*74a9c6d7SMark de Wever       State.PauseTiming();
425*74a9c6d7SMark de Wever       Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000);
426*74a9c6d7SMark de Wever       State.ResumeTiming();
427*74a9c6d7SMark de Wever     }
428*74a9c6d7SMark de Wever   }
429*74a9c6d7SMark de Wever 
430*74a9c6d7SMark de Wever   template < ::Hint hint>
431*74a9c6d7SMark de Wever   typename std::enable_if<hint != ::Hint::Correct>::type
run__anon8b67eae20111::InsertAssignHint432*74a9c6d7SMark de Wever   run(benchmark::State& State) const {
433*74a9c6d7SMark de Wever     auto Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000);
434*74a9c6d7SMark de Wever     while (State.KeepRunningBatch(MapSize * Data.Maps.size())) {
435*74a9c6d7SMark de Wever       for (size_t I = 0; I < Data.Maps.size(); ++I) {
436*74a9c6d7SMark de Wever         auto& Map = Data.Maps[I];
437*74a9c6d7SMark de Wever         auto Third = *(Data.Hints[I].begin() + 2);
438*74a9c6d7SMark de Wever         for (auto K : Data.Keys) {
439*74a9c6d7SMark de Wever           auto Itor = hint == ::Hint::Begin
440*74a9c6d7SMark de Wever                           ? Map.begin()
441*74a9c6d7SMark de Wever                           : hint == ::Hint::Third ? Third : Map.end();
442*74a9c6d7SMark de Wever #ifndef VALIDATE
443*74a9c6d7SMark de Wever           benchmark::DoNotOptimize(Map.insert_or_assign(Itor, K, 1));
444*74a9c6d7SMark de Wever #else
445*74a9c6d7SMark de Wever           size_t Size = Map.size();
446*74a9c6d7SMark de Wever           Map.insert_or_assign(Itor, K, 1);
447*74a9c6d7SMark de Wever           if (Mode() == ::Mode::Hit) {
448*74a9c6d7SMark de Wever             if (Size != Map.size())
449*74a9c6d7SMark de Wever               State.SkipWithError("Inserted a duplicate element");
450*74a9c6d7SMark de Wever           } else {
451*74a9c6d7SMark de Wever             if (Size + 1 != Map.size())
452*74a9c6d7SMark de Wever               State.SkipWithError("Failed to insert a new element");
453*74a9c6d7SMark de Wever           }
454*74a9c6d7SMark de Wever #endif
455*74a9c6d7SMark de Wever         }
456*74a9c6d7SMark de Wever       }
457*74a9c6d7SMark de Wever 
458*74a9c6d7SMark de Wever       State.PauseTiming();
459*74a9c6d7SMark de Wever       Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000);
460*74a9c6d7SMark de Wever       State.ResumeTiming();
461*74a9c6d7SMark de Wever     }
462*74a9c6d7SMark de Wever   }
463*74a9c6d7SMark de Wever 
run__anon8b67eae20111::InsertAssignHint464*74a9c6d7SMark de Wever   void run(benchmark::State& State) const {
465*74a9c6d7SMark de Wever     static constexpr auto h = Hint();
466*74a9c6d7SMark de Wever     run<h>(State);
467*74a9c6d7SMark de Wever   }
468*74a9c6d7SMark de Wever 
name__anon8b67eae20111::InsertAssignHint469*74a9c6d7SMark de Wever   std::string name() const {
470*74a9c6d7SMark de Wever     return "BM_InsertAssignHint" + baseName() + Mode::name() + Hint::name();
471*74a9c6d7SMark de Wever   }
472*74a9c6d7SMark de Wever };
473*74a9c6d7SMark de Wever 
474*74a9c6d7SMark de Wever template <class Mode, class Order>
475*74a9c6d7SMark de Wever struct Emplace : Base {
476*74a9c6d7SMark de Wever   using Base::Base;
477*74a9c6d7SMark de Wever 
run__anon8b67eae20111::Emplace478*74a9c6d7SMark de Wever   void run(benchmark::State& State) const {
479*74a9c6d7SMark de Wever 
480*74a9c6d7SMark de Wever     auto Data = makeTestingSets(
481*74a9c6d7SMark de Wever         MapSize, Mode(),
482*74a9c6d7SMark de Wever         Order::value == ::Order::Random ? Shuffle::Keys : Shuffle::None, 1000);
483*74a9c6d7SMark de Wever     while (State.KeepRunningBatch(MapSize * Data.Maps.size())) {
484*74a9c6d7SMark de Wever       for (auto& Map : Data.Maps) {
485*74a9c6d7SMark de Wever         for (auto K : Data.Keys) {
486*74a9c6d7SMark de Wever #ifndef VALIDATE
487*74a9c6d7SMark de Wever           benchmark::DoNotOptimize(Map.emplace(K, 1));
488*74a9c6d7SMark de Wever #else
489*74a9c6d7SMark de Wever           bool Inserted = Map.emplace(K, 1).second;
490*74a9c6d7SMark de Wever           if (Mode() == ::Mode::Hit) {
491*74a9c6d7SMark de Wever             if (Inserted)
492*74a9c6d7SMark de Wever               State.SkipWithError("Emplaced a duplicate element");
493*74a9c6d7SMark de Wever           } else {
494*74a9c6d7SMark de Wever             if (!Inserted)
495*74a9c6d7SMark de Wever               State.SkipWithError("Failed to emplace a new element");
496*74a9c6d7SMark de Wever           }
497*74a9c6d7SMark de Wever #endif
498*74a9c6d7SMark de Wever         }
499*74a9c6d7SMark de Wever       }
500*74a9c6d7SMark de Wever 
501*74a9c6d7SMark de Wever       State.PauseTiming();
502*74a9c6d7SMark de Wever       Data = makeTestingSets(MapSize, Mode(),
503*74a9c6d7SMark de Wever                              Order::value == ::Order::Random ? Shuffle::Keys
504*74a9c6d7SMark de Wever                                                              : Shuffle::None,
505*74a9c6d7SMark de Wever                              1000);
506*74a9c6d7SMark de Wever       State.ResumeTiming();
507*74a9c6d7SMark de Wever     }
508*74a9c6d7SMark de Wever   }
509*74a9c6d7SMark de Wever 
name__anon8b67eae20111::Emplace510*74a9c6d7SMark de Wever   std::string name() const {
511*74a9c6d7SMark de Wever     return "BM_Emplace" + baseName() + Mode::name() + Order::name();
512*74a9c6d7SMark de Wever   }
513*74a9c6d7SMark de Wever };
514*74a9c6d7SMark de Wever 
515*74a9c6d7SMark de Wever template <class Mode, class Hint>
516*74a9c6d7SMark de Wever struct EmplaceHint : Base {
517*74a9c6d7SMark de Wever   using Base::Base;
518*74a9c6d7SMark de Wever 
519*74a9c6d7SMark de Wever   template < ::Hint hint>
520*74a9c6d7SMark de Wever   typename std::enable_if<hint == ::Hint::Correct>::type
run__anon8b67eae20111::EmplaceHint521*74a9c6d7SMark de Wever   run(benchmark::State& State) const {
522*74a9c6d7SMark de Wever     auto Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000);
523*74a9c6d7SMark de Wever     while (State.KeepRunningBatch(MapSize * Data.Maps.size())) {
524*74a9c6d7SMark de Wever       for (size_t I = 0; I < Data.Maps.size(); ++I) {
525*74a9c6d7SMark de Wever         auto& Map = Data.Maps[I];
526*74a9c6d7SMark de Wever         auto H = Data.Hints[I].begin();
527*74a9c6d7SMark de Wever         for (auto K : Data.Keys) {
528*74a9c6d7SMark de Wever #ifndef VALIDATE
529*74a9c6d7SMark de Wever           benchmark::DoNotOptimize(Map.emplace_hint(*H, K, 1));
530*74a9c6d7SMark de Wever #else
531*74a9c6d7SMark de Wever           auto Inserted = Map.emplace_hint(*H, K, 1);
532*74a9c6d7SMark de Wever           if (Mode() == ::Mode::Hit) {
533*74a9c6d7SMark de Wever             if (Inserted != *H)
534*74a9c6d7SMark de Wever               State.SkipWithError("Emplaced a duplicate element");
535*74a9c6d7SMark de Wever           } else {
536*74a9c6d7SMark de Wever             if (++Inserted != *H)
537*74a9c6d7SMark de Wever               State.SkipWithError("Failed to emplace a new element");
538*74a9c6d7SMark de Wever           }
539*74a9c6d7SMark de Wever #endif
540*74a9c6d7SMark de Wever           ++H;
541*74a9c6d7SMark de Wever         }
542*74a9c6d7SMark de Wever       }
543*74a9c6d7SMark de Wever 
544*74a9c6d7SMark de Wever       State.PauseTiming();
545*74a9c6d7SMark de Wever       Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000);
546*74a9c6d7SMark de Wever       State.ResumeTiming();
547*74a9c6d7SMark de Wever     }
548*74a9c6d7SMark de Wever   }
549*74a9c6d7SMark de Wever 
550*74a9c6d7SMark de Wever   template < ::Hint hint>
551*74a9c6d7SMark de Wever   typename std::enable_if<hint != ::Hint::Correct>::type
run__anon8b67eae20111::EmplaceHint552*74a9c6d7SMark de Wever   run(benchmark::State& State) const {
553*74a9c6d7SMark de Wever     auto Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000);
554*74a9c6d7SMark de Wever     while (State.KeepRunningBatch(MapSize * Data.Maps.size())) {
555*74a9c6d7SMark de Wever       for (size_t I = 0; I < Data.Maps.size(); ++I) {
556*74a9c6d7SMark de Wever         auto& Map = Data.Maps[I];
557*74a9c6d7SMark de Wever         auto Third = *(Data.Hints[I].begin() + 2);
558*74a9c6d7SMark de Wever         for (auto K : Data.Keys) {
559*74a9c6d7SMark de Wever           auto Itor = hint == ::Hint::Begin
560*74a9c6d7SMark de Wever                           ? Map.begin()
561*74a9c6d7SMark de Wever                           : hint == ::Hint::Third ? Third : Map.end();
562*74a9c6d7SMark de Wever #ifndef VALIDATE
563*74a9c6d7SMark de Wever           benchmark::DoNotOptimize(Map.emplace_hint(Itor, K, 1));
564*74a9c6d7SMark de Wever #else
565*74a9c6d7SMark de Wever           size_t Size = Map.size();
566*74a9c6d7SMark de Wever           Map.emplace_hint(Itor, K, 1);
567*74a9c6d7SMark de Wever           if (Mode() == ::Mode::Hit) {
568*74a9c6d7SMark de Wever             if (Size != Map.size())
569*74a9c6d7SMark de Wever               State.SkipWithError("Emplaced a duplicate element");
570*74a9c6d7SMark de Wever           } else {
571*74a9c6d7SMark de Wever             if (Size + 1 != Map.size())
572*74a9c6d7SMark de Wever               State.SkipWithError("Failed to emplace a new element");
573*74a9c6d7SMark de Wever           }
574*74a9c6d7SMark de Wever #endif
575*74a9c6d7SMark de Wever         }
576*74a9c6d7SMark de Wever       }
577*74a9c6d7SMark de Wever 
578*74a9c6d7SMark de Wever       State.PauseTiming();
579*74a9c6d7SMark de Wever       Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000);
580*74a9c6d7SMark de Wever       State.ResumeTiming();
581*74a9c6d7SMark de Wever     }
582*74a9c6d7SMark de Wever   }
583*74a9c6d7SMark de Wever 
run__anon8b67eae20111::EmplaceHint584*74a9c6d7SMark de Wever   void run(benchmark::State& State) const {
585*74a9c6d7SMark de Wever     static constexpr auto h = Hint();
586*74a9c6d7SMark de Wever     run<h>(State);
587*74a9c6d7SMark de Wever   }
588*74a9c6d7SMark de Wever 
name__anon8b67eae20111::EmplaceHint589*74a9c6d7SMark de Wever   std::string name() const {
590*74a9c6d7SMark de Wever     return "BM_EmplaceHint" + baseName() + Mode::name() + Hint::name();
591*74a9c6d7SMark de Wever   }
592*74a9c6d7SMark de Wever };
593*74a9c6d7SMark de Wever 
594*74a9c6d7SMark de Wever template <class Mode, class Order>
595*74a9c6d7SMark de Wever struct TryEmplace : Base {
596*74a9c6d7SMark de Wever   using Base::Base;
597*74a9c6d7SMark de Wever 
run__anon8b67eae20111::TryEmplace598*74a9c6d7SMark de Wever   void run(benchmark::State& State) const {
599*74a9c6d7SMark de Wever 
600*74a9c6d7SMark de Wever     auto Data = makeTestingSets(
601*74a9c6d7SMark de Wever         MapSize, Mode(),
602*74a9c6d7SMark de Wever         Order::value == ::Order::Random ? Shuffle::Keys : Shuffle::None, 1000);
603*74a9c6d7SMark de Wever     while (State.KeepRunningBatch(MapSize * Data.Maps.size())) {
604*74a9c6d7SMark de Wever       for (auto& Map : Data.Maps) {
605*74a9c6d7SMark de Wever         for (auto K : Data.Keys) {
606*74a9c6d7SMark de Wever #ifndef VALIDATE
607*74a9c6d7SMark de Wever           benchmark::DoNotOptimize(Map.try_emplace(K, 1));
608*74a9c6d7SMark de Wever #else
609*74a9c6d7SMark de Wever           bool Inserted = Map.try_emplace(K, 1).second;
610*74a9c6d7SMark de Wever           if (Mode() == ::Mode::Hit) {
611*74a9c6d7SMark de Wever             if (Inserted)
612*74a9c6d7SMark de Wever               State.SkipWithError("Emplaced a duplicate element");
613*74a9c6d7SMark de Wever           } else {
614*74a9c6d7SMark de Wever             if (!Inserted)
615*74a9c6d7SMark de Wever               State.SkipWithError("Failed to emplace a new element");
616*74a9c6d7SMark de Wever           }
617*74a9c6d7SMark de Wever #endif
618*74a9c6d7SMark de Wever         }
619*74a9c6d7SMark de Wever       }
620*74a9c6d7SMark de Wever 
621*74a9c6d7SMark de Wever       State.PauseTiming();
622*74a9c6d7SMark de Wever       Data = makeTestingSets(MapSize, Mode(),
623*74a9c6d7SMark de Wever                              Order::value == ::Order::Random ? Shuffle::Keys
624*74a9c6d7SMark de Wever                                                              : Shuffle::None,
625*74a9c6d7SMark de Wever                              1000);
626*74a9c6d7SMark de Wever       State.ResumeTiming();
627*74a9c6d7SMark de Wever     }
628*74a9c6d7SMark de Wever   }
629*74a9c6d7SMark de Wever 
name__anon8b67eae20111::TryEmplace630*74a9c6d7SMark de Wever   std::string name() const {
631*74a9c6d7SMark de Wever     return "BM_TryEmplace" + baseName() + Mode::name() + Order::name();
632*74a9c6d7SMark de Wever   }
633*74a9c6d7SMark de Wever };
634*74a9c6d7SMark de Wever 
635*74a9c6d7SMark de Wever template <class Mode, class Hint>
636*74a9c6d7SMark de Wever struct TryEmplaceHint : Base {
637*74a9c6d7SMark de Wever   using Base::Base;
638*74a9c6d7SMark de Wever 
639*74a9c6d7SMark de Wever   template < ::Hint hint>
640*74a9c6d7SMark de Wever   typename std::enable_if<hint == ::Hint::Correct>::type
run__anon8b67eae20111::TryEmplaceHint641*74a9c6d7SMark de Wever   run(benchmark::State& State) const {
642*74a9c6d7SMark de Wever     auto Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000);
643*74a9c6d7SMark de Wever     while (State.KeepRunningBatch(MapSize * Data.Maps.size())) {
644*74a9c6d7SMark de Wever       for (size_t I = 0; I < Data.Maps.size(); ++I) {
645*74a9c6d7SMark de Wever         auto& Map = Data.Maps[I];
646*74a9c6d7SMark de Wever         auto H = Data.Hints[I].begin();
647*74a9c6d7SMark de Wever         for (auto K : Data.Keys) {
648*74a9c6d7SMark de Wever #ifndef VALIDATE
649*74a9c6d7SMark de Wever           benchmark::DoNotOptimize(Map.try_emplace(*H, K, 1));
650*74a9c6d7SMark de Wever #else
651*74a9c6d7SMark de Wever           auto Inserted = Map.try_emplace(*H, K, 1);
652*74a9c6d7SMark de Wever           if (Mode() == ::Mode::Hit) {
653*74a9c6d7SMark de Wever             if (Inserted != *H)
654*74a9c6d7SMark de Wever               State.SkipWithError("Emplaced a duplicate element");
655*74a9c6d7SMark de Wever           } else {
656*74a9c6d7SMark de Wever             if (++Inserted != *H)
657*74a9c6d7SMark de Wever               State.SkipWithError("Failed to emplace a new element");
658*74a9c6d7SMark de Wever           }
659*74a9c6d7SMark de Wever #endif
660*74a9c6d7SMark de Wever           ++H;
661*74a9c6d7SMark de Wever         }
662*74a9c6d7SMark de Wever       }
663*74a9c6d7SMark de Wever 
664*74a9c6d7SMark de Wever       State.PauseTiming();
665*74a9c6d7SMark de Wever       Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000);
666*74a9c6d7SMark de Wever       State.ResumeTiming();
667*74a9c6d7SMark de Wever     }
668*74a9c6d7SMark de Wever   }
669*74a9c6d7SMark de Wever 
670*74a9c6d7SMark de Wever   template < ::Hint hint>
671*74a9c6d7SMark de Wever   typename std::enable_if<hint != ::Hint::Correct>::type
run__anon8b67eae20111::TryEmplaceHint672*74a9c6d7SMark de Wever   run(benchmark::State& State) const {
673*74a9c6d7SMark de Wever     auto Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000);
674*74a9c6d7SMark de Wever     while (State.KeepRunningBatch(MapSize * Data.Maps.size())) {
675*74a9c6d7SMark de Wever       for (size_t I = 0; I < Data.Maps.size(); ++I) {
676*74a9c6d7SMark de Wever         auto& Map = Data.Maps[I];
677*74a9c6d7SMark de Wever         auto Third = *(Data.Hints[I].begin() + 2);
678*74a9c6d7SMark de Wever         for (auto K : Data.Keys) {
679*74a9c6d7SMark de Wever           auto Itor = hint == ::Hint::Begin
680*74a9c6d7SMark de Wever                           ? Map.begin()
681*74a9c6d7SMark de Wever                           : hint == ::Hint::Third ? Third : Map.end();
682*74a9c6d7SMark de Wever #ifndef VALIDATE
683*74a9c6d7SMark de Wever           benchmark::DoNotOptimize(Map.try_emplace(Itor, K, 1));
684*74a9c6d7SMark de Wever #else
685*74a9c6d7SMark de Wever           size_t Size = Map.size();
686*74a9c6d7SMark de Wever           Map.try_emplace(Itor, K, 1);
687*74a9c6d7SMark de Wever           if (Mode() == ::Mode::Hit) {
688*74a9c6d7SMark de Wever             if (Size != Map.size())
689*74a9c6d7SMark de Wever               State.SkipWithError("Emplaced a duplicate element");
690*74a9c6d7SMark de Wever           } else {
691*74a9c6d7SMark de Wever             if (Size + 1 != Map.size())
692*74a9c6d7SMark de Wever               State.SkipWithError("Failed to emplace a new element");
693*74a9c6d7SMark de Wever           }
694*74a9c6d7SMark de Wever #endif
695*74a9c6d7SMark de Wever         }
696*74a9c6d7SMark de Wever       }
697*74a9c6d7SMark de Wever 
698*74a9c6d7SMark de Wever       State.PauseTiming();
699*74a9c6d7SMark de Wever       Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000);
700*74a9c6d7SMark de Wever       State.ResumeTiming();
701*74a9c6d7SMark de Wever     }
702*74a9c6d7SMark de Wever   }
703*74a9c6d7SMark de Wever 
run__anon8b67eae20111::TryEmplaceHint704*74a9c6d7SMark de Wever   void run(benchmark::State& State) const {
705*74a9c6d7SMark de Wever     static constexpr auto h = Hint();
706*74a9c6d7SMark de Wever     run<h>(State);
707*74a9c6d7SMark de Wever   }
708*74a9c6d7SMark de Wever 
name__anon8b67eae20111::TryEmplaceHint709*74a9c6d7SMark de Wever   std::string name() const {
710*74a9c6d7SMark de Wever     return "BM_TryEmplaceHint" + baseName() + Mode::name() + Hint::name();
711*74a9c6d7SMark de Wever   }
712*74a9c6d7SMark de Wever };
713*74a9c6d7SMark de Wever 
714*74a9c6d7SMark de Wever template <class Mode, class Order>
715*74a9c6d7SMark de Wever struct Erase : Base {
716*74a9c6d7SMark de Wever   using Base::Base;
717*74a9c6d7SMark de Wever 
run__anon8b67eae20111::Erase718*74a9c6d7SMark de Wever   void run(benchmark::State& State) const {
719*74a9c6d7SMark de Wever     auto Data = makeTestingSets(
720*74a9c6d7SMark de Wever         MapSize, Mode(),
721*74a9c6d7SMark de Wever         Order::value == ::Order::Random ? Shuffle::Keys : Shuffle::None, 1000);
722*74a9c6d7SMark de Wever     while (State.KeepRunningBatch(MapSize * Data.Maps.size())) {
723*74a9c6d7SMark de Wever       for (auto& Map : Data.Maps) {
724*74a9c6d7SMark de Wever         for (auto K : Data.Keys) {
725*74a9c6d7SMark de Wever #ifndef VALIDATE
726*74a9c6d7SMark de Wever           benchmark::DoNotOptimize(Map.erase(K));
727*74a9c6d7SMark de Wever #else
728*74a9c6d7SMark de Wever           size_t I = Map.erase(K);
729*74a9c6d7SMark de Wever           if (Mode() == ::Mode::Hit) {
730*74a9c6d7SMark de Wever             if (I == 0)
731*74a9c6d7SMark de Wever               State.SkipWithError("Did not find the existing element");
732*74a9c6d7SMark de Wever           } else {
733*74a9c6d7SMark de Wever             if (I == 1)
734*74a9c6d7SMark de Wever               State.SkipWithError("Did find the non-existing element");
735*74a9c6d7SMark de Wever           }
736*74a9c6d7SMark de Wever #endif
737*74a9c6d7SMark de Wever         }
738*74a9c6d7SMark de Wever       }
739*74a9c6d7SMark de Wever 
740*74a9c6d7SMark de Wever       State.PauseTiming();
741*74a9c6d7SMark de Wever       Data = makeTestingSets(MapSize, Mode(),
742*74a9c6d7SMark de Wever                              Order::value == ::Order::Random ? Shuffle::Keys
743*74a9c6d7SMark de Wever                                                              : Shuffle::None,
744*74a9c6d7SMark de Wever                              1000);
745*74a9c6d7SMark de Wever       State.ResumeTiming();
746*74a9c6d7SMark de Wever     }
747*74a9c6d7SMark de Wever   }
748*74a9c6d7SMark de Wever 
name__anon8b67eae20111::Erase749*74a9c6d7SMark de Wever   std::string name() const {
750*74a9c6d7SMark de Wever     return "BM_Erase" + baseName() + Mode::name() + Order::name();
751*74a9c6d7SMark de Wever   }
752*74a9c6d7SMark de Wever };
753*74a9c6d7SMark de Wever 
754*74a9c6d7SMark de Wever template <class Order>
755*74a9c6d7SMark de Wever struct EraseIterator : Base {
756*74a9c6d7SMark de Wever   using Base::Base;
757*74a9c6d7SMark de Wever 
run__anon8b67eae20111::EraseIterator758*74a9c6d7SMark de Wever   void run(benchmark::State& State) const {
759*74a9c6d7SMark de Wever     auto Data = makeTestingSets(
760*74a9c6d7SMark de Wever         MapSize, Mode::Hit,
761*74a9c6d7SMark de Wever         Order::value == ::Order::Random ? Shuffle::Hints : Shuffle::None, 1000);
762*74a9c6d7SMark de Wever     while (State.KeepRunningBatch(MapSize * Data.Maps.size())) {
763*74a9c6d7SMark de Wever       for (size_t I = 0; I < Data.Maps.size(); ++I) {
764*74a9c6d7SMark de Wever         auto& Map = Data.Maps[I];
765*74a9c6d7SMark de Wever         for (auto H : Data.Hints[I]) {
766*74a9c6d7SMark de Wever           benchmark::DoNotOptimize(Map.erase(H));
767*74a9c6d7SMark de Wever         }
768*74a9c6d7SMark de Wever #ifdef VALIDATE
769*74a9c6d7SMark de Wever         if (!Map.empty())
770*74a9c6d7SMark de Wever           State.SkipWithError("Did not erase the entire map");
771*74a9c6d7SMark de Wever #endif
772*74a9c6d7SMark de Wever       }
773*74a9c6d7SMark de Wever 
774*74a9c6d7SMark de Wever       State.PauseTiming();
775*74a9c6d7SMark de Wever       Data = makeTestingSets(MapSize, Mode::Hit,
776*74a9c6d7SMark de Wever                              Order::value == ::Order::Random ? Shuffle::Hints
777*74a9c6d7SMark de Wever                                                              : Shuffle::None,
778*74a9c6d7SMark de Wever                              1000);
779*74a9c6d7SMark de Wever       State.ResumeTiming();
780*74a9c6d7SMark de Wever     }
781*74a9c6d7SMark de Wever   }
782*74a9c6d7SMark de Wever 
name__anon8b67eae20111::EraseIterator783*74a9c6d7SMark de Wever   std::string name() const {
784*74a9c6d7SMark de Wever     return "BM_EraseIterator" + baseName() + Order::name();
785*74a9c6d7SMark de Wever   }
786*74a9c6d7SMark de Wever };
787*74a9c6d7SMark de Wever 
788*74a9c6d7SMark de Wever struct EraseRange : Base {
789*74a9c6d7SMark de Wever   using Base::Base;
790*74a9c6d7SMark de Wever 
run__anon8b67eae20111::EraseRange791*74a9c6d7SMark de Wever   void run(benchmark::State& State) const {
792*74a9c6d7SMark de Wever     auto Data = makeTestingSets(MapSize, Mode::Hit, Shuffle::None, 1000);
793*74a9c6d7SMark de Wever     while (State.KeepRunningBatch(MapSize * Data.Maps.size())) {
794*74a9c6d7SMark de Wever       for (auto& Map : Data.Maps) {
795*74a9c6d7SMark de Wever #ifndef VALIDATE
796*74a9c6d7SMark de Wever         benchmark::DoNotOptimize(Map.erase(Map.begin(), Map.end()));
797*74a9c6d7SMark de Wever #else
798*74a9c6d7SMark de Wever         Map.erase(Map.begin(), Map.end());
799*74a9c6d7SMark de Wever         if (!Map.empty())
800*74a9c6d7SMark de Wever           State.SkipWithError("Did not erase the entire map");
801*74a9c6d7SMark de Wever #endif
802*74a9c6d7SMark de Wever       }
803*74a9c6d7SMark de Wever 
804*74a9c6d7SMark de Wever       State.PauseTiming();
805*74a9c6d7SMark de Wever       Data = makeTestingSets(MapSize, Mode::Hit, Shuffle::None, 1000);
806*74a9c6d7SMark de Wever       State.ResumeTiming();
807*74a9c6d7SMark de Wever     }
808*74a9c6d7SMark de Wever   }
809*74a9c6d7SMark de Wever 
name__anon8b67eae20111::EraseRange810*74a9c6d7SMark de Wever   std::string name() const { return "BM_EraseRange" + baseName(); }
811*74a9c6d7SMark de Wever };
812*74a9c6d7SMark de Wever 
813*74a9c6d7SMark de Wever //*******************************************************************|
814*74a9c6d7SMark de Wever //                            Lookup                                 |
815*74a9c6d7SMark de Wever //*******************************************************************|
816*74a9c6d7SMark de Wever 
817*74a9c6d7SMark de Wever template <class Mode, class Order>
818*74a9c6d7SMark de Wever struct Count : Base {
819*74a9c6d7SMark de Wever   using Base::Base;
820*74a9c6d7SMark de Wever 
run__anon8b67eae20111::Count821*74a9c6d7SMark de Wever   void run(benchmark::State& State) const {
822*74a9c6d7SMark de Wever     auto Data = makeTestingSets(
823*74a9c6d7SMark de Wever         MapSize, Mode(),
824*74a9c6d7SMark de Wever         Order::value == ::Order::Random ? Shuffle::Keys : Shuffle::None, 1);
825*74a9c6d7SMark de Wever     auto& Map = Data.Maps.front();
826*74a9c6d7SMark de Wever     while (State.KeepRunningBatch(MapSize)) {
827*74a9c6d7SMark de Wever       for (auto K : Data.Keys) {
828*74a9c6d7SMark de Wever #ifndef VALIDATE
829*74a9c6d7SMark de Wever         benchmark::DoNotOptimize(Map.count(K));
830*74a9c6d7SMark de Wever #else
831*74a9c6d7SMark de Wever         size_t I = Map.count(K);
832*74a9c6d7SMark de Wever         if (Mode() == ::Mode::Hit) {
833*74a9c6d7SMark de Wever           if (I == 0)
834*74a9c6d7SMark de Wever             State.SkipWithError("Did not find the existing element");
835*74a9c6d7SMark de Wever         } else {
836*74a9c6d7SMark de Wever           if (I == 1)
837*74a9c6d7SMark de Wever             State.SkipWithError("Did find the non-existing element");
838*74a9c6d7SMark de Wever         }
839*74a9c6d7SMark de Wever #endif
840*74a9c6d7SMark de Wever       }
841*74a9c6d7SMark de Wever     }
842*74a9c6d7SMark de Wever   }
843*74a9c6d7SMark de Wever 
name__anon8b67eae20111::Count844*74a9c6d7SMark de Wever   std::string name() const {
845*74a9c6d7SMark de Wever     return "BM_Count" + baseName() + Mode::name() + Order::name();
846*74a9c6d7SMark de Wever   }
847*74a9c6d7SMark de Wever };
848*74a9c6d7SMark de Wever 
849*74a9c6d7SMark de Wever template <class Mode, class Order>
850*74a9c6d7SMark de Wever struct Find : Base {
851*74a9c6d7SMark de Wever   using Base::Base;
852*74a9c6d7SMark de Wever 
run__anon8b67eae20111::Find853*74a9c6d7SMark de Wever   void run(benchmark::State& State) const {
854*74a9c6d7SMark de Wever     auto Data = makeTestingSets(
855*74a9c6d7SMark de Wever         MapSize, Mode(),
856*74a9c6d7SMark de Wever         Order::value == ::Order::Random ? Shuffle::Keys : Shuffle::None, 1);
857*74a9c6d7SMark de Wever     auto& Map = Data.Maps.front();
858*74a9c6d7SMark de Wever     while (State.KeepRunningBatch(MapSize)) {
859*74a9c6d7SMark de Wever       for (auto K : Data.Keys) {
860*74a9c6d7SMark de Wever #ifndef VALIDATE
861*74a9c6d7SMark de Wever         benchmark::DoNotOptimize(Map.find(K));
862*74a9c6d7SMark de Wever #else
863*74a9c6d7SMark de Wever         auto Itor = Map.find(K);
864*74a9c6d7SMark de Wever         if (Mode() == ::Mode::Hit) {
865*74a9c6d7SMark de Wever           if (Itor == Map.end())
866*74a9c6d7SMark de Wever             State.SkipWithError("Did not find the existing element");
867*74a9c6d7SMark de Wever         } else {
868*74a9c6d7SMark de Wever           if (Itor != Map.end())
869*74a9c6d7SMark de Wever             State.SkipWithError("Did find the non-existing element");
870*74a9c6d7SMark de Wever         }
871*74a9c6d7SMark de Wever #endif
872*74a9c6d7SMark de Wever       }
873*74a9c6d7SMark de Wever     }
874*74a9c6d7SMark de Wever   }
875*74a9c6d7SMark de Wever 
name__anon8b67eae20111::Find876*74a9c6d7SMark de Wever   std::string name() const {
877*74a9c6d7SMark de Wever     return "BM_Find" + baseName() + Mode::name() + Order::name();
878*74a9c6d7SMark de Wever   }
879*74a9c6d7SMark de Wever };
880*74a9c6d7SMark de Wever 
881*74a9c6d7SMark de Wever template <class Mode, class Order>
882*74a9c6d7SMark de Wever struct EqualRange : Base {
883*74a9c6d7SMark de Wever   using Base::Base;
884*74a9c6d7SMark de Wever 
run__anon8b67eae20111::EqualRange885*74a9c6d7SMark de Wever   void run(benchmark::State& State) const {
886*74a9c6d7SMark de Wever     auto Data = makeTestingSets(
887*74a9c6d7SMark de Wever         MapSize, Mode(),
888*74a9c6d7SMark de Wever         Order::value == ::Order::Random ? Shuffle::Keys : Shuffle::None, 1);
889*74a9c6d7SMark de Wever     auto& Map = Data.Maps.front();
890*74a9c6d7SMark de Wever     while (State.KeepRunningBatch(MapSize)) {
891*74a9c6d7SMark de Wever       for (auto K : Data.Keys) {
892*74a9c6d7SMark de Wever #ifndef VALIDATE
893*74a9c6d7SMark de Wever         benchmark::DoNotOptimize(Map.equal_range(K));
894*74a9c6d7SMark de Wever #else
895*74a9c6d7SMark de Wever         auto Range = Map.equal_range(K);
896*74a9c6d7SMark de Wever         if (Mode() == ::Mode::Hit) {
897*74a9c6d7SMark de Wever           // Adjust validation for the last element.
898*74a9c6d7SMark de Wever           auto Key = K;
899*74a9c6d7SMark de Wever           if (Range.second == Map.end() && K == 2 * MapSize) {
900*74a9c6d7SMark de Wever             --Range.second;
901*74a9c6d7SMark de Wever             Key -= 2;
902*74a9c6d7SMark de Wever           }
903*74a9c6d7SMark de Wever           if (Range.first == Map.end() || Range.first->first != K ||
904*74a9c6d7SMark de Wever               Range.second == Map.end() || Range.second->first - 2 != Key)
905*74a9c6d7SMark de Wever             State.SkipWithError("Did not find the existing element");
906*74a9c6d7SMark de Wever         } else {
907*74a9c6d7SMark de Wever           if (Range.first == Map.end() || Range.first->first - 1 != K ||
908*74a9c6d7SMark de Wever               Range.second == Map.end() || Range.second->first - 1 != K)
909*74a9c6d7SMark de Wever             State.SkipWithError("Did find the non-existing element");
910*74a9c6d7SMark de Wever         }
911*74a9c6d7SMark de Wever #endif
912*74a9c6d7SMark de Wever       }
913*74a9c6d7SMark de Wever     }
914*74a9c6d7SMark de Wever   }
915*74a9c6d7SMark de Wever 
name__anon8b67eae20111::EqualRange916*74a9c6d7SMark de Wever   std::string name() const {
917*74a9c6d7SMark de Wever     return "BM_EqualRange" + baseName() + Mode::name() + Order::name();
918*74a9c6d7SMark de Wever   }
919*74a9c6d7SMark de Wever };
920*74a9c6d7SMark de Wever 
921*74a9c6d7SMark de Wever template <class Mode, class Order>
922*74a9c6d7SMark de Wever struct LowerBound : Base {
923*74a9c6d7SMark de Wever   using Base::Base;
924*74a9c6d7SMark de Wever 
run__anon8b67eae20111::LowerBound925*74a9c6d7SMark de Wever   void run(benchmark::State& State) const {
926*74a9c6d7SMark de Wever     auto Data = makeTestingSets(
927*74a9c6d7SMark de Wever         MapSize, Mode(),
928*74a9c6d7SMark de Wever         Order::value == ::Order::Random ? Shuffle::Keys : Shuffle::None, 1);
929*74a9c6d7SMark de Wever     auto& Map = Data.Maps.front();
930*74a9c6d7SMark de Wever     while (State.KeepRunningBatch(MapSize)) {
931*74a9c6d7SMark de Wever       for (auto K : Data.Keys) {
932*74a9c6d7SMark de Wever #ifndef VALIDATE
933*74a9c6d7SMark de Wever         benchmark::DoNotOptimize(Map.lower_bound(K));
934*74a9c6d7SMark de Wever #else
935*74a9c6d7SMark de Wever         auto Itor = Map.lower_bound(K);
936*74a9c6d7SMark de Wever         if (Mode() == ::Mode::Hit) {
937*74a9c6d7SMark de Wever           if (Itor == Map.end() || Itor->first != K)
938*74a9c6d7SMark de Wever             State.SkipWithError("Did not find the existing element");
939*74a9c6d7SMark de Wever         } else {
940*74a9c6d7SMark de Wever           if (Itor == Map.end() || Itor->first - 1 != K)
941*74a9c6d7SMark de Wever             State.SkipWithError("Did find the non-existing element");
942*74a9c6d7SMark de Wever         }
943*74a9c6d7SMark de Wever #endif
944*74a9c6d7SMark de Wever       }
945*74a9c6d7SMark de Wever     }
946*74a9c6d7SMark de Wever   }
947*74a9c6d7SMark de Wever 
name__anon8b67eae20111::LowerBound948*74a9c6d7SMark de Wever   std::string name() const {
949*74a9c6d7SMark de Wever     return "BM_LowerBound" + baseName() + Mode::name() + Order::name();
950*74a9c6d7SMark de Wever   }
951*74a9c6d7SMark de Wever };
952*74a9c6d7SMark de Wever 
953*74a9c6d7SMark de Wever template <class Mode, class Order>
954*74a9c6d7SMark de Wever struct UpperBound : Base {
955*74a9c6d7SMark de Wever   using Base::Base;
956*74a9c6d7SMark de Wever 
run__anon8b67eae20111::UpperBound957*74a9c6d7SMark de Wever   void run(benchmark::State& State) const {
958*74a9c6d7SMark de Wever     auto Data = makeTestingSets(
959*74a9c6d7SMark de Wever         MapSize, Mode(),
960*74a9c6d7SMark de Wever         Order::value == ::Order::Random ? Shuffle::Keys : Shuffle::None, 1);
961*74a9c6d7SMark de Wever     auto& Map = Data.Maps.front();
962*74a9c6d7SMark de Wever     while (State.KeepRunningBatch(MapSize)) {
963*74a9c6d7SMark de Wever       for (auto K : Data.Keys) {
964*74a9c6d7SMark de Wever #ifndef VALIDATE
965*74a9c6d7SMark de Wever         benchmark::DoNotOptimize(Map.upper_bound(K));
966*74a9c6d7SMark de Wever #else
967*74a9c6d7SMark de Wever         std::map<uint64_t, int64_t>::iterator Itor = Map.upper_bound(K);
968*74a9c6d7SMark de Wever         if (Mode() == ::Mode::Hit) {
969*74a9c6d7SMark de Wever           // Adjust validation for the last element.
970*74a9c6d7SMark de Wever           auto Key = K;
971*74a9c6d7SMark de Wever           if (Itor == Map.end() && K == 2 * MapSize) {
972*74a9c6d7SMark de Wever             --Itor;
973*74a9c6d7SMark de Wever             Key -= 2;
974*74a9c6d7SMark de Wever           }
975*74a9c6d7SMark de Wever           if (Itor == Map.end() || Itor->first - 2 != Key)
976*74a9c6d7SMark de Wever             State.SkipWithError("Did not find the existing element");
977*74a9c6d7SMark de Wever         } else {
978*74a9c6d7SMark de Wever           if (Itor == Map.end() || Itor->first - 1 != K)
979*74a9c6d7SMark de Wever             State.SkipWithError("Did find the non-existing element");
980*74a9c6d7SMark de Wever         }
981*74a9c6d7SMark de Wever #endif
982*74a9c6d7SMark de Wever       }
983*74a9c6d7SMark de Wever     }
984*74a9c6d7SMark de Wever   }
985*74a9c6d7SMark de Wever 
name__anon8b67eae20111::UpperBound986*74a9c6d7SMark de Wever   std::string name() const {
987*74a9c6d7SMark de Wever     return "BM_UpperBound" + baseName() + Mode::name() + Order::name();
988*74a9c6d7SMark de Wever   }
989*74a9c6d7SMark de Wever };
990*74a9c6d7SMark de Wever 
991*74a9c6d7SMark de Wever } // namespace
992*74a9c6d7SMark de Wever 
main(int argc,char ** argv)993*74a9c6d7SMark de Wever int main(int argc, char** argv) {
994*74a9c6d7SMark de Wever   benchmark::Initialize(&argc, argv);
995*74a9c6d7SMark de Wever   if (benchmark::ReportUnrecognizedArguments(argc, argv))
996*74a9c6d7SMark de Wever     return 1;
997*74a9c6d7SMark de Wever 
998*74a9c6d7SMark de Wever #ifdef VALIDATE
999*74a9c6d7SMark de Wever   const std::vector<size_t> MapSize{10};
1000*74a9c6d7SMark de Wever #else
1001*74a9c6d7SMark de Wever   const std::vector<size_t> MapSize{10, 100, 1000, 10000, 100000, 1000000};
1002*74a9c6d7SMark de Wever #endif
1003*74a9c6d7SMark de Wever 
1004*74a9c6d7SMark de Wever   // Member functions
1005*74a9c6d7SMark de Wever   makeCartesianProductBenchmark<ConstructorDefault>();
1006*74a9c6d7SMark de Wever   makeCartesianProductBenchmark<ConstructorIterator>(MapSize);
1007*74a9c6d7SMark de Wever   makeCartesianProductBenchmark<ConstructorCopy>(MapSize);
1008*74a9c6d7SMark de Wever   makeCartesianProductBenchmark<ConstructorMove>(MapSize);
1009*74a9c6d7SMark de Wever 
1010*74a9c6d7SMark de Wever   // Capacity
1011*74a9c6d7SMark de Wever   makeCartesianProductBenchmark<Empty>(MapSize);
1012*74a9c6d7SMark de Wever   makeCartesianProductBenchmark<Size>(MapSize);
1013*74a9c6d7SMark de Wever 
1014*74a9c6d7SMark de Wever   // Modifiers
1015*74a9c6d7SMark de Wever   makeCartesianProductBenchmark<Clear>(MapSize);
1016*74a9c6d7SMark de Wever   makeCartesianProductBenchmark<Insert, AllModes, AllOrders>(MapSize);
1017*74a9c6d7SMark de Wever   makeCartesianProductBenchmark<InsertHint, AllModes, AllHints>(MapSize);
1018*74a9c6d7SMark de Wever   makeCartesianProductBenchmark<InsertAssign, AllModes, AllOrders>(MapSize);
1019*74a9c6d7SMark de Wever   makeCartesianProductBenchmark<InsertAssignHint, AllModes, AllHints>(MapSize);
1020*74a9c6d7SMark de Wever 
1021*74a9c6d7SMark de Wever   makeCartesianProductBenchmark<Emplace, AllModes, AllOrders>(MapSize);
1022*74a9c6d7SMark de Wever   makeCartesianProductBenchmark<EmplaceHint, AllModes, AllHints>(MapSize);
1023*74a9c6d7SMark de Wever   makeCartesianProductBenchmark<TryEmplace, AllModes, AllOrders>(MapSize);
1024*74a9c6d7SMark de Wever   makeCartesianProductBenchmark<TryEmplaceHint, AllModes, AllHints>(MapSize);
1025*74a9c6d7SMark de Wever   makeCartesianProductBenchmark<Erase, AllModes, AllOrders>(MapSize);
1026*74a9c6d7SMark de Wever   makeCartesianProductBenchmark<EraseIterator, AllOrders>(MapSize);
1027*74a9c6d7SMark de Wever   makeCartesianProductBenchmark<EraseRange>(MapSize);
1028*74a9c6d7SMark de Wever 
1029*74a9c6d7SMark de Wever   // Lookup
1030*74a9c6d7SMark de Wever   makeCartesianProductBenchmark<Count, AllModes, AllOrders>(MapSize);
1031*74a9c6d7SMark de Wever   makeCartesianProductBenchmark<Find, AllModes, AllOrders>(MapSize);
1032*74a9c6d7SMark de Wever   makeCartesianProductBenchmark<EqualRange, AllModes, AllOrders>(MapSize);
1033*74a9c6d7SMark de Wever   makeCartesianProductBenchmark<LowerBound, AllModes, AllOrders>(MapSize);
1034*74a9c6d7SMark de Wever   makeCartesianProductBenchmark<UpperBound, AllModes, AllOrders>(MapSize);
1035*74a9c6d7SMark de Wever 
1036*74a9c6d7SMark de Wever   benchmark::RunSpecifiedBenchmarks();
1037*74a9c6d7SMark de Wever }
1038