# How cpgf decuce function works

How cpgf decuce function works

//c:\Users\aeejshe\Downloads\cpgf-last-pre-c-11-version\cpgf-last-pre-c-11-version\include\cpgf\private\gcallback_p.h
    
#ifndef CPGF_GCALLBACK_P_H
#define CPGF_GCALLBACK_P_H

#include "cpgf/gcompiler.h"
#include "cpgf/gpp.h"
#include "cpgf/gconfig.h"
#include "cpgf/greference.h"
#include "cpgf/gtypetraits.h"
#include "cpgf/genableif.h"

#include <algorithm>
#include <utility>
#include <stdexcept>
#include <assert.h>

#if defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable:4267)
#endif


#if !defined(CB_MAX_ARITY)
	#define CB_MAX_ARITY G_MAX_ARITY
#endif

#define CB_PARAM_TYPEVALUE(N, P)		GPP_COMMA_IF(N) typename GArgumentTraits<P ## N>::Result  p ## N
#define CB_PARAM_PASSVALUE(N, P)		GPP_COMMA_IF(N) callback_internal::ForwardValue<typename GArgumentTraits<P ## N>::Result, typename GArgumentTraits<P ## N>::Result>::forward(p ## N)


#define CB_DEF_MEMBER(N) \
	template <typename InnerOT, typename InnerFT> \
	struct GCallbackMember { \
    	typedef GCallbackMember_ ## N <InnerOT, InnerFT, RT GPP_REPEAT_TAIL_PARAMS(N, PT)> Type; \
	};

#define CB_DEF_GLOBAL(N) \
	template <typename InnerFT> \
	struct GCallbackGlobal { \
    	typedef GCallbackGlobal_ ## N <InnerFT, RT GPP_REPEAT_TAIL_PARAMS(N, PT)> Type; \
	};

#define CB_DEF_MEMBER_N(N) \
	template <typename InnerOT, typename InnerFT, typename RT GPP_COMMA_IF(N) GPP_REPEAT(N, GPP_COMMA_PARAM, typename PT) > \
	class GCallbackMember_ ## N : public GCallbackMemberBase<GCallbackMember_ ## N <InnerOT, InnerFT, RT GPP_REPEAT_TAIL_PARAMS(N, PT)>, InnerOT, InnerFT, RT (*)(void * self GPP_COMMA_IF(N) GPP_REPEAT(N, CB_PARAM_TYPEVALUE, PT))> { \
	private: \
		typedef GCallbackMember_ ## N <InnerOT, InnerFT, RT GPP_REPEAT_TAIL_PARAMS(N, PT)> ThisType; \
		typedef GCallbackMemberBase<ThisType, InnerOT, InnerFT, RT (*)(void * self GPP_COMMA_IF(N) GPP_REPEAT(N, CB_PARAM_TYPEVALUE, PT))> super; \
	public: \
		GCallbackMember_ ## N(InnerOT * instance, const InnerFT & func) : super(instance, func) {} \
		static RT virtualInvoke(void * self GPP_COMMA_IF(N) GPP_REPEAT(N, CB_PARAM_TYPEVALUE, PT)) { return (static_cast<ThisType *>(self)->instance->*(*&(static_cast<ThisType *>(self)->func)))(GPP_REPEAT(N, CB_PARAM_PASSVALUE, PT)); } \
	};

#define CB_DEF_GLOBAL_N(N) \
	template <typename InnerFT, typename RT GPP_COMMA_IF(N) GPP_REPEAT(N, GPP_COMMA_PARAM, typename PT) > \
	class GCallbackGlobal_ ## N : public GCallbackGlobalBase<GCallbackGlobal_ ## N <InnerFT, RT GPP_REPEAT_TAIL_PARAMS(N, PT)>, InnerFT, RT (*)(void * self GPP_COMMA_IF(N) GPP_REPEAT(N, CB_PARAM_TYPEVALUE, PT))> { \
	private: \
		typedef GCallbackGlobal_ ## N <InnerFT, RT GPP_REPEAT_TAIL_PARAMS(N, PT)> ThisType; \
		typedef GCallbackGlobalBase<ThisType, InnerFT, RT (*)(void * self GPP_COMMA_IF(N) GPP_REPEAT(N, CB_PARAM_TYPEVALUE, PT))> super; \
	public: \
		GCallbackGlobal_ ## N(const InnerFT & func) : super(func) {} \
		static RT virtualInvoke(void * self GPP_COMMA_IF(N) GPP_REPEAT(N, CB_PARAM_TYPEVALUE, PT)) { return (*&(static_cast<ThisType *>(self)->func))(GPP_REPEAT(N, CB_PARAM_PASSVALUE, PT)); } \
	};


#define CB_FUNC_TRAITS_ARGS(N, P) GPP_COMMA_IF(N) typename FunctionTraits::ArgList::Arg ## N

#define CB_DEF_FUNC_TRAITS(N, P) \
	template <typename FT> \
	struct GCallbackFunctionTraits <N, FT> { \
		typedef GFunctionTraits<FT> FunctionTraits; \
		typedef GCallbackAgent_ ## N <typename FunctionTraits::ResultType GPP_COMMA_IF(N) GPP_REPEAT(N, CB_FUNC_TRAITS_ARGS, GPP_EMPTY)> CallbackAgentType; \
	};

#define CB_DEF_AGENT_N(N, P) \
	CB_DEF_MEMBER_N(N) \
	CB_DEF_GLOBAL_N(N) \
	template<typename RT GPP_COMMA_IF(N) GPP_REPEAT(N, GPP_COMMA_PARAM, typename PT) > \
	class GCallbackAgent_ ## N : public GCallbackBase<RT (*)(void * self GPP_COMMA_IF(N) GPP_REPEAT(N, CB_PARAM_TYPEVALUE, PT))> { \
	protected: \
		typedef GCallbackAgent_ ## N < RT GPP_REPEAT_TAIL_PARAMS(N, PT) > ThisType; \
		typedef GCallbackBase<RT (*)(void * self GPP_COMMA_IF(N) GPP_REPEAT(N, CB_PARAM_TYPEVALUE, PT))> super; \
		typedef typename super::BaseType BaseType; \
	protected: \
		typedef RT FunctionType(void * self GPP_COMMA_IF(N) GPP_REPEAT(N, CB_PARAM_TYPEVALUE, PT)); \
		typedef FunctionType * FunctionPointer; \
		CB_DEF_MEMBER(N) \
		CB_DEF_GLOBAL(N) \
		template <typename RR> int doInvoke(GPP_REPEAT(N, CB_PARAM_TYPEVALUE, PT) GPP_COMMA_IF(N) typename GEnableIfResult<IsSameType<RR, void> >::Result * = 0) const { if(this->getBase()) { ((FunctionPointer)(this->getBase()->getInvoke()))(this->getBase() GPP_COMMA_IF(N) GPP_REPEAT(N, CB_PARAM_PASSVALUE, PT)); } else { invokeEmptyCallback<int>(); } return 0; } \
		template <typename RR> RT doInvoke(GPP_REPEAT(N, CB_PARAM_TYPEVALUE, PT) GPP_COMMA_IF(N) typename GDisableIfResult<IsSameType<RR, void> >::Result * = 0) const { if(this->getBase()) { return ((FunctionPointer)(this->getBase()->getInvoke()))(this->getBase() GPP_COMMA_IF(N) GPP_REPEAT(N, CB_PARAM_PASSVALUE, PT)); } else { return invokeEmptyCallback<RT>(); } } \
		template<typename OT, typename FT>	void init(OT * instance, const FT & func) { \
			this->setBase(this->allocator.template newObject<typename GCallbackMember<OT, FT>::Type >(instance, func)); \
		} \
		template<typename Derived, typename FT> void init(const FT & func) { \
			this->setBase(callback_internal::ThisTypeTrait<BaseType, GCallbackGlobal, Derived, FT>::createBase(func, &this->allocator)); \
		} \
	public: \
		typename cpgf::callback_internal::ReturnType<RT>::Result invoke(GPP_REPEAT(N, CB_PARAM_TYPEVALUE, PT)) const { return doInvoke<RT>(GPP_REPEAT(N, CB_PARAM_PASSVALUE, PT)); } \
		typename cpgf::callback_internal::ReturnType<RT>::Result operator () (GPP_REPEAT(N, CB_PARAM_TYPEVALUE, PT)) const { return this->doInvoke<RT>(GPP_REPEAT(N, CB_PARAM_PASSVALUE, PT)); } \
	};

namespace cpgf {


namespace callback_internal {

template <typename To, typename From>
struct ForwardValue
{
	static typename AddReference<To>::Result forward(typename AddReference<From>::Result value) {
		return value;
	}
};

#if G_SUPPORT_RVALUE_REFERENCE
template <typename To, typename From>
struct ForwardValue <To &&, From>
{
	static To && forward(From & value) {
		return static_cast<To &&>(value);
	}
};
#endif


template <typename RT>
struct ReturnType
{
	typedef RT Result;
};

template <>
struct ReturnType <void>
{
	typedef int Result;
};

template <typename T>
inline T invokeEmptyCallback() {
	throw std:: runtime_error("Invoking uninitialized callback.");
}

template <bool tooBig>
struct CBInplaceMeasure;

template <>
struct CBInplaceMeasure<true> {
	template <typename T, typename PT1, typename PT2>
	static T * newObject(void * /*buffer*/, const PT1 & p1, const PT2 & p2) {
		return new T(p1, p2);
	}

	template <typename T, typename PT1>
	static T * newObject(void * /*buffer*/, const PT1 & p1) {
		return new T(p1);
	}

	template <typename T>
	static void deleteObject(T * p) {
		if(p) {
			p->deleteFunctor();
			delete p;
		}
	}
};

template <>
struct CBInplaceMeasure<false> {
	template <typename T, typename PT1, typename PT2>
	static T * newObject(void * buffer, const PT1 & p1, const PT2 & p2) {
		return new(buffer) T(p1, p2);
	}

	template <typename T, typename PT1>
	static T * newObject(void * buffer, const PT1 & p1) {
		return new(buffer) T(p1);
	}

	template <typename T>
	static void deleteObject(T * p) {
		p->deleteFunctor(); // p can never be NULL
	}
};

struct SizeOfCallbackBase {
	void * p;
};

struct SizeOfCallbackSon : public SizeOfCallbackBase {
	virtual void a(int) { (void)a(0); }
};

class CBAllocator
{
private:
	typedef CBAllocator ThisType;

	enum { BufferSize = sizeof(&SizeOfCallbackSon::a) + sizeof(SizeOfCallbackBase) };

public:
	template <typename T, typename PT1, typename PT2>
	T * newObject(const PT1 & p1, const PT2 & p2) {
		return CBInplaceMeasure<(sizeof(T) > BufferSize)>::template newObject<T>(this->buffer, p1, p2);
	}

	template <typename T, typename PT1>
	T * newObject(const PT1 & p1) {
		return CBInplaceMeasure<(sizeof(T) > BufferSize)>::template newObject<T>(this->buffer, p1);
	}

	template <typename T>
	void deleteObject(T * p) const {
		// We can't call CBInplaceMeasure::deleteObject since T here maybe a base class
		// and p points to a derived object.
		if(p) {
			p->deleteFunctor();

			if(const_cast<const char *>(reinterpret_cast<char *>(p)) != this->buffer) {
				delete p;
			}
		}
	}

	template <typename T>
	T * take(T * p, CBAllocator * allocator) const {
		if(const_cast<const char *>(reinterpret_cast<char *>(p)) == this->buffer) {
			T * instance = p->clone(allocator);
			p->~T();
			return instance;
		}
		else {
			return p;
		}
	}

private:
	void * base;
	char buffer[BufferSize];

private:
	template <typename InvokeType>
	friend class GCallbackBase;
};


template <typename BT, template<typename>class GT, typename MyCT, typename FT>
struct ThisTypeTrait {
	static BT * createBase(const FT & func, CBAllocator * allocator) {
		return allocator->newObject<typename GT<FT>::Type >(func);
	}
};

template <typename BT, template<typename>class GT, typename MyCT, typename FT>
struct ThisTypeTrait<BT, GT, MyCT, const FT> {
	static BT * createBase(const FT & func, CBAllocator * allocator) {
		return allocator->newObject<typename GT<const FT>::Type >(func);
	}
};

template <typename BT, template<typename>class GT, typename FT>
struct ThisTypeTrait<BT, GT, FT, FT> {
	static BT * createBase(const FT & func, CBAllocator * allocator) {
		return func.getBase() ? func.getBase()->clone(allocator) : NULL;
	}
};

template <typename BT, template<typename>class GT, typename MyCT>
struct ThisTypeTrait<BT, GT, MyCT, GReference<MyCT> > {
	static BT * createBase(const GReference<MyCT> & func, CBAllocator * allocator) {
		return ThisTypeTrait<BT, GT, MyCT, MyCT>::createBase(func, allocator);
	}
};

template <typename BT, template<typename>class GT, typename MyCT>
struct ThisTypeTrait<BT, GT, MyCT, GReference<const MyCT> > {
	static BT * createBase(const GReference<const MyCT> & func, CBAllocator * allocator) {
		return ThisTypeTrait<BT, GT, MyCT, const MyCT>::createBase(func, allocator);
	}
};

template <typename BT, template<typename>class GT, typename MyCT>
struct ThisTypeTrait<BT, GT, MyCT, const GReference<MyCT> > {
	static BT * createBase(const GReference<MyCT> & func, CBAllocator * allocator) {
		return ThisTypeTrait<BT, GT, MyCT, MyCT>::createBase(func, allocator);
	}
};

template <typename BT, template<typename>class GT, typename MyCT>
struct ThisTypeTrait<BT, GT, MyCT, const GReference<const MyCT> > {
	static BT * createBase(const GReference<const MyCT> & func, CBAllocator * allocator) {
		return ThisTypeTrait<BT, GT, MyCT, const MyCT>::createBase(func, allocator);
	}
};


template <typename InvokeType>
struct GCallbackVirtual
{
	void (*destructObject)(void * self);
	void * (*setOrGetObject)(const void * self, void * o, bool set);
	void * (*clone)(const void * self, CBAllocator * allocator);
	bool (*isSameCallback)(const void * self, const void * other);
	InvokeType invoke;
};

template <typename InvokeType>
class GCallbackFunctorBase
{
public:
	void deleteFunctor() {
		this->virtualFunctions->destructObject(this);
	}

	void * getObject() {
		return this->virtualFunctions->setOrGetObject(this, NULL, false);
	};

	const void * getObject() const {
		return this->virtualFunctions->setOrGetObject(this, NULL, false);
	};

	void setObject(void * instance) const {
		this->virtualFunctions->setOrGetObject(this, instance, true);
	}

	GCallbackFunctorBase * clone(CBAllocator * allocator) const {
		return static_cast<GCallbackFunctorBase *>(this->virtualFunctions->clone(this, allocator));
	}

	bool isSameCallback(const GCallbackFunctorBase * other) const {
		return this->virtualFunctions->isSameCallback(this, other);
	}

	InvokeType getInvoke() const {
		return this->virtualFunctions->invoke;
	}

protected:
	GCallbackVirtual<InvokeType> * virtualFunctions;
};

template <typename DerivedT, typename InnerOT, typename InnerFT, typename InvokeType>
class GCallbackMemberBase : public GCallbackFunctorBase <InvokeType> {
protected:
	typedef GCallbackMemberBase<DerivedT, InnerOT, InnerFT, InvokeType> ThisType;
	typedef GCallbackFunctorBase<InvokeType> BaseType;
	typedef DerivedT DerivedType;

	static void virtualDestructObject(void * self) {
		(void)self; // VC will issue unused parameter without this line?
		static_cast<ThisType *>(self)->~GCallbackMemberBase();
	}

	static void * virtualSetOrGetObject(const void * self, void * o, bool set) {
		if(set) {
			static_cast<const ThisType *>(self)->instance = reinterpret_cast<InnerOT *>(o);
			return NULL;
		}
		else {
			return reinterpret_cast<void *>(
				const_cast<char *>(
				reinterpret_cast<const volatile char *>(static_cast<const ThisType *>(self)->instance)));
		}
	}

	static void * virtualClone(const void * self, callback_internal::CBAllocator * allocator) {
		return allocator->newObject<DerivedType>(static_cast<const DerivedType *>(self)->instance, static_cast<const DerivedType *>(self)->func);
	}

	static bool virtualIsSameCallback(const void * self, const void * other) {
		return static_cast<const ThisType *>(self)->instance == static_cast<const ThisType *>(other)->instance && static_cast<const ThisType *>(self)->func == static_cast<const ThisType *>(other)->func;
	}

public:
	GCallbackMemberBase(InnerOT * instance, const InnerFT & func) : instance(instance), func(func) {
		static GCallbackVirtual<InvokeType> thisFunctions = {
			&virtualDestructObject, &virtualSetOrGetObject,
			&virtualClone, &virtualIsSameCallback, &DerivedType::virtualInvoke };

		this->virtualFunctions = &thisFunctions;
	}

protected:
	mutable InnerOT * instance;
	InnerFT func;
};

namespace _test_equal {

// Go here if T has no operator ==
// But if T has a private == or declared but undefined ==, compiler or linker will raise error.
template <typename T>
inline bool operator == (const T & a, const T & b) {
	return &a == &b;
}

template <typename T>
inline bool testEqual(const T & a, const T & b) {
	return *&a == *&b;
}

} // namespace _test_equal

template <typename DerivedT, typename InnerFT, typename InvokeType>
class GCallbackGlobalBase : public GCallbackFunctorBase <InvokeType> {
protected:
	typedef GCallbackGlobalBase<DerivedT, InnerFT, InvokeType> ThisType;
	typedef DerivedT DerivedType;
	typedef GCallbackFunctorBase<InvokeType> BaseType;

	static void virtualDestructObject(void * self) {
		(void)self; // 'self" is unused, weird
		static_cast<ThisType *>(self)->~GCallbackGlobalBase();
	}

	static void * virtualSetOrGetObject(const void * /*self*/, void * /*o*/, bool /*set*/) {
		return NULL;
	}

	static void * virtualClone(const void * self, callback_internal::CBAllocator * allocator) {
		return allocator->newObject<DerivedType>(static_cast<const DerivedType *>(self)->func);
	}

	static bool virtualIsSameCallback(const void * self, const void * other) {
		return _test_equal::testEqual<InnerFT>(static_cast<const ThisType *>(self)->func, static_cast<const ThisType *>(other)->func);
	}

public:
	GCallbackGlobalBase(const InnerFT & func) : func(func) {
		static GCallbackVirtual<InvokeType> thisFunctions = {
			&virtualDestructObject, &virtualSetOrGetObject,
			&virtualClone, &virtualIsSameCallback, &DerivedType::virtualInvoke };

		this->virtualFunctions = &thisFunctions;
	}

protected:
	InnerFT func;
};


template <typename InvokeType>
class GCallbackBase
{
public:
	typedef GCallbackFunctorBase<InvokeType> BaseType;

public:
	GCallbackBase() {
		this->allocator.base = NULL;
	}

    GCallbackBase(const GCallbackBase & other) {
		this->allocator.base = other.getBase() ? other.getBase()->clone(&this->allocator) : NULL;
	}

	~GCallbackBase() {
		this->allocator.deleteObject(this->getBase());
	}

    GCallbackBase & operator = (const GCallbackBase & other) {
		if(this != &other) {
			void * newBase = other.getBase() ? other.getBase()->clone(&this->allocator) : NULL;
			this->allocator.deleteObject(this->getBase());
			this->allocator.base = newBase;
		}
		return *this;
	}

	bool operator == (const GCallbackBase & other) const {
		return this->getBase() ? this->getBase()->isSameCallback(other.getBase()) : (! other.getBase());
	}

	bool operator != (const GCallbackBase & other) const {
		return ! this->operator == (other);
	}

	void takeOver(GCallbackBase & other) {
		this->allocator.deleteObject(this->getBase());
		this->setBase(other.allocator.take(other.getBase(), &this->allocator));
		other.setBase(NULL);
	}

public:
	BaseType * getBase() const {
		return reinterpret_cast<BaseType * >(this->allocator.base);
	}

	void setBase(BaseType * base) {
		this->allocator.base = base;
	}

#ifndef G_NO_MEMBER_TEMPLATE_FRIENDS
protected:
#else
public:
#endif
	CBAllocator allocator;

#ifndef G_NO_MEMBER_TEMPLATE_FRIENDS
private:
	template <typename CallbackType, template<typename> class ConnectionT, template<typename T, typename = std::allocator<T> > class ListType>
	friend class GCallbackListBase;

	template <typename CallbackType>
	friend class GCallbackConnection;

	template <typename BT, template<typename>class GT, typename MyCT, typename CT>
	friend struct ThisTypeTrait;
#endif
};


template <int arity, typename FT>
struct GCallbackFunctionTraits;

GPP_REPEAT_2(CB_MAX_ARITY, CB_DEF_AGENT_N, GPP_EMPTY)

GPP_REPEAT_2(CB_MAX_ARITY, CB_DEF_FUNC_TRAITS, GPP_EMPTY)


template <typename FT>
struct TypeMaybeFunctor
{
private:
	typedef typename RemoveConstVolatile<typename RemovePointer<typename RemoveConstVolatile<typename RemoveReference<FT>::Result>::Result>::Result>::Result BaseType;

public:
	G_STATIC_CONSTANT(bool,
		Result = (
			! IsFundamental<BaseType>::Result
			&& ! IsSameType<BaseType, void>::Result
			&& (IsFunction<BaseType>::Result
				|| IsClass<typename RemoveConstVolatile<typename RemoveReference<FT>::Result>::Result>::Result
                )
        )
	);
};


} // namespace callback_internal



} // namespace cpgf


#undef CB_DEF_AGENT_N
#undef CB_DEF_FUNC_TRAITS
#undef CB_DEF_GLOBAL
#undef CB_DEF_MEMBER
#undef CB_FUNC_TRAITS_ARGS
#undef CB_PARAM_TYPEVALUE


#if defined(_MSC_VER)
#pragma warning(pop)
#endif


#endif


 	tutorials.exe!cpgf::callback_internal::CBAllocator::newObject<cpgf::callback_internal::GCallbackMember_1<`anonymous namespace'::Point,void (__cdecl A0xe50ffc0c::Point::*)(int) __ptr64,void,int>,`anonymous namespace'::Point * __ptr64,void (__cdecl A0xe50ffc0c::Point::*)(int) __ptr64>(`anonymous-namespace'::Point * const & p1, void (int)* const & p2)  Line 202	C++
>	tutorials.exe!cpgf::callback_internal::GCallbackAgent_1<void,int>::init<`anonymous namespace'::Point,void (__cdecl A0xe50ffc0c::Point::*)(int) __ptr64>(`anonymous-namespace'::Point * instance, void (int)* const & func)  Line 516 + 0x3c bytes	C++
 	tutorials.exe!cpgf::GCallback<void __cdecl(int)>::GCallback<void __cdecl(int)><`anonymous namespace'::Point,void (__cdecl A0xe50ffc0c::Point::*)(int) __ptr64>(`anonymous-namespace'::Point * instance, void (int)* const & func)  Line 42 + 0x14 bytes	C++
 	tutorials.exe!cpgf::makeCallback<`anonymous namespace'::Point,void (__cdecl A0xe50ffc0c::Point::*)(int) __ptr64>(`anonymous-namespace'::Point * instance, void (int)* const & func)  Line 162 + 0x14 bytes	C++
 	tutorials.exe!cpgf::meta_internal::GMetaMethodCallbackMaker<`anonymous namespace'::Point,void (__cdecl A0xe50ffc0c::Point::*)(int) __ptr64,void>::make<void (__cdecl `anonymous namespace'::Point::*)(int) __ptr64>(void (int)* const & func)  Line 299 + 0x11 bytes	C++
 	tutorials.exe!cpgf::GMetaMethod::newMethod<`anonymous namespace'::Point,void (__cdecl A0xe50ffc0c::Point::*)(int) __ptr64,cpgf::MakePolicy<cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType> >(const char * name, void (int)* const & func, const cpgf::MakePolicy<cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType,cpgf::GNullType> & policy)  Line 26 + 0x2d bytes	C++
 	tutorials.exe!cpgf::GDefineMetaCommon<`anonymous namespace'::Point,cpgf::GDefineMetaClass<`anonymous namespace'::Point,void,void,void,void,void,void,void,void,void,void,void,void,void,void,void,void,void,void,void,void> >::_method<void (__cdecl `anonymous namespace'::Point::*)(int) __ptr64>(const char * name, void (int)* func)  Line 254 + 0x35 bytes	C++
 	tutorials.exe!`anonymous namespace'::reflectPoint<cpgf::GDefineMetaClass<`anonymous namespace'::Point,void,void,void,void,void,void,void,void,void,void,void,void,void,void,void,void,void,void,void,void> >(cpgf::GDefineMetaClass<`anonymous namespace'::Point,void,void,void,void,void,void,void,void,void,void,void,void,void,void,void,void,void,void,void,void> * define)  Line 67 + 0x20 bytes	C++
 	tutorials.exe!run_a01()  Line 108	C++
 	tutorials.exe!main()  Line 11	C++

How luabind deduce works

// Copyright Daniel Wallin 2008. Use, modification and distribution is
// subject to 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 !BOOST_PP_IS_ITERATING

# ifndef LUABIND_DEDUCE_SIGNATURE_080911_HPP
#  define LUABIND_DEDUCE_SIGNATURE_080911_HPP

#  include <luabind/detail/most_derived.hpp>

#  if LUABIND_MAX_ARITY <= 8
#   include <boost/mpl/vector/vector10.hpp>
#  else
#   include <boost/mpl/vector/vector50.hpp>
#  endif
#  include <boost/preprocessor/cat.hpp>
#  include <boost/preprocessor/iteration/iterate.hpp>
#  include <boost/preprocessor/repetition/enum_params.hpp>

namespace luabind { namespace detail {

namespace mpl = boost::mpl;

template <class R>
mpl::vector1<R> deduce_signature(R(*)(), ...)
{
    return mpl::vector1<R>();
}

template <class R, class T>
mpl::vector2<R,T&> deduce_signature(R(T::*)())
{
    return mpl::vector2<R,T&>();
}

template <class R, class T, class Wrapped>
mpl::vector2<R,typename most_derived<T,Wrapped>::type&>
deduce_signature(R(T::*)(), Wrapped*)
{
    return mpl::vector2<R,typename most_derived<T,Wrapped>::type&>();
}

template <class R, class T>
mpl::vector2<R,T const&> deduce_signature(R(T::*)() const)
{
    return mpl::vector2<R,T const&>();
}

template <class R, class T, class Wrapped>
mpl::vector2<R,typename most_derived<T,Wrapped>::type const&>
deduce_signature(R(T::*)() const, Wrapped*)
{
    return mpl::vector2<R,typename most_derived<T,Wrapped>::type const&>();
}

#  define BOOST_PP_ITERATION_PARAMS_1 \
    (3, (1, LUABIND_MAX_ARITY, <luabind/detail/deduce_signature.hpp>))
#  include BOOST_PP_ITERATE()

}} // namespace luabind::detail

# endif // LUABIND_DEDUCE_SIGNATURE_080911_HPP

#else // BOOST_PP_IS_ITERATING

# define N BOOST_PP_ITERATION()
# define NPLUS1 BOOST_PP_INC(N)

template <class R, BOOST_PP_ENUM_PARAMS(N,class A)>
BOOST_PP_CAT(mpl::vector,NPLUS1)<R, BOOST_PP_ENUM_PARAMS(N,A)>
deduce_signature(R(*)(BOOST_PP_ENUM_PARAMS(N,A)), ...)
{
    return BOOST_PP_CAT(mpl::vector,NPLUS1)<R,BOOST_PP_ENUM_PARAMS(N,A)>();
}

# define NPLUS2 BOOST_PP_INC(NPLUS1)

template <class R, class T, BOOST_PP_ENUM_PARAMS(N,class A)>
BOOST_PP_CAT(mpl::vector,NPLUS2)<R, T&, BOOST_PP_ENUM_PARAMS(N,A)>
deduce_signature(R(T::*)(BOOST_PP_ENUM_PARAMS(N,A)))
{
    return BOOST_PP_CAT(mpl::vector,NPLUS2)<R,T&,BOOST_PP_ENUM_PARAMS(N,A)>();
}

template <class R, class T, BOOST_PP_ENUM_PARAMS(N,class A), class Wrapped>
BOOST_PP_CAT(mpl::vector,NPLUS2)<
    R, typename most_derived<T,Wrapped>::type&, BOOST_PP_ENUM_PARAMS(N,A)
>
deduce_signature(R(T::*)(BOOST_PP_ENUM_PARAMS(N,A)), Wrapped*)
{
    return BOOST_PP_CAT(mpl::vector,NPLUS2)<
        R,typename most_derived<T,Wrapped>::type&,BOOST_PP_ENUM_PARAMS(N,A)>();
}

template <class R, class T, BOOST_PP_ENUM_PARAMS(N,class A)>
BOOST_PP_CAT(mpl::vector,NPLUS2)<R, T const&, BOOST_PP_ENUM_PARAMS(N,A)>
deduce_signature(R(T::*)(BOOST_PP_ENUM_PARAMS(N,A)) const)
{
    return BOOST_PP_CAT(mpl::vector,NPLUS2)<R,T const&,BOOST_PP_ENUM_PARAMS(N,A)>();
}

template <class R, class T, BOOST_PP_ENUM_PARAMS(N,class A), class Wrapped>
BOOST_PP_CAT(mpl::vector,NPLUS2)<
    R, typename most_derived<T,Wrapped>::type const&, BOOST_PP_ENUM_PARAMS(N,A)
>
deduce_signature(R(T::*)(BOOST_PP_ENUM_PARAMS(N,A)) const, Wrapped*)
{
    return BOOST_PP_CAT(mpl::vector,NPLUS2)<
        R,typename most_derived<T,Wrapped>::type const&,BOOST_PP_ENUM_PARAMS(N,A)>();
}

# undef NPLUS2
# undef NPLUS1
# undef N

#endif  // BOOST_PP_IS_ITERATING


posted on 2020-01-26 01:04  cutepig  阅读(182)  评论(0编辑  收藏  举报

导航