// Copyright 2017 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Unit tests for the variant template. The 'is' and 'IsEmpty' methods
// of variant are not explicitly tested because they are used repeatedly
// in building other tests. All other public variant methods should have
// explicit tests.

#include "absl/types/variant.h"

#include <cstddef>
#include <cstdlib>
#include <string>
#include <tuple>

#include "benchmark/benchmark.h"
#include "absl/utility/utility.h"

namespace absl {
namespace {

template <std::size_t I>
struct VariantAlternative {
  char member;
};

template <class Indices>
struct VariantOfAlternativesImpl;

template <std::size_t... Indices>
struct VariantOfAlternativesImpl<absl::index_sequence<Indices...>> {
  using type = absl::variant<VariantAlternative<Indices>...>;
};

template <std::size_t NumAlternatives>
using VariantOfAlternatives = typename VariantOfAlternativesImpl<
    absl::make_index_sequence<NumAlternatives>>::type;

struct Empty {};

template <class... T>
void Ignore(T...) noexcept {}

template <class T>
Empty DoNotOptimizeAndReturnEmpty(T&& arg) noexcept {
  benchmark::DoNotOptimize(arg);
  return {};
}

struct VisitorApplier {
  struct Visitor {
    template <class... T>
    void operator()(T&&... args) const noexcept {
      Ignore(DoNotOptimizeAndReturnEmpty(args)...);
    }
  };

  template <class... Vars>
  void operator()(const Vars&... vars) const noexcept {
    absl::visit(Visitor(), vars...);
  }
};

template <std::size_t NumIndices, std::size_t CurrIndex = NumIndices - 1>
struct MakeWithIndex {
  using Variant = VariantOfAlternatives<NumIndices>;

  static Variant Run(std::size_t index) {
    return index == CurrIndex
               ? Variant(absl::in_place_index_t<CurrIndex>())
               : MakeWithIndex<NumIndices, CurrIndex - 1>::Run(index);
  }
};

template <std::size_t NumIndices>
struct MakeWithIndex<NumIndices, 0> {
  using Variant = VariantOfAlternatives<NumIndices>;

  static Variant Run(std::size_t /*index*/) { return Variant(); }
};

template <std::size_t NumIndices, class Dimensions>
struct MakeVariantTuple;

template <class T, std::size_t /*I*/>
using always_t = T;

template <std::size_t NumIndices>
VariantOfAlternatives<NumIndices> MakeVariant(std::size_t dimension,
                                              std::size_t index) {
  return dimension == 0
             ? MakeWithIndex<NumIndices>::Run(index % NumIndices)
             : MakeVariant<NumIndices>(dimension - 1, index / NumIndices);
}

template <std::size_t NumIndices, std::size_t... Dimensions>
struct MakeVariantTuple<NumIndices, absl::index_sequence<Dimensions...>> {
  using VariantTuple =
      std::tuple<always_t<VariantOfAlternatives<NumIndices>, Dimensions>...>;

  static VariantTuple Run(int index) {
    return std::make_tuple(MakeVariant<NumIndices>(Dimensions, index)...);
  }
};

constexpr std::size_t integral_pow(std::size_t base, std::size_t power) {
  return power == 0 ? 1 : base * integral_pow(base, power - 1);
}

template <std::size_t End, std::size_t I = 0>
struct VisitTestBody {
  template <class Vars, class State>
  static bool Run(Vars& vars, State& state) {
    if (state.KeepRunning()) {
      absl::apply(VisitorApplier(), vars[I]);
      return VisitTestBody<End, I + 1>::Run(vars, state);
    }
    return false;
  }
};

template <std::size_t End>
struct VisitTestBody<End, End> {
  template <class Vars, class State>
  static bool Run(Vars& /*vars*/, State& /*state*/) {
    return true;
  }
};

// Visit operations where branch prediction is likely to give a boost.
template <std::size_t NumIndices, std::size_t NumDimensions = 1>
void BM_RedundantVisit(benchmark::State& state) {
  auto vars =
      MakeVariantTuple<NumIndices, absl::make_index_sequence<NumDimensions>>::
          Run(static_cast<std::size_t>(state.range(0)));

  for (auto _ : state) {  // NOLINT
    benchmark::DoNotOptimize(vars);
    absl::apply(VisitorApplier(), vars);
  }
}

// Visit operations where branch prediction is unlikely to give a boost.
template <std::size_t NumIndices, std::size_t NumDimensions = 1>
void BM_Visit(benchmark::State& state) {
  constexpr std::size_t num_possibilities =
      integral_pow(NumIndices, NumDimensions);

  using VariantTupleMaker =
      MakeVariantTuple<NumIndices, absl::make_index_sequence<NumDimensions>>;
  using Tuple = typename VariantTupleMaker::VariantTuple;

  Tuple vars[num_possibilities];
  for (std::size_t i = 0; i < num_possibilities; ++i)
    vars[i] = VariantTupleMaker::Run(i);

  while (VisitTestBody<num_possibilities>::Run(vars, state)) {
  }
}

// Visitation
//   Each visit is on a different variant with a different active alternative)

// Unary visit
BENCHMARK_TEMPLATE(BM_Visit, 1);
BENCHMARK_TEMPLATE(BM_Visit, 2);
BENCHMARK_TEMPLATE(BM_Visit, 3);
BENCHMARK_TEMPLATE(BM_Visit, 4);
BENCHMARK_TEMPLATE(BM_Visit, 5);
BENCHMARK_TEMPLATE(BM_Visit, 6);
BENCHMARK_TEMPLATE(BM_Visit, 7);
BENCHMARK_TEMPLATE(BM_Visit, 8);
BENCHMARK_TEMPLATE(BM_Visit, 16);
BENCHMARK_TEMPLATE(BM_Visit, 32);
BENCHMARK_TEMPLATE(BM_Visit, 64);

// Binary visit
BENCHMARK_TEMPLATE(BM_Visit, 1, 2);
BENCHMARK_TEMPLATE(BM_Visit, 2, 2);
BENCHMARK_TEMPLATE(BM_Visit, 3, 2);
BENCHMARK_TEMPLATE(BM_Visit, 4, 2);
BENCHMARK_TEMPLATE(BM_Visit, 5, 2);

// Ternary visit
BENCHMARK_TEMPLATE(BM_Visit, 1, 3);
BENCHMARK_TEMPLATE(BM_Visit, 2, 3);
BENCHMARK_TEMPLATE(BM_Visit, 3, 3);

// Quaternary visit
BENCHMARK_TEMPLATE(BM_Visit, 1, 4);
BENCHMARK_TEMPLATE(BM_Visit, 2, 4);

// Redundant Visitation
//   Each visit consistently has the same alternative active

// Unary visit
BENCHMARK_TEMPLATE(BM_RedundantVisit, 1)->Arg(0);
BENCHMARK_TEMPLATE(BM_RedundantVisit, 2)->DenseRange(0, 1);
BENCHMARK_TEMPLATE(BM_RedundantVisit, 8)->DenseRange(0, 7);

// Binary visit
BENCHMARK_TEMPLATE(BM_RedundantVisit, 1, 2)->Arg(0);
BENCHMARK_TEMPLATE(BM_RedundantVisit, 2, 2)
    ->DenseRange(0, integral_pow(2, 2) - 1);
BENCHMARK_TEMPLATE(BM_RedundantVisit, 4, 2)
    ->DenseRange(0, integral_pow(4, 2) - 1);

}  // namespace
}  // namespace absl
