namespace my {
template < typename Function , class Class >
struct MemberFunction
{
using MemFun = Function Class::*;
MemFun f_;
Class* c_;
public:
MemberFunction( MemFun f , Class* c ) : f_(f) , c_(c) {}
template < typename... Args >
auto operator()( Args&&... args)
{ return (c_->*f_)( std::forward<Args>(args)... ); }
};
template < typename Function , class Class >
auto bind_member( Class& c , Function Class::* f )
{
return MemberFunction<Function, Class>( f , &c );
}
// syntactic sugar
template < typename Function , class Class >
auto operator&& ( Class& c , Function Class::* f )
{
return MemberFunction<Function, Class>( f , &c );
}
}
------------------------------------------------------------
test_function_performance.cpp
#include <iostream>
#include <memory>
#include <chrono>
#include <functional>
#include <boost/function.hpp>
#include "function.h"
using namespace std;
using namespace std::chrono;
inline int foo(int x) { return x + 1; }
int bar(int x) { return x + 1; }
class SomeInterface { public: virtual int foo(int) = 0; };
class V : public SomeInterface { public: virtual int foo(int x) { return x + 1; } };
V v;
SomeInterface* w = new V;
int main()
{
my ::function< int( int ) > mf;
std ::function< int( int ) > sf;
boost::function< int( int ) > bf;
#define MEASURE_PERFORMANCE( info , fun ) \
\
cout << info << " "; \
size_t n = 0; \
\
auto tick = steady_clock::now(); \
\
for ( size_t k = 0 ; k < 100000000 ; ++k ) \
n += fun(n); \
\
auto tock = steady_clock::now(); \
cout << "time needed: " \
<< duration_cast<milliseconds>(tock-tick).count() \
<< " millisec. result = " \
<< n \
<< endl; \
{ MEASURE_PERFORMANCE( "plain foo " , foo ) }
{ MEASURE_PERFORMANCE( "virtual mem foo " , v.foo ) }
{ MEASURE_PERFORMANCE( "polymorphic foo " , w->foo ) }
{ mf = foo; MEASURE_PERFORMANCE( "my::fun foo " , mf ) }
{ mf = bar; MEASURE_PERFORMANCE( "my::fun bar " , mf ) }
{ sf = foo; MEASURE_PERFORMANCE( "std::fun foo " , sf ) }
{ sf = bar; MEASURE_PERFORMANCE( "std::fun bar " , sf ) }
{ bf = foo; MEASURE_PERFORMANCE( "boost::fun foo " , bf ) }
{ bf = bar; MEASURE_PERFORMANCE( "boost::fun bar " , bf ) }
{ mf = [](int i) { return foo(i); };
MEASURE_PERFORMANCE( "my::fun( /l foo) " , mf ) }
{ mf = [](int i) { return i+1; };
MEASURE_PERFORMANCE( "my::fun( /l ) " , mf ) }
}