1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
|
// Copyright 2019 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
//
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
#if defined(ONLY_V2)
# define NO_BV
# define NO_SV
#endif
#if defined(ONLY_BV)
# define NO_V2
# define NO_SV
#endif
#if defined(ONLY_SV)
# define NO_V2
# define NO_BV
#endif
#if !defined(NO_V2)
#include <boost/variant2/variant.hpp>
#endif
#if !defined(NO_BV)
#include <boost/variant.hpp>
#endif
#if !defined(NO_SV)
#include <variant>
#endif
#include <type_traits>
#include <chrono>
#include <iostream>
#include <iomanip>
#include <vector>
struct prefix
{
int v_;
};
struct X1: prefix {};
struct X2: prefix {};
struct X3: prefix {};
struct X4: prefix {};
struct X5: prefix {};
struct X6: prefix {};
struct X7: prefix {};
struct X8: prefix {};
struct X9: prefix {};
struct X10: prefix {};
struct X11: prefix {};
struct X12: prefix {};
inline int get_value( prefix const& v )
{
return v.v_;
}
#if !defined(NO_V2)
template<class... T> int get_value( boost::variant2::variant<T...> const& v )
{
return visit( []( prefix const& x ) { return x.v_; }, v );
}
#endif
#if !defined(NO_BV)
template<class... T> int get_value( boost::variant<T...> const& v )
{
return boost::apply_visitor( []( prefix const& x ) { return x.v_; }, v );
}
#endif
#if !defined(NO_SV)
template<class... T> int get_value( std::variant<T...> const& v )
{
return visit( []( prefix const& x ) { return x.v_; }, v );
}
#endif
template<class V> void test_( int N )
{
std::vector<V> w;
// lack of reserve is deliberate
auto tp1 = std::chrono::high_resolution_clock::now();
for( int i = 0; i < N / 12; ++i )
{
w.push_back( X1{ i } );
w.push_back( X2{ i } );
w.push_back( X3{ i } );
w.push_back( X4{ i } );
w.push_back( X5{ i } );
w.push_back( X6{ i } );
w.push_back( X7{ i } );
w.push_back( X8{ i } );
w.push_back( X9{ i } );
w.push_back( X10{ i } );
w.push_back( X11{ i } );
w.push_back( X12{ i } );
}
unsigned long long s = 0;
for( std::size_t i = 0, n = w.size(); i < n; ++i )
{
s = s + get_value( w[ i ] );
}
auto tp2 = std::chrono::high_resolution_clock::now();
std::cout << std::setw( 6 ) << std::chrono::duration_cast<std::chrono::milliseconds>( tp2 - tp1 ).count() << " ms; S=" << s << "\n";
}
template<class... T> void test( int N )
{
std::cout << "N=" << N << ":\n";
std::cout << " prefix: "; test_<prefix>( N );
#if !defined(NO_V2)
std::cout << " variant2: "; test_<boost::variant2::variant<T...>>( N );
#endif
#if !defined(NO_BV)
std::cout << "boost::variant: "; test_<boost::variant<T...>>( N );
#endif
#if !defined(NO_SV)
std::cout << " std::variant: "; test_<std::variant<T...>>( N );
#endif
std::cout << '\n';
}
int main()
{
int const N = 100'000'000;
test<X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12>( N );
}
|