-
Notifications
You must be signed in to change notification settings - Fork 13
/
overload.cpp
117 lines (98 loc) · 2.25 KB
/
overload.cpp
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
#include <iostream>
#include <random>
#include <string>
#include <chrono>
#include <memory>
#include <boost/type_erasure/any.hpp>
#include <boost/type_erasure/builtin.hpp>
#include <boost/type_erasure/callable.hpp>
#include <boost/function.hpp>
#include "function.h"
#include "delegate.hpp"
#include "stdex.hpp"
#include "cxx_function.hpp"
#include "function2.hpp"
#include "measure.hpp"
#define MAX_REPEAT 100000
template<class... Sig>
using multifunction =
boost::type_erasure::any<
boost::mpl::vector<
boost::type_erasure::copy_constructible<>,
boost::type_erasure::typeid_<>,
boost::type_erasure::relaxed,
boost::type_erasure::callable<Sig>...
>
>;
template<int i>
struct tag {};
struct empty_base {};
struct virtual_base
{
virtual int operator()(tag<0>) = 0;
virtual int operator()(tag<1>) = 0;
virtual int operator()(tag<2>) = 0;
};
template<class Base>
struct functor : Base
{
int operator()(tag<0>)
{
return 0;
}
int operator()(tag<1>)
{
return 1;
}
int operator()(tag<2>)
{
return 2;
}
};
template<class F>
struct use_base
{
typedef empty_base type;
};
template<>
struct use_base<virtual_base&>
{
typedef virtual_base type;
};
template<class F>
struct Perf : test::base
{
Perf()
: f(h)
{}
void benchmark()
{
this->val += f(tag<0>());
this->val += f(tag<1>());
this->val += f(tag<2>());
}
F f;
functor<typename use_base<F>::type> h;
};
template<class... Sig>
void benchmark()
{
typedef functor<empty_base> no_abstraction;
BOOST_SPIRIT_TEST_BENCHMARK(
MAX_REPEAT,
(Perf< no_abstraction >)
(Perf< stdex::function<Sig...> >)
(Perf< multifunction<Sig...> >)
(Perf< cxx_function::function<Sig...> >)
(Perf< fu2::function<Sig...> >)
(Perf< virtual_base& >)
)
}
int main(int /*argc*/, char* /*argv*/[])
{
benchmark<int(tag<0>), int(tag<1>), int(tag<2>)>();
// This is ultimately responsible for preventing all the test code
// from being optimized away. Change this to return 0 and you
// unplug the whole test's life support system.
return test::live_code != 0;
}