#ifndef __FB_H__
#define __FB_H__
  
#include <map>
#include <string>
 
 
  namespace FB
{
  
struct FunctionCall
{
  	virtual ~FunctionCall(void) throw() { }	
	virtual void execute(void* res, void* pars) const = 0;
  
};
  
struct MethodCall
{
  	virtual ~MethodCall(void) throw() { }	
	virtual void execute(void* instance, void* res, void* pars) const = 0;
  
};
  
template <typename Base>
class Registry
{
  	typedef std::map<std::string, Base*> RegistryMap;
  	RegistryMap m_map; 
  	Registry(void) { }
	Registry(const Registry&) { }
	Registry& operator=(const Registry&) { return *this; }
  public:
  	~Registry(void) throw()
	{
		for(RegistryMap::iterator iit = m_map.begin(); iit != m_map.end(); ++iit)
			delete (*iit).second;
	}
	
  	inline static Registry& getInstance(void)
	{
	static Registry s_registry;
	
		return s_registry;
	}
	
	
	void registrate(std::string name, Base* call)
	{
	RegistryMap::iterator iit = m_map.find(name);
	
		if(iit != m_map.end())
			throw "binding already registered";
  		m_map[name] = call;
	}
	
	
	Base* operator[](std::string name) const
	{
	RegistryMap::const_iterator iit = m_map.find(name);
	
		if(iit == m_map.end())
			return 0;
		else
			return (*iit).second;
	}
	
  };
  
template <typename R>
class Function0p: public FunctionCall
{
public:
	
	typedef R (*Type)();
		
private:
			
	Type m_ptr;
			
	Function0p(Type ptr): m_ptr(ptr) { }
	Function0p(const Function0p&) { }
	Function0p& operator=(const Function0p&) { return *this; }
	
public:
					
	void execute(void* res, void*) const
	{
		*(reinterpret_cast<R*>(res)) = (*m_ptr)();
	}
	
	
	static void registrate(std::string name, Type ptr)
	{
	Function0p* function = new Function0p(ptr);
		
		try
		{
			Registry<FunctionCall>::getInstance().registrate(name, function);
		}
		catch(...)
		{
			delete function;
			throw;
		}
	}
	
  };
  
template <>
class Function0p<void>: public FunctionCall
{
public:
	
	typedef void (*Type)();
		
private:
			
	Type m_ptr;
			
	Function0p(Type ptr): m_ptr(ptr) { }
	Function0p(const Function0p&) { }
	Function0p& operator=(const Function0p&) { return *this; }
	
public:
					
	void execute(void*, void*) const
	{
		(*m_ptr)();
	}
	
	
	static void registrate(std::string name, Type ptr)
	{
	Function0p* function = new Function0p(ptr);
		
		try
		{
			Registry<FunctionCall>::getInstance().registrate(name, function);
		}
		catch(...)
		{
			delete function;
			throw;
		}
	}
	
  };
  
template <typename R, typename P0>
class Function1p: public FunctionCall
{
public:
  	#pragma pack(push)
	#pragma pack(1)
	
	struct Pars
	{
	
		P0 p0;
		
	
	};
	
	#pragma pack(pop)
	
	typedef R (*Type)(P0);
		
private:
			
	Type m_ptr;
			
	Function1p(Type ptr): m_ptr(ptr) { }
	Function1p(const Function1p&) { }
	Function1p& operator=(const Function1p&) { return *this; }
	
public:
					
	void execute(void* res, void* pars) const
	{
	Pars& lean = *reinterpret_cast<Pars*>(pars);
	
		*(reinterpret_cast<R*>(res)) = (*m_ptr)(lean.p0);
	}
	
	
	static void registrate(std::string name, Type ptr)
	{
	Function1p* function = new Function1p(ptr);
		
		try
		{
			Registry<FunctionCall>::getInstance().registrate(name, function);
		}
		catch(...)
		{
			delete function;
			throw;
		}
	}
	
  };
  
template <typename P0>
class Function1p<void, P0>: public FunctionCall
{
public:
  	#pragma pack(push)
	#pragma pack(1)
	
	struct Pars
	{
	
		P0 p0;
		
	
	};
	
	#pragma pack(pop)
		
	typedef void (*Type)(P0);
		
private:
			
	Type m_ptr;
			
	Function1p(Type ptr): m_ptr(ptr) { }
	Function1p(const Function1p&) { }
	Function1p& operator=(const Function1p&) { return *this; }
	
public:
					
	void execute(void*, void* pars) const
	{
	Pars& lean = *reinterpret_cast<Pars*>(pars);
  		(*m_ptr)(lean.p0);
	}
	
	
	static void registrate(std::string name, Type ptr)
	{
	Function1p* function = new Function1p(ptr);
		
		try
		{
			Registry<FunctionCall>::getInstance().registrate(name, function);
		}
		catch(...)
		{
			delete function;
			throw;
		}
	}
	
  };
  
template <typename C, typename R>
class Method0p: public MethodCall
{
public:
	
	typedef R (C::*Type)();
		
private:
			
	Type m_ptr;
			
	Method0p(Type ptr): m_ptr(ptr) { }
	Method0p(const Method0p&) { }
	Method0p& operator=(const	Method0p&) { return *this; }
	
public:
					
	void execute(void* instance, void* res, void*) const
	{
		*(reinterpret_cast<R*>(res)) = (reinterpret_cast<C*>(instance)->*m_ptr)();
	}
	
	
	static void registrate(std::string name, Type ptr)
	{
	Method0p* method = new Method0p(ptr);
		
		try
		{
			Registry<MethodCall>::getInstance().registrate(name, method);
		}
		catch(...)
		{
			delete method;
			throw;
		}
	}
	
  };
  
template <typename C>
class Method0p<C, void>: public MethodCall
{
public:
	
	typedef void (C::*Type)();
		
private:
			
	Type m_ptr;
			
	Method0p(Type ptr): m_ptr(ptr) { }
	Method0p(const Method0p&) { }
	Method0p& operator=(const	Method0p&) { return *this; }
	
public:
					
	void execute(void* instance, void*, void*) const
	{
		(reinterpret_cast<C*>(instance)->*m_ptr)();
	}
	
	
	static void registrate(std::string name, Type ptr)
	{
	Method0p* method = new Method0p(ptr);
		
		try
		{
			Registry<MethodCall>::getInstance().registrate(name, method);
		}
		catch(...)
		{
			delete method;
			throw;
		}
	}
	
  };
  
template <typename C, typename R, typename P0>
class Method1p: public MethodCall
{
public:
  	#pragma pack(push)
	#pragma pack(1)
	
	struct Pars
	{
	
		P0 p0;
		
	
	};
	
	#pragma pack(pop)
	
	typedef R (C::*Type)(P0);
		
private:
			
	Type m_ptr;
			
	Method1p(Type ptr): m_ptr(ptr) { }
	Method1p(const Method1p&) { }
	Method1p& operator=(const	Method1p&) { return *this; }
	
public:
					
	void execute(void* instance, void* res, void*) const
	{
	Pars& lean = *reinterpret_cast<Pars*>(pars);
	
		*(reinterpret_cast<R*>(res)) = (reinterpret_cast<C*>(instance)->*m_ptr)(lean.p0);
	}
	
	
	static void registrate(std::string name, Type ptr)
	{
	Method1p* method = new Method1p(ptr);
		
		try
		{
			Registry<MethodCall>::getInstance().registrate(name, method);
		}
		catch(...)
		{
			delete method;
			throw;
		}
	}
	
  };
  
template <typename C, typename P0>
class Method1p<C, void, P0>: public MethodCall
{
public:
  	#pragma pack(push)
	#pragma pack(1)
	
	struct Pars
	{
	
		P0 p0;
		
	
	};
	
	#pragma pack(pop)
	
	typedef void (C::*Type)(P0);
		
private:
			
	Type m_ptr;
			
	Method1p(Type ptr): m_ptr(ptr) { }
	Method1p(const Method1p&) { }
	Method1p& operator=(const	Method1p&) { return *this; }
	
public:
					
	void execute(void* instance, void*, void* pars) const
	{
	Pars& lean = *reinterpret_cast<Pars*>(pars);	
  		(reinterpret_cast<C*>(instance)->*m_ptr)(lean.p0);
	}
	
	
	static void registrate(std::string name, Type ptr)
	{
	Method1p* method = new Method1p(ptr);
		
		try
		{
			Registry<MethodCall>::getInstance().registrate(name, method);
		}
		catch(...)
		{
			delete method;
			throw;
		}
	}
	
  };
  
template <typename R>
void registrateFunction(std::string name, R (*ptr)())
{
	Function0p<R>::registrate(name, ptr);
}
  
template <typename C, typename R>
void registrateMethod(std::string name, R (C::*ptr)())
{
	Method0p<C, R>::registrate(name, ptr);
}
  
struct FunctionRegistration
{
  	template <typename R>
	inline FunctionRegistration(std::string name, R (*ptr)())
	{
		Function0p<R>::registrate(name, ptr);
	}
	
	
	template <typename R, typename P0>
	inline FunctionRegistration(std::string name, R (*ptr)(P0))
	{
		Function1p<R, P0>::registrate(name, ptr);
	}
	
	
};
  
struct MethodRegistration
{
  	template <typename C, typename R>
	inline MethodRegistration(std::string name, R (C::*ptr)())
	{
		Method0p<C, R>::registrate(name, ptr);
	}
	
	
	template <typename C, typename R, typename P0>
	inline MethodRegistration(std::string name, R (C::*ptr)(P0))
	{
		Method1p<C, R, P0>::registrate(name, ptr);
	}
	
	
};
  
}
  
#define __FB_REGISTRATE_FUNCTION(function_name) \
static struct RegistrateFunction_##function_name \
{ \
\
	inline RegistrateFunction_##function_name() {	static FB::FunctionRegistration s_functionRegistration(#function_name, #function_name); } \
\
\
} registrateFunction_##function_name;
  
#define __FB_REGISTRATE_METHOD(class_name, method_name) \
static struct RegistrateMethod_##class_name_##method_name \
{ \
\
	inline RegistrateMethod_##class_name_##method_name () { static FB::MethodRegistration s_methodRegistration(#class_name "_" #method_name, #class_name::##method_name); } \
\
\
} registrateMethod_##class_name_##method_name;
  
#define __FB_CALL_FUNCTION(function_name, res, pars) FB::Registry<FB::FunctionCall>::getInstance()[#function_name]->execute(res, pars)
#define __FB_CALL_METHOD(class_name, method_name, instance, res, pars) FB::Registry<FB::MethodCall>::getInstance()[#class_name "_" #method_name]->execute(instance, res, pars);
 
 
  #endif
   |