//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include <algorithm>
#include <cstdint>
#include <map>
#include <random>
#include <vector>

#include "CartesianBenchmarks.h"
#include "benchmark/benchmark.h"
#include "test_macros.h"

// When VALIDATE is defined the benchmark will run to validate the benchmarks.
// The time taken by several operations depend on whether or not an element
// exists. To avoid errors in the benchmark these operations have a validation
// mode to test the benchmark. Since they are not meant to be benchmarked the
// number of sizes tested is limited to 1.
//#define VALIDATE

namespace {

enum class Mode { Hit, Miss };

struct AllModes : EnumValuesAsTuple<AllModes, Mode, 2> {
  static constexpr const char* Names[] = {"ExistingElement", "NewElement"};
};

// The positions of the hints to pick:
// - Begin picks the first item. The item cannot be put before this element.
// - Thrid picks the third item. This is just an element with a valid entry
//   before and after it.
// - Correct contains the correct hint.
// - End contains a hint to the end of the map.
enum class Hint { Begin, Third, Correct, End };
struct AllHints : EnumValuesAsTuple<AllHints, Hint, 4> {
  static constexpr const char* Names[] = {"Begin", "Third", "Correct", "End"};
};

enum class Order { Sorted, Random };
struct AllOrders : EnumValuesAsTuple<AllOrders, Order, 2> {
  static constexpr const char* Names[] = {"Sorted", "Random"};
};

struct TestSets {
  std::vector<uint64_t> Keys;
  std::vector<std::map<uint64_t, int64_t> > Maps;
  std::vector<
      std::vector<typename std::map<uint64_t, int64_t>::const_iterator> >
      Hints;
};

enum class Shuffle { None, Keys, Hints };

TestSets makeTestingSets(size_t MapSize, Mode mode, Shuffle shuffle,
                         size_t max_maps) {
  /*
   * The shuffle does not retain the random number generator to use the same
   * set of random numbers for every iteration.
   */
  TestSets R;

  int MapCount = std::min(max_maps, 1000000 / MapSize);

  for (uint64_t I = 0; I < MapSize; ++I) {
    R.Keys.push_back(mode == Mode::Hit ? 2 * I + 2 : 2 * I + 1);
  }
  if (shuffle == Shuffle::Keys)
    std::shuffle(R.Keys.begin(), R.Keys.end(), std::mt19937());

  for (int M = 0; M < MapCount; ++M) {
    auto& map = R.Maps.emplace_back();
    auto& hints = R.Hints.emplace_back();
    for (uint64_t I = 0; I < MapSize; ++I) {
      hints.push_back(map.insert(std::make_pair(2 * I + 2, 0)).first);
    }
    if (shuffle == Shuffle::Hints)
      std::shuffle(hints.begin(), hints.end(), std::mt19937());
  }

  return R;
}

struct Base {
  size_t MapSize;
  Base(size_t T) : MapSize(T) {}

  std::string baseName() const { return "_MapSize=" + std::to_string(MapSize); }
};

//*******************************************************************|
//                       Member functions                            |
//*******************************************************************|

struct ConstructorDefault {
  void run(benchmark::State& State) const {
    for (auto _ : State) {
      benchmark::DoNotOptimize(std::map<uint64_t, int64_t>());
    }
  }

  std::string name() const { return "BM_ConstructorDefault"; }
};

struct ConstructorIterator : Base {
  using Base::Base;

  void run(benchmark::State& State) const {
    auto Data = makeTestingSets(MapSize, Mode::Hit, Shuffle::None, 1);
    auto& Map = Data.Maps.front();
    while (State.KeepRunningBatch(MapSize)) {
#ifndef VALIDATE
      benchmark::DoNotOptimize(
          std::map<uint64_t, int64_t>(Map.begin(), Map.end()));
#else
      std::map<uint64_t, int64_t> M{Map.begin(), Map.end()};
      if (M != Map)
        State.SkipWithError("Map copy not identical");
#endif
    }
  }

  std::string name() const { return "BM_ConstructorIterator" + baseName(); }
};

struct ConstructorCopy : Base {
  using Base::Base;

  void run(benchmark::State& State) const {
    auto Data = makeTestingSets(MapSize, Mode::Hit, Shuffle::None, 1);
    auto& Map = Data.Maps.front();
    while (State.KeepRunningBatch(MapSize)) {
#ifndef VALIDATE
      std::map<uint64_t, int64_t> M(Map);
      benchmark::DoNotOptimize(M);
#else
      std::map<uint64_t, int64_t> M(Map);
      if (M != Map)
        State.SkipWithError("Map copy not identical");
#endif
    }
  }

  std::string name() const { return "BM_ConstructorCopy" + baseName(); }
};

struct ConstructorMove : Base {
  using Base::Base;

  void run(benchmark::State& State) const {
    auto Data = makeTestingSets(MapSize, Mode::Hit, Shuffle::None, 1000);
    while (State.KeepRunningBatch(MapSize * Data.Maps.size())) {
      for (auto& Map : Data.Maps) {
        std::map<uint64_t, int64_t> M(std::move(Map));
        benchmark::DoNotOptimize(M);
      }
      State.PauseTiming();
      Data = makeTestingSets(MapSize, Mode::Hit, Shuffle::None, 1000);
      State.ResumeTiming();
    }
  }

  std::string name() const { return "BM_ConstructorMove" + baseName(); }
};

//*******************************************************************|
//                           Capacity                                |
//*******************************************************************|

struct Empty : Base {
  using Base::Base;

  void run(benchmark::State& State) const {
    auto Data = makeTestingSets(MapSize, Mode::Hit, Shuffle::None, 1);
    auto& Map = Data.Maps.front();
    for (auto _ : State) {
#ifndef VALIDATE
      benchmark::DoNotOptimize(Map.empty());
#else
      if (Map.empty())
        State.SkipWithError("Map contains an invalid number of elements.");
#endif
    }
  }

  std::string name() const { return "BM_Empty" + baseName(); }
};

struct Size : Base {
  using Base::Base;

  void run(benchmark::State& State) const {
    auto Data = makeTestingSets(MapSize, Mode::Hit, Shuffle::None, 1);
    auto& Map = Data.Maps.front();
    for (auto _ : State) {
#ifndef VALIDATE
      benchmark::DoNotOptimize(Map.size());
#else
      if (Map.size() != MapSize)
        State.SkipWithError("Map contains an invalid number of elements.");
#endif
    }
  }

  std::string name() const { return "BM_Size" + baseName(); }
};

//*******************************************************************|
//                           Modifiers                               |
//*******************************************************************|

struct Clear : Base {
  using Base::Base;

  void run(benchmark::State& State) const {
    auto Data = makeTestingSets(MapSize, Mode::Hit, Shuffle::None, 1000);
    while (State.KeepRunningBatch(MapSize * Data.Maps.size())) {
      for (auto& Map : Data.Maps) {
        Map.clear();
        benchmark::DoNotOptimize(Map);
      }
      State.PauseTiming();
      Data = makeTestingSets(MapSize, Mode::Hit, Shuffle::None, 1000);
      State.ResumeTiming();
    }
  }

  std::string name() const { return "BM_Clear" + baseName(); }
};

template <class Mode, class Order>
struct Insert : Base {
  using Base::Base;

  void run(benchmark::State& State) const {
    auto Data = makeTestingSets(
        MapSize, Mode(),
        Order::value == ::Order::Random ? Shuffle::Keys : Shuffle::None, 1000);
    while (State.KeepRunningBatch(MapSize * Data.Maps.size())) {
      for (auto& Map : Data.Maps) {
        for (auto K : Data.Keys) {
#ifndef VALIDATE
          benchmark::DoNotOptimize(Map.insert(std::make_pair(K, 1)));
#else
          bool Inserted = Map.insert(std::make_pair(K, 1)).second;
          if (Mode() == ::Mode::Hit) {
            if (Inserted)
              State.SkipWithError("Inserted a duplicate element");
          } else {
            if (!Inserted)
              State.SkipWithError("Failed to insert e new element");
          }
#endif
        }
      }

      State.PauseTiming();
      Data = makeTestingSets(MapSize, Mode(),
                             Order::value == ::Order::Random ? Shuffle::Keys
                                                             : Shuffle::None,
                             1000);
      State.ResumeTiming();
    }
  }

  std::string name() const {
    return "BM_Insert" + baseName() + Mode::name() + Order::name();
  }
};

template <class Mode, class Hint>
struct InsertHint : Base {
  using Base::Base;

  template < ::Hint hint>
  typename std::enable_if<hint == ::Hint::Correct>::type
  run(benchmark::State& State) const {
    auto Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000);
    while (State.KeepRunningBatch(MapSize * Data.Maps.size())) {
      for (size_t I = 0; I < Data.Maps.size(); ++I) {
        auto& Map = Data.Maps[I];
        auto H = Data.Hints[I].begin();
        for (auto K : Data.Keys) {
#ifndef VALIDATE
          benchmark::DoNotOptimize(Map.insert(*H, std::make_pair(K, 1)));
#else
          auto Inserted = Map.insert(*H, std::make_pair(K, 1));
          if (Mode() == ::Mode::Hit) {
            if (Inserted != *H)
              State.SkipWithError("Inserted a duplicate element");
          } else {
            if (++Inserted != *H)
              State.SkipWithError("Failed to insert a new element");
          }
#endif
          ++H;
        }
      }

      State.PauseTiming();
      Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000);
      State.ResumeTiming();
    }
  }

  template < ::Hint hint>
  typename std::enable_if<hint != ::Hint::Correct>::type
  run(benchmark::State& State) const {
    auto Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000);
    while (State.KeepRunningBatch(MapSize * Data.Maps.size())) {
      for (size_t I = 0; I < Data.Maps.size(); ++I) {
        auto& Map = Data.Maps[I];
        auto Third = *(Data.Hints[I].begin() + 2);
        for (auto K : Data.Keys) {
          auto Itor = hint == ::Hint::Begin
                          ? Map.begin()
                          : hint == ::Hint::Third ? Third : Map.end();
#ifndef VALIDATE
          benchmark::DoNotOptimize(Map.insert(Itor, std::make_pair(K, 1)));
#else
          size_t Size = Map.size();
          Map.insert(Itor, std::make_pair(K, 1));
          if (Mode() == ::Mode::Hit) {
            if (Size != Map.size())
              State.SkipWithError("Inserted a duplicate element");
          } else {
            if (Size + 1 != Map.size())
              State.SkipWithError("Failed to insert a new element");
          }
#endif
        }
      }

      State.PauseTiming();
      Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000);
      State.ResumeTiming();
    }
  }

  void run(benchmark::State& State) const {
    static constexpr auto h = Hint();
    run<h>(State);
  }

  std::string name() const {
    return "BM_InsertHint" + baseName() + Mode::name() + Hint::name();
  }
};

template <class Mode, class Order>
struct InsertAssign : Base {
  using Base::Base;

  void run(benchmark::State& State) const {
    auto Data = makeTestingSets(
        MapSize, Mode(),
        Order::value == ::Order::Random ? Shuffle::Keys : Shuffle::None, 1000);
    while (State.KeepRunningBatch(MapSize * Data.Maps.size())) {
      for (auto& Map : Data.Maps) {
        for (auto K : Data.Keys) {
#ifndef VALIDATE
          benchmark::DoNotOptimize(Map.insert_or_assign(K, 1));
#else
          bool Inserted = Map.insert_or_assign(K, 1).second;
          if (Mode() == ::Mode::Hit) {
            if (Inserted)
              State.SkipWithError("Inserted a duplicate element");
          } else {
            if (!Inserted)
              State.SkipWithError("Failed to insert e new element");
          }
#endif
        }
      }

      State.PauseTiming();
      Data = makeTestingSets(MapSize, Mode(),
                             Order::value == ::Order::Random ? Shuffle::Keys
                                                             : Shuffle::None,
                             1000);
      State.ResumeTiming();
    }
  }

  std::string name() const {
    return "BM_InsertAssign" + baseName() + Mode::name() + Order::name();
  }
};

template <class Mode, class Hint>
struct InsertAssignHint : Base {
  using Base::Base;

  template < ::Hint hint>
  typename std::enable_if<hint == ::Hint::Correct>::type
  run(benchmark::State& State) const {
    auto Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000);
    while (State.KeepRunningBatch(MapSize * Data.Maps.size())) {
      for (size_t I = 0; I < Data.Maps.size(); ++I) {
        auto& Map = Data.Maps[I];
        auto H = Data.Hints[I].begin();
        for (auto K : Data.Keys) {
#ifndef VALIDATE
          benchmark::DoNotOptimize(Map.insert_or_assign(*H, K, 1));
#else
          auto Inserted = Map.insert_or_assign(*H, K, 1);
          if (Mode() == ::Mode::Hit) {
            if (Inserted != *H)
              State.SkipWithError("Inserted a duplicate element");
          } else {
            if (++Inserted != *H)
              State.SkipWithError("Failed to insert a new element");
          }
#endif
          ++H;
        }
      }

      State.PauseTiming();
      Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000);
      State.ResumeTiming();
    }
  }

  template < ::Hint hint>
  typename std::enable_if<hint != ::Hint::Correct>::type
  run(benchmark::State& State) const {
    auto Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000);
    while (State.KeepRunningBatch(MapSize * Data.Maps.size())) {
      for (size_t I = 0; I < Data.Maps.size(); ++I) {
        auto& Map = Data.Maps[I];
        auto Third = *(Data.Hints[I].begin() + 2);
        for (auto K : Data.Keys) {
          auto Itor = hint == ::Hint::Begin
                          ? Map.begin()
                          : hint == ::Hint::Third ? Third : Map.end();
#ifndef VALIDATE
          benchmark::DoNotOptimize(Map.insert_or_assign(Itor, K, 1));
#else
          size_t Size = Map.size();
          Map.insert_or_assign(Itor, K, 1);
          if (Mode() == ::Mode::Hit) {
            if (Size != Map.size())
              State.SkipWithError("Inserted a duplicate element");
          } else {
            if (Size + 1 != Map.size())
              State.SkipWithError("Failed to insert a new element");
          }
#endif
        }
      }

      State.PauseTiming();
      Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000);
      State.ResumeTiming();
    }
  }

  void run(benchmark::State& State) const {
    static constexpr auto h = Hint();
    run<h>(State);
  }

  std::string name() const {
    return "BM_InsertAssignHint" + baseName() + Mode::name() + Hint::name();
  }
};

template <class Mode, class Order>
struct Emplace : Base {
  using Base::Base;

  void run(benchmark::State& State) const {

    auto Data = makeTestingSets(
        MapSize, Mode(),
        Order::value == ::Order::Random ? Shuffle::Keys : Shuffle::None, 1000);
    while (State.KeepRunningBatch(MapSize * Data.Maps.size())) {
      for (auto& Map : Data.Maps) {
        for (auto K : Data.Keys) {
#ifndef VALIDATE
          benchmark::DoNotOptimize(Map.emplace(K, 1));
#else
          bool Inserted = Map.emplace(K, 1).second;
          if (Mode() == ::Mode::Hit) {
            if (Inserted)
              State.SkipWithError("Emplaced a duplicate element");
          } else {
            if (!Inserted)
              State.SkipWithError("Failed to emplace a new element");
          }
#endif
        }
      }

      State.PauseTiming();
      Data = makeTestingSets(MapSize, Mode(),
                             Order::value == ::Order::Random ? Shuffle::Keys
                                                             : Shuffle::None,
                             1000);
      State.ResumeTiming();
    }
  }

  std::string name() const {
    return "BM_Emplace" + baseName() + Mode::name() + Order::name();
  }
};

template <class Mode, class Hint>
struct EmplaceHint : Base {
  using Base::Base;

  template < ::Hint hint>
  typename std::enable_if<hint == ::Hint::Correct>::type
  run(benchmark::State& State) const {
    auto Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000);
    while (State.KeepRunningBatch(MapSize * Data.Maps.size())) {
      for (size_t I = 0; I < Data.Maps.size(); ++I) {
        auto& Map = Data.Maps[I];
        auto H = Data.Hints[I].begin();
        for (auto K : Data.Keys) {
#ifndef VALIDATE
          benchmark::DoNotOptimize(Map.emplace_hint(*H, K, 1));
#else
          auto Inserted = Map.emplace_hint(*H, K, 1);
          if (Mode() == ::Mode::Hit) {
            if (Inserted != *H)
              State.SkipWithError("Emplaced a duplicate element");
          } else {
            if (++Inserted != *H)
              State.SkipWithError("Failed to emplace a new element");
          }
#endif
          ++H;
        }
      }

      State.PauseTiming();
      Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000);
      State.ResumeTiming();
    }
  }

  template < ::Hint hint>
  typename std::enable_if<hint != ::Hint::Correct>::type
  run(benchmark::State& State) const {
    auto Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000);
    while (State.KeepRunningBatch(MapSize * Data.Maps.size())) {
      for (size_t I = 0; I < Data.Maps.size(); ++I) {
        auto& Map = Data.Maps[I];
        auto Third = *(Data.Hints[I].begin() + 2);
        for (auto K : Data.Keys) {
          auto Itor = hint == ::Hint::Begin
                          ? Map.begin()
                          : hint == ::Hint::Third ? Third : Map.end();
#ifndef VALIDATE
          benchmark::DoNotOptimize(Map.emplace_hint(Itor, K, 1));
#else
          size_t Size = Map.size();
          Map.emplace_hint(Itor, K, 1);
          if (Mode() == ::Mode::Hit) {
            if (Size != Map.size())
              State.SkipWithError("Emplaced a duplicate element");
          } else {
            if (Size + 1 != Map.size())
              State.SkipWithError("Failed to emplace a new element");
          }
#endif
        }
      }

      State.PauseTiming();
      Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000);
      State.ResumeTiming();
    }
  }

  void run(benchmark::State& State) const {
    static constexpr auto h = Hint();
    run<h>(State);
  }

  std::string name() const {
    return "BM_EmplaceHint" + baseName() + Mode::name() + Hint::name();
  }
};

template <class Mode, class Order>
struct TryEmplace : Base {
  using Base::Base;

  void run(benchmark::State& State) const {

    auto Data = makeTestingSets(
        MapSize, Mode(),
        Order::value == ::Order::Random ? Shuffle::Keys : Shuffle::None, 1000);
    while (State.KeepRunningBatch(MapSize * Data.Maps.size())) {
      for (auto& Map : Data.Maps) {
        for (auto K : Data.Keys) {
#ifndef VALIDATE
          benchmark::DoNotOptimize(Map.try_emplace(K, 1));
#else
          bool Inserted = Map.try_emplace(K, 1).second;
          if (Mode() == ::Mode::Hit) {
            if (Inserted)
              State.SkipWithError("Emplaced a duplicate element");
          } else {
            if (!Inserted)
              State.SkipWithError("Failed to emplace a new element");
          }
#endif
        }
      }

      State.PauseTiming();
      Data = makeTestingSets(MapSize, Mode(),
                             Order::value == ::Order::Random ? Shuffle::Keys
                                                             : Shuffle::None,
                             1000);
      State.ResumeTiming();
    }
  }

  std::string name() const {
    return "BM_TryEmplace" + baseName() + Mode::name() + Order::name();
  }
};

template <class Mode, class Hint>
struct TryEmplaceHint : Base {
  using Base::Base;

  template < ::Hint hint>
  typename std::enable_if<hint == ::Hint::Correct>::type
  run(benchmark::State& State) const {
    auto Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000);
    while (State.KeepRunningBatch(MapSize * Data.Maps.size())) {
      for (size_t I = 0; I < Data.Maps.size(); ++I) {
        auto& Map = Data.Maps[I];
        auto H = Data.Hints[I].begin();
        for (auto K : Data.Keys) {
#ifndef VALIDATE
          benchmark::DoNotOptimize(Map.try_emplace(*H, K, 1));
#else
          auto Inserted = Map.try_emplace(*H, K, 1);
          if (Mode() == ::Mode::Hit) {
            if (Inserted != *H)
              State.SkipWithError("Emplaced a duplicate element");
          } else {
            if (++Inserted != *H)
              State.SkipWithError("Failed to emplace a new element");
          }
#endif
          ++H;
        }
      }

      State.PauseTiming();
      Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000);
      State.ResumeTiming();
    }
  }

  template < ::Hint hint>
  typename std::enable_if<hint != ::Hint::Correct>::type
  run(benchmark::State& State) const {
    auto Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000);
    while (State.KeepRunningBatch(MapSize * Data.Maps.size())) {
      for (size_t I = 0; I < Data.Maps.size(); ++I) {
        auto& Map = Data.Maps[I];
        auto Third = *(Data.Hints[I].begin() + 2);
        for (auto K : Data.Keys) {
          auto Itor = hint == ::Hint::Begin
                          ? Map.begin()
                          : hint == ::Hint::Third ? Third : Map.end();
#ifndef VALIDATE
          benchmark::DoNotOptimize(Map.try_emplace(Itor, K, 1));
#else
          size_t Size = Map.size();
          Map.try_emplace(Itor, K, 1);
          if (Mode() == ::Mode::Hit) {
            if (Size != Map.size())
              State.SkipWithError("Emplaced a duplicate element");
          } else {
            if (Size + 1 != Map.size())
              State.SkipWithError("Failed to emplace a new element");
          }
#endif
        }
      }

      State.PauseTiming();
      Data = makeTestingSets(MapSize, Mode(), Shuffle::None, 1000);
      State.ResumeTiming();
    }
  }

  void run(benchmark::State& State) const {
    static constexpr auto h = Hint();
    run<h>(State);
  }

  std::string name() const {
    return "BM_TryEmplaceHint" + baseName() + Mode::name() + Hint::name();
  }
};

template <class Mode, class Order>
struct Erase : Base {
  using Base::Base;

  void run(benchmark::State& State) const {
    auto Data = makeTestingSets(
        MapSize, Mode(),
        Order::value == ::Order::Random ? Shuffle::Keys : Shuffle::None, 1000);
    while (State.KeepRunningBatch(MapSize * Data.Maps.size())) {
      for (auto& Map : Data.Maps) {
        for (auto K : Data.Keys) {
#ifndef VALIDATE
          benchmark::DoNotOptimize(Map.erase(K));
#else
          size_t I = Map.erase(K);
          if (Mode() == ::Mode::Hit) {
            if (I == 0)
              State.SkipWithError("Did not find the existing element");
          } else {
            if (I == 1)
              State.SkipWithError("Did find the non-existing element");
          }
#endif
        }
      }

      State.PauseTiming();
      Data = makeTestingSets(MapSize, Mode(),
                             Order::value == ::Order::Random ? Shuffle::Keys
                                                             : Shuffle::None,
                             1000);
      State.ResumeTiming();
    }
  }

  std::string name() const {
    return "BM_Erase" + baseName() + Mode::name() + Order::name();
  }
};

template <class Order>
struct EraseIterator : Base {
  using Base::Base;

  void run(benchmark::State& State) const {
    auto Data = makeTestingSets(
        MapSize, Mode::Hit,
        Order::value == ::Order::Random ? Shuffle::Hints : Shuffle::None, 1000);
    while (State.KeepRunningBatch(MapSize * Data.Maps.size())) {
      for (size_t I = 0; I < Data.Maps.size(); ++I) {
        auto& Map = Data.Maps[I];
        for (auto H : Data.Hints[I]) {
          benchmark::DoNotOptimize(Map.erase(H));
        }
#ifdef VALIDATE
        if (!Map.empty())
          State.SkipWithError("Did not erase the entire map");
#endif
      }

      State.PauseTiming();
      Data = makeTestingSets(MapSize, Mode::Hit,
                             Order::value == ::Order::Random ? Shuffle::Hints
                                                             : Shuffle::None,
                             1000);
      State.ResumeTiming();
    }
  }

  std::string name() const {
    return "BM_EraseIterator" + baseName() + Order::name();
  }
};

struct EraseRange : Base {
  using Base::Base;

  void run(benchmark::State& State) const {
    auto Data = makeTestingSets(MapSize, Mode::Hit, Shuffle::None, 1000);
    while (State.KeepRunningBatch(MapSize * Data.Maps.size())) {
      for (auto& Map : Data.Maps) {
#ifndef VALIDATE
        benchmark::DoNotOptimize(Map.erase(Map.begin(), Map.end()));
#else
        Map.erase(Map.begin(), Map.end());
        if (!Map.empty())
          State.SkipWithError("Did not erase the entire map");
#endif
      }

      State.PauseTiming();
      Data = makeTestingSets(MapSize, Mode::Hit, Shuffle::None, 1000);
      State.ResumeTiming();
    }
  }

  std::string name() const { return "BM_EraseRange" + baseName(); }
};

//*******************************************************************|
//                            Lookup                                 |
//*******************************************************************|

template <class Mode, class Order>
struct Count : Base {
  using Base::Base;

  void run(benchmark::State& State) const {
    auto Data = makeTestingSets(
        MapSize, Mode(),
        Order::value == ::Order::Random ? Shuffle::Keys : Shuffle::None, 1);
    auto& Map = Data.Maps.front();
    while (State.KeepRunningBatch(MapSize)) {
      for (auto K : Data.Keys) {
#ifndef VALIDATE
        benchmark::DoNotOptimize(Map.count(K));
#else
        size_t I = Map.count(K);
        if (Mode() == ::Mode::Hit) {
          if (I == 0)
            State.SkipWithError("Did not find the existing element");
        } else {
          if (I == 1)
            State.SkipWithError("Did find the non-existing element");
        }
#endif
      }
    }
  }

  std::string name() const {
    return "BM_Count" + baseName() + Mode::name() + Order::name();
  }
};

template <class Mode, class Order>
struct Find : Base {
  using Base::Base;

  void run(benchmark::State& State) const {
    auto Data = makeTestingSets(
        MapSize, Mode(),
        Order::value == ::Order::Random ? Shuffle::Keys : Shuffle::None, 1);
    auto& Map = Data.Maps.front();
    while (State.KeepRunningBatch(MapSize)) {
      for (auto K : Data.Keys) {
#ifndef VALIDATE
        benchmark::DoNotOptimize(Map.find(K));
#else
        auto Itor = Map.find(K);
        if (Mode() == ::Mode::Hit) {
          if (Itor == Map.end())
            State.SkipWithError("Did not find the existing element");
        } else {
          if (Itor != Map.end())
            State.SkipWithError("Did find the non-existing element");
        }
#endif
      }
    }
  }

  std::string name() const {
    return "BM_Find" + baseName() + Mode::name() + Order::name();
  }
};

template <class Mode, class Order>
struct EqualRange : Base {
  using Base::Base;

  void run(benchmark::State& State) const {
    auto Data = makeTestingSets(
        MapSize, Mode(),
        Order::value == ::Order::Random ? Shuffle::Keys : Shuffle::None, 1);
    auto& Map = Data.Maps.front();
    while (State.KeepRunningBatch(MapSize)) {
      for (auto K : Data.Keys) {
#ifndef VALIDATE
        benchmark::DoNotOptimize(Map.equal_range(K));
#else
        auto Range = Map.equal_range(K);
        if (Mode() == ::Mode::Hit) {
          // Adjust validation for the last element.
          auto Key = K;
          if (Range.second == Map.end() && K == 2 * MapSize) {
            --Range.second;
            Key -= 2;
          }
          if (Range.first == Map.end() || Range.first->first != K ||
              Range.second == Map.end() || Range.second->first - 2 != Key)
            State.SkipWithError("Did not find the existing element");
        } else {
          if (Range.first == Map.end() || Range.first->first - 1 != K ||
              Range.second == Map.end() || Range.second->first - 1 != K)
            State.SkipWithError("Did find the non-existing element");
        }
#endif
      }
    }
  }

  std::string name() const {
    return "BM_EqualRange" + baseName() + Mode::name() + Order::name();
  }
};

template <class Mode, class Order>
struct LowerBound : Base {
  using Base::Base;

  void run(benchmark::State& State) const {
    auto Data = makeTestingSets(
        MapSize, Mode(),
        Order::value == ::Order::Random ? Shuffle::Keys : Shuffle::None, 1);
    auto& Map = Data.Maps.front();
    while (State.KeepRunningBatch(MapSize)) {
      for (auto K : Data.Keys) {
#ifndef VALIDATE
        benchmark::DoNotOptimize(Map.lower_bound(K));
#else
        auto Itor = Map.lower_bound(K);
        if (Mode() == ::Mode::Hit) {
          if (Itor == Map.end() || Itor->first != K)
            State.SkipWithError("Did not find the existing element");
        } else {
          if (Itor == Map.end() || Itor->first - 1 != K)
            State.SkipWithError("Did find the non-existing element");
        }
#endif
      }
    }
  }

  std::string name() const {
    return "BM_LowerBound" + baseName() + Mode::name() + Order::name();
  }
};

template <class Mode, class Order>
struct UpperBound : Base {
  using Base::Base;

  void run(benchmark::State& State) const {
    auto Data = makeTestingSets(
        MapSize, Mode(),
        Order::value == ::Order::Random ? Shuffle::Keys : Shuffle::None, 1);
    auto& Map = Data.Maps.front();
    while (State.KeepRunningBatch(MapSize)) {
      for (auto K : Data.Keys) {
#ifndef VALIDATE
        benchmark::DoNotOptimize(Map.upper_bound(K));
#else
        std::map<uint64_t, int64_t>::iterator Itor = Map.upper_bound(K);
        if (Mode() == ::Mode::Hit) {
          // Adjust validation for the last element.
          auto Key = K;
          if (Itor == Map.end() && K == 2 * MapSize) {
            --Itor;
            Key -= 2;
          }
          if (Itor == Map.end() || Itor->first - 2 != Key)
            State.SkipWithError("Did not find the existing element");
        } else {
          if (Itor == Map.end() || Itor->first - 1 != K)
            State.SkipWithError("Did find the non-existing element");
        }
#endif
      }
    }
  }

  std::string name() const {
    return "BM_UpperBound" + baseName() + Mode::name() + Order::name();
  }
};

} // namespace

int main(int argc, char** argv) {
  benchmark::Initialize(&argc, argv);
  if (benchmark::ReportUnrecognizedArguments(argc, argv))
    return 1;

#ifdef VALIDATE
  const std::vector<size_t> MapSize{10};
#else
  const std::vector<size_t> MapSize{10, 100, 1000, 10000, 100000, 1000000};
#endif

  // Member functions
  makeCartesianProductBenchmark<ConstructorDefault>();
  makeCartesianProductBenchmark<ConstructorIterator>(MapSize);
  makeCartesianProductBenchmark<ConstructorCopy>(MapSize);
  makeCartesianProductBenchmark<ConstructorMove>(MapSize);

  // Capacity
  makeCartesianProductBenchmark<Empty>(MapSize);
  makeCartesianProductBenchmark<Size>(MapSize);

  // Modifiers
  makeCartesianProductBenchmark<Clear>(MapSize);
  makeCartesianProductBenchmark<Insert, AllModes, AllOrders>(MapSize);
  makeCartesianProductBenchmark<InsertHint, AllModes, AllHints>(MapSize);
  makeCartesianProductBenchmark<InsertAssign, AllModes, AllOrders>(MapSize);
  makeCartesianProductBenchmark<InsertAssignHint, AllModes, AllHints>(MapSize);

  makeCartesianProductBenchmark<Emplace, AllModes, AllOrders>(MapSize);
  makeCartesianProductBenchmark<EmplaceHint, AllModes, AllHints>(MapSize);
  makeCartesianProductBenchmark<TryEmplace, AllModes, AllOrders>(MapSize);
  makeCartesianProductBenchmark<TryEmplaceHint, AllModes, AllHints>(MapSize);
  makeCartesianProductBenchmark<Erase, AllModes, AllOrders>(MapSize);
  makeCartesianProductBenchmark<EraseIterator, AllOrders>(MapSize);
  makeCartesianProductBenchmark<EraseRange>(MapSize);

  // Lookup
  makeCartesianProductBenchmark<Count, AllModes, AllOrders>(MapSize);
  makeCartesianProductBenchmark<Find, AllModes, AllOrders>(MapSize);
  makeCartesianProductBenchmark<EqualRange, AllModes, AllOrders>(MapSize);
  makeCartesianProductBenchmark<LowerBound, AllModes, AllOrders>(MapSize);
  makeCartesianProductBenchmark<UpperBound, AllModes, AllOrders>(MapSize);

  benchmark::RunSpecifiedBenchmarks();
}
