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