#include <iostream>
#include <memory>
#include <functional>
#include <cassert>
Raw bind-simulating Auto Storage behavior for static storage data
Template <typename Bindfunctor, TypeName Funcwrapper> class Scoped_raw_bind
{
Public
typedef scoped_raw_bind<bindfunctor, funcwrapper> This_type;
Make it move-constructible only
Scoped_raw_bind (const this_type&) = delete;
this_type& operator= (const this_type&) = delete;
this_type& operator= (this_type&& rhs) = delete;
Scoped_raw_bind (this_type&& RHS): m_owning (rhs.m_owning)
{
Rhs.m_owning = false;
}
Scoped_raw_bind (Bindfunctor B): M_owning (False)
{
Precondition-check that we don ' t override the static data for another raw bind instance
if (get_bind_ptr ()! = nullptr)
{
ASSERT (FALSE);
Return
}
Smart pointer is required because BIND expression is copy-constructible and not copy-assignable
Get_bind_ptr (). Reset (new Bindfunctor (b));
M_owning = true;
}
~scoped_raw_bind ()
{
if (m_owning)
{
ASSERT (Get_bind_ptr ()! = nullptr);
Get_bind_ptr (). reset ();
}
}
Decltype (&funcwrapper::call) get_raw_ptr ()
{
Return &FuncWrapper::call;
}
Static bindfunctor& Get_bind ()
{
return *get_bind_ptr ();
}
Private
BOOL m_owning;
Static std::unique_ptr<bindfunctor>& Get_bind_ptr ()
{
Static std::unique_ptr<bindfunctor> s_funcptr;
return s_funcptr;
}
};
HANDY macro for creating raw bind object
W is target function wrapper, and B is source bind expression
#define RAW_BIND (w,b) Std::move (Scoped_raw_bind<decltype (b), W<decltype (b), __counter__>> (b));
Usage
///////////////////////////////////////////////////////////////////////////
Target Raw Function signature
typedef void (*TARGETFUNCPTR) (double, int, const char*);
Function that need-be called via bind
void f (double d, int i, const char* s1, const char* s2)
{
Std::cout << "f (" << D << "," << I << "," << S1 << "," << S2 << " ) "<< Std::endl;
}
Wrapper for bound function
ID is required to generate a unique type with a static data for
Each raw bind instantiation.
The only THING so need to WRITE manually!
Template <typename bindfunc, int id = 0> struct fwrapper
{
static void Call (double d, int i, const char* s)
{
Scoped_raw_bind<bindfunc, Fwrapper<bindfunc, Id>>::get_bind (d, I, s);
}
};
For the test code:
Using namespace std::p laceholders;
Auto Rf1 = Raw_bind (Fwrapper, Std::bind (&f, _1, _2, _3, "This is F trail-1"));
Targetfuncptr f1 = Rf1.get_raw_ptr ();
F1 (1.2345, "f1:bind! Bind! ");
C + + closure to C function pointer conversion