xref: /openbsd-src/gnu/llvm/libcxx/benchmarks/VariantBenchmarks.h (revision 76d0caaeb19ae0808d90af1d0b3b7b50b3e5383f)
1*76d0caaeSpatrick // -*- C++ -*-
2*76d0caaeSpatrick //===----------------------------------------------------------------------===//
3*76d0caaeSpatrick //
4*76d0caaeSpatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5*76d0caaeSpatrick // See https://llvm.org/LICENSE.txt for license information.
6*76d0caaeSpatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7*76d0caaeSpatrick //
8*76d0caaeSpatrick //===----------------------------------------------------------------------===//
9*76d0caaeSpatrick 
10*76d0caaeSpatrick #ifndef BENCHMARK_VARIANT_BENCHMARKS_H
11*76d0caaeSpatrick #define BENCHMARK_VARIANT_BENCHMARKS_H
12*76d0caaeSpatrick 
13*76d0caaeSpatrick #include <array>
14*76d0caaeSpatrick #include <cstddef>
15*76d0caaeSpatrick #include <tuple>
16*76d0caaeSpatrick #include <type_traits>
17*76d0caaeSpatrick #include <variant>
18*76d0caaeSpatrick 
19*76d0caaeSpatrick #include "benchmark/benchmark.h"
20*76d0caaeSpatrick 
21*76d0caaeSpatrick #include "GenerateInput.h"
22*76d0caaeSpatrick 
23*76d0caaeSpatrick namespace VariantBenchmarks {
24*76d0caaeSpatrick 
25*76d0caaeSpatrick template <std::size_t I>
26*76d0caaeSpatrick struct S {
27*76d0caaeSpatrick   static constexpr size_t v = I;
28*76d0caaeSpatrick };
29*76d0caaeSpatrick 
30*76d0caaeSpatrick template <std::size_t N, std::size_t... Is>
genVariants(std::index_sequence<Is...>)31*76d0caaeSpatrick static auto genVariants(std::index_sequence<Is...>) {
32*76d0caaeSpatrick   using V = std::variant<S<Is>...>;
33*76d0caaeSpatrick   using F = V (*)();
34*76d0caaeSpatrick   static constexpr F fs[] = {[] { return V(std::in_place_index<Is>); }...};
35*76d0caaeSpatrick 
36*76d0caaeSpatrick   std::array<V, N> result = {};
37*76d0caaeSpatrick   for (auto& v : result) {
38*76d0caaeSpatrick     v = fs[getRandomInteger(0ul, sizeof...(Is) - 1)]();
39*76d0caaeSpatrick   }
40*76d0caaeSpatrick 
41*76d0caaeSpatrick   return result;
42*76d0caaeSpatrick }
43*76d0caaeSpatrick 
44*76d0caaeSpatrick template <std::size_t N, std::size_t Alts>
BM_Visit(benchmark::State & state)45*76d0caaeSpatrick static void BM_Visit(benchmark::State& state) {
46*76d0caaeSpatrick   auto args = genVariants<N>(std::make_index_sequence<Alts>{});
47*76d0caaeSpatrick   for (auto _ : state) {
48*76d0caaeSpatrick     benchmark::DoNotOptimize(std::apply(
49*76d0caaeSpatrick         [](auto... vs) {
50*76d0caaeSpatrick           return std::visit([](auto... is) { return (is.v + ... + 0); }, vs...);
51*76d0caaeSpatrick         },
52*76d0caaeSpatrick         args));
53*76d0caaeSpatrick   }
54*76d0caaeSpatrick }
55*76d0caaeSpatrick 
56*76d0caaeSpatrick } // end namespace VariantBenchmarks
57*76d0caaeSpatrick 
58*76d0caaeSpatrick #endif // BENCHMARK_VARIANT_BENCHMARKS_H
59