C + + closure to C function pointer conversion

Source: Internet
Author: User

#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

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.